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