seroval 1.5.6 → 1.6.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/dist/index.d.ts +761 -0
- package/dist/index.js +2928 -0
- package/package.json +14 -23
- package/dist/cjs/development/index.cjs +0 -4232
- package/dist/cjs/development/index.cjs.map +0 -7
- package/dist/cjs/production/index.cjs +0 -3
- package/dist/esm/development/index.mjs +0 -4209
- package/dist/esm/development/index.mjs.map +0 -7
- package/dist/esm/production/index.mjs +0 -3
- package/dist/types/core/Serializer.d.ts +0 -28
- package/dist/types/core/Serializer.d.ts.map +0 -1
- package/dist/types/core/base-primitives.d.ts +0 -28
- package/dist/types/core/base-primitives.d.ts.map +0 -1
- package/dist/types/core/compat.d.ts +0 -15
- package/dist/types/core/compat.d.ts.map +0 -1
- package/dist/types/core/constants.d.ts +0 -105
- package/dist/types/core/constants.d.ts.map +0 -1
- package/dist/types/core/constructors.d.ts +0 -50
- package/dist/types/core/constructors.d.ts.map +0 -1
- package/dist/types/core/context/async-parser.d.ts +0 -20
- package/dist/types/core/context/async-parser.d.ts.map +0 -1
- package/dist/types/core/context/deserializer.d.ts +0 -52
- package/dist/types/core/context/deserializer.d.ts.map +0 -1
- package/dist/types/core/context/parser.d.ts +0 -62
- package/dist/types/core/context/parser.d.ts.map +0 -1
- package/dist/types/core/context/serializer.d.ts +0 -103
- package/dist/types/core/context/serializer.d.ts.map +0 -1
- package/dist/types/core/context/sync-parser.d.ts +0 -61
- package/dist/types/core/context/sync-parser.d.ts.map +0 -1
- package/dist/types/core/cross/index.d.ts +0 -24
- package/dist/types/core/cross/index.d.ts.map +0 -1
- package/dist/types/core/errors.d.ts +0 -47
- package/dist/types/core/errors.d.ts.map +0 -1
- package/dist/types/core/function-string.d.ts +0 -3
- package/dist/types/core/function-string.d.ts.map +0 -1
- package/dist/types/core/keys.d.ts +0 -4
- package/dist/types/core/keys.d.ts.map +0 -1
- package/dist/types/core/literals.d.ts +0 -10
- package/dist/types/core/literals.d.ts.map +0 -1
- package/dist/types/core/node.d.ts +0 -8
- package/dist/types/core/node.d.ts.map +0 -1
- package/dist/types/core/opaque-reference.d.ts +0 -9
- package/dist/types/core/opaque-reference.d.ts.map +0 -1
- package/dist/types/core/plugin.d.ts +0 -52
- package/dist/types/core/plugin.d.ts.map +0 -1
- package/dist/types/core/reference.d.ts +0 -6
- package/dist/types/core/reference.d.ts.map +0 -1
- package/dist/types/core/sequence.d.ts +0 -11
- package/dist/types/core/sequence.d.ts.map +0 -1
- package/dist/types/core/special-reference.d.ts +0 -16
- package/dist/types/core/special-reference.d.ts.map +0 -1
- package/dist/types/core/stream.d.ts +0 -17
- package/dist/types/core/stream.d.ts.map +0 -1
- package/dist/types/core/string.d.ts +0 -4
- package/dist/types/core/string.d.ts.map +0 -1
- package/dist/types/core/symbols.d.ts +0 -14
- package/dist/types/core/symbols.d.ts.map +0 -1
- package/dist/types/core/tree/index.d.ts +0 -21
- package/dist/types/core/tree/index.d.ts.map +0 -1
- package/dist/types/core/types.d.ts +0 -233
- package/dist/types/core/types.d.ts.map +0 -1
- package/dist/types/core/utils/error.d.ts +0 -6
- package/dist/types/core/utils/error.d.ts.map +0 -1
- package/dist/types/core/utils/get-identifier.d.ts +0 -2
- package/dist/types/core/utils/get-identifier.d.ts.map +0 -1
- package/dist/types/core/utils/get-object-flag.d.ts +0 -3
- package/dist/types/core/utils/get-object-flag.d.ts.map +0 -1
- package/dist/types/core/utils/is-valid-identifier.d.ts +0 -2
- package/dist/types/core/utils/is-valid-identifier.d.ts.map +0 -1
- package/dist/types/core/utils/promise-to-result.d.ts +0 -2
- package/dist/types/core/utils/promise-to-result.d.ts.map +0 -1
- package/dist/types/core/utils/typed-array.d.ts +0 -6
- package/dist/types/core/utils/typed-array.d.ts.map +0 -1
- package/dist/types/core/utils/valid-properties.d.ts +0 -3
- package/dist/types/core/utils/valid-properties.d.ts.map +0 -1
- package/dist/types/index.d.ts +0 -18
- package/dist/types/index.d.ts.map +0 -1
- package/src/core/Serializer.ts +0 -119
- package/src/core/base-primitives.ts +0 -537
- package/src/core/compat.ts +0 -23
- package/src/core/constants.ts +0 -202
- package/src/core/constructors.ts +0 -265
- package/src/core/context/async-parser.ts +0 -666
- package/src/core/context/deserializer.ts +0 -832
- package/src/core/context/parser.ts +0 -335
- package/src/core/context/serializer.ts +0 -1524
- package/src/core/context/sync-parser.ts +0 -943
- package/src/core/cross/index.ts +0 -190
- package/src/core/errors.ts +0 -196
- package/src/core/function-string.ts +0 -31
- package/src/core/keys.ts +0 -17
- package/src/core/literals.ts +0 -43
- package/src/core/node.ts +0 -40
- package/src/core/opaque-reference.ts +0 -9
- package/src/core/plugin.ts +0 -105
- package/src/core/reference.ts +0 -66
- package/src/core/sequence.ts +0 -59
- package/src/core/special-reference.ts +0 -42
- package/src/core/stream.ts +0 -71
- package/src/core/string.ts +0 -86
- package/src/core/symbols.ts +0 -20
- package/src/core/tree/index.ts +0 -134
- package/src/core/types.ts +0 -377
- package/src/core/utils/error.ts +0 -73
- package/src/core/utils/get-identifier.ts +0 -18
- package/src/core/utils/get-object-flag.ts +0 -14
- package/src/core/utils/is-valid-identifier.ts +0 -12
- package/src/core/utils/promise-to-result.ts +0 -9
- package/src/core/utils/typed-array.ts +0 -56
- package/src/core/utils/valid-properties.ts +0 -34
- package/src/index.ts +0 -36
|
@@ -1,666 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createAggregateErrorNode,
|
|
3
|
-
createArrayNode,
|
|
4
|
-
createAsyncIteratorFactoryInstanceNode,
|
|
5
|
-
createBigIntNode,
|
|
6
|
-
createBigIntTypedArrayNode,
|
|
7
|
-
createBoxedNode,
|
|
8
|
-
createDataViewNode,
|
|
9
|
-
createDateNode,
|
|
10
|
-
createErrorNode,
|
|
11
|
-
createIteratorFactoryInstanceNode,
|
|
12
|
-
createNumberNode,
|
|
13
|
-
createPluginNode,
|
|
14
|
-
createRegExpNode,
|
|
15
|
-
createSequenceNode,
|
|
16
|
-
createSetNode,
|
|
17
|
-
createStreamConstructorNode,
|
|
18
|
-
createStreamNextNode,
|
|
19
|
-
createStreamReturnNode,
|
|
20
|
-
createStreamThrowNode,
|
|
21
|
-
createStringNode,
|
|
22
|
-
createTypedArrayNode,
|
|
23
|
-
} from '../base-primitives';
|
|
24
|
-
import { Feature } from '../compat';
|
|
25
|
-
import { NIL, SerovalNodeType } from '../constants';
|
|
26
|
-
import { SerovalDepthLimitError, SerovalParserError, SerovalUnsupportedTypeError } from '../errors';
|
|
27
|
-
import { FALSE_NODE, NULL_NODE, TRUE_NODE, UNDEFINED_NODE } from '../literals';
|
|
28
|
-
import { createSerovalNode } from '../node';
|
|
29
|
-
import { OpaqueReference } from '../opaque-reference';
|
|
30
|
-
import type { SerovalMode } from '../plugin';
|
|
31
|
-
import {
|
|
32
|
-
createSequenceFromIterable,
|
|
33
|
-
isSequence,
|
|
34
|
-
type Sequence,
|
|
35
|
-
} from '../sequence';
|
|
36
|
-
import { SpecialReference } from '../special-reference';
|
|
37
|
-
import type { Stream } from '../stream';
|
|
38
|
-
import { createStreamFromAsyncIterable, isStream } from '../stream';
|
|
39
|
-
import { serializeString } from '../string';
|
|
40
|
-
import {
|
|
41
|
-
SYM_ASYNC_ITERATOR,
|
|
42
|
-
SYM_IS_CONCAT_SPREADABLE,
|
|
43
|
-
SYM_ITERATOR,
|
|
44
|
-
SYM_TO_STRING_TAG,
|
|
45
|
-
} from '../symbols';
|
|
46
|
-
import type {
|
|
47
|
-
SerovalAggregateErrorNode,
|
|
48
|
-
SerovalArrayNode,
|
|
49
|
-
SerovalBigIntTypedArrayNode,
|
|
50
|
-
SerovalBoxedNode,
|
|
51
|
-
SerovalDataViewNode,
|
|
52
|
-
SerovalErrorNode,
|
|
53
|
-
SerovalMapNode,
|
|
54
|
-
SerovalNode,
|
|
55
|
-
SerovalNodeWithID,
|
|
56
|
-
SerovalNullConstructorNode,
|
|
57
|
-
SerovalObjectNode,
|
|
58
|
-
SerovalObjectRecordKey,
|
|
59
|
-
SerovalObjectRecordNode,
|
|
60
|
-
SerovalPluginNode,
|
|
61
|
-
SerovalPromiseNode,
|
|
62
|
-
SerovalSequenceNode,
|
|
63
|
-
SerovalSetNode,
|
|
64
|
-
SerovalStreamConstructorNode,
|
|
65
|
-
SerovalTypedArrayNode,
|
|
66
|
-
} from '../types';
|
|
67
|
-
import { getErrorOptions } from '../utils/error';
|
|
68
|
-
import promiseToResult from '../utils/promise-to-result';
|
|
69
|
-
import type {
|
|
70
|
-
BigIntTypedArrayValue,
|
|
71
|
-
TypedArrayValue,
|
|
72
|
-
} from '../utils/typed-array';
|
|
73
|
-
import type { BaseParserContext, BaseParserContextOptions } from './parser';
|
|
74
|
-
import {
|
|
75
|
-
createArrayBufferNode,
|
|
76
|
-
createBaseParserContext,
|
|
77
|
-
createMapNode,
|
|
78
|
-
createObjectNode,
|
|
79
|
-
getReferenceNode,
|
|
80
|
-
markParserRef,
|
|
81
|
-
parseAsyncIteratorFactory,
|
|
82
|
-
parseIteratorFactory,
|
|
83
|
-
ParserNodeType,
|
|
84
|
-
parseSpecialReference,
|
|
85
|
-
parseWellKnownSymbol,
|
|
86
|
-
} from './parser';
|
|
87
|
-
|
|
88
|
-
type ObjectLikeNode =
|
|
89
|
-
| SerovalObjectNode
|
|
90
|
-
| SerovalNullConstructorNode
|
|
91
|
-
| SerovalPromiseNode;
|
|
92
|
-
|
|
93
|
-
export type AsyncParserContextOptions = BaseParserContextOptions;
|
|
94
|
-
|
|
95
|
-
export interface AsyncParserContext {
|
|
96
|
-
base: BaseParserContext;
|
|
97
|
-
child: AsyncParsePluginContext | undefined;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export function createAsyncParserContext(
|
|
101
|
-
mode: SerovalMode,
|
|
102
|
-
options: AsyncParserContextOptions,
|
|
103
|
-
): AsyncParserContext {
|
|
104
|
-
return {
|
|
105
|
-
base: createBaseParserContext(mode, options),
|
|
106
|
-
child: undefined,
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
export class AsyncParsePluginContext {
|
|
111
|
-
constructor(
|
|
112
|
-
private _p: AsyncParserContext,
|
|
113
|
-
private depth: number,
|
|
114
|
-
) {}
|
|
115
|
-
|
|
116
|
-
parse<T>(current: T): Promise<SerovalNode> {
|
|
117
|
-
return parseAsync(this._p, this.depth, current);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
async function parseItems(
|
|
122
|
-
ctx: AsyncParserContext,
|
|
123
|
-
depth: number,
|
|
124
|
-
current: unknown[],
|
|
125
|
-
): Promise<(SerovalNode | 0)[]> {
|
|
126
|
-
const nodes: (SerovalNode | 0)[] = [];
|
|
127
|
-
for (let i = 0, len = current.length; i < len; i++) {
|
|
128
|
-
// For consistency in holes
|
|
129
|
-
if (i in current) {
|
|
130
|
-
nodes[i] = await parseAsync(ctx, depth, current[i]);
|
|
131
|
-
} else {
|
|
132
|
-
nodes[i] = 0;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
return nodes;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
async function parseArray(
|
|
139
|
-
ctx: AsyncParserContext,
|
|
140
|
-
depth: number,
|
|
141
|
-
id: number,
|
|
142
|
-
current: unknown[],
|
|
143
|
-
): Promise<SerovalArrayNode> {
|
|
144
|
-
return createArrayNode(id, current, await parseItems(ctx, depth, current));
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
async function parseProperties(
|
|
148
|
-
ctx: AsyncParserContext,
|
|
149
|
-
depth: number,
|
|
150
|
-
properties: Record<string | symbol, unknown>,
|
|
151
|
-
): Promise<SerovalObjectRecordNode> {
|
|
152
|
-
const entries = Object.entries(properties);
|
|
153
|
-
const keyNodes: SerovalObjectRecordKey[] = [];
|
|
154
|
-
const valueNodes: SerovalNode[] = [];
|
|
155
|
-
for (let i = 0, len = entries.length; i < len; i++) {
|
|
156
|
-
keyNodes.push(serializeString(entries[i][0]));
|
|
157
|
-
valueNodes.push(await parseAsync(ctx, depth, entries[i][1]));
|
|
158
|
-
}
|
|
159
|
-
// Check special properties
|
|
160
|
-
if (SYM_ITERATOR in properties) {
|
|
161
|
-
keyNodes.push(parseWellKnownSymbol(ctx.base, SYM_ITERATOR));
|
|
162
|
-
valueNodes.push(
|
|
163
|
-
createIteratorFactoryInstanceNode(
|
|
164
|
-
parseIteratorFactory(ctx.base),
|
|
165
|
-
(await parseAsync(
|
|
166
|
-
ctx,
|
|
167
|
-
depth,
|
|
168
|
-
createSequenceFromIterable(
|
|
169
|
-
properties as unknown as Iterable<unknown>,
|
|
170
|
-
),
|
|
171
|
-
)) as SerovalNodeWithID,
|
|
172
|
-
),
|
|
173
|
-
);
|
|
174
|
-
}
|
|
175
|
-
if (SYM_ASYNC_ITERATOR in properties) {
|
|
176
|
-
keyNodes.push(parseWellKnownSymbol(ctx.base, SYM_ASYNC_ITERATOR));
|
|
177
|
-
valueNodes.push(
|
|
178
|
-
createAsyncIteratorFactoryInstanceNode(
|
|
179
|
-
parseAsyncIteratorFactory(ctx.base),
|
|
180
|
-
(await parseAsync(
|
|
181
|
-
ctx,
|
|
182
|
-
depth,
|
|
183
|
-
createStreamFromAsyncIterable(
|
|
184
|
-
properties as unknown as AsyncIterable<unknown>,
|
|
185
|
-
),
|
|
186
|
-
)) as SerovalNodeWithID,
|
|
187
|
-
),
|
|
188
|
-
);
|
|
189
|
-
}
|
|
190
|
-
if (SYM_TO_STRING_TAG in properties) {
|
|
191
|
-
keyNodes.push(parseWellKnownSymbol(ctx.base, SYM_TO_STRING_TAG));
|
|
192
|
-
valueNodes.push(createStringNode(properties[SYM_TO_STRING_TAG] as string));
|
|
193
|
-
}
|
|
194
|
-
if (SYM_IS_CONCAT_SPREADABLE in properties) {
|
|
195
|
-
keyNodes.push(parseWellKnownSymbol(ctx.base, SYM_IS_CONCAT_SPREADABLE));
|
|
196
|
-
valueNodes.push(
|
|
197
|
-
properties[SYM_IS_CONCAT_SPREADABLE] ? TRUE_NODE : FALSE_NODE,
|
|
198
|
-
);
|
|
199
|
-
}
|
|
200
|
-
return {
|
|
201
|
-
k: keyNodes,
|
|
202
|
-
v: valueNodes,
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
async function parsePlainObject(
|
|
207
|
-
ctx: AsyncParserContext,
|
|
208
|
-
depth: number,
|
|
209
|
-
id: number,
|
|
210
|
-
current: Record<string, unknown>,
|
|
211
|
-
empty: boolean,
|
|
212
|
-
): Promise<ObjectLikeNode> {
|
|
213
|
-
return createObjectNode(
|
|
214
|
-
id,
|
|
215
|
-
current,
|
|
216
|
-
empty,
|
|
217
|
-
await parseProperties(ctx, depth, current),
|
|
218
|
-
);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// TODO: check if parseBoxedSync can be used
|
|
222
|
-
async function parseBoxed(
|
|
223
|
-
ctx: AsyncParserContext,
|
|
224
|
-
depth: number,
|
|
225
|
-
id: number,
|
|
226
|
-
current: object,
|
|
227
|
-
): Promise<SerovalBoxedNode> {
|
|
228
|
-
return createBoxedNode(id, await parseAsync(ctx, depth, current.valueOf()));
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
async function parseTypedArray(
|
|
232
|
-
ctx: AsyncParserContext,
|
|
233
|
-
depth: number,
|
|
234
|
-
id: number,
|
|
235
|
-
current: TypedArrayValue,
|
|
236
|
-
): Promise<SerovalTypedArrayNode> {
|
|
237
|
-
return createTypedArrayNode(
|
|
238
|
-
id,
|
|
239
|
-
current,
|
|
240
|
-
await parseAsync(ctx, depth, current.buffer),
|
|
241
|
-
);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
async function parseBigIntTypedArray(
|
|
245
|
-
ctx: AsyncParserContext,
|
|
246
|
-
depth: number,
|
|
247
|
-
id: number,
|
|
248
|
-
current: BigIntTypedArrayValue,
|
|
249
|
-
): Promise<SerovalBigIntTypedArrayNode> {
|
|
250
|
-
return createBigIntTypedArrayNode(
|
|
251
|
-
id,
|
|
252
|
-
current,
|
|
253
|
-
await parseAsync(ctx, depth, current.buffer),
|
|
254
|
-
);
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
async function parseDataView(
|
|
258
|
-
ctx: AsyncParserContext,
|
|
259
|
-
depth: number,
|
|
260
|
-
id: number,
|
|
261
|
-
current: DataView,
|
|
262
|
-
): Promise<SerovalDataViewNode> {
|
|
263
|
-
return createDataViewNode(
|
|
264
|
-
id,
|
|
265
|
-
current,
|
|
266
|
-
await parseAsync(ctx, depth, current.buffer),
|
|
267
|
-
);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
async function parseError(
|
|
271
|
-
ctx: AsyncParserContext,
|
|
272
|
-
depth: number,
|
|
273
|
-
id: number,
|
|
274
|
-
current: Error,
|
|
275
|
-
): Promise<SerovalErrorNode> {
|
|
276
|
-
const options = getErrorOptions(current, ctx.base.features);
|
|
277
|
-
return createErrorNode(
|
|
278
|
-
id,
|
|
279
|
-
current,
|
|
280
|
-
options ? await parseProperties(ctx, depth, options) : NIL,
|
|
281
|
-
);
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
async function parseAggregateError(
|
|
285
|
-
ctx: AsyncParserContext,
|
|
286
|
-
depth: number,
|
|
287
|
-
id: number,
|
|
288
|
-
current: AggregateError,
|
|
289
|
-
): Promise<SerovalAggregateErrorNode> {
|
|
290
|
-
const options = getErrorOptions(current, ctx.base.features);
|
|
291
|
-
return createAggregateErrorNode(
|
|
292
|
-
id,
|
|
293
|
-
current,
|
|
294
|
-
options ? await parseProperties(ctx, depth, options) : NIL,
|
|
295
|
-
);
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
async function parseMap(
|
|
299
|
-
ctx: AsyncParserContext,
|
|
300
|
-
depth: number,
|
|
301
|
-
id: number,
|
|
302
|
-
current: Map<unknown, unknown>,
|
|
303
|
-
): Promise<SerovalMapNode> {
|
|
304
|
-
const keyNodes: SerovalNode[] = [];
|
|
305
|
-
const valueNodes: SerovalNode[] = [];
|
|
306
|
-
for (const [key, value] of current.entries()) {
|
|
307
|
-
keyNodes.push(await parseAsync(ctx, depth, key));
|
|
308
|
-
valueNodes.push(await parseAsync(ctx, depth, value));
|
|
309
|
-
}
|
|
310
|
-
return createMapNode(ctx.base, id, keyNodes, valueNodes);
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
async function parseSet(
|
|
314
|
-
ctx: AsyncParserContext,
|
|
315
|
-
depth: number,
|
|
316
|
-
id: number,
|
|
317
|
-
current: Set<unknown>,
|
|
318
|
-
): Promise<SerovalSetNode> {
|
|
319
|
-
const items: SerovalNode[] = [];
|
|
320
|
-
for (const item of current.keys()) {
|
|
321
|
-
items.push(await parseAsync(ctx, depth, item));
|
|
322
|
-
}
|
|
323
|
-
return createSetNode(id, items);
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
async function parsePlugin(
|
|
327
|
-
ctx: AsyncParserContext,
|
|
328
|
-
depth: number,
|
|
329
|
-
id: number,
|
|
330
|
-
current: unknown,
|
|
331
|
-
): Promise<SerovalPluginNode | undefined> {
|
|
332
|
-
const currentPlugins = ctx.base.plugins;
|
|
333
|
-
if (currentPlugins) {
|
|
334
|
-
for (let i = 0, len = currentPlugins.length; i < len; i++) {
|
|
335
|
-
const plugin = currentPlugins[i];
|
|
336
|
-
if (plugin.parse.async && plugin.test(current)) {
|
|
337
|
-
return createPluginNode(
|
|
338
|
-
id,
|
|
339
|
-
plugin.tag,
|
|
340
|
-
await plugin.parse.async(
|
|
341
|
-
current,
|
|
342
|
-
new AsyncParsePluginContext(ctx, depth),
|
|
343
|
-
{
|
|
344
|
-
id,
|
|
345
|
-
},
|
|
346
|
-
),
|
|
347
|
-
);
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
return NIL;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
async function parsePromise(
|
|
355
|
-
ctx: AsyncParserContext,
|
|
356
|
-
depth: number,
|
|
357
|
-
id: number,
|
|
358
|
-
current: Promise<unknown>,
|
|
359
|
-
): Promise<SerovalPromiseNode> {
|
|
360
|
-
const [status, result] = await promiseToResult(current);
|
|
361
|
-
|
|
362
|
-
return createSerovalNode(
|
|
363
|
-
SerovalNodeType.Promise,
|
|
364
|
-
id,
|
|
365
|
-
status,
|
|
366
|
-
NIL,
|
|
367
|
-
NIL,
|
|
368
|
-
NIL,
|
|
369
|
-
NIL,
|
|
370
|
-
NIL,
|
|
371
|
-
await parseAsync(ctx, depth, result),
|
|
372
|
-
NIL,
|
|
373
|
-
NIL,
|
|
374
|
-
NIL,
|
|
375
|
-
);
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
function parseStreamHandle<T>(
|
|
379
|
-
this: AsyncParserContext,
|
|
380
|
-
depth: number,
|
|
381
|
-
id: number,
|
|
382
|
-
current: Stream<T>,
|
|
383
|
-
resolve: (value: SerovalNode[] | PromiseLike<SerovalNode[]>) => void,
|
|
384
|
-
reject: (reason?: any) => void,
|
|
385
|
-
): void {
|
|
386
|
-
const sequence: SerovalNode[] = [];
|
|
387
|
-
// TODO Optimizable
|
|
388
|
-
const cleanup = current.on({
|
|
389
|
-
next: value => {
|
|
390
|
-
markParserRef(this.base, id);
|
|
391
|
-
parseAsync(this, depth, value).then(
|
|
392
|
-
data => {
|
|
393
|
-
sequence.push(createStreamNextNode(id, data));
|
|
394
|
-
},
|
|
395
|
-
data => {
|
|
396
|
-
reject(data);
|
|
397
|
-
cleanup();
|
|
398
|
-
},
|
|
399
|
-
);
|
|
400
|
-
},
|
|
401
|
-
throw: value => {
|
|
402
|
-
markParserRef(this.base, id);
|
|
403
|
-
parseAsync(this, depth, value).then(
|
|
404
|
-
data => {
|
|
405
|
-
sequence.push(createStreamThrowNode(id, data));
|
|
406
|
-
resolve(sequence);
|
|
407
|
-
cleanup();
|
|
408
|
-
},
|
|
409
|
-
data => {
|
|
410
|
-
reject(data);
|
|
411
|
-
cleanup();
|
|
412
|
-
},
|
|
413
|
-
);
|
|
414
|
-
},
|
|
415
|
-
return: value => {
|
|
416
|
-
markParserRef(this.base, id);
|
|
417
|
-
parseAsync(this, depth, value).then(
|
|
418
|
-
data => {
|
|
419
|
-
sequence.push(createStreamReturnNode(id, data));
|
|
420
|
-
resolve(sequence);
|
|
421
|
-
cleanup();
|
|
422
|
-
},
|
|
423
|
-
data => {
|
|
424
|
-
reject(data);
|
|
425
|
-
cleanup();
|
|
426
|
-
},
|
|
427
|
-
);
|
|
428
|
-
},
|
|
429
|
-
});
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
async function parseStream(
|
|
433
|
-
ctx: AsyncParserContext,
|
|
434
|
-
depth: number,
|
|
435
|
-
id: number,
|
|
436
|
-
current: Stream<unknown>,
|
|
437
|
-
): Promise<SerovalStreamConstructorNode> {
|
|
438
|
-
return createStreamConstructorNode(
|
|
439
|
-
id,
|
|
440
|
-
parseSpecialReference(ctx.base, SpecialReference.StreamConstructor),
|
|
441
|
-
await new Promise<SerovalNode[]>(
|
|
442
|
-
parseStreamHandle.bind(ctx, depth, id, current),
|
|
443
|
-
),
|
|
444
|
-
);
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
async function parseSequence(
|
|
448
|
-
ctx: AsyncParserContext,
|
|
449
|
-
depth: number,
|
|
450
|
-
id: number,
|
|
451
|
-
current: Sequence,
|
|
452
|
-
): Promise<SerovalSequenceNode> {
|
|
453
|
-
const nodes: SerovalNode[] = [];
|
|
454
|
-
for (let i = 0, len = current.v.length; i < len; i++) {
|
|
455
|
-
nodes[i] = await parseAsync(ctx, depth, current.v[i]);
|
|
456
|
-
}
|
|
457
|
-
return createSequenceNode(id, nodes, current.t, current.d);
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
export async function parseObjectAsync(
|
|
461
|
-
ctx: AsyncParserContext,
|
|
462
|
-
depth: number,
|
|
463
|
-
id: number,
|
|
464
|
-
current: object,
|
|
465
|
-
): Promise<SerovalNode> {
|
|
466
|
-
if (Array.isArray(current)) {
|
|
467
|
-
return parseArray(ctx, depth, id, current);
|
|
468
|
-
}
|
|
469
|
-
if (isStream(current)) {
|
|
470
|
-
return parseStream(ctx, depth, id, current);
|
|
471
|
-
}
|
|
472
|
-
if (isSequence(current)) {
|
|
473
|
-
return parseSequence(ctx, depth, id, current);
|
|
474
|
-
}
|
|
475
|
-
const currentClass = current.constructor;
|
|
476
|
-
if (currentClass === OpaqueReference) {
|
|
477
|
-
return parseAsync(
|
|
478
|
-
ctx,
|
|
479
|
-
depth,
|
|
480
|
-
(current as OpaqueReference<unknown, unknown>).replacement,
|
|
481
|
-
);
|
|
482
|
-
}
|
|
483
|
-
const parsed = await parsePlugin(ctx, depth, id, current);
|
|
484
|
-
if (parsed) {
|
|
485
|
-
return parsed;
|
|
486
|
-
}
|
|
487
|
-
switch (currentClass) {
|
|
488
|
-
case Object:
|
|
489
|
-
return parsePlainObject(
|
|
490
|
-
ctx,
|
|
491
|
-
depth,
|
|
492
|
-
id,
|
|
493
|
-
current as Record<string, unknown>,
|
|
494
|
-
false,
|
|
495
|
-
);
|
|
496
|
-
case NIL:
|
|
497
|
-
return parsePlainObject(
|
|
498
|
-
ctx,
|
|
499
|
-
depth,
|
|
500
|
-
id,
|
|
501
|
-
current as Record<string, unknown>,
|
|
502
|
-
true,
|
|
503
|
-
);
|
|
504
|
-
case Date:
|
|
505
|
-
return createDateNode(id, current as unknown as Date);
|
|
506
|
-
case Error:
|
|
507
|
-
case EvalError:
|
|
508
|
-
case RangeError:
|
|
509
|
-
case ReferenceError:
|
|
510
|
-
case SyntaxError:
|
|
511
|
-
case TypeError:
|
|
512
|
-
case URIError:
|
|
513
|
-
return parseError(ctx, depth, id, current as unknown as Error);
|
|
514
|
-
case Number:
|
|
515
|
-
case Boolean:
|
|
516
|
-
case String:
|
|
517
|
-
case BigInt:
|
|
518
|
-
return parseBoxed(ctx, depth, id, current);
|
|
519
|
-
case ArrayBuffer:
|
|
520
|
-
return createArrayBufferNode(
|
|
521
|
-
ctx.base,
|
|
522
|
-
id,
|
|
523
|
-
current as unknown as ArrayBuffer,
|
|
524
|
-
);
|
|
525
|
-
case Int8Array:
|
|
526
|
-
case Int16Array:
|
|
527
|
-
case Int32Array:
|
|
528
|
-
case Uint8Array:
|
|
529
|
-
case Uint16Array:
|
|
530
|
-
case Uint32Array:
|
|
531
|
-
case Uint8ClampedArray:
|
|
532
|
-
case Float32Array:
|
|
533
|
-
case Float64Array:
|
|
534
|
-
return parseTypedArray(
|
|
535
|
-
ctx,
|
|
536
|
-
depth,
|
|
537
|
-
id,
|
|
538
|
-
current as unknown as TypedArrayValue,
|
|
539
|
-
);
|
|
540
|
-
case DataView:
|
|
541
|
-
return parseDataView(ctx, depth, id, current as unknown as DataView);
|
|
542
|
-
case Map:
|
|
543
|
-
return parseMap(
|
|
544
|
-
ctx,
|
|
545
|
-
depth,
|
|
546
|
-
id,
|
|
547
|
-
current as unknown as Map<unknown, unknown>,
|
|
548
|
-
);
|
|
549
|
-
case Set:
|
|
550
|
-
return parseSet(ctx, depth, id, current as unknown as Set<unknown>);
|
|
551
|
-
default:
|
|
552
|
-
break;
|
|
553
|
-
}
|
|
554
|
-
// Promises
|
|
555
|
-
if (currentClass === Promise || current instanceof Promise) {
|
|
556
|
-
return parsePromise(ctx, depth, id, current as unknown as Promise<unknown>);
|
|
557
|
-
}
|
|
558
|
-
const currentFeatures = ctx.base.features;
|
|
559
|
-
if (currentFeatures & Feature.RegExp && currentClass === RegExp) {
|
|
560
|
-
return createRegExpNode(id, current as unknown as RegExp);
|
|
561
|
-
}
|
|
562
|
-
// BigInt Typed Arrays
|
|
563
|
-
if (currentFeatures & Feature.BigIntTypedArray) {
|
|
564
|
-
switch (currentClass) {
|
|
565
|
-
case BigInt64Array:
|
|
566
|
-
case BigUint64Array:
|
|
567
|
-
return parseBigIntTypedArray(
|
|
568
|
-
ctx,
|
|
569
|
-
depth,
|
|
570
|
-
id,
|
|
571
|
-
current as unknown as BigIntTypedArrayValue,
|
|
572
|
-
);
|
|
573
|
-
default:
|
|
574
|
-
break;
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
if (
|
|
578
|
-
currentFeatures & Feature.AggregateError &&
|
|
579
|
-
typeof AggregateError !== 'undefined' &&
|
|
580
|
-
(currentClass === AggregateError || current instanceof AggregateError)
|
|
581
|
-
) {
|
|
582
|
-
return parseAggregateError(
|
|
583
|
-
ctx,
|
|
584
|
-
depth,
|
|
585
|
-
id,
|
|
586
|
-
current as unknown as AggregateError,
|
|
587
|
-
);
|
|
588
|
-
}
|
|
589
|
-
// Slow path. We only need to handle Errors and Iterators
|
|
590
|
-
// since they have very broad implementations.
|
|
591
|
-
if (current instanceof Error) {
|
|
592
|
-
return parseError(ctx, depth, id, current);
|
|
593
|
-
}
|
|
594
|
-
// Generator functions don't have a global constructor
|
|
595
|
-
// despite existing
|
|
596
|
-
if (SYM_ITERATOR in current || SYM_ASYNC_ITERATOR in current) {
|
|
597
|
-
return parsePlainObject(ctx, depth, id, current, !!currentClass);
|
|
598
|
-
}
|
|
599
|
-
throw new SerovalUnsupportedTypeError(current);
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
export async function parseFunctionAsync(
|
|
603
|
-
ctx: AsyncParserContext,
|
|
604
|
-
depth: number,
|
|
605
|
-
current: unknown,
|
|
606
|
-
): Promise<SerovalNode> {
|
|
607
|
-
const ref = getReferenceNode(ctx.base, current);
|
|
608
|
-
if (ref.type !== ParserNodeType.Fresh) {
|
|
609
|
-
return ref.value;
|
|
610
|
-
}
|
|
611
|
-
const plugin = await parsePlugin(ctx, depth, ref.value, current);
|
|
612
|
-
if (plugin) {
|
|
613
|
-
return plugin;
|
|
614
|
-
}
|
|
615
|
-
throw new SerovalUnsupportedTypeError(current);
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
export async function parseAsync<T>(
|
|
619
|
-
ctx: AsyncParserContext,
|
|
620
|
-
depth: number,
|
|
621
|
-
current: T,
|
|
622
|
-
): Promise<SerovalNode> {
|
|
623
|
-
if (depth >= ctx.base.depthLimit) {
|
|
624
|
-
throw new SerovalDepthLimitError(ctx.base.depthLimit);
|
|
625
|
-
}
|
|
626
|
-
switch (typeof current) {
|
|
627
|
-
case 'boolean':
|
|
628
|
-
return current ? TRUE_NODE : FALSE_NODE;
|
|
629
|
-
case 'undefined':
|
|
630
|
-
return UNDEFINED_NODE;
|
|
631
|
-
case 'string':
|
|
632
|
-
return createStringNode(current as string);
|
|
633
|
-
case 'number':
|
|
634
|
-
return createNumberNode(current as number);
|
|
635
|
-
case 'bigint':
|
|
636
|
-
return createBigIntNode(current as bigint);
|
|
637
|
-
case 'object': {
|
|
638
|
-
if (current) {
|
|
639
|
-
const ref = getReferenceNode(ctx.base, current);
|
|
640
|
-
return ref.type === 0
|
|
641
|
-
? await parseObjectAsync(ctx, depth + 1, ref.value, current as object)
|
|
642
|
-
: ref.value;
|
|
643
|
-
}
|
|
644
|
-
return NULL_NODE;
|
|
645
|
-
}
|
|
646
|
-
case 'symbol':
|
|
647
|
-
return parseWellKnownSymbol(ctx.base, current);
|
|
648
|
-
case 'function':
|
|
649
|
-
return parseFunctionAsync(ctx, depth, current);
|
|
650
|
-
default:
|
|
651
|
-
throw new SerovalUnsupportedTypeError(current);
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
export async function parseTopAsync<T>(
|
|
656
|
-
ctx: AsyncParserContext,
|
|
657
|
-
current: T,
|
|
658
|
-
): Promise<SerovalNode> {
|
|
659
|
-
try {
|
|
660
|
-
return await parseAsync(ctx, 0, current);
|
|
661
|
-
} catch (error) {
|
|
662
|
-
throw error instanceof SerovalParserError
|
|
663
|
-
? error
|
|
664
|
-
: new SerovalParserError(error);
|
|
665
|
-
}
|
|
666
|
-
}
|