Skip to content

Commit 3cf6f7b

Browse files
committed
feat: improve serialize-javascript
1 parent 7f87c17 commit 3cf6f7b

File tree

1 file changed

+39
-9
lines changed

1 file changed

+39
-9
lines changed

test/utils/serialize-javascript.ts

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ import { version } from './version';
3333
* 4. Supports serialization of Symbol keys and values.
3434
* 5. Supports serialization of custom property descriptors.
3535
* 6. Supports serialization of non-enumerable properties.
36+
* 7. Supports toJSON and fromJSON methods for custom serialization and deserialization.
37+
* 8. Supports raw JSON objects (via JSON.rawJSON() method).
3638
*/
3739

3840
const DefaultStartTag = '$SJS$_';
@@ -42,6 +44,19 @@ const SymbolKeyRegExps: [RegExp, RegExp] = [/\[Symbol\.\w+\]/, /\[Symbol\.for\([
4244
const SymbolKeyPrefixRegExp = /\[/;
4345
const SymbolKeySuffixRegExp = /\]/;
4446
const wellKnownSymbols = getWellKnownSymbols();
47+
const TypedArrays = [
48+
Int8Array,
49+
Uint8Array,
50+
Uint8ClampedArray,
51+
Int16Array,
52+
Uint16Array,
53+
Int32Array,
54+
Uint32Array,
55+
Float32Array,
56+
Float64Array,
57+
BigInt64Array,
58+
BigUint64Array,
59+
];
4560

4661
/**
4762
* Serialize JavaScript object to string, support functions. Should including all fields of both
@@ -185,10 +200,11 @@ function expandPrototypeChainRecursively(
185200
api.fromJSON = stringToBase64(serializeFunction(source.fromJSON.toString())!);
186201
}
187202
apis.push(api);
188-
// todo: 1. 序列化result 2. 解析apis
189203
result = source.toJSON();
190-
}
191-
if (Array.isArray(source)) {
204+
if (result == null) {
205+
return result;
206+
}
207+
} else if (Array.isArray(source)) {
192208
result = [...source];
193209
} else if (source instanceof Map) {
194210
result = Array.from(source.keys()).reduce(
@@ -206,6 +222,9 @@ function expandPrototypeChainRecursively(
206222
result = {};
207223
} else if (source instanceof WeakSet) {
208224
result = [];
225+
} else if (TypedArrays.some((Type) => source instanceof Type)) {
226+
result = Array.from(source);
227+
types.push({ path: paths, type: source.constructor.name });
209228
} else if (source instanceof ArrayBuffer) {
210229
result = source.slice(0);
211230
types.push({ path: paths, type: 'ArrayBuffer' });
@@ -336,7 +355,7 @@ function expandPrototypeChainRecursively(
336355
if (hasExtra) {
337356
patches.push({
338357
path: paths,
339-
info: patchValue,
358+
patch: patchValue,
340359
});
341360
}
342361
}
@@ -602,9 +621,13 @@ function generateDeserializationCode(result: SerializedResult, options: Internal
602621
function restoreOriginalTypes(root, types = []) {
603622
// Apply types to the deserialized object
604623
types.forEach(({ path, type, metadata }) => {
624+
// todo: path = [] 时,下面的逻辑会有问题
625+
// todo: 测试支持BigInt64Array的序列化
626+
// todo: 支持URL、URLSearchParams、支持Buffer
605627
const keyName = getLastKey(path);
606628
const parent = getParent(root, path);
607629
const value = get(root, path);
630+
console.log('Restoring type:', type, 'at', path, 'with value:', value, parent[keyName] === value);
608631
if (value && parent && parent[keyName] === value) {
609632
if (type === 'Map' && typeof value === 'object') {
610633
// Convert array to Map
@@ -618,7 +641,14 @@ function generateDeserializationCode(result: SerializedResult, options: Internal
618641
// Convert array to Set
619642
const set = new Set(value);
620643
parent[keyName] = set;
621-
} else if (type === 'ArrayBuffer' && typeof ArrayBuffer === 'function' && typeof Uint8Array === 'function' && Array.isArray(value)) {
644+
}
645+
else if ([${TypedArrays.map((t) => `'${t.name}'`).join(', ')}].includes(type) &&
646+
typeof globalThis[type] === 'function' &&
647+
Array.isArray(value)) {
648+
console.log('Creating TypedArray:', type, value);
649+
parent[keyName] = new globalThis[type](value);
650+
}
651+
else if (type === 'ArrayBuffer' && typeof ArrayBuffer === 'function' && typeof Uint8Array === 'function' && Array.isArray(value)) {
622652
const buffer = new ArrayBuffer(value.length);
623653
const view = new Uint8Array(buffer);
624654
value.forEach((item, index) => {
@@ -643,13 +673,13 @@ function generateDeserializationCode(result: SerializedResult, options: Internal
643673
644674
function restorePatches(root, patches = []) {
645675
// Apply patches to the deserialized object
646-
patches.forEach(({ path, info }) => {
676+
patches.forEach(({ path, patch }) => {
647677
const sourceObj = get(root, path);
648678
if (sourceObj) {
649679
const sourceKeys = getFullKeys(sourceObj);
650-
getFullKeys(info).forEach((key) => {
680+
getFullKeys(patch).forEach((key) => {
651681
if (!sourceKeys.includes(key) || sourceObj[key] == null) {
652-
sourceObj[key] = info[key];
682+
sourceObj[key] = patch[key];
653683
}
654684
});
655685
}
@@ -890,7 +920,7 @@ type PathType = string | number | symbol;
890920
/** Information about a patch applied to an Array or function. */
891921
interface PatchInfo {
892922
path: PathType[];
893-
info: any;
923+
patch: any;
894924
}
895925
interface DescriptorInfo {
896926
ownerPath: PathType[];

0 commit comments

Comments
 (0)