seroval 0.4.0-alpha.12 → 0.4.0-alpha.13
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/dist/cjs/development/index.cjs +298 -329
- package/dist/cjs/development/index.cjs.map +3 -3
- package/dist/cjs/production/index.cjs +2 -2
- package/dist/esm/development/index.mjs +298 -329
- package/dist/esm/development/index.mjs.map +3 -3
- package/dist/esm/production/index.mjs +2 -2
- package/dist/types/context.d.ts +11 -11
- package/dist/types/tree/primitives.d.ts +1 -10
- package/dist/types/tree/types.d.ts +57 -38
- package/package.json +2 -2
- package/src/context.ts +37 -39
- package/src/index.ts +8 -9
- package/src/tree/async.ts +48 -111
- package/src/tree/primitives.ts +7 -143
- package/src/tree/sync.ts +45 -94
- package/src/tree/types.ts +202 -53
package/src/tree/async.ts
CHANGED
|
@@ -10,14 +10,9 @@ import {
|
|
|
10
10
|
TypedArrayValue,
|
|
11
11
|
} from '../types';
|
|
12
12
|
import {
|
|
13
|
-
createBigIntNode,
|
|
14
|
-
createBigIntTypedArrayNode,
|
|
15
|
-
createDateNode,
|
|
16
|
-
createPrimitiveNode,
|
|
17
|
-
createReferenceNode,
|
|
18
|
-
createRegExpNode,
|
|
19
|
-
createTypedArrayNode,
|
|
20
13
|
FALSE_NODE,
|
|
14
|
+
INFINITY_NODE,
|
|
15
|
+
NEG_INFINITY_NODE,
|
|
21
16
|
NEG_ZERO_NODE,
|
|
22
17
|
NULL_NODE,
|
|
23
18
|
TRUE_NODE,
|
|
@@ -32,16 +27,24 @@ import {
|
|
|
32
27
|
import {
|
|
33
28
|
SerovalAggregateErrorNode,
|
|
34
29
|
SerovalArrayNode,
|
|
30
|
+
SerovalBigIntNode,
|
|
31
|
+
SerovalBigIntTypedArrayNode,
|
|
32
|
+
SerovalDateNode,
|
|
35
33
|
SerovalErrorNode,
|
|
36
34
|
SerovalIterableNode,
|
|
37
35
|
SerovalMapNode,
|
|
36
|
+
SerovalMapRecordNode,
|
|
38
37
|
SerovalNode,
|
|
39
38
|
SerovalNodeType,
|
|
40
39
|
SerovalNullConstructorNode,
|
|
41
40
|
SerovalObjectNode,
|
|
42
41
|
SerovalObjectRecordNode,
|
|
42
|
+
SerovalPrimitiveNode,
|
|
43
43
|
SerovalPromiseNode,
|
|
44
|
+
SerovalReferenceNode,
|
|
45
|
+
SerovalRegExpNode,
|
|
44
46
|
SerovalSetNode,
|
|
47
|
+
SerovalTypedArrayNode,
|
|
45
48
|
} from './types';
|
|
46
49
|
|
|
47
50
|
type ObjectLikeNode =
|
|
@@ -91,17 +94,7 @@ class AsyncParser {
|
|
|
91
94
|
id: number,
|
|
92
95
|
current: AsyncServerValue[],
|
|
93
96
|
): Promise<SerovalArrayNode> {
|
|
94
|
-
return
|
|
95
|
-
t: SerovalNodeType.Array,
|
|
96
|
-
i: id,
|
|
97
|
-
a: await this.generateNodeList(current),
|
|
98
|
-
s: undefined,
|
|
99
|
-
l: undefined,
|
|
100
|
-
m: undefined,
|
|
101
|
-
c: undefined,
|
|
102
|
-
d: undefined,
|
|
103
|
-
n: undefined,
|
|
104
|
-
};
|
|
97
|
+
return new SerovalArrayNode(id, await this.generateNodeList(current));
|
|
105
98
|
}
|
|
106
99
|
|
|
107
100
|
async generateMapNode(
|
|
@@ -132,17 +125,7 @@ class AsyncParser {
|
|
|
132
125
|
keyNodes[nodeSize + i] = await this.parse(deferredKey[i]);
|
|
133
126
|
valueNodes[nodeSize + i] = await this.parse(deferredValue[i]);
|
|
134
127
|
}
|
|
135
|
-
return
|
|
136
|
-
t: SerovalNodeType.Map,
|
|
137
|
-
i: id,
|
|
138
|
-
a: undefined,
|
|
139
|
-
s: undefined,
|
|
140
|
-
l: undefined,
|
|
141
|
-
m: undefined,
|
|
142
|
-
c: undefined,
|
|
143
|
-
d: { k: keyNodes, v: valueNodes, s: len },
|
|
144
|
-
n: undefined,
|
|
145
|
-
};
|
|
128
|
+
return new SerovalMapNode(id, new SerovalMapRecordNode(keyNodes, valueNodes, len));
|
|
146
129
|
}
|
|
147
130
|
|
|
148
131
|
async generateSetNode(
|
|
@@ -167,17 +150,7 @@ class AsyncParser {
|
|
|
167
150
|
for (let i = 0; i < deferredSize; i++) {
|
|
168
151
|
nodes[nodeSize + i] = await this.parse(deferred[i]);
|
|
169
152
|
}
|
|
170
|
-
return
|
|
171
|
-
t: SerovalNodeType.Set,
|
|
172
|
-
i: id,
|
|
173
|
-
a: nodes,
|
|
174
|
-
s: undefined,
|
|
175
|
-
l: undefined,
|
|
176
|
-
m: undefined,
|
|
177
|
-
c: undefined,
|
|
178
|
-
d: undefined,
|
|
179
|
-
n: undefined,
|
|
180
|
-
};
|
|
153
|
+
return new SerovalSetNode(id, nodes);
|
|
181
154
|
}
|
|
182
155
|
|
|
183
156
|
async generateProperties(
|
|
@@ -208,11 +181,7 @@ class AsyncParser {
|
|
|
208
181
|
keyNodes[nodesSize + i] = deferredKeys[i];
|
|
209
182
|
valueNodes[nodesSize + i] = await this.parse(deferredValues[i]);
|
|
210
183
|
}
|
|
211
|
-
return
|
|
212
|
-
k: keyNodes,
|
|
213
|
-
v: valueNodes,
|
|
214
|
-
s: size,
|
|
215
|
-
};
|
|
184
|
+
return new SerovalObjectRecordNode(keyNodes, valueNodes, size);
|
|
216
185
|
}
|
|
217
186
|
|
|
218
187
|
async generateIterableNode(
|
|
@@ -221,20 +190,14 @@ class AsyncParser {
|
|
|
221
190
|
): Promise<SerovalIterableNode> {
|
|
222
191
|
assert(this.ctx.features & Feature.SymbolIterator, 'Unsupported type "Iterable"');
|
|
223
192
|
const options = getIterableOptions(current);
|
|
224
|
-
return
|
|
225
|
-
|
|
226
|
-
i: id,
|
|
227
|
-
s: undefined,
|
|
228
|
-
l: undefined,
|
|
229
|
-
m: undefined,
|
|
230
|
-
c: undefined,
|
|
193
|
+
return new SerovalIterableNode(
|
|
194
|
+
id,
|
|
231
195
|
// Parse options first before the items
|
|
232
|
-
|
|
196
|
+
options
|
|
233
197
|
? await this.generateProperties(options as Record<string, AsyncServerValue>)
|
|
234
198
|
: undefined,
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
};
|
|
199
|
+
await this.generateNodeList(Array.from(current)),
|
|
200
|
+
);
|
|
238
201
|
}
|
|
239
202
|
|
|
240
203
|
async generatePromiseNode(
|
|
@@ -242,18 +205,7 @@ class AsyncParser {
|
|
|
242
205
|
current: PromiseLike<AsyncServerValue>,
|
|
243
206
|
): Promise<SerovalPromiseNode> {
|
|
244
207
|
assert(this.ctx.features & Feature.Promise, 'Unsupported type "Promise"');
|
|
245
|
-
return current.then(async (value) => (
|
|
246
|
-
t: SerovalNodeType.Promise,
|
|
247
|
-
i: id,
|
|
248
|
-
s: undefined,
|
|
249
|
-
l: undefined,
|
|
250
|
-
m: undefined,
|
|
251
|
-
c: undefined,
|
|
252
|
-
// Parse options first before the items
|
|
253
|
-
d: undefined,
|
|
254
|
-
a: undefined,
|
|
255
|
-
n: await this.parse(value),
|
|
256
|
-
}));
|
|
208
|
+
return current.then(async (value) => new SerovalPromiseNode(id, await this.parse(value)));
|
|
257
209
|
}
|
|
258
210
|
|
|
259
211
|
async generateObjectNode(
|
|
@@ -267,17 +219,11 @@ class AsyncParser {
|
|
|
267
219
|
if ('then' in current && typeof current.then === 'function') {
|
|
268
220
|
return this.generatePromiseNode(id, current as PromiseLike<AsyncServerValue>);
|
|
269
221
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
m: undefined,
|
|
276
|
-
c: undefined,
|
|
277
|
-
d: await this.generateProperties(current as Record<string, AsyncServerValue>),
|
|
278
|
-
a: undefined,
|
|
279
|
-
n: undefined,
|
|
280
|
-
};
|
|
222
|
+
const properties = await this.generateProperties(current as Record<string, AsyncServerValue>);
|
|
223
|
+
if (empty) {
|
|
224
|
+
return new SerovalNullConstructorNode(id, properties);
|
|
225
|
+
}
|
|
226
|
+
return new SerovalObjectNode(id, properties);
|
|
281
227
|
}
|
|
282
228
|
|
|
283
229
|
async generateAggregateErrorNode(
|
|
@@ -288,17 +234,12 @@ class AsyncParser {
|
|
|
288
234
|
const optionsNode = options
|
|
289
235
|
? await this.generateProperties(options)
|
|
290
236
|
: undefined;
|
|
291
|
-
return
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
m: current.message,
|
|
298
|
-
c: undefined,
|
|
299
|
-
d: optionsNode,
|
|
300
|
-
n: await this.parse(current.errors),
|
|
301
|
-
};
|
|
237
|
+
return new SerovalAggregateErrorNode(
|
|
238
|
+
id,
|
|
239
|
+
current.message,
|
|
240
|
+
optionsNode,
|
|
241
|
+
await this.parse(current.errors),
|
|
242
|
+
);
|
|
302
243
|
}
|
|
303
244
|
|
|
304
245
|
async generateErrorNode(
|
|
@@ -309,17 +250,7 @@ class AsyncParser {
|
|
|
309
250
|
const optionsNode = options
|
|
310
251
|
? await this.generateProperties(options)
|
|
311
252
|
: undefined;
|
|
312
|
-
return
|
|
313
|
-
t: SerovalNodeType.Error,
|
|
314
|
-
i: id,
|
|
315
|
-
a: undefined,
|
|
316
|
-
s: undefined,
|
|
317
|
-
l: undefined,
|
|
318
|
-
m: current.message,
|
|
319
|
-
c: getErrorConstructor(current),
|
|
320
|
-
d: optionsNode,
|
|
321
|
-
n: undefined,
|
|
322
|
-
};
|
|
253
|
+
return new SerovalErrorNode(id, getErrorConstructor(current), current.message, optionsNode);
|
|
323
254
|
}
|
|
324
255
|
|
|
325
256
|
async parse(current: AsyncServerValue): Promise<SerovalNode> {
|
|
@@ -329,20 +260,21 @@ class AsyncParser {
|
|
|
329
260
|
case 'undefined':
|
|
330
261
|
return UNDEFINED_NODE;
|
|
331
262
|
case 'string':
|
|
332
|
-
return
|
|
263
|
+
return new SerovalPrimitiveNode(quote(current));
|
|
333
264
|
case 'number':
|
|
334
265
|
if (Object.is(current, -0)) {
|
|
335
266
|
return NEG_ZERO_NODE;
|
|
336
267
|
}
|
|
337
268
|
if (Object.is(current, Infinity)) {
|
|
338
|
-
return
|
|
269
|
+
return INFINITY_NODE;
|
|
339
270
|
}
|
|
340
271
|
if (Object.is(current, -Infinity)) {
|
|
341
|
-
return
|
|
272
|
+
return NEG_INFINITY_NODE;
|
|
342
273
|
}
|
|
343
|
-
return
|
|
274
|
+
return new SerovalPrimitiveNode(current);
|
|
344
275
|
case 'bigint':
|
|
345
|
-
|
|
276
|
+
assert(this.ctx.features & Feature.BigInt, 'Unsupported type "BigInt"');
|
|
277
|
+
return new SerovalBigIntNode(current);
|
|
346
278
|
case 'object': {
|
|
347
279
|
if (!current) {
|
|
348
280
|
return NULL_NODE;
|
|
@@ -351,16 +283,16 @@ class AsyncParser {
|
|
|
351
283
|
// mostly because the values themselves are stateful
|
|
352
284
|
const id = createRef(this.ctx, current, true);
|
|
353
285
|
if (this.ctx.markedRefs[id]) {
|
|
354
|
-
return
|
|
286
|
+
return new SerovalReferenceNode(id);
|
|
355
287
|
}
|
|
356
288
|
if (Array.isArray(current)) {
|
|
357
289
|
return this.generateArrayNode(id, current);
|
|
358
290
|
}
|
|
359
291
|
switch (current.constructor) {
|
|
360
292
|
case Date:
|
|
361
|
-
return
|
|
293
|
+
return new SerovalDateNode(id, current as Date);
|
|
362
294
|
case RegExp:
|
|
363
|
-
return
|
|
295
|
+
return new SerovalRegExpNode(id, current as RegExp);
|
|
364
296
|
case Promise:
|
|
365
297
|
return this.generatePromiseNode(id, current as Promise<AsyncServerValue>);
|
|
366
298
|
case Int8Array:
|
|
@@ -372,10 +304,15 @@ class AsyncParser {
|
|
|
372
304
|
case Uint8ClampedArray:
|
|
373
305
|
case Float32Array:
|
|
374
306
|
case Float64Array:
|
|
375
|
-
|
|
307
|
+
assert(this.ctx.features & Feature.TypedArray, `Unsupported value type "${current.constructor.name}"`);
|
|
308
|
+
return new SerovalTypedArrayNode(id, current as TypedArrayValue);
|
|
376
309
|
case BigInt64Array:
|
|
377
310
|
case BigUint64Array:
|
|
378
|
-
|
|
311
|
+
assert(
|
|
312
|
+
this.ctx.features & (Feature.BigIntTypedArray),
|
|
313
|
+
`Unsupported value type "${current.constructor.name}"`,
|
|
314
|
+
);
|
|
315
|
+
return new SerovalBigIntTypedArrayNode(id, current as BigIntTypedArrayValue);
|
|
379
316
|
case Map:
|
|
380
317
|
return this.generateMapNode(id, current as Map<AsyncServerValue, AsyncServerValue>);
|
|
381
318
|
case Set:
|
package/src/tree/primitives.ts
CHANGED
|
@@ -1,147 +1,11 @@
|
|
|
1
|
-
import assert from '../assert';
|
|
2
|
-
import { Feature } from '../compat';
|
|
3
|
-
import { ParserContext } from '../context';
|
|
4
|
-
import { BigIntTypedArrayValue, TypedArrayValue } from '../types';
|
|
5
1
|
import {
|
|
6
|
-
SerovalBigIntNode,
|
|
7
|
-
SerovalBigIntTypedArrayNode,
|
|
8
|
-
SerovalDateNode,
|
|
9
|
-
SerovalNodeType,
|
|
10
2
|
SerovalPrimitiveNode,
|
|
11
|
-
SerovalReferenceNode,
|
|
12
|
-
SerovalRegExpNode,
|
|
13
|
-
SerovalTypedArrayNode,
|
|
14
3
|
} from './types';
|
|
15
4
|
|
|
16
|
-
export
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
l: undefined,
|
|
24
|
-
m: undefined,
|
|
25
|
-
c: undefined,
|
|
26
|
-
d: undefined,
|
|
27
|
-
a: undefined,
|
|
28
|
-
n: undefined,
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export const TRUE_NODE = createPrimitiveNode('!0');
|
|
33
|
-
export const FALSE_NODE = createPrimitiveNode('!1');
|
|
34
|
-
export const UNDEFINED_NODE = createPrimitiveNode('void 0');
|
|
35
|
-
export const NULL_NODE = createPrimitiveNode(null);
|
|
36
|
-
export const NEG_ZERO_NODE = createPrimitiveNode('-0');
|
|
37
|
-
export const INFINITY_NODE = createPrimitiveNode('1/0');
|
|
38
|
-
export const NEG_INFINITY_NODE = createPrimitiveNode('-1/0');
|
|
39
|
-
|
|
40
|
-
export function createBigIntNode(
|
|
41
|
-
ctx: ParserContext,
|
|
42
|
-
current: bigint,
|
|
43
|
-
): SerovalBigIntNode {
|
|
44
|
-
assert(ctx.features & Feature.BigInt, 'Unsupported type "BigInt"');
|
|
45
|
-
return {
|
|
46
|
-
t: SerovalNodeType.BigInt,
|
|
47
|
-
i: undefined,
|
|
48
|
-
a: undefined,
|
|
49
|
-
s: `${current}n`,
|
|
50
|
-
l: undefined,
|
|
51
|
-
m: undefined,
|
|
52
|
-
c: undefined,
|
|
53
|
-
d: undefined,
|
|
54
|
-
n: undefined,
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export function createReferenceNode(id: number): SerovalReferenceNode {
|
|
59
|
-
return {
|
|
60
|
-
t: SerovalNodeType.Reference,
|
|
61
|
-
i: id,
|
|
62
|
-
a: undefined,
|
|
63
|
-
s: undefined,
|
|
64
|
-
l: undefined,
|
|
65
|
-
m: undefined,
|
|
66
|
-
c: undefined,
|
|
67
|
-
d: undefined,
|
|
68
|
-
n: undefined,
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export function createDateNode(id: number, current: Date): SerovalDateNode {
|
|
73
|
-
return {
|
|
74
|
-
t: SerovalNodeType.Date,
|
|
75
|
-
i: id,
|
|
76
|
-
a: undefined,
|
|
77
|
-
s: current.toISOString(),
|
|
78
|
-
l: undefined,
|
|
79
|
-
m: undefined,
|
|
80
|
-
c: undefined,
|
|
81
|
-
d: undefined,
|
|
82
|
-
n: undefined,
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export function createRegExpNode(id: number, current: RegExp): SerovalRegExpNode {
|
|
87
|
-
return {
|
|
88
|
-
t: SerovalNodeType.RegExp,
|
|
89
|
-
i: id,
|
|
90
|
-
a: undefined,
|
|
91
|
-
s: String(current),
|
|
92
|
-
l: undefined,
|
|
93
|
-
m: undefined,
|
|
94
|
-
c: undefined,
|
|
95
|
-
d: undefined,
|
|
96
|
-
n: undefined,
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export function createTypedArrayNode(
|
|
101
|
-
ctx: ParserContext,
|
|
102
|
-
id: number,
|
|
103
|
-
current: TypedArrayValue,
|
|
104
|
-
): SerovalTypedArrayNode {
|
|
105
|
-
const constructor = current.constructor.name;
|
|
106
|
-
assert(ctx.features & Feature.TypedArray, `Unsupported value type "${constructor}"`);
|
|
107
|
-
return {
|
|
108
|
-
t: SerovalNodeType.TypedArray,
|
|
109
|
-
i: id,
|
|
110
|
-
a: undefined,
|
|
111
|
-
s: current.toString(),
|
|
112
|
-
l: current.byteOffset,
|
|
113
|
-
m: undefined,
|
|
114
|
-
c: constructor,
|
|
115
|
-
d: undefined,
|
|
116
|
-
n: undefined,
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export function createBigIntTypedArrayNode(
|
|
121
|
-
ctx: ParserContext,
|
|
122
|
-
id: number,
|
|
123
|
-
current: BigIntTypedArrayValue,
|
|
124
|
-
): SerovalBigIntTypedArrayNode {
|
|
125
|
-
const constructor = current.constructor.name;
|
|
126
|
-
assert(
|
|
127
|
-
ctx.features & (Feature.BigIntTypedArray),
|
|
128
|
-
`Unsupported value type "${constructor}"`,
|
|
129
|
-
);
|
|
130
|
-
let result = '';
|
|
131
|
-
const cap = current.length - 1;
|
|
132
|
-
for (let i = 0; i < cap; i++) {
|
|
133
|
-
result += `${current[i]}n,`;
|
|
134
|
-
}
|
|
135
|
-
result += `"${current[cap]}"`;
|
|
136
|
-
return {
|
|
137
|
-
t: SerovalNodeType.BigIntTypedArray,
|
|
138
|
-
i: id,
|
|
139
|
-
a: undefined,
|
|
140
|
-
s: result,
|
|
141
|
-
l: (current as BigInt64Array).byteOffset,
|
|
142
|
-
m: undefined,
|
|
143
|
-
c: constructor,
|
|
144
|
-
d: undefined,
|
|
145
|
-
n: undefined,
|
|
146
|
-
};
|
|
147
|
-
}
|
|
5
|
+
export const TRUE_NODE = new SerovalPrimitiveNode('!0');
|
|
6
|
+
export const FALSE_NODE = new SerovalPrimitiveNode('!1');
|
|
7
|
+
export const UNDEFINED_NODE = new SerovalPrimitiveNode('void 0');
|
|
8
|
+
export const NULL_NODE = new SerovalPrimitiveNode(null);
|
|
9
|
+
export const NEG_ZERO_NODE = new SerovalPrimitiveNode('-0');
|
|
10
|
+
export const INFINITY_NODE = new SerovalPrimitiveNode('1/0');
|
|
11
|
+
export const NEG_INFINITY_NODE = new SerovalPrimitiveNode('-1/0');
|
package/src/tree/sync.ts
CHANGED
|
@@ -5,14 +5,9 @@ import { createRef, ParserContext } from '../context';
|
|
|
5
5
|
import quote from '../quote';
|
|
6
6
|
import { BigIntTypedArrayValue, ServerValue, TypedArrayValue } from '../types';
|
|
7
7
|
import {
|
|
8
|
-
createBigIntNode,
|
|
9
|
-
createBigIntTypedArrayNode,
|
|
10
|
-
createDateNode,
|
|
11
|
-
createPrimitiveNode,
|
|
12
|
-
createReferenceNode,
|
|
13
|
-
createRegExpNode,
|
|
14
|
-
createTypedArrayNode,
|
|
15
8
|
FALSE_NODE,
|
|
9
|
+
INFINITY_NODE,
|
|
10
|
+
NEG_INFINITY_NODE,
|
|
16
11
|
NEG_ZERO_NODE,
|
|
17
12
|
NULL_NODE,
|
|
18
13
|
TRUE_NODE,
|
|
@@ -27,15 +22,23 @@ import {
|
|
|
27
22
|
import {
|
|
28
23
|
SerovalAggregateErrorNode,
|
|
29
24
|
SerovalArrayNode,
|
|
25
|
+
SerovalBigIntNode,
|
|
26
|
+
SerovalBigIntTypedArrayNode,
|
|
27
|
+
SerovalDateNode,
|
|
30
28
|
SerovalErrorNode,
|
|
31
29
|
SerovalIterableNode,
|
|
32
30
|
SerovalMapNode,
|
|
31
|
+
SerovalMapRecordNode,
|
|
33
32
|
SerovalNode,
|
|
34
33
|
SerovalNodeType,
|
|
35
34
|
SerovalNullConstructorNode,
|
|
36
35
|
SerovalObjectNode,
|
|
37
36
|
SerovalObjectRecordNode,
|
|
37
|
+
SerovalPrimitiveNode,
|
|
38
|
+
SerovalReferenceNode,
|
|
39
|
+
SerovalRegExpNode,
|
|
38
40
|
SerovalSetNode,
|
|
41
|
+
SerovalTypedArrayNode,
|
|
39
42
|
} from './types';
|
|
40
43
|
|
|
41
44
|
type ObjectLikeNode = SerovalObjectNode | SerovalNullConstructorNode | SerovalIterableNode;
|
|
@@ -71,17 +74,7 @@ class SyncParser {
|
|
|
71
74
|
}
|
|
72
75
|
|
|
73
76
|
generateArrayNode(id: number, current: ServerValue[]): SerovalArrayNode {
|
|
74
|
-
return
|
|
75
|
-
t: SerovalNodeType.Array,
|
|
76
|
-
i: id,
|
|
77
|
-
a: this.generateNodeList(current),
|
|
78
|
-
s: undefined,
|
|
79
|
-
l: undefined,
|
|
80
|
-
m: undefined,
|
|
81
|
-
c: undefined,
|
|
82
|
-
d: undefined,
|
|
83
|
-
n: undefined,
|
|
84
|
-
};
|
|
77
|
+
return new SerovalArrayNode(id, this.generateNodeList(current));
|
|
85
78
|
}
|
|
86
79
|
|
|
87
80
|
generateMapNode(
|
|
@@ -112,17 +105,7 @@ class SyncParser {
|
|
|
112
105
|
keyNodes[nodeSize + i] = this.parse(deferredKey[i]);
|
|
113
106
|
valueNodes[nodeSize + i] = this.parse(deferredValue[i]);
|
|
114
107
|
}
|
|
115
|
-
return
|
|
116
|
-
t: SerovalNodeType.Map,
|
|
117
|
-
i: id,
|
|
118
|
-
a: undefined,
|
|
119
|
-
s: undefined,
|
|
120
|
-
l: undefined,
|
|
121
|
-
m: undefined,
|
|
122
|
-
c: undefined,
|
|
123
|
-
d: { k: keyNodes, v: valueNodes, s: len },
|
|
124
|
-
n: undefined,
|
|
125
|
-
};
|
|
108
|
+
return new SerovalMapNode(id, new SerovalMapRecordNode(keyNodes, valueNodes, len));
|
|
126
109
|
}
|
|
127
110
|
|
|
128
111
|
generateSetNode(
|
|
@@ -147,17 +130,7 @@ class SyncParser {
|
|
|
147
130
|
for (let i = 0; i < deferredSize; i++) {
|
|
148
131
|
nodes[nodeSize + i] = this.parse(deferred[i]);
|
|
149
132
|
}
|
|
150
|
-
return
|
|
151
|
-
t: SerovalNodeType.Set,
|
|
152
|
-
i: id,
|
|
153
|
-
a: nodes,
|
|
154
|
-
s: undefined,
|
|
155
|
-
l: undefined,
|
|
156
|
-
m: undefined,
|
|
157
|
-
c: undefined,
|
|
158
|
-
d: undefined,
|
|
159
|
-
n: undefined,
|
|
160
|
-
};
|
|
133
|
+
return new SerovalSetNode(id, nodes);
|
|
161
134
|
}
|
|
162
135
|
|
|
163
136
|
generateProperties(properties: Record<string, ServerValue>): SerovalObjectRecordNode {
|
|
@@ -199,20 +172,14 @@ class SyncParser {
|
|
|
199
172
|
): SerovalIterableNode {
|
|
200
173
|
assert(this.ctx.features & Feature.SymbolIterator, 'Unsupported type "Iterable"');
|
|
201
174
|
const options = getIterableOptions(current);
|
|
202
|
-
return
|
|
203
|
-
|
|
204
|
-
i: id,
|
|
205
|
-
s: undefined,
|
|
206
|
-
l: undefined,
|
|
207
|
-
m: undefined,
|
|
208
|
-
c: undefined,
|
|
175
|
+
return new SerovalIterableNode(
|
|
176
|
+
id,
|
|
209
177
|
// Parse options first before the items
|
|
210
|
-
|
|
178
|
+
options
|
|
211
179
|
? this.generateProperties(options as Record<string, ServerValue>)
|
|
212
180
|
: undefined,
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
};
|
|
181
|
+
this.generateNodeList(Array.from(current)),
|
|
182
|
+
);
|
|
216
183
|
}
|
|
217
184
|
|
|
218
185
|
generateObjectNode(
|
|
@@ -223,17 +190,10 @@ class SyncParser {
|
|
|
223
190
|
if (Symbol.iterator in current) {
|
|
224
191
|
return this.generateIterableNode(id, current);
|
|
225
192
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
l: undefined,
|
|
231
|
-
m: undefined,
|
|
232
|
-
c: undefined,
|
|
233
|
-
d: this.generateProperties(current),
|
|
234
|
-
a: undefined,
|
|
235
|
-
n: undefined,
|
|
236
|
-
};
|
|
193
|
+
if (empty) {
|
|
194
|
+
return new SerovalNullConstructorNode(id, this.generateProperties(current));
|
|
195
|
+
}
|
|
196
|
+
return new SerovalObjectNode(id, this.generateProperties(current));
|
|
237
197
|
}
|
|
238
198
|
|
|
239
199
|
generateAggregateErrorNode(
|
|
@@ -244,17 +204,12 @@ class SyncParser {
|
|
|
244
204
|
const optionsNode = options
|
|
245
205
|
? this.generateProperties(options)
|
|
246
206
|
: undefined;
|
|
247
|
-
return
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
m: current.message,
|
|
254
|
-
c: undefined,
|
|
255
|
-
d: optionsNode,
|
|
256
|
-
n: this.parse(current.errors),
|
|
257
|
-
};
|
|
207
|
+
return new SerovalAggregateErrorNode(
|
|
208
|
+
id,
|
|
209
|
+
current.message,
|
|
210
|
+
optionsNode,
|
|
211
|
+
this.parse(current.errors),
|
|
212
|
+
);
|
|
258
213
|
}
|
|
259
214
|
|
|
260
215
|
generateErrorNode(
|
|
@@ -265,17 +220,7 @@ class SyncParser {
|
|
|
265
220
|
const optionsNode = options
|
|
266
221
|
? this.generateProperties(options)
|
|
267
222
|
: undefined;
|
|
268
|
-
return
|
|
269
|
-
t: SerovalNodeType.Error,
|
|
270
|
-
i: id,
|
|
271
|
-
a: undefined,
|
|
272
|
-
s: undefined,
|
|
273
|
-
l: undefined,
|
|
274
|
-
m: current.message,
|
|
275
|
-
c: getErrorConstructor(current),
|
|
276
|
-
d: optionsNode,
|
|
277
|
-
n: undefined,
|
|
278
|
-
};
|
|
223
|
+
return new SerovalErrorNode(id, getErrorConstructor(current), current.message, optionsNode);
|
|
279
224
|
}
|
|
280
225
|
|
|
281
226
|
parse(current: ServerValue): SerovalNode {
|
|
@@ -285,20 +230,21 @@ class SyncParser {
|
|
|
285
230
|
case 'undefined':
|
|
286
231
|
return UNDEFINED_NODE;
|
|
287
232
|
case 'string':
|
|
288
|
-
return
|
|
233
|
+
return new SerovalPrimitiveNode(quote(current));
|
|
289
234
|
case 'number':
|
|
290
235
|
if (Object.is(current, -0)) {
|
|
291
236
|
return NEG_ZERO_NODE;
|
|
292
237
|
}
|
|
293
238
|
if (Object.is(current, Infinity)) {
|
|
294
|
-
return
|
|
239
|
+
return INFINITY_NODE;
|
|
295
240
|
}
|
|
296
241
|
if (Object.is(current, -Infinity)) {
|
|
297
|
-
return
|
|
242
|
+
return NEG_INFINITY_NODE;
|
|
298
243
|
}
|
|
299
|
-
return
|
|
244
|
+
return new SerovalPrimitiveNode(current);
|
|
300
245
|
case 'bigint':
|
|
301
|
-
|
|
246
|
+
assert(this.ctx.features & Feature.BigInt, 'Unsupported type "BigInt"');
|
|
247
|
+
return new SerovalBigIntNode(current);
|
|
302
248
|
case 'object': {
|
|
303
249
|
if (!current) {
|
|
304
250
|
return NULL_NODE;
|
|
@@ -307,16 +253,16 @@ class SyncParser {
|
|
|
307
253
|
// mostly because the values themselves are stateful
|
|
308
254
|
const id = createRef(this.ctx, current, true);
|
|
309
255
|
if (this.ctx.markedRefs[id]) {
|
|
310
|
-
return
|
|
256
|
+
return new SerovalReferenceNode(id);
|
|
311
257
|
}
|
|
312
258
|
if (Array.isArray(current)) {
|
|
313
259
|
return this.generateArrayNode(id, current);
|
|
314
260
|
}
|
|
315
261
|
switch (current.constructor) {
|
|
316
262
|
case Date:
|
|
317
|
-
return
|
|
263
|
+
return new SerovalDateNode(id, current as Date);
|
|
318
264
|
case RegExp:
|
|
319
|
-
return
|
|
265
|
+
return new SerovalRegExpNode(id, current as RegExp);
|
|
320
266
|
case Int8Array:
|
|
321
267
|
case Int16Array:
|
|
322
268
|
case Int32Array:
|
|
@@ -326,10 +272,15 @@ class SyncParser {
|
|
|
326
272
|
case Uint8ClampedArray:
|
|
327
273
|
case Float32Array:
|
|
328
274
|
case Float64Array:
|
|
329
|
-
|
|
275
|
+
assert(this.ctx.features & Feature.TypedArray, `Unsupported value type "${current.constructor.name}"`);
|
|
276
|
+
return new SerovalTypedArrayNode(id, current as TypedArrayValue);
|
|
330
277
|
case BigInt64Array:
|
|
331
278
|
case BigUint64Array:
|
|
332
|
-
|
|
279
|
+
assert(
|
|
280
|
+
this.ctx.features & (Feature.BigIntTypedArray),
|
|
281
|
+
`Unsupported value type "${current.constructor.name}"`,
|
|
282
|
+
);
|
|
283
|
+
return new SerovalBigIntTypedArrayNode(id, current as BigIntTypedArrayValue);
|
|
333
284
|
case Map:
|
|
334
285
|
return this.generateMapNode(id, current as Map<ServerValue, ServerValue>);
|
|
335
286
|
case Set:
|