seroval 0.7.0 → 0.8.0

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.
Files changed (41) hide show
  1. package/dist/cjs/development/index.cjs +1109 -1039
  2. package/dist/cjs/development/index.cjs.map +4 -4
  3. package/dist/cjs/production/index.cjs +3 -3
  4. package/dist/esm/development/index.mjs +1109 -1039
  5. package/dist/esm/development/index.mjs.map +4 -4
  6. package/dist/esm/production/index.mjs +3 -3
  7. package/dist/types/assert.d.ts +1 -1
  8. package/dist/types/context.d.ts +2 -2
  9. package/dist/types/index.d.ts +3 -4
  10. package/dist/types/string.d.ts +1 -1
  11. package/dist/types/tree/UnsupportedTypeError.d.ts +3 -0
  12. package/dist/types/tree/async.d.ts +3 -3
  13. package/dist/types/tree/constants.d.ts +11 -0
  14. package/dist/types/tree/deserialize.d.ts +2 -2
  15. package/dist/types/tree/primitives.d.ts +9 -15
  16. package/dist/types/tree/serialize.d.ts +2 -2
  17. package/dist/types/tree/shared.d.ts +10 -8
  18. package/dist/types/tree/sync.d.ts +3 -3
  19. package/dist/types/tree/types.d.ts +64 -71
  20. package/dist/types/tree/web-api.d.ts +2 -2
  21. package/dist/types/types.d.ts +4 -4
  22. package/package.json +10 -8
  23. package/src/assert.ts +2 -2
  24. package/src/compat.ts +0 -1
  25. package/src/context.ts +10 -7
  26. package/src/get-identifier.ts +1 -1
  27. package/src/index.ts +35 -26
  28. package/src/string.ts +2 -2
  29. package/src/tree/UnsupportedTypeError.ts +8 -0
  30. package/src/tree/async.ts +245 -233
  31. package/src/tree/constants.ts +72 -0
  32. package/src/tree/deserialize.ts +96 -93
  33. package/src/tree/primitives.ts +81 -134
  34. package/src/tree/reference.ts +4 -3
  35. package/src/tree/serialize.ts +251 -197
  36. package/src/tree/shared.ts +31 -22
  37. package/src/tree/symbols.ts +13 -13
  38. package/src/tree/sync.ts +226 -198
  39. package/src/tree/types.ts +74 -93
  40. package/src/tree/web-api.ts +10 -7
  41. package/src/types.ts +7 -3
package/src/tree/sync.ts CHANGED
@@ -1,9 +1,17 @@
1
1
  /* eslint-disable @typescript-eslint/no-use-before-define */
2
2
  import assert from '../assert';
3
3
  import { Feature } from '../compat';
4
- import { createIndexedValue, getRootID, ParserContext } from '../context';
4
+ import type { ParserContext } from '../context';
5
+ import { createIndexedValue } from '../context';
5
6
  import { serializeString } from '../string';
