seroval 0.4.0-alpha.9 → 0.4.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.
- package/README.md +81 -55
- package/dist/cjs/development/index.cjs +894 -934
- package/dist/cjs/development/index.cjs.map +4 -4
- package/dist/cjs/production/index.cjs +2 -2
- package/dist/esm/development/index.mjs +894 -934
- package/dist/esm/development/index.mjs.map +4 -4
- package/dist/esm/production/index.mjs +2 -2
- package/dist/types/compat.d.ts +10 -25
- package/dist/types/context.d.ts +17 -15
- package/dist/types/index.d.ts +14 -5
- package/dist/types/tree/primitives.d.ts +17 -0
- package/dist/types/tree/shared.d.ts +4 -8
- package/dist/types/types.d.ts +3 -2
- package/package.json +2 -2
- package/src/compat.ts +10 -246
- package/src/context.ts +37 -26
- package/src/index.ts +37 -46
- package/src/quote.ts +1 -1
- package/src/tree/async.ts +319 -197
- package/src/tree/primitives.ts +150 -0
- package/src/tree/serialize.ts +266 -235
- package/src/tree/shared.ts +43 -175
- package/src/tree/sync.ts +255 -180
- package/src/types.ts +4 -1
- package/dist/types/checks.d.ts +0 -5
- package/src/checks.ts +0 -40
package/src/tree/async.ts
CHANGED
|
@@ -1,22 +1,33 @@
|
|
|
1
1
|
/* eslint-disable no-await-in-loop */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
3
3
|
import assert from '../assert';
|
|
4
|
-
import {
|
|
5
|
-
isIterable,
|
|
6
|
-
isPrimitive,
|
|
7
|
-
constructorCheck,
|
|
8
|
-
isPromise,
|
|
9
|
-
} from '../checks';
|
|
10
4
|
import { Feature } from '../compat';
|
|
11
5
|
import { createRef, ParserContext } from '../context';
|
|
12
|
-
import
|
|
6
|
+
import quote from '../quote';
|
|
7
|
+
import {
|
|
8
|
+
AsyncServerValue,
|
|
9
|
+
BigIntTypedArrayValue,
|
|
10
|
+
TypedArrayValue,
|
|
11
|
+
} from '../types';
|
|
12
|
+
import {
|
|
13
|
+
createBigIntNode,
|
|
14
|
+
createBigIntTypedArrayNode,
|
|
15
|
+
createDateNode,
|
|
16
|
+
createPrimitiveNode,
|
|
17
|
+
createReferenceNode,
|
|
18
|
+
createRegExpNode,
|
|
19
|
+
createTypedArrayNode,
|
|
20
|
+
FALSE_NODE,
|
|
21
|
+
NEG_ZERO_NODE,
|
|
22
|
+
NULL_NODE,
|
|
23
|
+
TRUE_NODE,
|
|
24
|
+
UNDEFINED_NODE,
|
|
25
|
+
} from './primitives';
|
|
13
26
|
import {
|
|
14
|
-
generateRef,
|
|
15
|
-
generateSemiPrimitiveValue,
|
|
16
27
|
getErrorConstructor,
|
|
17
28
|
getErrorOptions,
|
|
18
29
|
getIterableOptions,
|
|
19
|
-
|
|
30
|
+
isIterable,
|
|
20
31
|
} from './shared';
|
|
21
32
|
import {
|
|
22
33
|
SerovalAggregateErrorNode,
|
|
@@ -26,48 +37,114 @@ import {
|
|
|
26
37
|
SerovalMapNode,
|
|
27
38
|
SerovalNode,
|
|
28
39
|
SerovalNodeType,
|
|
40
|
+
SerovalNullConstructorNode,
|
|
41
|
+
SerovalObjectNode,
|
|
29
42
|
SerovalObjectRecordNode,
|
|
43
|
+
SerovalPromiseNode,
|
|
30
44
|
SerovalSetNode,
|
|
31
45
|
} from './types';
|
|
32
46
|
|
|
33
|
-
|
|
47
|
+
type ObjectLikeNode =
|
|
48
|
+
| SerovalObjectNode
|
|
49
|
+
| SerovalNullConstructorNode
|
|
50
|
+
| SerovalIterableNode
|
|
51
|
+
| SerovalPromiseNode;
|
|
52
|
+
|
|
53
|
+
type ObjectLikeValue =
|
|
54
|
+
| Record<string, AsyncServerValue>
|
|
55
|
+
| Iterable<AsyncServerValue>
|
|
56
|
+
| PromiseLike<AsyncServerValue>;
|
|
57
|
+
|
|
58
|
+
async function generateNodeList(
|
|
34
59
|
ctx: ParserContext,
|
|
35
|
-
|
|
36
|
-
)
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
60
|
+
current: AsyncServerValue[],
|
|
61
|
+
) {
|
|
62
|
+
const size = current.length;
|
|
63
|
+
const nodes = new Array<SerovalNode>(size);
|
|
64
|
+
const deferred = new Array<AsyncServerValue>(size);
|
|
65
|
+
let item: AsyncServerValue;
|
|
66
|
+
for (let i = 0; i < size; i++) {
|
|
67
|
+
if (i in current) {
|
|
68
|
+
item = current[i];
|
|
69
|
+
if (isIterable(item)) {
|
|
70
|
+
deferred[i] = item;
|
|
71
|
+
} else {
|
|
72
|
+
nodes[i] = await parse(ctx, item);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
for (let i = 0; i < size; i++) {
|
|
77
|
+
if (i in deferred) {
|
|
78
|
+
nodes[i] = await parse(ctx, deferred[i]);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return nodes;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async function generateArrayNode(
|
|
85
|
+
ctx: ParserContext,
|
|
86
|
+
id: number,
|
|
87
|
+
current: AsyncServerValue[],
|
|
88
|
+
): Promise<SerovalArrayNode> {
|
|
89
|
+
return {
|
|
90
|
+
t: SerovalNodeType.Array,
|
|
91
|
+
i: id,
|
|
92
|
+
s: undefined,
|
|
93
|
+
l: undefined,
|
|
94
|
+
c: undefined,
|
|
95
|
+
m: undefined,
|
|
96
|
+
d: undefined,
|
|
97
|
+
a: await generateNodeList(ctx, current),
|
|
98
|
+
n: undefined,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async function generateMapNode(
|
|
103
|
+
ctx: ParserContext,
|
|
104
|
+
id: number,
|
|
105
|
+
current: Map<AsyncServerValue, AsyncServerValue>,
|
|
106
|
+
): Promise<SerovalMapNode> {
|
|
107
|
+
assert(ctx.features & Feature.Map, 'Unsupported type "Map"');
|
|
108
|
+
const len = current.size;
|
|
109
|
+
const keyNodes = new Array<SerovalNode>(len);
|
|
110
|
+
const valueNodes = new Array<SerovalNode>(len);
|
|
111
|
+
const deferredKey = new Array<AsyncServerValue>(len);
|
|
112
|
+
const deferredValue = new Array<AsyncServerValue>(len);
|
|
43
113
|
let deferredSize = 0;
|
|
44
|
-
let
|
|
45
|
-
for (const key of
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
114
|
+
let nodeSize = 0;
|
|
115
|
+
for (const [key, value] of current.entries()) {
|
|
116
|
+
// Either key or value might be an iterable
|
|
117
|
+
if (isIterable(key) || isIterable(value)) {
|
|
118
|
+
deferredKey[deferredSize] = key;
|
|
119
|
+
deferredValue[deferredSize] = value;
|
|
49
120
|
deferredSize++;
|
|
50
121
|
} else {
|
|
51
|
-
keyNodes[
|
|
52
|
-
valueNodes[
|
|
53
|
-
|
|
122
|
+
keyNodes[nodeSize] = await parse(ctx, key);
|
|
123
|
+
valueNodes[nodeSize] = await parse(ctx, value);
|
|
124
|
+
nodeSize++;
|
|
54
125
|
}
|
|
55
126
|
}
|
|
56
127
|
for (let i = 0; i < deferredSize; i++) {
|
|
57
|
-
keyNodes[
|
|
58
|
-
valueNodes[
|
|
128
|
+
keyNodes[nodeSize + i] = await parse(ctx, deferredKey[i]);
|
|
129
|
+
valueNodes[nodeSize + i] = await parse(ctx, deferredValue[i]);
|
|
59
130
|
}
|
|
60
131
|
return {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
s:
|
|
132
|
+
t: SerovalNodeType.Map,
|
|
133
|
+
i: id,
|
|
134
|
+
s: undefined,
|
|
135
|
+
l: undefined,
|
|
136
|
+
c: undefined,
|
|
137
|
+
m: undefined,
|
|
138
|
+
d: { k: keyNodes, v: valueNodes, s: len },
|
|
139
|
+
a: undefined,
|
|
140
|
+
n: undefined,
|
|
64
141
|
};
|
|
65
142
|
}
|
|
66
143
|
|
|
67
144
|
async function generateSetNode(
|
|
68
145
|
ctx: ParserContext,
|
|
69
|
-
current: Set<AsyncServerValue>,
|
|
70
146
|
id: number,
|
|
147
|
+
current: Set<AsyncServerValue>,
|
|
71
148
|
): Promise<SerovalSetNode> {
|
|
72
149
|
assert(ctx.features & Feature.Set, 'Unsupported type "Set"');
|
|
73
150
|
const len = current.size;
|
|
@@ -80,258 +157,303 @@ async function generateSetNode(
|
|
|
80
157
|
if (isIterable(item)) {
|
|
81
158
|
deferred[deferredSize++] = item;
|
|
82
159
|
} else {
|
|
83
|
-
nodes[nodeSize++] = await
|
|
160
|
+
nodes[nodeSize++] = await parse(ctx, item);
|
|
84
161
|
}
|
|
85
162
|
}
|
|
86
163
|
// Parse deferred items
|
|
87
164
|
for (let i = 0; i < deferredSize; i++) {
|
|
88
|
-
nodes[nodeSize + i] = await
|
|
165
|
+
nodes[nodeSize + i] = await parse(ctx, deferred[i]);
|
|
89
166
|
}
|
|
90
167
|
return {
|
|
91
168
|
t: SerovalNodeType.Set,
|
|
92
169
|
i: id,
|
|
93
|
-
a: nodes,
|
|
94
170
|
s: undefined,
|
|
95
171
|
l: undefined,
|
|
96
|
-
m: undefined,
|
|
97
172
|
c: undefined,
|
|
173
|
+
m: undefined,
|
|
98
174
|
d: undefined,
|
|
175
|
+
a: nodes,
|
|
99
176
|
n: undefined,
|
|
100
177
|
};
|
|
101
178
|
}
|
|
102
179
|
|
|
103
|
-
async function
|
|
180
|
+
async function generateProperties(
|
|
104
181
|
ctx: ParserContext,
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const
|
|
110
|
-
const
|
|
111
|
-
const
|
|
112
|
-
const
|
|
113
|
-
const deferredValue = new Array<AsyncServerValue>(len);
|
|
182
|
+
properties: Record<string, AsyncServerValue>,
|
|
183
|
+
): Promise<SerovalObjectRecordNode> {
|
|
184
|
+
const keys = Object.keys(properties);
|
|
185
|
+
const size = keys.length;
|
|
186
|
+
const keyNodes = new Array<string>(size);
|
|
187
|
+
const valueNodes = new Array<SerovalNode>(size);
|
|
188
|
+
const deferredKeys = new Array<string>(size);
|
|
189
|
+
const deferredValues = new Array<AsyncServerValue>(size);
|
|
114
190
|
let deferredSize = 0;
|
|
115
|
-
let
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
191
|
+
let nodesSize = 0;
|
|
192
|
+
let item: AsyncServerValue;
|
|
193
|
+
for (const key of keys) {
|
|
194
|
+
item = properties[key];
|
|
195
|
+
if (isIterable(item)) {
|
|
196
|
+
deferredKeys[deferredSize] = key;
|
|
197
|
+
deferredValues[deferredSize] = item;
|
|
121
198
|
deferredSize++;
|
|
122
199
|
} else {
|
|
123
|
-
keyNodes[
|
|
124
|
-
valueNodes[
|
|
125
|
-
|
|
200
|
+
keyNodes[nodesSize] = key;
|
|
201
|
+
valueNodes[nodesSize] = await parse(ctx, item);
|
|
202
|
+
nodesSize++;
|
|
126
203
|
}
|
|
127
204
|
}
|
|
128
205
|
for (let i = 0; i < deferredSize; i++) {
|
|
129
|
-
keyNodes[
|
|
130
|
-
valueNodes[
|
|
206
|
+
keyNodes[nodesSize + i] = deferredKeys[i];
|
|
207
|
+
valueNodes[nodesSize + i] = await parse(ctx, deferredValues[i]);
|
|
131
208
|
}
|
|
132
209
|
return {
|
|
133
|
-
|
|
210
|
+
k: keyNodes,
|
|
211
|
+
v: valueNodes,
|
|
212
|
+
s: size,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
async function generateIterableNode(
|
|
217
|
+
ctx: ParserContext,
|
|
218
|
+
id: number,
|
|
219
|
+
current: Iterable<AsyncServerValue>,
|
|
220
|
+
): Promise<SerovalIterableNode> {
|
|
221
|
+
assert(ctx.features & Feature.SymbolIterator, 'Unsupported type "Iterable"');
|
|
222
|
+
const options = getIterableOptions(current);
|
|
223
|
+
return {
|
|
224
|
+
t: SerovalNodeType.Iterable,
|
|
134
225
|
i: id,
|
|
135
|
-
a: undefined,
|
|
136
226
|
s: undefined,
|
|
137
227
|
l: undefined,
|
|
138
|
-
m: undefined,
|
|
139
228
|
c: undefined,
|
|
140
|
-
|
|
229
|
+
m: undefined,
|
|
230
|
+
// Parse options first before the items
|
|
231
|
+
d: options
|
|
232
|
+
? await generateProperties(ctx, options as Record<string, AsyncServerValue>)
|
|
233
|
+
: undefined,
|
|
234
|
+
a: await generateNodeList(ctx, Array.from(current)),
|
|
141
235
|
n: undefined,
|
|
142
236
|
};
|
|
143
237
|
}
|
|
144
238
|
|
|
145
|
-
async function
|
|
239
|
+
async function generatePromiseNode(
|
|
146
240
|
ctx: ParserContext,
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
nodes[i] = await generateTreeAsync(ctx, deferred[i]);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
return nodes;
|
|
241
|
+
id: number,
|
|
242
|
+
current: PromiseLike<AsyncServerValue>,
|
|
243
|
+
): Promise<SerovalPromiseNode> {
|
|
244
|
+
assert(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
|
+
c: undefined,
|
|
251
|
+
m: undefined,
|
|
252
|
+
// Parse options first before the items
|
|
253
|
+
d: undefined,
|
|
254
|
+
a: undefined,
|
|
255
|
+
n: await parse(ctx, value),
|
|
256
|
+
}));
|
|
167
257
|
}
|
|
168
258
|
|
|
169
|
-
async function
|
|
259
|
+
async function generateObjectNode(
|
|
170
260
|
ctx: ParserContext,
|
|
171
|
-
current: AsyncServerValue[],
|
|
172
261
|
id: number,
|
|
173
|
-
|
|
262
|
+
current: ObjectLikeValue,
|
|
263
|
+
empty: boolean,
|
|
264
|
+
): Promise<ObjectLikeNode> {
|
|
265
|
+
if (Symbol.iterator in current) {
|
|
266
|
+
return generateIterableNode(ctx, id, current);
|
|
267
|
+
}
|
|
268
|
+
if ('then' in current && typeof current.then === 'function') {
|
|
269
|
+
return generatePromiseNode(ctx, id, current as PromiseLike<AsyncServerValue>);
|
|
270
|
+
}
|
|
174
271
|
return {
|
|
175
|
-
t: SerovalNodeType.
|
|
272
|
+
t: empty ? SerovalNodeType.NullConstructor : SerovalNodeType.Object,
|
|
176
273
|
i: id,
|
|
177
|
-
a: await generateNodeList(ctx, current),
|
|
178
274
|
s: undefined,
|
|
179
275
|
l: undefined,
|
|
180
|
-
m: undefined,
|
|
181
276
|
c: undefined,
|
|
182
|
-
|
|
277
|
+
m: undefined,
|
|
278
|
+
d: await generateProperties(ctx, current as Record<string, AsyncServerValue>),
|
|
279
|
+
a: undefined,
|
|
183
280
|
n: undefined,
|
|
184
281
|
};
|
|
185
282
|
}
|
|
186
283
|
|
|
187
284
|
async function generateAggregateErrorNode(
|
|
188
285
|
ctx: ParserContext,
|
|
189
|
-
current: AggregateError,
|
|
190
286
|
id: number,
|
|
287
|
+
current: AggregateError,
|
|
191
288
|
): Promise<SerovalAggregateErrorNode> {
|
|
192
|
-
const options = getErrorOptions(current);
|
|
289
|
+
const options = getErrorOptions(ctx, current);
|
|
193
290
|
const optionsNode = options
|
|
194
|
-
? await
|
|
291
|
+
? await generateProperties(ctx, options)
|
|
195
292
|
: undefined;
|
|
196
293
|
return {
|
|
197
294
|
t: SerovalNodeType.AggregateError,
|
|
198
295
|
i: id,
|
|
199
|
-
a: undefined,
|
|
200
296
|
s: undefined,
|
|
201
297
|
l: undefined,
|
|
202
|
-
m: current.message,
|
|
203
298
|
c: undefined,
|
|
299
|
+
m: current.message,
|
|
204
300
|
d: optionsNode,
|
|
205
|
-
|
|
301
|
+
a: undefined,
|
|
302
|
+
n: await parse(ctx, current.errors),
|
|
206
303
|
};
|
|
207
304
|
}
|
|
208
305
|
|
|
209
306
|
async function generateErrorNode(
|
|
210
307
|
ctx: ParserContext,
|
|
211
|
-
current: Error,
|
|
212
308
|
id: number,
|
|
309
|
+
current: Error,
|
|
213
310
|
): Promise<SerovalErrorNode> {
|
|
214
|
-
const options = getErrorOptions(current);
|
|
311
|
+
const options = getErrorOptions(ctx, current);
|
|
215
312
|
const optionsNode = options
|
|
216
|
-
? await
|
|
313
|
+
? await generateProperties(ctx, options)
|
|
217
314
|
: undefined;
|
|
218
315
|
return {
|
|
219
316
|
t: SerovalNodeType.Error,
|
|
220
317
|
i: id,
|
|
221
|
-
a: undefined,
|
|
222
318
|
s: undefined,
|
|
223
319
|
l: undefined,
|
|
224
|
-
m: current.message,
|
|
225
320
|
c: getErrorConstructor(current),
|
|
321
|
+
m: current.message,
|
|
226
322
|
d: optionsNode,
|
|
323
|
+
a: undefined,
|
|
227
324
|
n: undefined,
|
|
228
325
|
};
|
|
229
326
|
}
|
|
230
327
|
|
|
231
|
-
async function
|
|
232
|
-
ctx: ParserContext,
|
|
233
|
-
current: Iterable<AsyncServerValue>,
|
|
234
|
-
id: number,
|
|
235
|
-
): Promise<SerovalIterableNode> {
|
|
236
|
-
assert(ctx.features & Feature.SymbolIterator, 'Unsupported type "Iterable"');
|
|
237
|
-
const options = getIterableOptions(current);
|
|
238
|
-
return {
|
|
239
|
-
t: SerovalNodeType.Iterable,
|
|
240
|
-
i: id,
|
|
241
|
-
s: undefined,
|
|
242
|
-
l: undefined,
|
|
243
|
-
m: undefined,
|
|
244
|
-
c: undefined,
|
|
245
|
-
// Parse options first before the items
|
|
246
|
-
d: options ? await serializePropertiesAsync(ctx, options) : undefined,
|
|
247
|
-
a: await generateNodeList(ctx, Array.from(current)),
|
|
248
|
-
n: undefined,
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
async function generateTreeAsync(
|
|
328
|
+
async function parse(
|
|
253
329
|
ctx: ParserContext,
|
|
254
330
|
current: AsyncServerValue,
|
|
255
331
|
): Promise<SerovalNode> {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
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
|
-
|
|
332
|
+
switch (typeof current) {
|
|
333
|
+
case 'boolean':
|
|
334
|
+
return current ? TRUE_NODE : FALSE_NODE;
|
|
335
|
+
case 'undefined':
|
|
336
|
+
return UNDEFINED_NODE;
|
|
337
|
+
case 'string':
|
|
338
|
+
return createPrimitiveNode(quote(current));
|
|
339
|
+
case 'number':
|
|
340
|
+
if (Object.is(current, -0)) {
|
|
341
|
+
return NEG_ZERO_NODE;
|
|
342
|
+
}
|
|
343
|
+
if (Object.is(current, Infinity)) {
|
|
344
|
+
return createPrimitiveNode('1/0');
|
|
345
|
+
}
|
|
346
|
+
if (Object.is(current, -Infinity)) {
|
|
347
|
+
return createPrimitiveNode('-1/0');
|
|
348
|
+
}
|
|
349
|
+
return createPrimitiveNode(current);
|
|
350
|
+
case 'bigint':
|
|
351
|
+
return createBigIntNode(ctx, current);
|
|
352
|
+
case 'object': {
|
|
353
|
+
if (!current) {
|
|
354
|
+
return NULL_NODE;
|
|
355
|
+
}
|
|
356
|
+
// Non-primitive values needs a reference ID
|
|
357
|
+
// mostly because the values themselves are stateful
|
|
358
|
+
const id = createRef(ctx, current, true);
|
|
359
|
+
if (ctx.markedRefs.has(id)) {
|
|
360
|
+
return createReferenceNode(id);
|
|
361
|
+
}
|
|
362
|
+
if (Array.isArray(current)) {
|
|
363
|
+
return generateArrayNode(ctx, id, current);
|
|
364
|
+
}
|
|
365
|
+
switch (current.constructor) {
|
|
366
|
+
case Date:
|
|
367
|
+
return createDateNode(id, current as Date);
|
|
368
|
+
case RegExp:
|
|
369
|
+
return createRegExpNode(id, current as RegExp);
|
|
370
|
+
case Promise:
|
|
371
|
+
return generatePromiseNode(ctx, id, current as Promise<AsyncServerValue>);
|
|
372
|
+
case Int8Array:
|
|
373
|
+
case Int16Array:
|
|
374
|
+
case Int32Array:
|
|
375
|
+
case Uint8Array:
|
|
376
|
+
case Uint16Array:
|
|
377
|
+
case Uint32Array:
|
|
378
|
+
case Uint8ClampedArray:
|
|
379
|
+
case Float32Array:
|
|
380
|
+
case Float64Array:
|
|
381
|
+
return createTypedArrayNode(ctx, id, current as TypedArrayValue);
|
|
382
|
+
case BigInt64Array:
|
|
383
|
+
case BigUint64Array:
|
|
384
|
+
return createBigIntTypedArrayNode(ctx, id, current as BigIntTypedArrayValue);
|
|
385
|
+
case Map:
|
|
386
|
+
return generateMapNode(
|
|
387
|
+
ctx,
|
|
388
|
+
id,
|
|
389
|
+
current as Map<AsyncServerValue, AsyncServerValue>,
|
|
390
|
+
);
|
|
391
|
+
case Set:
|
|
392
|
+
return generateSetNode(
|
|
393
|
+
ctx,
|
|
394
|
+
id,
|
|
395
|
+
current as Set<AsyncServerValue>,
|
|
396
|
+
);
|
|
397
|
+
case Object:
|
|
398
|
+
return generateObjectNode(
|
|
399
|
+
ctx,
|
|
400
|
+
id,
|
|
401
|
+
current as Record<string, AsyncServerValue>,
|
|
402
|
+
false,
|
|
403
|
+
);
|
|
404
|
+
case undefined:
|
|
405
|
+
return generateObjectNode(
|
|
406
|
+
ctx,
|
|
407
|
+
id,
|
|
408
|
+
current as Record<string, AsyncServerValue>,
|
|
409
|
+
true,
|
|
410
|
+
);
|
|
411
|
+
case AggregateError:
|
|
412
|
+
if (ctx.features & Feature.AggregateError) {
|
|
413
|
+
return generateAggregateErrorNode(ctx, id, current as AggregateError);
|
|
414
|
+
}
|
|
415
|
+
return generateErrorNode(ctx, id, current as AggregateError);
|
|
416
|
+
case Error:
|
|
417
|
+
case EvalError:
|
|
418
|
+
case RangeError:
|
|
419
|
+
case ReferenceError:
|
|
420
|
+
case SyntaxError:
|
|
421
|
+
case TypeError:
|
|
422
|
+
case URIError:
|
|
423
|
+
return generateErrorNode(ctx, id, current as Error);
|
|
424
|
+
default:
|
|
425
|
+
break;
|
|
426
|
+
}
|
|
427
|
+
if (current instanceof AggregateError && ctx.features & Feature.AggregateError) {
|
|
428
|
+
return generateAggregateErrorNode(ctx, id, current);
|
|
429
|
+
}
|
|
430
|
+
if (current instanceof Error) {
|
|
431
|
+
return generateErrorNode(ctx, id, current);
|
|
432
|
+
}
|
|
433
|
+
if (current instanceof Promise) {
|
|
434
|
+
return generatePromiseNode(ctx, id, current);
|
|
435
|
+
}
|
|
436
|
+
// Generator functions don't have a global constructor
|
|
437
|
+
if (Symbol.iterator in current) {
|
|
438
|
+
return generateIterableNode(ctx, id, current);
|
|
439
|
+
}
|
|
440
|
+
// For Promise-like objects
|
|
441
|
+
if ('then' in current && typeof current.then === 'function') {
|
|
442
|
+
return generatePromiseNode(ctx, id, current as PromiseLike<AsyncServerValue>);
|
|
443
|
+
}
|
|
444
|
+
throw new Error('Unsupported type');
|
|
445
|
+
}
|
|
446
|
+
default:
|
|
447
|
+
throw new Error('Unsupported type');
|
|
327
448
|
}
|
|
328
|
-
throw new Error('Unsupported value');
|
|
329
449
|
}
|
|
330
450
|
|
|
331
451
|
export default async function parseAsync(
|
|
332
452
|
ctx: ParserContext,
|
|
333
453
|
current: AsyncServerValue,
|
|
334
454
|
) {
|
|
335
|
-
const result = await
|
|
336
|
-
|
|
455
|
+
const result = await parse(ctx, current);
|
|
456
|
+
const isObject = result.t === SerovalNodeType.Object
|
|
457
|
+
|| result.t === SerovalNodeType.Iterable;
|
|
458
|
+
return [result, createRef(ctx, current, false), isObject] as const;
|
|
337
459
|
}
|