seroval 0.4.0-alpha.11 → 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 +694 -708
- package/dist/cjs/development/index.cjs.map +4 -4
- package/dist/cjs/production/index.cjs +2 -2
- package/dist/esm/development/index.mjs +696 -708
- package/dist/esm/development/index.mjs.map +4 -4
- 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 +298 -366
- package/src/tree/primitives.ts +7 -143
- package/src/tree/sync.ts +266 -326
- package/src/tree/types.ts +202 -53
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,359 +22,304 @@ 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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const valueNodes = new Array<SerovalNode>(size);
|
|
49
|
-
const deferredKeys = new Array<string>(size);
|
|
50
|
-
const deferredValues = new Array<ServerValue>(size);
|
|
51
|
-
let deferredSize = 0;
|
|
52
|
-
let nodesSize = 0;
|
|
53
|
-
let item: ServerValue;
|
|
54
|
-
for (const key of keys) {
|
|
55
|
-
item = properties[key];
|
|
56
|
-
if (isIterable(item)) {
|
|
57
|
-
deferredKeys[deferredSize] = key;
|
|
58
|
-
deferredValues[deferredSize] = item;
|
|
59
|
-
deferredSize++;
|
|
60
|
-
} else {
|
|
61
|
-
keyNodes[nodesSize] = key;
|
|
62
|
-
valueNodes[nodesSize] = generateTreeSync(ctx, item);
|
|
63
|
-
nodesSize++;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
for (let i = 0; i < deferredSize; i++) {
|
|
67
|
-
keyNodes[nodesSize + i] = deferredKeys[i];
|
|
68
|
-
valueNodes[nodesSize + i] = generateTreeSync(ctx, deferredValues[i]);
|
|
44
|
+
type ObjectLikeNode = SerovalObjectNode | SerovalNullConstructorNode | SerovalIterableNode;
|
|
45
|
+
|
|
46
|
+
class SyncParser {
|
|
47
|
+
ctx: ParserContext;
|
|
48
|
+
|
|
49
|
+
constructor(ctx: ParserContext) {
|
|
50
|
+
this.ctx = ctx;
|
|
69
51
|
}
|
|
70
|
-
return {
|
|
71
|
-
k: keyNodes,
|
|
72
|
-
v: valueNodes,
|
|
73
|
-
s: size,
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
52
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
53
|
+
generateNodeList(current: ServerValue[]) {
|
|
54
|
+
const size = current.length;
|
|
55
|
+
const nodes = new Array<SerovalNode>(size);
|
|
56
|
+
const deferred = new Array<ServerValue>(size);
|
|
57
|
+
let item: ServerValue;
|
|
58
|
+
for (let i = 0; i < size; i++) {
|
|
59
|
+
if (i in current) {
|
|
60
|
+
item = current[i];
|
|
61
|
+
if (isIterable(item)) {
|
|
62
|
+
deferred[i] = item;
|
|
63
|
+
} else {
|
|
64
|
+
nodes[i] = this.parse(item);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
for (let i = 0; i < size; i++) {
|
|
69
|
+
if (i in deferred) {
|
|
70
|
+
nodes[i] = this.parse(deferred[i]);
|
|
71
|
+
}
|
|
94
72
|
}
|
|
73
|
+
return nodes;
|
|
95
74
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
75
|
+
|
|
76
|
+
generateArrayNode(id: number, current: ServerValue[]): SerovalArrayNode {
|
|
77
|
+
return new SerovalArrayNode(id, this.generateNodeList(current));
|
|
99
78
|
}
|
|
100
|
-
return {
|
|
101
|
-
t: SerovalNodeType.Set,
|
|
102
|
-
i: id,
|
|
103
|
-
a: nodes,
|
|
104
|
-
s: undefined,
|
|
105
|
-
l: undefined,
|
|
106
|
-
m: undefined,
|
|
107
|
-
c: undefined,
|
|
108
|
-
d: undefined,
|
|
109
|
-
n: undefined,
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
79
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
80
|
+
generateMapNode(
|
|
81
|
+
id: number,
|
|
82
|
+
current: Map<ServerValue, ServerValue>,
|
|
83
|
+
): SerovalMapNode {
|
|
84
|
+
assert(this.ctx.features & Feature.Map, 'Unsupported type "Map"');
|
|
85
|
+
const len = current.size;
|
|
86
|
+
const keyNodes = new Array<SerovalNode>(len);
|
|
87
|
+
const valueNodes = new Array<SerovalNode>(len);
|
|
88
|
+
const deferredKey = new Array<ServerValue>(len);
|
|
89
|
+
const deferredValue = new Array<ServerValue>(len);
|
|
90
|
+
let deferredSize = 0;
|
|
91
|
+
let nodeSize = 0;
|
|
92
|
+
for (const [key, value] of current.entries()) {
|
|
93
|
+
// Either key or value might be an iterable
|
|
94
|
+
if (isIterable(key) || isIterable(value)) {
|
|
95
|
+
deferredKey[deferredSize] = key;
|
|
96
|
+
deferredValue[deferredSize] = value;
|
|
97
|
+
deferredSize++;
|
|
98
|
+
} else {
|
|
99
|
+
keyNodes[nodeSize] = this.parse(key);
|
|
100
|
+
valueNodes[nodeSize] = this.parse(value);
|
|
101
|
+
nodeSize++;
|
|
102
|
+
}
|
|
136
103
|
}
|
|
104
|
+
for (let i = 0; i < deferredSize; i++) {
|
|
105
|
+
keyNodes[nodeSize + i] = this.parse(deferredKey[i]);
|
|
106
|
+
valueNodes[nodeSize + i] = this.parse(deferredValue[i]);
|
|
107
|
+
}
|
|
108
|
+
return new SerovalMapNode(id, new SerovalMapRecordNode(keyNodes, valueNodes, len));
|
|
137
109
|
}
|
|
138
|
-
for (let i = 0; i < deferredSize; i++) {
|
|
139
|
-
keyNodes[nodeSize + i] = generateTreeSync(ctx, deferredKey[i]);
|
|
140
|
-
valueNodes[nodeSize + i] = generateTreeSync(ctx, deferredValue[i]);
|
|
141
|
-
}
|
|
142
|
-
return {
|
|
143
|
-
t: SerovalNodeType.Map,
|
|
144
|
-
i: id,
|
|
145
|
-
a: undefined,
|
|
146
|
-
s: undefined,
|
|
147
|
-
l: undefined,
|
|
148
|
-
m: undefined,
|
|
149
|
-
c: undefined,
|
|
150
|
-
d: { k: keyNodes, v: valueNodes, s: len },
|
|
151
|
-
n: undefined,
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
110
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
) {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
111
|
+
generateSetNode(
|
|
112
|
+
id: number,
|
|
113
|
+
current: Set<ServerValue>,
|
|
114
|
+
): SerovalSetNode {
|
|
115
|
+
assert(this.ctx.features & Feature.Set, 'Unsupported type "Set"');
|
|
116
|
+
const len = current.size;
|
|
117
|
+
const nodes = new Array<SerovalNode>(len);
|
|
118
|
+
const deferred = new Array<ServerValue>(len);
|
|
119
|
+
let deferredSize = 0;
|
|
120
|
+
let nodeSize = 0;
|
|
121
|
+
for (const item of current.keys()) {
|
|
122
|
+
// Iterables are lazy, so the evaluation must be deferred
|
|
166
123
|
if (isIterable(item)) {
|
|
167
|
-
deferred[
|
|
124
|
+
deferred[deferredSize++] = item;
|
|
168
125
|
} else {
|
|
169
|
-
nodes[
|
|
126
|
+
nodes[nodeSize++] = this.parse(item);
|
|
170
127
|
}
|
|
171
128
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
nodes[i] = generateTreeSync(ctx, deferred[i]);
|
|
129
|
+
// Parse deferred items
|
|
130
|
+
for (let i = 0; i < deferredSize; i++) {
|
|
131
|
+
nodes[nodeSize + i] = this.parse(deferred[i]);
|
|
176
132
|
}
|
|
133
|
+
return new SerovalSetNode(id, nodes);
|
|
177
134
|
}
|
|
178
|
-
return nodes;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
function generateArrayNode(
|
|
182
|
-
ctx: ParserContext,
|
|
183
|
-
current: ServerValue[],
|
|
184
|
-
id: number,
|
|
185
|
-
): SerovalArrayNode {
|
|
186
|
-
return {
|
|
187
|
-
t: SerovalNodeType.Array,
|
|
188
|
-
i: id,
|
|
189
|
-
a: generateNodeList(ctx, current),
|
|
190
|
-
s: undefined,
|
|
191
|
-
l: undefined,
|
|
192
|
-
m: undefined,
|
|
193
|
-
c: undefined,
|
|
194
|
-
d: undefined,
|
|
195
|
-
n: undefined,
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
135
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
}
|
|
136
|
+
generateProperties(properties: Record<string, ServerValue>): SerovalObjectRecordNode {
|
|
137
|
+
const keys = Object.keys(properties);
|
|
138
|
+
const size = keys.length;
|
|
139
|
+
const keyNodes = new Array<string>(size);
|
|
140
|
+
const valueNodes = new Array<SerovalNode>(size);
|
|
141
|
+
const deferredKeys = new Array<string>(size);
|
|
142
|
+
const deferredValues = new Array<ServerValue>(size);
|
|
143
|
+
let deferredSize = 0;
|
|
144
|
+
let nodesSize = 0;
|
|
145
|
+
let item: ServerValue;
|
|
146
|
+
for (const key of keys) {
|
|
147
|
+
item = properties[key];
|
|
148
|
+
if (isIterable(item)) {
|
|
149
|
+
deferredKeys[deferredSize] = key;
|
|
150
|
+
deferredValues[deferredSize] = item;
|
|
151
|
+
deferredSize++;
|
|
152
|
+
} else {
|
|
153
|
+
keyNodes[nodesSize] = key;
|
|
154
|
+
valueNodes[nodesSize] = this.parse(item);
|
|
155
|
+
nodesSize++;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
for (let i = 0; i < deferredSize; i++) {
|
|
159
|
+
keyNodes[nodesSize + i] = deferredKeys[i];
|
|
160
|
+
valueNodes[nodesSize + i] = this.parse(deferredValues[i]);
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
k: keyNodes,
|
|
164
|
+
v: valueNodes,
|
|
165
|
+
s: size,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
220
168
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
m: current.message,
|
|
237
|
-
c: getErrorConstructor(current),
|
|
238
|
-
d: optionsNode,
|
|
239
|
-
n: undefined,
|
|
240
|
-
};
|
|
241
|
-
}
|
|
169
|
+
generateIterableNode(
|
|
170
|
+
id: number,
|
|
171
|
+
current: Iterable<ServerValue>,
|
|
172
|
+
): SerovalIterableNode {
|
|
173
|
+
assert(this.ctx.features & Feature.SymbolIterator, 'Unsupported type "Iterable"');
|
|
174
|
+
const options = getIterableOptions(current);
|
|
175
|
+
return new SerovalIterableNode(
|
|
176
|
+
id,
|
|
177
|
+
// Parse options first before the items
|
|
178
|
+
options
|
|
179
|
+
? this.generateProperties(options as Record<string, ServerValue>)
|
|
180
|
+
: undefined,
|
|
181
|
+
this.generateNodeList(Array.from(current)),
|
|
182
|
+
);
|
|
183
|
+
}
|
|
242
184
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
):
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
c: undefined,
|
|
257
|
-
// Parse options first before the items
|
|
258
|
-
d: options
|
|
259
|
-
? serializePropertiesSync(ctx, options as Record<string, ServerValue>)
|
|
260
|
-
: undefined,
|
|
261
|
-
a: generateNodeList(ctx, Array.from(current)),
|
|
262
|
-
n: undefined,
|
|
263
|
-
};
|
|
264
|
-
}
|
|
185
|
+
generateObjectNode(
|
|
186
|
+
id: number,
|
|
187
|
+
current: Record<string, ServerValue> | Iterable<ServerValue>,
|
|
188
|
+
empty: boolean,
|
|
189
|
+
): ObjectLikeNode {
|
|
190
|
+
if (Symbol.iterator in current) {
|
|
191
|
+
return this.generateIterableNode(id, current);
|
|
192
|
+
}
|
|
193
|
+
if (empty) {
|
|
194
|
+
return new SerovalNullConstructorNode(id, this.generateProperties(current));
|
|
195
|
+
}
|
|
196
|
+
return new SerovalObjectNode(id, this.generateProperties(current));
|
|
197
|
+
}
|
|
265
198
|
|
|
266
|
-
|
|
199
|
+
generateAggregateErrorNode(
|
|
200
|
+
id: number,
|
|
201
|
+
current: AggregateError,
|
|
202
|
+
): SerovalAggregateErrorNode {
|
|
203
|
+
const options = getErrorOptions(current);
|
|
204
|
+
const optionsNode = options
|
|
205
|
+
? this.generateProperties(options)
|
|
206
|
+
: undefined;
|
|
207
|
+
return new SerovalAggregateErrorNode(
|
|
208
|
+
id,
|
|
209
|
+
current.message,
|
|
210
|
+
optionsNode,
|
|
211
|
+
this.parse(current.errors),
|
|
212
|
+
);
|
|
213
|
+
}
|
|
267
214
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
215
|
+
generateErrorNode(
|
|
216
|
+
id: number,
|
|
217
|
+
current: Error,
|
|
218
|
+
): SerovalErrorNode {
|
|
219
|
+
const options = getErrorOptions(current);
|
|
220
|
+
const optionsNode = options
|
|
221
|
+
? this.generateProperties(options)
|
|
222
|
+
: undefined;
|
|
223
|
+
return new SerovalErrorNode(id, getErrorConstructor(current), current.message, optionsNode);
|
|
276
224
|
}
|
|
277
|
-
return {
|
|
278
|
-
t: empty ? SerovalNodeType.NullConstructor : SerovalNodeType.Object,
|
|
279
|
-
i: id,
|
|
280
|
-
s: undefined,
|
|
281
|
-
l: undefined,
|
|
282
|
-
m: undefined,
|
|
283
|
-
c: undefined,
|
|
284
|
-
d: serializePropertiesSync(ctx, current),
|
|
285
|
-
a: undefined,
|
|
286
|
-
n: undefined,
|
|
287
|
-
};
|
|
288
|
-
}
|
|
289
225
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
return
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
226
|
+
parse(current: ServerValue): SerovalNode {
|
|
227
|
+
switch (typeof current) {
|
|
228
|
+
case 'boolean':
|
|
229
|
+
return current ? TRUE_NODE : FALSE_NODE;
|
|
230
|
+
case 'undefined':
|
|
231
|
+
return UNDEFINED_NODE;
|
|
232
|
+
case 'string':
|
|
233
|
+
return new SerovalPrimitiveNode(quote(current));
|
|
234
|
+
case 'number':
|
|
235
|
+
if (Object.is(current, -0)) {
|
|
236
|
+
return NEG_ZERO_NODE;
|
|
237
|
+
}
|
|
238
|
+
if (Object.is(current, Infinity)) {
|
|
239
|
+
return INFINITY_NODE;
|
|
240
|
+
}
|
|
241
|
+
if (Object.is(current, -Infinity)) {
|
|
242
|
+
return NEG_INFINITY_NODE;
|
|
243
|
+
}
|
|
244
|
+
return new SerovalPrimitiveNode(current);
|
|
245
|
+
case 'bigint':
|
|
246
|
+
assert(this.ctx.features & Feature.BigInt, 'Unsupported type "BigInt"');
|
|
247
|
+
return new SerovalBigIntNode(current);
|
|
248
|
+
case 'object': {
|
|
249
|
+
if (!current) {
|
|
250
|
+
return NULL_NODE;
|
|
251
|
+
}
|
|
252
|
+
// Non-primitive values needs a reference ID
|
|
253
|
+
// mostly because the values themselves are stateful
|
|
254
|
+
const id = createRef(this.ctx, current, true);
|
|
255
|
+
if (this.ctx.markedRefs[id]) {
|
|
256
|
+
return new SerovalReferenceNode(id);
|
|
257
|
+
}
|
|
258
|
+
if (Array.isArray(current)) {
|
|
259
|
+
return this.generateArrayNode(id, current);
|
|
260
|
+
}
|
|
261
|
+
switch (current.constructor) {
|
|
262
|
+
case Date:
|
|
263
|
+
return new SerovalDateNode(id, current as Date);
|
|
264
|
+
case RegExp:
|
|
265
|
+
return new SerovalRegExpNode(id, current as RegExp);
|
|
266
|
+
case Int8Array:
|
|
267
|
+
case Int16Array:
|
|
268
|
+
case Int32Array:
|
|
269
|
+
case Uint8Array:
|
|
270
|
+
case Uint16Array:
|
|
271
|
+
case Uint32Array:
|
|
272
|
+
case Uint8ClampedArray:
|
|
273
|
+
case Float32Array:
|
|
274
|
+
case Float64Array:
|
|
275
|
+
assert(this.ctx.features & Feature.TypedArray, `Unsupported value type "${current.constructor.name}"`);
|
|
276
|
+
return new SerovalTypedArrayNode(id, current as TypedArrayValue);
|
|
277
|
+
case BigInt64Array:
|
|
278
|
+
case BigUint64Array:
|
|
279
|
+
assert(
|
|
280
|
+
this.ctx.features & (Feature.BigIntTypedArray),
|
|
281
|
+
`Unsupported value type "${current.constructor.name}"`,
|
|
282
|
+
);
|
|
283
|
+
return new SerovalBigIntTypedArrayNode(id, current as BigIntTypedArrayValue);
|
|
284
|
+
case Map:
|
|
285
|
+
return this.generateMapNode(id, current as Map<ServerValue, ServerValue>);
|
|
286
|
+
case Set:
|
|
287
|
+
return this.generateSetNode(id, current as Set<ServerValue>);
|
|
288
|
+
case Object:
|
|
289
|
+
return this.generateObjectNode(id, current as Record<string, ServerValue>, false);
|
|
290
|
+
case undefined:
|
|
291
|
+
return this.generateObjectNode(id, current as Record<string, ServerValue>, true);
|
|
292
|
+
case AggregateError:
|
|
293
|
+
if (this.ctx.features & Feature.AggregateError) {
|
|
294
|
+
return this.generateAggregateErrorNode(id, current as AggregateError);
|
|
295
|
+
}
|
|
296
|
+
return this.generateErrorNode(id, current as AggregateError);
|
|
297
|
+
case Error:
|
|
298
|
+
case EvalError:
|
|
299
|
+
case RangeError:
|
|
300
|
+
case ReferenceError:
|
|
301
|
+
case SyntaxError:
|
|
302
|
+
case TypeError:
|
|
303
|
+
case URIError:
|
|
304
|
+
return this.generateErrorNode(id, current as Error);
|
|
305
|
+
default:
|
|
306
|
+
break;
|
|
307
|
+
}
|
|
308
|
+
if (current instanceof AggregateError && this.ctx.features & Feature.AggregateError) {
|
|
309
|
+
return this.generateAggregateErrorNode(id, current);
|
|
310
|
+
}
|
|
311
|
+
if (current instanceof Error) {
|
|
312
|
+
return this.generateErrorNode(id, current);
|
|
313
|
+
}
|
|
314
|
+
// Generator functions don't have a global constructor
|
|
315
|
+
if (Symbol.iterator in current) {
|
|
316
|
+
return this.generateIterableNode(id, current);
|
|
317
|
+
}
|
|
318
|
+
throw new Error('Unsupported type');
|
|
378
319
|
}
|
|
379
|
-
|
|
320
|
+
default:
|
|
321
|
+
throw new Error('Unsupported type');
|
|
380
322
|
}
|
|
381
|
-
default:
|
|
382
|
-
throw new Error('Unsupported type');
|
|
383
323
|
}
|
|
384
324
|
}
|
|
385
325
|
|
|
@@ -387,7 +327,7 @@ export default function parseSync(
|
|
|
387
327
|
ctx: ParserContext,
|
|
388
328
|
current: ServerValue,
|
|
389
329
|
) {
|
|
390
|
-
const result =
|
|
330
|
+
const result = new SyncParser(ctx).parse(current);
|
|
391
331
|
const isObject = result.t === SerovalNodeType.Object
|
|
392
332
|
|| result.t === SerovalNodeType.Iterable;
|
|
393
333
|
return [result, createRef(ctx, current, false), isObject] as const;
|