6
- import { BigIntTypedArrayValue, TypedArrayValue } from '../types';
7
+ import type { BigIntTypedArrayValue, TypedArrayValue } from '../types';
8
+ import UnsupportedTypeError from './UnsupportedTypeError';
9
+ import {
10
+ TRUE_NODE,
11
+ FALSE_NODE,
12
+ UNDEFINED_NODE,
13
+ NULL_NODE,
14
+ } from './constants';
7
15
  import {
8
16
  createBigIntNode,
9
17
  createBigIntTypedArrayNode,
@@ -13,18 +21,11 @@ import {
13
21
  createRegExpNode,
14
22
  createStringNode,
15
23
  createTypedArrayNode,
16
- createWKSymbolNode,
17
- FALSE_NODE,
18
- INFINITY_NODE,
19
- NAN_NODE,
20
- NEG_INFINITY_NODE,
21
- NEG_ZERO_NODE,
22
- NULL_NODE,
23
- TRUE_NODE,
24
- UNDEFINED_NODE,
25
24
  createReferenceNode,
26
25
  createArrayBufferNode,
27
26
  createDataViewNode,
27
+ createSymbolNode,
28
+ createFunctionNode,
28
29
  } from './primitives';
29
30
  import {
30
31
  hasReferenceID,
@@ -32,30 +33,33 @@ import {
32
33
  import {
33
34
  getErrorConstructorName,
34
35
  getErrorOptions,
35
- getIterableOptions,
36
36
  isIterable,
37
37
  } from './shared';
38
- import { WellKnownSymbols } from './symbols';
39
- import {
38
+ import type {
40
39
  SerovalAggregateErrorNode,
41
40
  SerovalArrayNode,
41
+ SerovalBoxedNode,
42
42
  SerovalErrorNode,
43
43
  SerovalFormDataNode,
44
44
  SerovalHeadersNode,
45
- SerovalIterableNode,
46
45
  SerovalMapNode,
47
46
  SerovalNode,
48
- SerovalNodeType,
49
47
  SerovalNullConstructorNode,
50
48
  SerovalObjectNode,
49
+ SerovalObjectRecordKey,
51
50
  SerovalObjectRecordNode,
51
+ SerovalPlainRecordNode,
52
52
  SerovalSetNode,
53
53
  } from './types';
54
+ import {
55
+ SerovalNodeType,
56
+ SerovalObjectRecordSpecialKey,
57
+ } from './types';
54
58
  import { createURLNode, createURLSearchParamsNode } from './web-api';
55
59
 
56
- type ObjectLikeNode = SerovalObjectNode | SerovalNullConstructorNode | SerovalIterableNode;
60
+ type ObjectLikeNode = SerovalObjectNode | SerovalNullConstructorNode;
57
61
 
58
- function generateNodeList(ctx: ParserContext, current: unknown[]) {
62
+ function generateNodeList(ctx: ParserContext, current: unknown[]): SerovalNode[] {
59
63
  const size = current.length;
60
64
  const nodes = new Array<SerovalNode>(size);
61
65
  const deferred = new Array<unknown>(size);
@@ -66,13 +70,13 @@ function generateNodeList(ctx: ParserContext, current: unknown[]) {
66
70
  if (isIterable(item)) {
67
71
  deferred[i] = item;
68
72
  } else {
69
- nodes[i] = parse(ctx, item);
73
+ nodes[i] = parseSync(ctx, item);
70
74
  }
71
75
  }
72
76
  }
73
77
  for (let i = 0; i < size; i++) {
74
78
  if (i in deferred) {
75
- nodes[i] = parse(ctx, deferred[i]);
79
+ nodes[i] = parseSync(ctx, deferred[i]);
76
80
  }
77
81
  }
78
82
  return nodes;
@@ -102,7 +106,7 @@ function generateMapNode(
102
106
  id: number,
103
107
  current: Map<unknown, unknown>,
104
108
  ): SerovalMapNode {
105
- assert(ctx.features & Feature.Map, 'Unsupported type "Map"');
109
+ assert(ctx.features & Feature.Map, new UnsupportedTypeError(current));
106
110
  const len = current.size;
107
111
  const keyNodes = new Array<SerovalNode>(len);
108
112
  const valueNodes = new Array<SerovalNode>(len);
@@ -117,14 +121,14 @@ function generateMapNode(
117
121
  deferredValue[deferredSize] = value;
118
122
  deferredSize++;
119
123
  } else {
120
- keyNodes[nodeSize] = parse(ctx, key);
121
- valueNodes[nodeSize] = parse(ctx, value);
124
+ keyNodes[nodeSize] = parseSync(ctx, key);
125
+ valueNodes[nodeSize] = parseSync(ctx, value);
122
126
  nodeSize++;
123
127
  }
124
128
  }
125
129
  for (let i = 0; i < deferredSize; i++) {
126
- keyNodes[nodeSize + i] = parse(ctx, deferredKey[i]);
127
- valueNodes[nodeSize + i] = parse(ctx, deferredValue[i]);
130
+ keyNodes[nodeSize + i] = parseSync(ctx, deferredKey[i]);
131
+ valueNodes[nodeSize + i] = parseSync(ctx, deferredValue[i]);
128
132
  }
129
133
  return {
130
134
  t: SerovalNodeType.Map,
@@ -145,7 +149,7 @@ function generateSetNode(
145
149
  id: number,
146
150
  current: Set<unknown>,
147
151
  ): SerovalSetNode {
148
- assert(ctx.features & Feature.Set, 'Unsupported type "Set"');
152
+ assert(ctx.features & Feature.Set, new UnsupportedTypeError(current));
149
153
  const len = current.size;
150
154
  const nodes = new Array<SerovalNode>(len);
151
155
  const deferred = new Array<unknown>(len);
@@ -156,12 +160,12 @@ function generateSetNode(
156
160
  if (isIterable(item)) {
157
161
  deferred[deferredSize++] = item;
158
162
  } else {
159
- nodes[nodeSize++] = parse(ctx, item);
163
+ nodes[nodeSize++] = parseSync(ctx, item);
160
164
  }
161
165
  }
162
166
  // Parse deferred items
163
167
  for (let i = 0; i < deferredSize; i++) {
164
- nodes[nodeSize + i] = parse(ctx, deferred[i]);
168
+ nodes[nodeSize + i] = parseSync(ctx, deferred[i]);
165
169
  }
166
170
  return {
167
171
  t: SerovalNodeType.Set,
@@ -182,15 +186,15 @@ function generateProperties(
182
186
  properties: Record<string, unknown>,
183
187
  ): SerovalObjectRecordNode {
184
188
  const keys = Object.keys(properties);
185
- const size = keys.length;
186
- const keyNodes = new Array<string>(size);
189
+ let size = keys.length;
190
+ const keyNodes = new Array<SerovalObjectRecordKey>(size);
187
191
  const valueNodes = new Array<SerovalNode>(size);
188
- const deferredKeys = new Array<string>(size);
192
+ const deferredKeys = new Array<SerovalObjectRecordKey>(size);
189
193
  const deferredValues = new Array<unknown>(size);
190
194
  let deferredSize = 0;
191
195
  let nodesSize = 0;
192
196
  let item: unknown;
193
- let escaped: string;
197
+ let escaped: SerovalObjectRecordKey;
194
198
  for (const key of keys) {
195
199
  item = properties[key];
196
200
  escaped = serializeString(key);
@@ -200,13 +204,22 @@ function generateProperties(
200
204
  deferredSize++;
201
205
  } else {
202
206
  keyNodes[nodesSize] = escaped;
203
- valueNodes[nodesSize] = parse(ctx, item);
207
+ valueNodes[nodesSize] = parseSync(ctx, item);
204
208
  nodesSize++;
205
209
  }
206
210
  }
207
211
  for (let i = 0; i < deferredSize; i++) {
208
212
  keyNodes[nodesSize + i] = deferredKeys[i];
209
- valueNodes[nodesSize + i] = parse(ctx, deferredValues[i]);
213
+ valueNodes[nodesSize + i] = parseSync(ctx, deferredValues[i]);
214
+ }
215
+ if (ctx.features & Feature.Symbol) {
216
+ if (Symbol.iterator in properties) {
217
+ keyNodes[size] = SerovalObjectRecordSpecialKey.SymbolIterator;
218
+ const items = Array.from(properties as Iterable<unknown>);
219
+ const id = createIndexedValue(ctx, items);
220
+ valueNodes[size] = generateArrayNode(ctx, id, items);
221
+ size++;
222
+ }
210
223
  }
211
224
  return {
212
225
  k: keyNodes,
@@ -215,40 +228,50 @@ function generateProperties(
215
228
  };
216
229
  }
217
230
 
218
- function generateIterableNode(
231
+ function generatePlainProperties(
219
232
  ctx: ParserContext,
220
- id: number,
221
- current: Iterable<unknown>,
222
- ): SerovalIterableNode {
223
- assert(ctx.features & Feature.Symbol, 'Unsupported type "Iterable"');
224
- const options = getIterableOptions(current);
225
- const array = Array.from(current);
233
+ properties: Record<string, unknown>,
234
+ ): SerovalPlainRecordNode {
235
+ const keys = Object.keys(properties);
236
+ const size = keys.length;
237
+ const keyNodes = new Array<string>(size);
238
+ const valueNodes = new Array<SerovalNode>(size);
239
+ const deferredKeys = new Array<string>(size);
240
+ const deferredValues = new Array<unknown>(size);
241
+ let deferredSize = 0;
242
+ let nodesSize = 0;
243
+ let item: unknown;
244
+ let escaped: string;
245
+ for (const key of keys) {
246
+ item = properties[key];
247
+ escaped = serializeString(key);
248
+ if (isIterable(item)) {
249
+ deferredKeys[deferredSize] = escaped;
250
+ deferredValues[deferredSize] = item;
251
+ deferredSize++;
252
+ } else {
253
+ keyNodes[nodesSize] = escaped;
254
+ valueNodes[nodesSize] = parseSync(ctx, item);
255
+ nodesSize++;
256
+ }
257
+ }
258
+ for (let i = 0; i < deferredSize; i++) {
259
+ keyNodes[nodesSize + i] = deferredKeys[i];
260
+ valueNodes[nodesSize + i] = parseSync(ctx, deferredValues[i]);
261
+ }
226
262
  return {
227
- t: SerovalNodeType.Iterable,
228
- i: id,
229
- s: undefined,
230
- l: array.length,
231
- c: undefined,
232
- m: undefined,
233
- // Parse options first before the items
234
- d: options
235
- ? generateProperties(ctx, options)
236
- : undefined,
237
- a: generateNodeList(ctx, array),
238
- f: undefined,
239
- b: undefined,
263
+ k: keyNodes,
264
+ v: valueNodes,
265
+ s: size,
240
266
  };
241
267
  }
242
268
 
243
269
  function generateObjectNode(
244
270
  ctx: ParserContext,
245
271
  id: number,
246
- current: Record<string, unknown> | Iterable<unknown>,
272
+ current: Record<string, unknown>,
247
273
  empty: boolean,
248
274
  ): ObjectLikeNode {
249
- if (Symbol.iterator in current) {
250
- return generateIterableNode(ctx, id, current);
251
- }
252
275
  return {
253
276
  t: empty ? SerovalNodeType.NullConstructor : SerovalNodeType.Object,
254
277
  i: id,
@@ -314,8 +337,9 @@ function generateHeadersNode(
314
337
  id: number,
315
338
  current: Headers,
316
339
  ): SerovalHeadersNode {
317
- assert(ctx.features & Feature.WebAPI, 'Unsupported type "Headers"');
340
+ assert(ctx.features & Feature.WebAPI, new UnsupportedTypeError(current));
318
341
  const items: Record<string, string> = {};
342
+ // TS Headers not an Iterable
319
343
  current.forEach((value, key) => {
320
344
  items[key] = value;
321
345
  });
@@ -326,7 +350,7 @@ function generateHeadersNode(
326
350
  l: undefined,
327
351
  c: undefined,
328
352
  m: undefined,
329
- d: generateProperties(ctx, items),
353
+ d: generatePlainProperties(ctx, items),
330
354
  a: undefined,
331
355
  f: undefined,
332
356
  b: undefined,
@@ -338,8 +362,9 @@ function generateFormDataNode(
338
362
  id: number,
339
363
  current: FormData,
340
364
  ): SerovalFormDataNode {
341
- assert(ctx.features & Feature.WebAPI, 'Unsupported type "FormData"');
365
+ assert(ctx.features & Feature.WebAPI, new UnsupportedTypeError(current));
342
366
  const items: Record<string, FormDataEntryValue> = {};
367
+ // TS FormData isn't an Iterable sadly
343
368
  current.forEach((value, key) => {
344
369
  items[key] = value;
345
370
  });
@@ -350,14 +375,145 @@ function generateFormDataNode(
350
375
  l: undefined,
351
376
  c: undefined,
352
377
  m: undefined,
353
- d: generateProperties(ctx, items),
378
+ d: generatePlainProperties(ctx, items),
354
379
  a: undefined,
355
380
  f: undefined,
356
381
  b: undefined,
357
382
  };
358
383
  }
359
384
 
360
- function parse<T>(
385
+ function generateBoxedNode(
386
+ ctx: ParserContext,
387
+ id: number,
388
+ current: object,
389
+ ): SerovalBoxedNode {
390
+ return {
391
+ t: SerovalNodeType.Boxed,
392
+ i: id,
393
+ s: undefined,
394
+ l: undefined,
395
+ c: undefined,
396
+ m: undefined,
397
+ d: undefined,
398
+ a: undefined,
399
+ f: parseSync(ctx, current.valueOf()),
400
+ b: undefined,
401
+ };
402
+ }
403
+
404
+ function parseObject(
405
+ ctx: ParserContext,
406
+ current: object | null,
407
+ ): SerovalNode {
408
+ if (!current) {
409
+ return NULL_NODE;
410
+ }
411
+ // Non-primitive values needs a reference ID
412
+ // mostly because the values themselves are stateful
413
+ const id = createIndexedValue(ctx, current);
414
+ if (ctx.markedRefs.has(id)) {
415
+ return createIndexedValueNode(id);
416
+ }
417
+ if (hasReferenceID(current)) {
418
+ return createReferenceNode(id, current);
419
+ }
420
+ // Well well well
421
+ if (Array.isArray(current)) {
422
+ return generateArrayNode(ctx, id, current);
423
+ }
424
+ // Fast path
425
+ switch (current.constructor) {
426
+ case Number:
427
+ case Boolean:
428
+ case String:
429
+ case BigInt:
430
+ case Function:
431
+ case Symbol:
432
+ return generateBoxedNode(ctx, id, current);
433
+ case Date:
434
+ return createDateNode(id, current as unknown as Date);
435
+ case RegExp:
436
+ return createRegExpNode(id, current as unknown as RegExp);
437
+ case ArrayBuffer:
438
+ return createArrayBufferNode(id, current as unknown as ArrayBuffer);
439
+ case Int8Array:
440
+ case Int16Array:
441
+ case Int32Array:
442
+ case Uint8Array:
443
+ case Uint16Array:
444
+ case Uint32Array:
445
+ case Uint8ClampedArray:
446
+ case Float32Array:
447
+ case Float64Array:
448
+ return createTypedArrayNode(ctx, id, current as unknown as TypedArrayValue);
449
+ case BigInt64Array:
450
+ case BigUint64Array:
451
+ return createBigIntTypedArrayNode(ctx, id, current as unknown as BigIntTypedArrayValue);
452
+ case DataView:
453
+ return createDataViewNode(ctx, id, current as unknown as DataView);
454
+ case Map:
455
+ return generateMapNode(ctx, id, current as unknown as Map<unknown, unknown>);
456
+ case Set:
457
+ return generateSetNode(ctx, id, current as unknown as Set<unknown>);
458
+ case Object:
459
+ return generateObjectNode(
460
+ ctx,
461
+ id,
462
+ current as unknown as Record<string, unknown>,
463
+ false,
464
+ );
465
+ case undefined:
466
+ return generateObjectNode(
467
+ ctx,
468
+ id,
469
+ current as unknown as Record<string, unknown>,
470
+ true,
471
+ );
472
+ case AggregateError:
473
+ // Compile-down AggregateError to Error if disabled
474
+ if (ctx.features & Feature.AggregateError) {
475
+ return generateAggregateErrorNode(ctx, id, current as unknown as AggregateError);
476
+ }
477
+ return generateErrorNode(ctx, id, current as unknown as AggregateError);
478
+ case Error:
479
+ case EvalError:
480
+ case RangeError:
481
+ case ReferenceError:
482
+ case SyntaxError:
483
+ case TypeError:
484
+ case URIError:
485
+ return generateErrorNode(ctx, id, current as unknown as Error);
486
+ case URL:
487
+ return createURLNode(ctx, id, current as unknown as URL);
488
+ case URLSearchParams:
489
+ return createURLSearchParamsNode(ctx, id, current as unknown as URLSearchParams);
490
+ case Headers:
491
+ return generateHeadersNode(ctx, id, current as unknown as Headers);
492
+ case FormData:
493
+ return generateFormDataNode(ctx, id, current as unknown as FormData);
494
+ default:
495
+ break;
496
+ }
497
+ // Slow path. We only need to handle Errors and Iterators
498
+ // since they have very broad implementations.
499
+ if (current instanceof AggregateError) {
500
+ if (ctx.features & Feature.AggregateError) {
501
+ return generateAggregateErrorNode(ctx, id, current);
502
+ }
503
+ return generateErrorNode(ctx, id, current);
504
+ }
505
+ if (current instanceof Error) {
506
+ return generateErrorNode(ctx, id, current);
507
+ }
508
+ // Generator functions don't have a global constructor
509
+ // despite existing
510
+ if (Symbol.iterator in current) {
511
+ return generateObjectNode(ctx, id, current, !!current.constructor);
512
+ }
513
+ throw new UnsupportedTypeError(current);
514
+ }
515
+
516
+ export default function parseSync<T>(
361
517
  ctx: ParserContext,
362
518
  current: T,
363
519
  ): SerovalNode {
@@ -369,144 +525,16 @@ function parse<T>(
369
525
  case 'string':
370
526
  return createStringNode(current);
371
527
  case 'number':
372
- switch (current) {
373
- case Infinity: return INFINITY_NODE;
374
- case -Infinity: return NEG_INFINITY_NODE;
375
- default:
376
- // eslint-disable-next-line no-self-compare
377
- if (current !== current) {
378
- return NAN_NODE;
379
- }
380
- if (Object.is(current, -0)) {
381
- return NEG_ZERO_NODE;
382
- }
383
- return createNumberNode(current);
384
- }
528
+ return createNumberNode(current);
385
529
  case 'bigint':
386
530
  return createBigIntNode(ctx, current);
387
- case 'object': {
388
- if (!current) {
389
- return NULL_NODE;
390
- }
391
- // Non-primitive values needs a reference ID
392
- // mostly because the values themselves are stateful
393
- const id = createIndexedValue(ctx, current);
394
- if (ctx.markedRefs.has(id)) {
395
- return createIndexedValueNode(id);
396
- }
397
- if (hasReferenceID(current)) {
398
- return createReferenceNode(id, current);
399
- }
400
- if (Array.isArray(current)) {
401
- return generateArrayNode(ctx, id, current);
402
- }
403
- switch (current.constructor) {
404
- case Date:
405
- return createDateNode(id, current as unknown as Date);
406
- case RegExp:
407
- return createRegExpNode(id, current as unknown as RegExp);
408
- case ArrayBuffer:
409
- return createArrayBufferNode(id, current as unknown as ArrayBuffer);
410
- case Int8Array:
411
- case Int16Array:
412
- case Int32Array:
413
- case Uint8Array:
414
- case Uint16Array:
415
- case Uint32Array:
416
- case Uint8ClampedArray:
417
- case Float32Array:
418
- case Float64Array:
419
- return createTypedArrayNode(ctx, id, current as unknown as TypedArrayValue);
420
- case BigInt64Array:
421
- case BigUint64Array:
422
- return createBigIntTypedArrayNode(ctx, id, current as unknown as BigIntTypedArrayValue);
423
- case DataView:
424
- return createDataViewNode(ctx, id, current as unknown as DataView);
425
- case Map:
426
- return generateMapNode(ctx, id, current as unknown as Map<unknown, unknown>);
427
- case Set:
428
- return generateSetNode(ctx, id, current as unknown as Set<unknown>);
429
- case Object:
430
- return generateObjectNode(
431
- ctx,
432
- id,
433
- current as unknown as Record<string, unknown>,
434
- false,
435
- );
436
- case undefined:
437
- return generateObjectNode(
438
- ctx,
439
- id,
440
- current as unknown as Record<string, unknown>,
441
- true,
442
- );
443
- case AggregateError:
444
- if (ctx.features & Feature.AggregateError) {
445
- return generateAggregateErrorNode(ctx, id, current as unknown as AggregateError);
446
- }
447
- return generateErrorNode(ctx, id, current as unknown as AggregateError);
448
- case Error:
449
- case EvalError:
450
- case RangeError:
451
- case ReferenceError:
452
- case SyntaxError:
453
- case TypeError:
454
- case URIError:
455
- return generateErrorNode(ctx, id, current as unknown as Error);
456
- case URL:
457
- return createURLNode(ctx, id, current as unknown as URL);
458
- case URLSearchParams:
459
- return createURLSearchParamsNode(ctx, id, current as unknown as URLSearchParams);
460
- case Headers:
461
- return generateHeadersNode(ctx, id, current as unknown as Headers);
462
- case FormData:
463
- return generateFormDataNode(ctx, id, current as unknown as FormData);
464
- default:
465
- break;
466
- }
467
- if (current instanceof AggregateError) {
468
- if (ctx.features & Feature.AggregateError) {
469
- return generateAggregateErrorNode(ctx, id, current);
470
- }
471
- return generateErrorNode(ctx, id, current);
472
- }
473
- if (current instanceof Error) {
474
- return generateErrorNode(ctx, id, current);
475
- }
476
- // Generator functions don't have a global constructor
477
- if (Symbol.iterator in current) {
478
- return generateIterableNode(ctx, id, current as Iterable<unknown>);
479
- }
480
- throw new Error('Unsupported type');
481
- }
531
+ case 'object':
532
+ return parseObject(ctx, current);
482
533
  case 'symbol':
483
- if (hasReferenceID(current)) {
484
- const id = createIndexedValue(ctx, current);
485
- if (ctx.markedRefs.has(id)) {
486
- return createIndexedValueNode(id);
487
- }
488
- return createReferenceNode(id, current);
489
- }
490
- return createWKSymbolNode(ctx, current as WellKnownSymbols);
491
- case 'function': {
492
- assert(hasReferenceID(current), 'Cannot serialize function without reference ID.');
493
- const id = createIndexedValue(ctx, current);
494
- if (ctx.markedRefs.has(id)) {
495
- return createIndexedValueNode(id);
496
- }
497
- return createReferenceNode(id, current);
498
- }
534
+ return createSymbolNode(ctx, current);
535
+ case 'function':
536
+ return createFunctionNode(ctx, current);
499
537
  default:
500
- throw new Error('Unsupported type');
538
+ throw new UnsupportedTypeError(current);
501
539
  }
502
540
  }
503
-
504
- export default function parseSync<T>(
505
- ctx: ParserContext,
506
- current: T,
507
- ) {
508
- const result = parse(ctx, current);
509
- const isObject = result.t === SerovalNodeType.Object
510
- || result.t === SerovalNodeType.Iterable;
511
- return [result, getRootID(ctx, current), isObject] as const;
512
- }