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.
@@ -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
- if (item.t === 'index' && item.v === prev.v) {
52
- // Merge if the right-hand value is the same
53
- // saves at least 2 chars
54
- current = {
55
- t: 'index',
56
- s: item.s,
57
- k: undefined,
58
- v: getAssignmentExpression(current),
59
- };
60
- } else if (item.t === 'map' && item.s === prev.s) {
61
- // Maps has chaining methods, merge if source is the same
62
- current = {
63
- t: 'map',
64
- s: getAssignmentExpression(current),
65
- k: item.k,
66
- v: item.v,
67
- };
68
- } else if (item.t === 'set' && item.s === prev.s) {
69
- // Sets has chaining methods too
70
- current = {
71
- t: 'set',
72
- s: getAssignmentExpression(current),
73
- k: undefined,
74
- v: item.v,
75
- };
76
- } else {
77
- // Different assignment, push current
78
- newAssignments.push(current);
79
- current = item;
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.toString() + ']', value);
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
- if (isHoley) {
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
- if (hasPrev) {
274
- result += ',';
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
- const ref = getRefParam(ctx, i);
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
- if (hasPrev) {
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
- if (hasPrev) {
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.n)) {
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.n.i);
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.n);
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
- if (i !== 0) {
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 String(node.s);
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 'undefined';
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
- n: undefined,
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
- n: undefined,
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
- n: undefined,
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
- n: undefined,
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
- n: undefined,
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
- n: undefined,
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
- n: undefined,
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, true);
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 && ctx.features & Feature.AggregateError) {
377
- return generateAggregateErrorNode(ctx, id, current);
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, createRef(ctx, current, false), isObject] as const;
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
- // next node
49
- n: SerovalNode | undefined;
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
- n: SerovalNode;
200
+ f: SerovalNode;
201
201
  i: number;
202
202
  }
203
203