seroval 0.4.0-alpha.8 → 0.4.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.
- package/README.md +81 -55
- package/dist/cjs/development/index.cjs +999 -831
- package/dist/cjs/development/index.cjs.map +4 -4
- package/dist/cjs/production/index.cjs +2 -2
- package/dist/esm/development/index.mjs +999 -831
- 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 +2 -1
- package/dist/types/tree/primitives.d.ts +17 -0
- package/dist/types/tree/serialize.d.ts +1 -1
- package/dist/types/tree/shared.d.ts +4 -8
- package/dist/types/tree/types.d.ts +108 -59
- 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 +33 -41
- package/src/quote.ts +1 -1
- package/src/tree/async.ts +362 -163
- package/src/tree/primitives.ts +150 -0
- package/src/tree/serialize.ts +308 -282
- package/src/tree/shared.ts +43 -119
- package/src/tree/sync.ts +295 -146
- package/src/tree/types.ts +143 -65
- 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,69 +1,150 @@
|
|
|
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,
|
|
23
34
|
SerovalArrayNode,
|
|
24
|
-
SerovalDictionaryNode,
|
|
25
35
|
SerovalErrorNode,
|
|
26
36
|
SerovalIterableNode,
|
|
27
37
|
SerovalMapNode,
|
|
28
38
|
SerovalNode,
|
|
29
39
|
SerovalNodeType,
|
|
40
|
+
SerovalNullConstructorNode,
|
|
41
|
+
SerovalObjectNode,
|
|
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
|
-
return
|
|
131
|
+
return {
|
|
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,
|
|
141
|
+
};
|
|
61
142
|
}
|
|
62
143
|
|
|
63
144
|
async function generateSetNode(
|
|
64
145
|
ctx: ParserContext,
|
|
65
|
-
current: Set<AsyncServerValue>,
|
|
66
146
|
id: number,
|
|
147
|
+
current: Set<AsyncServerValue>,
|
|
67
148
|
): Promise<SerovalSetNode> {
|
|
68
149
|
assert(ctx.features & Feature.Set, 'Unsupported type "Set"');
|
|
69
150
|
const len = current.size;
|
|
@@ -76,185 +157,303 @@ async function generateSetNode(
|
|
|
76
157
|
if (isIterable(item)) {
|
|
77
158
|
deferred[deferredSize++] = item;
|
|
78
159
|
} else {
|
|
79
|
-
nodes[nodeSize++] = await
|
|
160
|
+
nodes[nodeSize++] = await parse(ctx, item);
|
|
80
161
|
}
|
|
81
162
|
}
|
|
82
163
|
// Parse deferred items
|
|
83
164
|
for (let i = 0; i < deferredSize; i++) {
|
|
84
|
-
nodes[nodeSize + i] = await
|
|
165
|
+
nodes[nodeSize + i] = await parse(ctx, deferred[i]);
|
|
85
166
|
}
|
|
86
|
-
return
|
|
167
|
+
return {
|
|
168
|
+
t: SerovalNodeType.Set,
|
|
169
|
+
i: id,
|
|
170
|
+
s: undefined,
|
|
171
|
+
l: undefined,
|
|
172
|
+
c: undefined,
|
|
173
|
+
m: undefined,
|
|
174
|
+
d: undefined,
|
|
175
|
+
a: nodes,
|
|
176
|
+
n: undefined,
|
|
177
|
+
};
|
|
87
178
|
}
|
|
88
179
|
|
|
89
|
-
async function
|
|
180
|
+
async function generateProperties(
|
|
90
181
|
ctx: ParserContext,
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const
|
|
96
|
-
const
|
|
97
|
-
const
|
|
98
|
-
const
|
|
99
|
-
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);
|
|
100
190
|
let deferredSize = 0;
|
|
101
|
-
let
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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;
|
|
107
198
|
deferredSize++;
|
|
108
199
|
} else {
|
|
109
|
-
keyNodes[
|
|
110
|
-
valueNodes[
|
|
111
|
-
|
|
200
|
+
keyNodes[nodesSize] = key;
|
|
201
|
+
valueNodes[nodesSize] = await parse(ctx, item);
|
|
202
|
+
nodesSize++;
|
|
112
203
|
}
|
|
113
204
|
}
|
|
114
205
|
for (let i = 0; i < deferredSize; i++) {
|
|
115
|
-
keyNodes[
|
|
116
|
-
valueNodes[
|
|
206
|
+
keyNodes[nodesSize + i] = deferredKeys[i];
|
|
207
|
+
valueNodes[nodesSize + i] = await parse(ctx, deferredValues[i]);
|
|
117
208
|
}
|
|
118
|
-
return
|
|
209
|
+
return {
|
|
210
|
+
k: keyNodes,
|
|
211
|
+
v: valueNodes,
|
|
212
|
+
s: size,
|
|
213
|
+
};
|
|
119
214
|
}
|
|
120
215
|
|
|
121
|
-
async function
|
|
216
|
+
async function generateIterableNode(
|
|
122
217
|
ctx: ParserContext,
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
return nodes;
|
|
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,
|
|
225
|
+
i: id,
|
|
226
|
+
s: undefined,
|
|
227
|
+
l: undefined,
|
|
228
|
+
c: undefined,
|
|
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)),
|
|
235
|
+
n: undefined,
|
|
236
|
+
};
|
|
143
237
|
}
|
|
144
238
|
|
|
145
|
-
async function
|
|
239
|
+
async function generatePromiseNode(
|
|
146
240
|
ctx: ParserContext,
|
|
147
|
-
current: AsyncServerValue[],
|
|
148
241
|
id: number,
|
|
149
|
-
|
|
150
|
-
|
|
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
|
+
}));
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
async function generateObjectNode(
|
|
260
|
+
ctx: ParserContext,
|
|
261
|
+
id: number,
|
|
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
|
+
}
|
|
271
|
+
return {
|
|
272
|
+
t: empty ? SerovalNodeType.NullConstructor : SerovalNodeType.Object,
|
|
273
|
+
i: id,
|
|
274
|
+
s: undefined,
|
|
275
|
+
l: undefined,
|
|
276
|
+
c: undefined,
|
|
277
|
+
m: undefined,
|
|
278
|
+
d: await generateProperties(ctx, current as Record<string, AsyncServerValue>),
|
|
279
|
+
a: undefined,
|
|
280
|
+
n: undefined,
|
|
281
|
+
};
|
|
151
282
|
}
|
|
152
283
|
|
|
153
284
|
async function generateAggregateErrorNode(
|
|
154
285
|
ctx: ParserContext,
|
|
155
|
-
current: AggregateError,
|
|
156
286
|
id: number,
|
|
287
|
+
current: AggregateError,
|
|
157
288
|
): Promise<SerovalAggregateErrorNode> {
|
|
158
|
-
const options = getErrorOptions(current);
|
|
289
|
+
const options = getErrorOptions(ctx, current);
|
|
159
290
|
const optionsNode = options
|
|
160
|
-
? await
|
|
291
|
+
? await generateProperties(ctx, options)
|
|
161
292
|
: undefined;
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
293
|
+
return {
|
|
294
|
+
t: SerovalNodeType.AggregateError,
|
|
295
|
+
i: id,
|
|
296
|
+
s: undefined,
|
|
297
|
+
l: undefined,
|
|
298
|
+
c: undefined,
|
|
299
|
+
m: current.message,
|
|
300
|
+
d: optionsNode,
|
|
301
|
+
a: undefined,
|
|
302
|
+
n: await parse(ctx, current.errors),
|
|
303
|
+
};
|
|
168
304
|
}
|
|
169
305
|
|
|
170
306
|
async function generateErrorNode(
|
|
171
307
|
ctx: ParserContext,
|
|
172
|
-
current: Error,
|
|
173
308
|
id: number,
|
|
309
|
+
current: Error,
|
|
174
310
|
): Promise<SerovalErrorNode> {
|
|
175
|
-
const options = getErrorOptions(current);
|
|
311
|
+
const options = getErrorOptions(ctx, current);
|
|
176
312
|
const optionsNode = options
|
|
177
|
-
? await
|
|
313
|
+
? await generateProperties(ctx, options)
|
|
178
314
|
: undefined;
|
|
179
|
-
return
|
|
180
|
-
SerovalNodeType.Error,
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
315
|
+
return {
|
|
316
|
+
t: SerovalNodeType.Error,
|
|
317
|
+
i: id,
|
|
318
|
+
s: undefined,
|
|
319
|
+
l: undefined,
|
|
320
|
+
c: getErrorConstructor(current),
|
|
321
|
+
m: current.message,
|
|
322
|
+
d: optionsNode,
|
|
323
|
+
a: undefined,
|
|
324
|
+
n: undefined,
|
|
325
|
+
};
|
|
184
326
|
}
|
|
185
327
|
|
|
186
|
-
async function
|
|
187
|
-
ctx: ParserContext,
|
|
188
|
-
current: Iterable<AsyncServerValue>,
|
|
189
|
-
id: number,
|
|
190
|
-
): Promise<SerovalIterableNode> {
|
|
191
|
-
assert(ctx.features & Feature.SymbolIterator, 'Unsupported type "Iterable"');
|
|
192
|
-
const options = getIterableOptions(current);
|
|
193
|
-
return [SerovalNodeType.Iterable, [
|
|
194
|
-
// Parse options first before the items
|
|
195
|
-
options ? await serializePropertiesAsync(ctx, options) : undefined,
|
|
196
|
-
await generateNodeList(ctx, Array.from(current)),
|
|
197
|
-
], id];
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
async function generateTreeAsync(
|
|
328
|
+
async function parse(
|
|
201
329
|
ctx: ParserContext,
|
|
202
330
|
current: AsyncServerValue,
|
|
203
331
|
): Promise<SerovalNode> {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
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');
|
|
250
448
|
}
|
|
251
|
-
throw new Error('Unsupported value');
|
|
252
449
|
}
|
|
253
450
|
|
|
254
451
|
export default async function parseAsync(
|
|
255
452
|
ctx: ParserContext,
|
|
256
453
|
current: AsyncServerValue,
|
|
257
454
|
) {
|
|
258
|
-
const result = await
|
|
259
|
-
|
|
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;
|
|
260
459
|
}
|