seroval 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -9
- package/dist/cjs/development/index.cjs +145 -139
- package/dist/cjs/development/index.cjs.map +2 -2
- package/dist/cjs/production/index.cjs +3 -3
- package/dist/esm/development/index.mjs +145 -139
- package/dist/esm/development/index.mjs.map +2 -2
- package/dist/esm/production/index.mjs +3 -3
- package/dist/types/context.d.ts +2 -4
- package/dist/types/tree/types.d.ts +2 -2
- package/package.json +2 -2
- package/src/context.ts +35 -45
- package/src/tree/async.ts +21 -19
- package/src/tree/deserialize.ts +1 -1
- package/src/tree/primitives.ts +21 -21
- package/src/tree/serialize.ts +65 -65
- package/src/tree/sync.ts +20 -18
- package/src/tree/types.ts +3 -3
package/src/tree/serialize.ts
CHANGED
|
@@ -48,35 +48,55 @@ function mergeAssignments(assignments: Assignment[]) {
|
|
|
48
48
|
for (let i = 1, len = assignments.length; i < len; i++) {
|
|
49
49
|
item = assignments[i];
|
|
50
50
|
if (item.t === prev.t) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
51
|
+
switch (item.t) {
|
|
52
|
+
case 'index':
|
|
53
|
+
if (item.v === prev.v) {
|
|
54
|
+
// Merge if the right-hand value is the same
|
|
55
|
+
// saves at least 2 chars
|
|
56
|
+
current = {
|
|
57
|
+
t: 'index',
|
|
58
|
+
s: item.s,
|
|
59
|
+
k: undefined,
|
|
60
|
+
v: getAssignmentExpression(current),
|
|
61
|
+
};
|
|
62
|
+
} else {
|
|
63
|
+
// Different assignment, push current
|
|
64
|
+
newAssignments.push(current);
|
|
65
|
+
current = item;
|
|
66
|
+
}
|
|
67
|
+
break;
|
|
68
|
+
case 'map':
|
|
69
|
+
if (item.s === prev.s) {
|
|
70
|
+
// Maps has chaining methods, merge if source is the same
|
|
71
|
+
current = {
|
|
72
|
+
t: 'map',
|
|
73
|
+
s: getAssignmentExpression(current),
|
|
74
|
+
k: item.k,
|
|
75
|
+
v: item.v,
|
|
76
|
+
};
|
|
77
|
+
} else {
|
|
78
|
+
// Different assignment, push current
|
|
79
|
+
newAssignments.push(current);
|
|
80
|
+
current = item;
|
|
81
|
+
}
|
|
82
|
+
break;
|
|
83
|
+
case 'set':
|
|
84
|
+
if (item.s === prev.s) {
|
|
85
|
+
// Sets has chaining methods too
|
|
86
|
+
current = {
|
|
87
|
+
t: 'set',
|
|
88
|
+
s: getAssignmentExpression(current),
|
|
89
|
+
k: undefined,
|
|
90
|
+
v: item.v,
|
|
91
|
+
};
|
|
92
|
+
} else {
|
|
93
|
+
// Different assignment, push current
|
|
94
|
+
newAssignments.push(current);
|
|
95
|
+
current = item;
|
|
96
|
+
}
|
|
97
|
+
break;
|
|
98
|
+
default:
|
|
99
|
+
break;
|
|
80
100
|
}
|
|
81
101
|
} else {
|
|
82
102
|
newAssignments.push(current);
|
|
@@ -161,7 +181,7 @@ function createArrayAssign(
|
|
|
161
181
|
value: string,
|
|
162
182
|
) {
|
|
163
183
|
markRef(ctx, ref);
|
|
164
|
-
createAssignment(ctx, getRefParam(ctx, ref) + '[' + index
|
|
184
|
+
createAssignment(ctx, getRefParam(ctx, ref) + '[' + index + ']', value);
|
|
165
185
|
}
|
|
166
186
|
|
|
167
187
|
function createObjectAssign(
|
|
@@ -223,10 +243,7 @@ function serializeNodeList(
|
|
|
223
243
|
isHoley = true;
|
|
224
244
|
}
|
|
225
245
|
}
|
|
226
|
-
|
|
227
|
-
values += ',';
|
|
228
|
-
}
|
|
229
|
-
return '[' + values + ']';
|
|
246
|
+
return '[' + values + (isHoley ? ',]' : ']');
|
|
230
247
|
}
|
|
231
248
|
|
|
232
249
|
function serializeArray(
|
|
@@ -270,11 +287,9 @@ function serializeProperties(
|
|
|
270
287
|
createArrayAssign(ctx, sourceID, isIdentifier ? key : ('"' + quote(key) + '"'), refParam);
|
|
271
288
|
}
|
|
272
289
|
} else {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
result += isIdentifier ? key : ('"' + quote(key) + '"');
|
|
277
|
-
result += ':' + serializeTree(ctx, val);
|
|
290
|
+
result += (hasPrev ? ',' : '')
|
|
291
|
+
+ (isIdentifier ? key : ('"' + quote(key) + '"'))
|
|
292
|
+
+ ':' + serializeTree(ctx, val);
|
|
278
293
|
hasPrev = true;
|
|
279
294
|
}
|
|
280
295
|
}
|
|
@@ -344,8 +359,7 @@ function serializeDictionary(
|
|
|
344
359
|
markRef(ctx, i);
|
|
345
360
|
const assignments = serializeAssignments(ctx, i, d);
|
|
346
361
|
if (assignments) {
|
|
347
|
-
|
|
348
|
-
return '(' + assignRef(ctx, i, init) + ',' + assignments + ref + ')';
|
|
362
|
+
return '(' + assignRef(ctx, i, init) + ',' + assignments + getRefParam(ctx, i) + ')';
|
|
349
363
|
}
|
|
350
364
|
}
|
|
351
365
|
}
|
|
@@ -383,10 +397,7 @@ function serializeSet(
|
|
|
383
397
|
createSetAdd(ctx, node.i, getRefParam(ctx, item.i));
|
|
384
398
|
} else {
|
|
385
399
|
// Push directly
|
|
386
|
-
|
|
387
|
-
result += ',';
|
|
388
|
-
}
|
|
389
|
-
result += serializeTree(ctx, item);
|
|
400
|
+
result += (hasPrev ? ',' : '') + serializeTree(ctx, item);
|
|
390
401
|
hasPrev = true;
|
|
391
402
|
}
|
|
392
403
|
}
|
|
@@ -446,10 +457,7 @@ function serializeMap(
|
|
|
446
457
|
createMapSet(ctx, node.i, serializeTree(ctx, key), valueRef);
|
|
447
458
|
ctx.stack = parent;
|
|
448
459
|
} else {
|
|
449
|
-
|
|
450
|
-
result += ',';
|
|
451
|
-
}
|
|
452
|
-
result += '[' + serializeTree(ctx, key) + ',' + serializeTree(ctx, val) + ']';
|
|
460
|
+
result += (hasPrev ? ',[' : '[') + serializeTree(ctx, key) + ',' + serializeTree(ctx, val) + ']';
|
|
453
461
|
hasPrev = true;
|
|
454
462
|
}
|
|
455
463
|
}
|
|
@@ -492,12 +500,12 @@ function serializePromise(
|
|
|
492
500
|
) {
|
|
493
501
|
let serialized: string;
|
|
494
502
|
// Check if resolved value is a parent expression
|
|
495
|
-
if (isReferenceInStack(ctx, node.
|
|
503
|
+
if (isReferenceInStack(ctx, node.f)) {
|
|
496
504
|
// A Promise trick, reference the value
|
|
497
505
|
// inside the `then` expression so that
|
|
498
506
|
// the Promise evaluates after the parent
|
|
499
507
|
// has initialized
|
|
500
|
-
const ref = getRefParam(ctx, node.
|
|
508
|
+
const ref = getRefParam(ctx, node.f.i);
|
|
501
509
|
if (ctx.features & Feature.ArrowFunction) {
|
|
502
510
|
serialized = 'Promise.resolve().then(()=>' + ref + ')';
|
|
503
511
|
} else {
|
|
@@ -505,7 +513,7 @@ function serializePromise(
|
|
|
505
513
|
}
|
|
506
514
|
} else {
|
|
507
515
|
ctx.stack.push(node.i);
|
|
508
|
-
const result = serializeTree(ctx, node.
|
|
516
|
+
const result = serializeTree(ctx, node.f);
|
|
509
517
|
ctx.stack.pop();
|
|
510
518
|
// just inline the value/reference here
|
|
511
519
|
serialized = 'Promise.resolve(' + result + ')';
|
|
@@ -518,19 +526,11 @@ function serializeTypedArray(
|
|
|
518
526
|
node: SerovalTypedArrayNode | SerovalBigIntTypedArrayNode,
|
|
519
527
|
) {
|
|
520
528
|
let result = '';
|
|
529
|
+
const isBigInt = node.t === SerovalNodeType.BigIntTypedArray;
|
|
521
530
|
for (let i = 0, len = node.s.length; i < len; i++) {
|
|
522
|
-
|
|
523
|
-
result += ',';
|
|
524
|
-
}
|
|
525
|
-
result += node.s[i];
|
|
526
|
-
if (node.t === SerovalNodeType.BigIntTypedArray) {
|
|
527
|
-
result += 'n';
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
let args = '[' + result + ']';
|
|
531
|
-
if (node.l !== 0) {
|
|
532
|
-
args += ',' + node.l.toString();
|
|
531
|
+
result += (i !== 0 ? ',' : '') + node.s[i] + (isBigInt ? 'n' : '');
|
|
533
532
|
}
|
|
533
|
+
const args = '[' + result + ']' + (node.l !== 0 ? (',' + node.l) : '');
|
|
534
534
|
return assignRef(ctx, node.i, 'new ' + node.c + '(' + args + ')');
|
|
535
535
|
}
|
|
536
536
|
|
|
@@ -564,13 +564,13 @@ export default function serializeTree(
|
|
|
564
564
|
): string {
|
|
565
565
|
switch (node.t) {
|
|
566
566
|
case SerovalNodeType.Number:
|
|
567
|
-
return
|
|
567
|
+
return '' + node.s;
|
|
568
568
|
case SerovalNodeType.String:
|
|
569
569
|
return '"' + node.s + '"';
|
|
570
570
|
case SerovalNodeType.Boolean:
|
|
571
571
|
return node.s ? '!0' : '!1';
|
|
572
572
|
case SerovalNodeType.Undefined:
|
|
573
|
-
return '
|
|
573
|
+
return 'void 0';
|
|
574
574
|
case SerovalNodeType.Null:
|
|
575
575
|
return 'null';
|
|
576
576
|
case SerovalNodeType.NegativeZero:
|
package/src/tree/sync.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
2
2
|
import assert from '../assert';
|
|
3
3
|
import { Feature } from '../compat';
|
|
4
|
-
import { createRef, ParserContext } from '../context';
|
|
4
|
+
import { createRef, getRootID, ParserContext } from '../context';
|
|
5
5
|
import { BigIntTypedArrayValue, ServerValue, TypedArrayValue } from '../types';
|
|
6
6
|
import {
|
|
7
7
|
createBigIntNode,
|
|
@@ -82,7 +82,7 @@ function generateArrayNode(
|
|
|
82
82
|
m: undefined,
|
|
83
83
|
d: undefined,
|
|
84
84
|
a: generateNodeList(ctx, current),
|
|
85
|
-
|
|
85
|
+
f: undefined,
|
|
86
86
|
};
|
|
87
87
|
}
|
|
88
88
|
|
|
@@ -124,7 +124,7 @@ function generateMapNode(
|
|
|
124
124
|
m: undefined,
|
|
125
125
|
d: { k: keyNodes, v: valueNodes, s: len },
|
|
126
126
|
a: undefined,
|
|
127
|
-
|
|
127
|
+
f: undefined,
|
|
128
128
|
};
|
|
129
129
|
}
|
|
130
130
|
|
|
@@ -160,7 +160,7 @@ function generateSetNode(
|
|
|
160
160
|
m: undefined,
|
|
161
161
|
d: undefined,
|
|
162
162
|
a: nodes,
|
|
163
|
-
|
|
163
|
+
f: undefined,
|
|
164
164
|
};
|
|
165
165
|
}
|
|
166
166
|
|
|
@@ -220,7 +220,7 @@ function generateIterableNode(
|
|
|
220
220
|
? generateProperties(ctx, options as Record<string, ServerValue>)
|
|
221
221
|
: undefined,
|
|
222
222
|
a: generateNodeList(ctx, array),
|
|
223
|
-
|
|
223
|
+
f: undefined,
|
|
224
224
|
};
|
|
225
225
|
}
|
|
226
226
|
|
|
@@ -242,7 +242,7 @@ function generateObjectNode(
|
|
|
242
242
|
m: undefined,
|
|
243
243
|
d: generateProperties(ctx, current),
|
|
244
244
|
a: undefined,
|
|
245
|
-
|
|
245
|
+
f: undefined,
|
|
246
246
|
};
|
|
247
247
|
}
|
|
248
248
|
|
|
@@ -264,7 +264,7 @@ function generateAggregateErrorNode(
|
|
|
264
264
|
m: current.message,
|
|
265
265
|
d: optionsNode,
|
|
266
266
|
a: generateNodeList(ctx, current.errors as ServerValue[]),
|
|
267
|
-
|
|
267
|
+
f: undefined,
|
|
268
268
|
};
|
|
269
269
|
}
|
|
270
270
|
|
|
@@ -286,7 +286,7 @@ function generateErrorNode(
|
|
|
286
286
|
m: current.message,
|
|
287
287
|
d: optionsNode,
|
|
288
288
|
a: undefined,
|
|
289
|
-
|
|
289
|
+
f: undefined,
|
|
290
290
|
};
|
|
291
291
|
}
|
|
292
292
|
|
|
@@ -302,6 +302,11 @@ function parse(
|
|
|
302
302
|
case 'string':
|
|
303
303
|
return createStringNode(current);
|
|
304
304
|
case 'number':
|
|
305
|
+
switch (current) {
|
|
306
|
+
case Infinity: return INFINITY_NODE;
|
|
307
|
+
case -Infinity: return NEG_INFINITY_NODE;
|
|
308
|
+
default: break;
|
|
309
|
+
}
|
|
305
310
|
// eslint-disable-next-line no-self-compare
|
|
306
311
|
if (current !== current) {
|
|
307
312
|
return NAN_NODE;
|
|
@@ -309,12 +314,6 @@ function parse(
|
|
|
309
314
|
if (Object.is(current, -0)) {
|
|
310
315
|
return NEG_ZERO_NODE;
|
|
311
316
|
}
|
|
312
|
-
if (Object.is(current, Infinity)) {
|
|
313
|
-
return INFINITY_NODE;
|
|
314
|
-
}
|
|
315
|
-
if (Object.is(current, -Infinity)) {
|
|
316
|
-
return NEG_INFINITY_NODE;
|
|
317
|
-
}
|
|
318
317
|
return createNumberNode(current);
|
|
319
318
|
case 'bigint':
|
|
320
319
|
return createBigIntNode(ctx, current);
|
|
@@ -324,7 +323,7 @@ function parse(
|
|
|
324
323
|
}
|
|
325
324
|
// Non-primitive values needs a reference ID
|
|
326
325
|
// mostly because the values themselves are stateful
|
|
327
|
-
const id = createRef(ctx, current
|
|
326
|
+
const id = createRef(ctx, current);
|
|
328
327
|
if (ctx.markedRefs.has(id)) {
|
|
329
328
|
return createReferenceNode(id);
|
|
330
329
|
}
|
|
@@ -373,8 +372,11 @@ function parse(
|
|
|
373
372
|
default:
|
|
374
373
|
break;
|
|
375
374
|
}
|
|
376
|
-
if (current instanceof AggregateError
|
|
377
|
-
|
|
375
|
+
if (current instanceof AggregateError) {
|
|
376
|
+
if (ctx.features & Feature.AggregateError) {
|
|
377
|
+
return generateAggregateErrorNode(ctx, id, current);
|
|
378
|
+
}
|
|
379
|
+
return generateErrorNode(ctx, id, current);
|
|
378
380
|
}
|
|
379
381
|
if (current instanceof Error) {
|
|
380
382
|
return generateErrorNode(ctx, id, current);
|
|
@@ -401,5 +403,5 @@ export default function parseSync(
|
|
|
401
403
|
const result = parse(ctx, current);
|
|
402
404
|
const isObject = result.t === SerovalNodeType.Object
|
|
403
405
|
|| result.t === SerovalNodeType.Iterable;
|
|
404
|
-
return [result,
|
|
406
|
+
return [result, getRootID(ctx, current), isObject] as const;
|
|
405
407
|
}
|
package/src/tree/types.ts
CHANGED
|
@@ -45,8 +45,8 @@ export interface SerovalBaseNode {
|
|
|
45
45
|
d: SerovalDictionaryNode | undefined;
|
|
46
46
|
// array of nodes
|
|
47
47
|
a: SerovalNode[] | undefined;
|
|
48
|
-
//
|
|
49
|
-
|
|
48
|
+
// fulfilled node
|
|
49
|
+
f: SerovalNode | undefined;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
export interface SerovalObjectRecordNode {
|
|
@@ -197,7 +197,7 @@ export interface SerovalNullConstructorNode extends SerovalBaseNode {
|
|
|
197
197
|
|
|
198
198
|
export interface SerovalPromiseNode extends SerovalBaseNode {
|
|
199
199
|
t: SerovalNodeType.Promise;
|
|
200
|
-
|
|
200
|
+
f: SerovalNode;
|
|
201
201
|
i: number;
|
|
202
202
|
}
|
|
203
203
|
|