Skip to content

Commit

Permalink
Fix: Typed arrays are no longer going to return Array
Browse files Browse the repository at this point in the history
  • Loading branch information
abumq committed Jul 25, 2023
1 parent 7978b8c commit 89e3000
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 84 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
## Unreleased
- Fix: Typed arrays are no longer going to return `Array`

## 1.0.7
- Merged `jjson` and `json` functions
Expand Down
14 changes: 14 additions & 0 deletions examples/typed-arrays.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const { json } = require('../src');

(async () => {
console.clear()
const uint8ArrayItem = new Uint8Array([21, 31])
const resultObj = await json({
uint8ArrayItem,
})
const resultArr = await json(
uint8ArrayItem
)
console.log(resultArr)
console.log(resultObj)
})()
130 changes: 48 additions & 82 deletions src/json.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ const NO_RESOLUTION_CLASS_LIST = [
];

let SPREAD_COUNTER = 0;
const SPREAD_KEY_NAME = '__airsync_special_key';
const SPREAD_KEY_NAME = '__airsync_spread_key';

// if [].from() is available use that otherwise use constructor
const createArrInstance = (ArrayInstanceType, items) =>
typeof ArrayInstanceType.from === 'function' ?
ArrayInstanceType.from(items) : new ArrayInstanceType(...items);
typeof ArrayInstanceType.from === 'function' ? ArrayInstanceType.from(items)
: new ArrayInstanceType(...items);

// do not use Array.isArray as it won't resolve typed arrays
const isArrayType = o => o && !!ARRAY_TYPES[o.constructor.name];
Expand All @@ -65,36 +65,32 @@ const createArray = (arr, depth, currentKey, opts = {}) => {
}

const ArrayInstanceType = ARRAY_TYPES[arr.constructor.name] || Array;
console.log('the array type', opts.arr)

if (opts.name && typeof opts.startTime === 'function') {
opts.startTime(opts.name, opts.description);
}

// Something to note here
// Promise.all resolves it to Array instead of typed array
// so we do not have a way to resolve correct array type at
// top level
return Promise.all(createArrInstance(ArrayInstanceType, arr.map(curr => {
if (isArrayType(curr)) {
return createArray(curr, depth + 1, currentKey);
}
return Promise.all(arr.map((curr) => {
if (isArrayType(curr)) {
return createArray(curr, depth + 1, currentKey);
}

const result = json(curr, opts);
if (opts.name && typeof opts.endTime === 'function') {
opts.endTime(opts.name);
}
return result;
})))
.catch(error => {
if (opts.name && typeof opts.endTime === 'function') {
opts.endTime(opts.name);
}
if (error instanceof Error) {
throw error;
}
throw new Error(error);
})
const result = json(curr, opts);
if (opts.name && typeof opts.endTime === 'function') {
opts.endTime(opts.name);
}
return result;
}))
.then(items => createArrInstance(ArrayInstanceType, items))
.catch(error => {
if (opts.name && typeof opts.endTime === 'function') {
opts.endTime(opts.name);
}
if (error instanceof Error) {
throw error;
}
throw new Error(error);
})
};

const createObject = (obj, depth, currentKey, opts = {}) => {
Expand All @@ -116,13 +112,6 @@ const createObject = (obj, depth, currentKey, opts = {}) => {
const constructorName = obj.constructor.name;
if (NO_RESOLUTION_CLASS_LIST.some(f => f === constructorName)) {
if (TYPED_ARRAY_NAMES.some(f => f === constructorName)) {
const result = createArray(obj, 1, currentKey, /*opts, */{
arr: currentKey === 'uint8ArrayItem' ? constructorName : undefined,
});
if (currentKey === 'uint8ArrayItem')
console.log('constructorName', constructorName, obj)

return result;
return createArray(obj, 1, currentKey, opts);
}
return obj;
Expand All @@ -134,55 +123,32 @@ const createObject = (obj, depth, currentKey, opts = {}) => {
if (opts.name && typeof opts.startTime === 'function') {
opts.startTime(opts.name, opts.description);
}
return Promise.all(
keys.map(key => createObject(obj[key], depth + 1, key))
)
.then(async values => {
if (opts.name && typeof opts.startTime === 'function') {
opts.endTime(opts.name);
}
let finalResult = {};
let idx = 0;
for (let key of keys) {
const finalValue = await createObject(values[idx], 0, key)
if (key.indexOf(SPREAD_KEY_NAME) === 0) {
//Object.assign(finalResult, finalValue);
finalResult = {
...finalResult,
...finalValue,
};
} else {
//Object.assign(finalResult, { [key] : finalValue });
finalResult = {
...finalResult,
[key]: finalValue,
};
return Promise.all(keys.map(key => createObject(obj[key], depth + 1, key)))
.then(async (values) => {
if (opts.name && typeof opts.startTime === 'function') {
opts.endTime(opts.name);
}
idx++;
}
return finalResult;
return keys.reduce((accum, key, idx) => {
if (key.indexOf(SPREAD_KEY_NAME) === 0) {
return {
...accum,
...values[idx],
};
};
return {
...accum,
[key]: values[idx],
};
}, {})
})
.catch(error => {
if (opts.name && typeof opts.endTime === 'function') {
opts.endTime(opts.name);
}
if (error instanceof Error) {
throw error;
}
throw new Error(error);
})
const finalResult = {};
for (let keyIdx in keys) {
const key = keys[keyIdx];
const finalValue = await createObject(values[keyIdx], 0, key)
if (key.indexOf(SPREAD_KEY_NAME) === 0) {
Object.assign(finalResult, finalValue);
} else {
Object.assign(finalResult, { [key] : finalValue });
}
}
return finalResult;
})
.catch(error => {
if (opts.name && typeof opts.endTime === 'function') {
opts.endTime(opts.name);
}
if (error instanceof Error) {
throw error;
}
throw new Error(error);
})
}
return obj;
};
Expand Down
6 changes: 4 additions & 2 deletions tests/simple-values.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ describe('Simple values are resolved correctly', () => {
describe('Simple Object & Array', async () => {
const theDate = new Date();

const getTypedNumb = async () => Uint8Array.from([33])[0];

const result = await airsync.json({
arr: [1,2,3],
arr: [1,2,3,getTypedNumb()],
arr2: new Array(1,2,3),
obj: new Object({ 1: 'one' }),
date: theDate,
Expand All @@ -40,7 +42,7 @@ describe('Simple values are resolved correctly', () => {
});

it('array is resolved correctly', () => {
assert.deepEqual(result.arr, [1,2,3]);
assert.deepEqual(result.arr, [1,2,3,33]);
});

it('array (typed) is resolved correctly', () => {
Expand Down

0 comments on commit 89e3000

Please sign in to comment.