seroval 0.4.0 → 0.5.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.
@@ -14,7 +14,7 @@ export declare const enum Feature {
14
14
  ObjectAssign = 128,
15
15
  Promise = 256,
16
16
  Set = 512,
17
- SymbolIterator = 1024,
17
+ Symbol = 1024,
18
18
  TypedArray = 2048,
19
19
  BigIntTypedArray = 4096
20
20
  }
@@ -1,3 +1,4 @@
1
+ import { AsyncServerValue } from './types';
1
2
  interface IndexAssignment {
2
3
  t: 'index';
3
4
  s: string;
@@ -30,6 +31,7 @@ export interface SerializationContext {
30
31
  vars: string[];
31
32
  assignments: Assignment[];
32
33
  features: number;
34
+ valueMap: Map<number, AsyncServerValue>;
33
35
  }
34
36
  export interface Options {
35
37
  disabledFeatures: number;
@@ -1,12 +1,20 @@
1
1
  import { Feature } from './compat';
2
2
  import { Options } from './context';
3
+ import { SerovalNode } from './tree/types';
3
4
  import { AsyncServerValue, PrimitiveValue, ServerValue, CommonServerValue, SemiPrimitiveValue, ErrorValue } from './types';
4
5
  export { AsyncServerValue, ServerValue, PrimitiveValue, CommonServerValue, SemiPrimitiveValue, ErrorValue, Feature, };
5
6
  export declare function serialize<T extends ServerValue>(source: T, options?: Partial<Options>): string;
6
7
  export declare function serializeAsync<T extends AsyncServerValue>(source: T, options?: Partial<Options>): Promise<string>;
7
8
  export declare function deserialize<T extends AsyncServerValue>(source: string): T;
8
- export declare function toJSON<T extends ServerValue>(source: T, options?: Partial<Options>): string;
9
- export declare function toJSONAsync<T extends AsyncServerValue>(source: T, options?: Partial<Options>): Promise<string>;
10
- export declare function compileJSON(source: string): string;
11
- export declare function fromJSON<T extends AsyncServerValue>(source: string): T;
9
+ export interface SerovalJSON {
10
+ t: SerovalNode;
11
+ r: number;
12
+ i: boolean;
13
+ f: number;
14
+ m: number[];
15
+ }
16
+ export declare function toJSON<T extends ServerValue>(source: T, options?: Partial<Options>): SerovalJSON;
17
+ export declare function toJSONAsync<T extends AsyncServerValue>(source: T, options?: Partial<Options>): Promise<SerovalJSON>;
18
+ export declare function compileJSON(source: SerovalJSON): string;
19
+ export declare function fromJSON<T extends AsyncServerValue>(source: SerovalJSON): T;
12
20
  export default serialize;
@@ -1 +1,2 @@
1
1
  export default function quote(str: string): string;
2
+ export declare function invQuote(str: string): string;
@@ -0,0 +1,4 @@
1
+ import { SerializationContext } from '../context';
2
+ import { AsyncServerValue } from '../types';
3
+ import { SerovalNode } from './types';
4
+ export default function deserializeTree(ctx: SerializationContext, node: SerovalNode): AsyncServerValue;
@@ -1,17 +1,21 @@
1
1
  import { ParserContext } from '../context';
2
2
  import { BigIntTypedArrayValue, TypedArrayValue } from '../types';
3
- import { SerovalBigIntNode, SerovalBigIntTypedArrayNode, SerovalDateNode, SerovalPrimitiveNode, SerovalReferenceNode, SerovalRegExpNode, SerovalTypedArrayNode } from './types';
4
- export declare function createPrimitiveNode(value: string | number | null): SerovalPrimitiveNode;
5
- export declare const TRUE_NODE: SerovalPrimitiveNode;
6
- export declare const FALSE_NODE: SerovalPrimitiveNode;
7
- export declare const UNDEFINED_NODE: SerovalPrimitiveNode;
8
- export declare const NULL_NODE: SerovalPrimitiveNode;
9
- export declare const NEG_ZERO_NODE: SerovalPrimitiveNode;
10
- export declare const INFINITY_NODE: SerovalPrimitiveNode;
11
- export declare const NEG_INFINITY_NODE: SerovalPrimitiveNode;
3
+ import { WellKnownSymbols } from './symbols';
4
+ import { SerovalBigIntNode, SerovalBigIntTypedArrayNode, SerovalBooleanNode, SerovalDateNode, SerovalInfinityNode, SerovalNaNNode, SerovalNegativeInfinityNode, SerovalNegativeZeroNode, SerovalNullNode, SerovalNumberNode, SerovalReferenceNode, SerovalRegExpNode, SerovalStringNode, SerovalTypedArrayNode, SerovalUndefinedNode, SerovalWKSymbolNode } from './types';
5
+ export declare const TRUE_NODE: SerovalBooleanNode;
6
+ export declare const FALSE_NODE: SerovalBooleanNode;
7
+ export declare const UNDEFINED_NODE: SerovalUndefinedNode;
8
+ export declare const NULL_NODE: SerovalNullNode;
9
+ export declare const NEG_ZERO_NODE: SerovalNegativeZeroNode;
10
+ export declare const INFINITY_NODE: SerovalInfinityNode;
11
+ export declare const NEG_INFINITY_NODE: SerovalNegativeInfinityNode;
12
+ export declare const NAN_NODE: SerovalNaNNode;
13
+ export declare function createNumberNode(value: number): SerovalNumberNode;
14
+ export declare function createStringNode(value: string): SerovalStringNode;
12
15
  export declare function createBigIntNode(ctx: ParserContext, current: bigint): SerovalBigIntNode;
13
16
  export declare function createReferenceNode(id: number): SerovalReferenceNode;
14
17
  export declare function createDateNode(id: number, current: Date): SerovalDateNode;
15
18
  export declare function createRegExpNode(id: number, current: RegExp): SerovalRegExpNode;
16
19
  export declare function createTypedArrayNode(ctx: ParserContext, id: number, current: TypedArrayValue): SerovalTypedArrayNode;
17
20
  export declare function createBigIntTypedArrayNode(ctx: ParserContext, id: number, current: BigIntTypedArrayValue): SerovalBigIntTypedArrayNode;
21
+ export declare function createWKSymbolNode(current: WellKnownSymbols): SerovalWKSymbolNode;
@@ -1,6 +1,9 @@
1
1
  import { ParserContext } from '../context';
2
2
  import { AsyncServerValue, ErrorValue } from '../types';
3
- export declare function getErrorConstructor(error: ErrorValue): "EvalError" | "RangeError" | "ReferenceError" | "SyntaxError" | "TypeError" | "URIError" | "Error";
3
+ export declare function getErrorConstructorName(error: ErrorValue): "EvalError" | "RangeError" | "ReferenceError" | "SyntaxError" | "TypeError" | "URIError" | "Error";
4
+ export declare function getErrorConstructor(errorName: string): ErrorConstructor;
4
5
  export declare function getErrorOptions(ctx: ParserContext, error: Error): Record<string, any> | undefined;
5
6
  export declare function getIterableOptions(obj: Iterable<any>): Record<string, unknown> | undefined;
6
7
  export declare function isIterable(value: unknown): value is Iterable<AsyncServerValue>;
8
+ export declare function getTypedArrayConstructor(name: string): Int8ArrayConstructor | Uint8ArrayConstructor | Uint8ClampedArrayConstructor | Int16ArrayConstructor | Uint16ArrayConstructor | Int32ArrayConstructor | Uint32ArrayConstructor | Float32ArrayConstructor | Float64ArrayConstructor | BigInt64ArrayConstructor | BigUint64ArrayConstructor;
9
+ export declare function isValidIdentifier(name: string): boolean;
@@ -0,0 +1,33 @@
1
+ export declare const enum Symbols {
2
+ AsyncIterator = 0,
3
+ HasInstance = 1,
4
+ IsConcatSpreadable = 2,
5
+ Iterator = 3,
6
+ Match = 4,
7
+ MatchAll = 5,
8
+ Replace = 6,
9
+ Search = 7,
10
+ Species = 8,
11
+ Split = 9,
12
+ ToPrimitive = 10,
13
+ ToStringTag = 11,
14
+ Unscopables = 12
15
+ }
16
+ export declare const SYMBOL_STRING: Record<Symbols, string>;
17
+ export declare const INV_SYMBOL_REF: {
18
+ [Symbol.asyncIterator]: Symbols;
19
+ [Symbol.hasInstance]: Symbols;
20
+ [Symbol.isConcatSpreadable]: Symbols;
21
+ [Symbol.iterator]: Symbols;
22
+ [Symbol.match]: Symbols;
23
+ [Symbol.matchAll]: Symbols;
24
+ [Symbol.replace]: Symbols;
25
+ [Symbol.search]: Symbols;
26
+ [Symbol.species]: Symbols;
27
+ [Symbol.split]: Symbols;
28
+ [Symbol.toPrimitive]: Symbols;
29
+ [Symbol.toStringTag]: Symbols;
30
+ [Symbol.unscopables]: Symbols;
31
+ };
32
+ export type WellKnownSymbols = keyof typeof INV_SYMBOL_REF;
33
+ export declare const SYMBOL_REF: Record<Symbols, WellKnownSymbols>;
@@ -1,32 +1,41 @@
1
- import { PrimitiveValue } from '../types';
1
+ import { Symbols } from './symbols';
2
2
  export declare const enum SerovalNodeType {
3
- Primitive = 0,
4
- BigInt = 1,
5
- Reference = 2,
6
- Date = 3,
7
- RegExp = 4,
8
- Set = 5,
9
- Map = 6,
10
- Array = 7,
11
- Object = 8,
12
- NullConstructor = 9,
13
- Promise = 10,
14
- Error = 11,
15
- AggregateError = 12,
16
- Iterable = 13,
17
- TypedArray = 14,
18
- BigIntTypedArray = 15
3
+ Number = 0,
4
+ String = 1,
5
+ Boolean = 2,
6
+ Null = 3,
7
+ Undefined = 4,
8
+ NegativeZero = 5,
9
+ Infinity = 6,
10
+ NegativeInfinity = 7,
11
+ NaN = 8,
12
+ BigInt = 9,
13
+ Reference = 10,
14
+ Date = 11,
15
+ RegExp = 12,
16
+ Set = 13,
17
+ Map = 14,
18
+ Array = 15,
19
+ Object = 16,
20
+ NullConstructor = 17,
21
+ Promise = 18,
22
+ Error = 19,
23
+ AggregateError = 20,
24
+ Iterable = 21,
25
+ TypedArray = 22,
26
+ BigIntTypedArray = 23,
27
+ WKSymbol = 24
19
28
  }
20
29
  export interface SerovalBaseNode {
21
30
  t: SerovalNodeType;
22
- s: PrimitiveValue | undefined;
23
31
  i: number | undefined;
32
+ s: any;
24
33
  l: number | undefined;
25
34
  c: string | undefined;
26
- d: SerovalDictionaryNode | undefined;
27
35
  m: string | undefined;
28
- n: SerovalNode | undefined;
36
+ d: SerovalDictionaryNode | undefined;
29
37
  a: SerovalNode[] | undefined;
38
+ n: SerovalNode | undefined;
30
39
  }
31
40
  export interface SerovalObjectRecordNode {
32
41
  k: string[];
@@ -39,9 +48,37 @@ export interface SerovalMapRecordNode {
39
48
  s: number;
40
49
  }
41
50
  export type SerovalDictionaryNode = SerovalObjectRecordNode | SerovalMapRecordNode;
42
- export interface SerovalPrimitiveNode extends SerovalBaseNode {
43
- t: SerovalNodeType.Primitive;
51
+ export interface SerovalNumberNode extends SerovalBaseNode {
52
+ t: SerovalNodeType.Number;
53
+ s: number;
54
+ }
55
+ export interface SerovalStringNode extends SerovalBaseNode {
56
+ t: SerovalNodeType.String;
57
+ s: string;
58
+ }
59
+ export interface SerovalBooleanNode extends SerovalBaseNode {
60
+ t: SerovalNodeType.Boolean;
61
+ s: boolean;
62
+ }
63
+ export interface SerovalNullNode extends SerovalBaseNode {
64
+ t: SerovalNodeType.Null;
65
+ }
66
+ export interface SerovalUndefinedNode extends SerovalBaseNode {
67
+ t: SerovalNodeType.Undefined;
68
+ }
69
+ export interface SerovalNegativeZeroNode extends SerovalBaseNode {
70
+ t: SerovalNodeType.NegativeZero;
71
+ }
72
+ export interface SerovalInfinityNode extends SerovalBaseNode {
73
+ t: SerovalNodeType.Infinity;
74
+ }
75
+ export interface SerovalNegativeInfinityNode extends SerovalBaseNode {
76
+ t: SerovalNodeType.NegativeInfinity;
44
77
  }
78
+ export interface SerovalNaNNode extends SerovalBaseNode {
79
+ t: SerovalNodeType.NaN;
80
+ }
81
+ export type SerovalPrimitiveNode = SerovalNumberNode | SerovalStringNode | SerovalBooleanNode | SerovalNullNode | SerovalUndefinedNode | SerovalNegativeZeroNode | SerovalNegativeInfinityNode | SerovalInfinityNode | SerovalNaNNode;
45
82
  export interface SerovalReferenceNode extends SerovalBaseNode {
46
83
  t: SerovalNodeType.Reference;
47
84
  i: number;
@@ -58,25 +95,27 @@ export interface SerovalDateNode extends SerovalBaseNode {
58
95
  export interface SerovalRegExpNode extends SerovalBaseNode {
59
96
  t: SerovalNodeType.RegExp;
60
97
  i: number;
61
- s: string;
98
+ c: string;
99
+ m: string;
62
100
  }
63
101
  export interface SerovalTypedArrayNode extends SerovalBaseNode {
64
102
  t: SerovalNodeType.TypedArray;
65
103
  i: number;
66
- s: string;
104
+ s: string[];
67
105
  l: number;
68
106
  c: string;
69
107
  }
70
108
  export interface SerovalBigIntTypedArrayNode extends SerovalBaseNode {
71
109
  t: SerovalNodeType.BigIntTypedArray;
72
110
  i: number;
73
- s: string;
111
+ s: string[];
74
112
  l: number;
75
113
  c: string;
76
114
  }
77
115
  export type SerovalSemiPrimitiveNode = SerovalBigIntNode | SerovalDateNode | SerovalRegExpNode | SerovalTypedArrayNode | SerovalBigIntTypedArrayNode;
78
116
  export interface SerovalSetNode extends SerovalBaseNode {
79
117
  t: SerovalNodeType.Set;
118
+ l: number;
80
119
  a: SerovalNode[];
81
120
  i: number;
82
121
  }
@@ -87,6 +126,7 @@ export interface SerovalMapNode extends SerovalBaseNode {
87
126
  }
88
127
  export interface SerovalArrayNode extends SerovalBaseNode {
89
128
  t: SerovalNodeType.Array;
129
+ l: number;
90
130
  a: SerovalNode[];
91
131
  i: number;
92
132
  }
@@ -116,13 +156,19 @@ export interface SerovalAggregateErrorNode extends SerovalBaseNode {
116
156
  t: SerovalNodeType.AggregateError;
117
157
  m: string;
118
158
  d: SerovalObjectRecordNode | undefined;
119
- n: SerovalNode;
159
+ l: number;
160
+ a: SerovalNode[];
120
161
  i: number;
121
162
  }
122
163
  export interface SerovalIterableNode extends SerovalBaseNode {
123
164
  t: SerovalNodeType.Iterable;
124
165
  d: SerovalObjectRecordNode | undefined;
166
+ l: number;
125
167
  a: SerovalNode[];
126
168
  i: number;
127
169
  }
128
- export type SerovalNode = SerovalPrimitiveNode | SerovalReferenceNode | SerovalSemiPrimitiveNode | SerovalSetNode | SerovalMapNode | SerovalArrayNode | SerovalObjectNode | SerovalNullConstructorNode | SerovalPromiseNode | SerovalErrorNode | SerovalAggregateErrorNode | SerovalIterableNode;
170
+ export interface SerovalWKSymbolNode extends SerovalBaseNode {
171
+ t: SerovalNodeType.WKSymbol;
172
+ s: Symbols;
173
+ }
174
+ export type SerovalNode = SerovalPrimitiveNode | SerovalReferenceNode | SerovalSemiPrimitiveNode | SerovalSetNode | SerovalMapNode | SerovalArrayNode | SerovalObjectNode | SerovalNullConstructorNode | SerovalPromiseNode | SerovalErrorNode | SerovalAggregateErrorNode | SerovalIterableNode | SerovalWKSymbolNode;
@@ -1,4 +1,5 @@
1
- export type PrimitiveValue = boolean | string | number | undefined | null;
1
+ import { WellKnownSymbols } from './tree/symbols';
2
+ export type PrimitiveValue = boolean | string | number | undefined | null | WellKnownSymbols;
2
3
  export type ErrorValue = Error | AggregateError | EvalError | RangeError | ReferenceError | TypeError | SyntaxError | URIError;
3
4
  export type TypedArrayValue = Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array;
4
5
  export type BigIntTypedArrayValue = BigInt64Array | BigUint64Array;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "seroval",
3
3
  "type": "module",
4
- "version": "0.4.0",
4
+ "version": "0.5.0",
5
5
  "files": [
6
6
  "dist",
7
7
  "src"
@@ -14,10 +14,10 @@
14
14
  "pridepack"
15
15
  ],
16
16
  "devDependencies": {
17
- "@types/node": "^18.11.18",
17
+ "@types/node": "^18.15.3",
18
18
  "eslint": "^8.32.0",
19
19
  "eslint-config-lxsmnsyc": "^0.4.8",
20
- "pridepack": "2.4.0",
20
+ "pridepack": "2.4.1",
21
21
  "tslib": "^2.4.1",
22
22
  "typescript": "^4.9.4",
23
23
  "vitest": "^0.28.1"
@@ -64,5 +64,5 @@
64
64
  "typesVersions": {
65
65
  "*": {}
66
66
  },
67
- "gitHead": "4767da3b4b6397d6830978b6f4d0f014d2115479"
67
+ "gitHead": "7c2e32b409df6bc01b5d5b38fdd3f9980a8b4984"
68
68
  }
package/src/compat.ts CHANGED
@@ -16,7 +16,7 @@ export const enum Feature {
16
16
  ObjectAssign = 0x80,
17
17
  Promise = 0x100,
18
18
  Set = 0x200,
19
- SymbolIterator = 0x400,
19
+ Symbol = 0x400,
20
20
  TypedArray = 0x800,
21
21
  BigIntTypedArray = 0x1000,
22
22
  }
package/src/context.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { ALL_ENABLED } from './compat';
2
2
  import getIdentifier from './get-identifier';
3
+ import { AsyncServerValue } from './types';
3
4
 
4
5
  interface IndexAssignment {
5
6
  t: 'index';
@@ -47,6 +48,8 @@ export interface SerializationContext {
47
48
  assignments: Assignment[];
48
49
  // Supported features
49
50
  features: number;
51
+
52
+ valueMap: Map<number, AsyncServerValue>;
50
53
  }
51
54
 
52
55
  export interface Options {
@@ -81,6 +84,7 @@ export function createSerializationContext(options: SerializationOptions): Seria
81
84
  refSize: 0,
82
85
  features: options.features,
83
86
  markedRefs: new Set(options.markedRefs),
87
+ valueMap: new Map(),
84
88
  };
85
89
  }
86
90
 
package/src/index.ts CHANGED
@@ -8,6 +8,7 @@ import {
8
8
  createSerializationContext,
9
9
  } from './context';
10
10
  import parseAsync from './tree/async';
11
+ import deserializeTree from './tree/deserialize';
11
12
  import serializeTree, { resolvePatches } from './tree/serialize';
12
13
  import parseSync from './tree/sync';
13
14
  import { SerovalNode } from './tree/types';
@@ -93,7 +94,7 @@ export function deserialize<T extends AsyncServerValue>(source: string): T {
93
94
  return (0, eval)(source) as T;
94
95
  }
95
96
 
96
- interface SerovalJSON {
97
+ export interface SerovalJSON {
97
98
  t: SerovalNode,
98
99
  r: number,
99
100
  i: boolean,
@@ -104,45 +105,48 @@ interface SerovalJSON {
104
105
  export function toJSON<T extends ServerValue>(
105
106
  source: T,
106
107
  options?: Partial<Options>,
107
- ) {
108
+ ): SerovalJSON {
108
109
  const ctx = createParserContext(options);
109
110
  const [tree, root, isObject] = parseSync(ctx, source);
110
- return JSON.stringify({
111
+ return {
111
112
  t: tree,
112
113
  r: root,
113
114
  i: isObject,
114
115
  f: ctx.features,
115
116
  m: Array.from(ctx.markedRefs),
116
- });
117
+ };
117
118
  }
118
119
 
119
120
  export async function toJSONAsync<T extends AsyncServerValue>(
120
121
  source: T,
121
122
  options?: Partial<Options>,
122
- ) {
123
+ ): Promise<SerovalJSON> {
123
124
  const ctx = createParserContext(options);
124
125
  const [tree, root, isObject] = await parseAsync(ctx, source);
125
- return JSON.stringify({
126
+ return {
126
127
  t: tree,
127
128
  r: root,
128
129
  i: isObject,
129
130
  f: ctx.features,
130
131
  m: Array.from(ctx.markedRefs),
131
- });
132
+ };
132
133
  }
133
134
 
134
- export function compileJSON(source: string): string {
135
- const parsed = JSON.parse(source) as SerovalJSON;
135
+ export function compileJSON(source: SerovalJSON): string {
136
136
  const serial = createSerializationContext({
137
- features: parsed.f,
138
- markedRefs: parsed.m,
137
+ features: source.f,
138
+ markedRefs: source.m,
139
139
  });
140
- const result = serializeTree(serial, parsed.t);
141
- return finalize(serial, parsed.r, parsed.i, result);
140
+ const result = serializeTree(serial, source.t);
141
+ return finalize(serial, source.r, source.i, result);
142
142
  }
143
143
 
144
- export function fromJSON<T extends AsyncServerValue>(source: string): T {
145
- return deserialize<T>(compileJSON(source));
144
+ export function fromJSON<T extends AsyncServerValue>(source: SerovalJSON): T {
145
+ const serial = createSerializationContext({
146
+ features: source.f,
147
+ markedRefs: source.m,
148
+ });
149
+ return deserializeTree(serial, source.t) as T;
146
150
  }
147
151
 
148
152
  export default serialize;
package/src/quote.ts CHANGED
@@ -41,5 +41,16 @@ export default function quote(str: string) {
41
41
  } else {
42
42
  result += str.slice(lastPos);
43
43
  }
44
- return '"' + result + '"';
44
+ return result;
45
+ }
46
+
47
+ export function invQuote(str: string): string {
48
+ return str
49
+ .replace(/\\"/g, '"')
50
+ .replace(/\\\\/g, '\\')
51
+ .replace(/\\x3C/g, '<')
52
+ .replace(/\\n/g, '\n')
53
+ .replace(/\\r/g, '\r')
54
+ .replace(/\\u2028/g, '\u2028')
55
+ .replace(/\\u2029/g, '\u2029');
45
56
  }
package/src/tree/async.ts CHANGED
@@ -3,7 +3,6 @@
3
3
  import assert from '../assert';
4
4
  import { Feature } from '../compat';
5
5
  import { createRef, ParserContext } from '../context';
6
- import quote from '../quote';
7
6
  import {
8
7
  AsyncServerValue,
9
8
  BigIntTypedArrayValue,
@@ -13,22 +12,28 @@ import {
13
12
  createBigIntNode,
14
13
  createBigIntTypedArrayNode,
15
14
  createDateNode,
16
- createPrimitiveNode,
15
+ createNumberNode,
17
16
  createReferenceNode,
18
17
  createRegExpNode,
18
+ createStringNode,
19
19
  createTypedArrayNode,
20
+ createWKSymbolNode,
20
21
  FALSE_NODE,
22
+ INFINITY_NODE,
23
+ NAN_NODE,
24
+ NEG_INFINITY_NODE,
21
25
  NEG_ZERO_NODE,
22
26
  NULL_NODE,
23
27
  TRUE_NODE,
24
28
  UNDEFINED_NODE,
25
29
  } from './primitives';
26
30
  import {
27
- getErrorConstructor,
31
+ getErrorConstructorName,
28
32
  getErrorOptions,
29
33
  getIterableOptions,
30
34
  isIterable,
31
35
  } from './shared';
36
+ import { INV_SYMBOL_REF } from './symbols';
32
37
  import {
33
38
  SerovalAggregateErrorNode,
34
39
  SerovalArrayNode,
@@ -90,7 +95,7 @@ async function generateArrayNode(
90
95
  t: SerovalNodeType.Array,
91
96
  i: id,
92
97
  s: undefined,
93
- l: undefined,
98
+ l: current.length,
94
99
  c: undefined,
95
100
  m: undefined,
96
101
  d: undefined,
@@ -168,7 +173,7 @@ async function generateSetNode(
168
173
  t: SerovalNodeType.Set,
169
174
  i: id,
170
175
  s: undefined,
171
- l: undefined,
176
+ l: len,
172
177
  c: undefined,
173
178
  m: undefined,
174
179
  d: undefined,
@@ -218,20 +223,21 @@ async function generateIterableNode(
218
223
  id: number,
219
224
  current: Iterable<AsyncServerValue>,
220
225
  ): Promise<SerovalIterableNode> {
221
- assert(ctx.features & Feature.SymbolIterator, 'Unsupported type "Iterable"');
226
+ assert(ctx.features & Feature.Symbol, 'Unsupported type "Iterable"');
222
227
  const options = getIterableOptions(current);
228
+ const array = Array.from(current);
223
229
  return {
224
230
  t: SerovalNodeType.Iterable,
225
231
  i: id,
226
232
  s: undefined,
227
- l: undefined,
233
+ l: array.length,
228
234
  c: undefined,
229
235
  m: undefined,
230
236
  // Parse options first before the items
231
237
  d: options
232
238
  ? await generateProperties(ctx, options as Record<string, AsyncServerValue>)
233
239
  : undefined,
234
- a: await generateNodeList(ctx, Array.from(current)),
240
+ a: await generateNodeList(ctx, array),
235
241
  n: undefined,
236
242
  };
237
243
  }
@@ -294,12 +300,12 @@ async function generateAggregateErrorNode(
294
300
  t: SerovalNodeType.AggregateError,
295
301
  i: id,
296
302
  s: undefined,
297
- l: undefined,
303
+ l: current.errors.length,
298
304
  c: undefined,
299
305
  m: current.message,
300
306
  d: optionsNode,
301
- a: undefined,
302
- n: await parse(ctx, current.errors),
307
+ a: await generateNodeList(ctx, current.errors as AsyncServerValue[]),
308
+ n: undefined,
303
309
  };
304
310
  }
305
311
 
@@ -317,7 +323,7 @@ async function generateErrorNode(
317
323
  i: id,
318
324
  s: undefined,
319
325
  l: undefined,
320
- c: getErrorConstructor(current),
326
+ c: getErrorConstructorName(current),
321
327
  m: current.message,
322
328
  d: optionsNode,
323
329
  a: undefined,
@@ -335,18 +341,22 @@ async function parse(
335
341
  case 'undefined':
336
342
  return UNDEFINED_NODE;
337
343
  case 'string':
338
- return createPrimitiveNode(quote(current));
344
+ return createStringNode(current);
339
345
  case 'number':
346
+ // eslint-disable-next-line no-self-compare
347
+ if (current !== current) {
348
+ return NAN_NODE;
349
+ }
340
350
  if (Object.is(current, -0)) {
341
351
  return NEG_ZERO_NODE;
342
352
  }
343
353
  if (Object.is(current, Infinity)) {
344
- return createPrimitiveNode('1/0');
354
+ return INFINITY_NODE;
345
355
  }
346
356
  if (Object.is(current, -Infinity)) {
347
- return createPrimitiveNode('-1/0');
357
+ return NEG_INFINITY_NODE;
348
358
  }
349
- return createPrimitiveNode(current);
359
+ return createNumberNode(current);
350
360
  case 'bigint':
351
361
  return createBigIntNode(ctx, current);
352
362
  case 'object': {
@@ -443,6 +453,10 @@ async function parse(
443
453
  }
444
454
  throw new Error('Unsupported type');
445
455
  }
456
+ case 'symbol':
457
+ assert(ctx.features & Feature.Symbol, 'Unsupported type "symbol"');
458
+ assert(current in INV_SYMBOL_REF, 'seroval only supports well-known symbols');
459
+ return createWKSymbolNode(current);
446
460
  default:
447
461
  throw new Error('Unsupported type');
448
462
  }