seroval 1.5.5 → 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 -4230
- package/dist/cjs/development/index.cjs.map +0 -7
- package/dist/cjs/production/index.cjs +0 -3
- package/dist/esm/development/index.mjs +0 -4207
- 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 -663
- 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,943 +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 {
|
|
27
|
-
SerovalDepthLimitError,
|
|
28
|
-
SerovalParserError,
|
|
29
|
-
SerovalUnsupportedTypeError,
|
|
30
|
-
} from '../errors';
|
|
31
|
-
import { FALSE_NODE, NULL_NODE, TRUE_NODE, UNDEFINED_NODE } from '../literals';
|
|
32
|
-
import { createSerovalNode } from '../node';
|
|
33
|
-
import { OpaqueReference } from '../opaque-reference';
|
|
34
|
-
import { type Plugin, SerovalMode } from '../plugin';
|
|
35
|
-
import {
|
|
36
|
-
createSequenceFromIterable,
|
|
37
|
-
isSequence,
|
|
38
|
-
type Sequence,
|
|
39
|
-
} from '../sequence';
|
|
40
|
-
import { SpecialReference } from '../special-reference';
|
|
41
|
-
import type { Stream } from '../stream';
|
|
42
|
-
import {
|
|
43
|
-
createStream,
|
|
44
|
-
createStreamFromAsyncIterable,
|
|
45
|
-
isStream,
|
|
46
|
-
} from '../stream';
|
|
47
|
-
import { serializeString } from '../string';
|
|
48
|
-
import {
|
|
49
|
-
SYM_ASYNC_ITERATOR,
|
|
50
|
-
SYM_IS_CONCAT_SPREADABLE,
|
|
51
|
-
SYM_ITERATOR,
|
|
52
|
-
SYM_TO_STRING_TAG,
|
|
53
|
-
} from '../symbols';
|
|
54
|
-
import type {
|
|
55
|
-
SerovalAggregateErrorNode,
|
|
56
|
-
SerovalArrayNode,
|
|
57
|
-
SerovalBigIntTypedArrayNode,
|
|
58
|
-
SerovalBoxedNode,
|
|
59
|
-
SerovalDataViewNode,
|
|
60
|
-
SerovalErrorNode,
|
|
61
|
-
SerovalMapNode,
|
|
62
|
-
SerovalNode,
|
|
63
|
-
SerovalNodeWithID,
|
|
64
|
-
SerovalNullConstructorNode,
|
|
65
|
-
SerovalObjectNode,
|
|
66
|
-
SerovalObjectRecordKey,
|
|
67
|
-
SerovalObjectRecordNode,
|
|
68
|
-
SerovalPluginNode,
|
|
69
|
-
SerovalPromiseConstructorNode,
|
|
70
|
-
SerovalSequenceNode,
|
|
71
|
-
SerovalSetNode,
|
|
72
|
-
SerovalTypedArrayNode,
|
|
73
|
-
} from '../types';
|
|
74
|
-
import { getErrorOptions } from '../utils/error';
|
|
75
|
-
import type {
|
|
76
|
-
BigIntTypedArrayValue,
|
|
77
|
-
TypedArrayValue,
|
|
78
|
-
} from '../utils/typed-array';
|
|
79
|
-
import type { BaseParserContext, BaseParserContextOptions } from './parser';
|
|
80
|
-
import {
|
|
81
|
-
createArrayBufferNode,
|
|
82
|
-
createBaseParserContext,
|
|
83
|
-
createIndexForValue,
|
|
84
|
-
createMapNode,
|
|
85
|
-
createObjectNode,
|
|
86
|
-
createPromiseConstructorNode,
|
|
87
|
-
getReferenceNode,
|
|
88
|
-
parseAsyncIteratorFactory,
|
|
89
|
-
parseIteratorFactory,
|
|
90
|
-
ParserNodeType,
|
|
91
|
-
parseSpecialReference,
|
|
92
|
-
parseWellKnownSymbol,
|
|
93
|
-
} from './parser';
|
|
94
|
-
|
|
95
|
-
type ObjectLikeNode = SerovalObjectNode | SerovalNullConstructorNode;
|
|
96
|
-
|
|
97
|
-
export type SyncParserContextOptions = BaseParserContextOptions;
|
|
98
|
-
|
|
99
|
-
const enum ParserMode {
|
|
100
|
-
Sync = 1,
|
|
101
|
-
Stream = 2,
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
export interface SyncParserContext {
|
|
105
|
-
type: ParserMode.Sync;
|
|
106
|
-
base: BaseParserContext;
|
|
107
|
-
child: SyncParsePluginContext | undefined;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
export function createSyncParserContext(
|
|
111
|
-
mode: SerovalMode,
|
|
112
|
-
options: SyncParserContextOptions,
|
|
113
|
-
): SyncParserContext {
|
|
114
|
-
return {
|
|
115
|
-
type: ParserMode.Sync,
|
|
116
|
-
base: createBaseParserContext(mode, options),
|
|
117
|
-
child: NIL,
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export class SyncParsePluginContext {
|
|
122
|
-
constructor(
|
|
123
|
-
private _p: SyncParserContext,
|
|
124
|
-
private depth: number,
|
|
125
|
-
) {}
|
|
126
|
-
|
|
127
|
-
parse<T>(current: T): SerovalNode {
|
|
128
|
-
return parseSOS(this._p, this.depth, current);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
export interface StreamParserContextOptions extends SyncParserContextOptions {
|
|
133
|
-
onParse: (node: SerovalNode, initial: boolean) => void;
|
|
134
|
-
onError?: (error: unknown) => void;
|
|
135
|
-
onDone?: () => void;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
export interface StreamParserContext {
|
|
139
|
-
type: ParserMode.Stream;
|
|
140
|
-
base: BaseParserContext;
|
|
141
|
-
state: StreamParserState;
|
|
142
|
-
}
|
|
143
|
-
export class StreamParsePluginContext {
|
|
144
|
-
constructor(
|
|
145
|
-
private _p: StreamParserContext,
|
|
146
|
-
private depth: number,
|
|
147
|
-
) {}
|
|
148
|
-
|
|
149
|
-
parse<T>(current: T): SerovalNode {
|
|
150
|
-
return parseSOS(this._p, this.depth, current);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
parseWithError<T>(current: T): SerovalNode | undefined {
|
|
154
|
-
return parseWithError(this._p, this.depth, current);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
isAlive(): boolean {
|
|
158
|
-
return this._p.state.alive;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
pushPendingState(): void {
|
|
162
|
-
pushPendingState(this._p);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
popPendingState(): void {
|
|
166
|
-
popPendingState(this._p);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
onParse(node: SerovalNode): void {
|
|
170
|
-
onParse(this._p, node);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
onError(error: unknown): void {
|
|
174
|
-
onError(this._p, error);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
addCleanup(callback: () => void): void {
|
|
178
|
-
this._p.state.cleanups.push(callback);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
interface StreamParserState {
|
|
183
|
-
// Life cycle
|
|
184
|
-
alive: boolean;
|
|
185
|
-
// Number of pending things
|
|
186
|
-
pending: number;
|
|
187
|
-
//
|
|
188
|
-
initial: boolean;
|
|
189
|
-
//
|
|
190
|
-
buffer: SerovalNode[];
|
|
191
|
-
// Callbacks
|
|
192
|
-
onParse: (node: SerovalNode, initial: boolean) => void;
|
|
193
|
-
onError?: (error: unknown) => void;
|
|
194
|
-
onDone?: () => void;
|
|
195
|
-
|
|
196
|
-
cleanups: (() => void)[];
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
function createStreamParserState(
|
|
200
|
-
options: StreamParserContextOptions,
|
|
201
|
-
): StreamParserState {
|
|
202
|
-
return {
|
|
203
|
-
alive: true,
|
|
204
|
-
pending: 0,
|
|
205
|
-
initial: true,
|
|
206
|
-
buffer: [],
|
|
207
|
-
onParse: options.onParse,
|
|
208
|
-
onError: options.onError,
|
|
209
|
-
onDone: options.onDone,
|
|
210
|
-
cleanups: [],
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
export function createStreamParserContext(
|
|
215
|
-
options: StreamParserContextOptions,
|
|
216
|
-
): StreamParserContext {
|
|
217
|
-
return {
|
|
218
|
-
type: ParserMode.Stream,
|
|
219
|
-
base: createBaseParserContext(SerovalMode.Cross, options),
|
|
220
|
-
state: createStreamParserState(options),
|
|
221
|
-
};
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
type SOSParserContext = SyncParserContext | StreamParserContext;
|
|
225
|
-
|
|
226
|
-
function parseItems(
|
|
227
|
-
ctx: SOSParserContext,
|
|
228
|
-
depth: number,
|
|
229
|
-
current: unknown[],
|
|
230
|
-
): (SerovalNode | 0)[] {
|
|
231
|
-
const nodes: (SerovalNode | 0)[] = [];
|
|
232
|
-
for (let i = 0, len = current.length; i < len; i++) {
|
|
233
|
-
if (i in current) {
|
|
234
|
-
nodes[i] = parseSOS(ctx, depth, current[i]);
|
|
235
|
-
} else {
|
|
236
|
-
nodes[i] = 0;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
return nodes;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
function parseArray(
|
|
243
|
-
ctx: SOSParserContext,
|
|
244
|
-
depth: number,
|
|
245
|
-
id: number,
|
|
246
|
-
current: unknown[],
|
|
247
|
-
): SerovalArrayNode {
|
|
248
|
-
return createArrayNode(id, current, parseItems(ctx, depth, current));
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
function parseProperties(
|
|
252
|
-
ctx: SOSParserContext,
|
|
253
|
-
depth: number,
|
|
254
|
-
properties: Record<string | symbol, unknown>,
|
|
255
|
-
): SerovalObjectRecordNode {
|
|
256
|
-
const entries = Object.entries(properties);
|
|
257
|
-
const keyNodes: SerovalObjectRecordKey[] = [];
|
|
258
|
-
const valueNodes: SerovalNode[] = [];
|
|
259
|
-
for (let i = 0, len = entries.length; i < len; i++) {
|
|
260
|
-
keyNodes.push(serializeString(entries[i][0]));
|
|
261
|
-
valueNodes.push(parseSOS(ctx, depth, entries[i][1]));
|
|
262
|
-
}
|
|
263
|
-
// Check special properties, symbols in this case
|
|
264
|
-
if (SYM_ITERATOR in properties) {
|
|
265
|
-
keyNodes.push(parseWellKnownSymbol(ctx.base, SYM_ITERATOR));
|
|
266
|
-
valueNodes.push(
|
|
267
|
-
createIteratorFactoryInstanceNode(
|
|
268
|
-
parseIteratorFactory(ctx.base),
|
|
269
|
-
parseSOS(
|
|
270
|
-
ctx,
|
|
271
|
-
depth,
|
|
272
|
-
createSequenceFromIterable(
|
|
273
|
-
properties as unknown as Iterable<unknown>,
|
|
274
|
-
),
|
|
275
|
-
) as SerovalNodeWithID,
|
|
276
|
-
),
|
|
277
|
-
);
|
|
278
|
-
}
|
|
279
|
-
if (SYM_ASYNC_ITERATOR in properties) {
|
|
280
|
-
keyNodes.push(parseWellKnownSymbol(ctx.base, SYM_ASYNC_ITERATOR));
|
|
281
|
-
valueNodes.push(
|
|
282
|
-
createAsyncIteratorFactoryInstanceNode(
|
|
283
|
-
parseAsyncIteratorFactory(ctx.base),
|
|
284
|
-
parseSOS(
|
|
285
|
-
ctx,
|
|
286
|
-
depth,
|
|
287
|
-
ctx.type === ParserMode.Sync
|
|
288
|
-
? createStream()
|
|
289
|
-
: createStreamFromAsyncIterable(
|
|
290
|
-
properties as unknown as AsyncIterable<unknown>,
|
|
291
|
-
),
|
|
292
|
-
) as SerovalNodeWithID,
|
|
293
|
-
),
|
|
294
|
-
);
|
|
295
|
-
}
|
|
296
|
-
if (SYM_TO_STRING_TAG in properties) {
|
|
297
|
-
keyNodes.push(parseWellKnownSymbol(ctx.base, SYM_TO_STRING_TAG));
|
|
298
|
-
valueNodes.push(createStringNode(properties[SYM_TO_STRING_TAG] as string));
|
|
299
|
-
}
|
|
300
|
-
if (SYM_IS_CONCAT_SPREADABLE in properties) {
|
|
301
|
-
keyNodes.push(parseWellKnownSymbol(ctx.base, SYM_IS_CONCAT_SPREADABLE));
|
|
302
|
-
valueNodes.push(
|
|
303
|
-
properties[SYM_IS_CONCAT_SPREADABLE] ? TRUE_NODE : FALSE_NODE,
|
|
304
|
-
);
|
|
305
|
-
}
|
|
306
|
-
return {
|
|
307
|
-
k: keyNodes,
|
|
308
|
-
v: valueNodes,
|
|
309
|
-
};
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
function parsePlainObject(
|
|
313
|
-
ctx: SOSParserContext,
|
|
314
|
-
depth: number,
|
|
315
|
-
id: number,
|
|
316
|
-
current: Record<string, unknown>,
|
|
317
|
-
empty: boolean,
|
|
318
|
-
): ObjectLikeNode {
|
|
319
|
-
return createObjectNode(
|
|
320
|
-
id,
|
|
321
|
-
current,
|
|
322
|
-
empty,
|
|
323
|
-
parseProperties(ctx, depth, current),
|
|
324
|
-
);
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
function parseBoxed(
|
|
328
|
-
ctx: SOSParserContext,
|
|
329
|
-
depth: number,
|
|
330
|
-
id: number,
|
|
331
|
-
current: object,
|
|
332
|
-
): SerovalBoxedNode {
|
|
333
|
-
return createBoxedNode(id, parseSOS(ctx, depth, current.valueOf()));
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
function parseTypedArray(
|
|
337
|
-
ctx: SOSParserContext,
|
|
338
|
-
depth: number,
|
|
339
|
-
id: number,
|
|
340
|
-
current: TypedArrayValue,
|
|
341
|
-
): SerovalTypedArrayNode {
|
|
342
|
-
return createTypedArrayNode(
|
|
343
|
-
id,
|
|
344
|
-
current,
|
|
345
|
-
parseSOS(ctx, depth, current.buffer),
|
|
346
|
-
);
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
function parseBigIntTypedArray(
|
|
350
|
-
ctx: SOSParserContext,
|
|
351
|
-
depth: number,
|
|
352
|
-
id: number,
|
|
353
|
-
current: BigIntTypedArrayValue,
|
|
354
|
-
): SerovalBigIntTypedArrayNode {
|
|
355
|
-
return createBigIntTypedArrayNode(
|
|
356
|
-
id,
|
|
357
|
-
current,
|
|
358
|
-
parseSOS(ctx, depth, current.buffer),
|
|
359
|
-
);
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
function parseDataView(
|
|
363
|
-
ctx: SOSParserContext,
|
|
364
|
-
depth: number,
|
|
365
|
-
id: number,
|
|
366
|
-
current: DataView,
|
|
367
|
-
): SerovalDataViewNode {
|
|
368
|
-
return createDataViewNode(id, current, parseSOS(ctx, depth, current.buffer));
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
function parseError(
|
|
372
|
-
ctx: SOSParserContext,
|
|
373
|
-
depth: number,
|
|
374
|
-
id: number,
|
|
375
|
-
current: Error,
|
|
376
|
-
): SerovalErrorNode {
|
|
377
|
-
const options = getErrorOptions(current, ctx.base.features);
|
|
378
|
-
return createErrorNode(
|
|
379
|
-
id,
|
|
380
|
-
current,
|
|
381
|
-
options ? parseProperties(ctx, depth, options) : NIL,
|
|
382
|
-
);
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
function parseAggregateError(
|
|
386
|
-
ctx: SOSParserContext,
|
|
387
|
-
depth: number,
|
|
388
|
-
id: number,
|
|
389
|
-
current: AggregateError,
|
|
390
|
-
): SerovalAggregateErrorNode {
|
|
391
|
-
const options = getErrorOptions(current, ctx.base.features);
|
|
392
|
-
return createAggregateErrorNode(
|
|
393
|
-
id,
|
|
394
|
-
current,
|
|
395
|
-
options ? parseProperties(ctx, depth, options) : NIL,
|
|
396
|
-
);
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
function parseMap(
|
|
400
|
-
ctx: SOSParserContext,
|
|
401
|
-
depth: number,
|
|
402
|
-
id: number,
|
|
403
|
-
current: Map<unknown, unknown>,
|
|
404
|
-
): SerovalMapNode {
|
|
405
|
-
const keyNodes: SerovalNode[] = [];
|
|
406
|
-
const valueNodes: SerovalNode[] = [];
|
|
407
|
-
for (const [key, value] of current.entries()) {
|
|
408
|
-
keyNodes.push(parseSOS(ctx, depth, key));
|
|
409
|
-
valueNodes.push(parseSOS(ctx, depth, value));
|
|
410
|
-
}
|
|
411
|
-
return createMapNode(ctx.base, id, keyNodes, valueNodes);
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
function parseSet(
|
|
415
|
-
ctx: SOSParserContext,
|
|
416
|
-
depth: number,
|
|
417
|
-
id: number,
|
|
418
|
-
current: Set<unknown>,
|
|
419
|
-
): SerovalSetNode {
|
|
420
|
-
const items: SerovalNode[] = [];
|
|
421
|
-
for (const item of current.keys()) {
|
|
422
|
-
items.push(parseSOS(ctx, depth, item));
|
|
423
|
-
}
|
|
424
|
-
return createSetNode(id, items);
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
function parseStream(
|
|
428
|
-
ctx: SOSParserContext,
|
|
429
|
-
depth: number,
|
|
430
|
-
id: number,
|
|
431
|
-
current: Stream<unknown>,
|
|
432
|
-
): SerovalNode {
|
|
433
|
-
const result = createStreamConstructorNode(
|
|
434
|
-
id,
|
|
435
|
-
parseSpecialReference(ctx.base, SpecialReference.StreamConstructor),
|
|
436
|
-
[],
|
|
437
|
-
);
|
|
438
|
-
if (ctx.type === ParserMode.Sync) {
|
|
439
|
-
return result;
|
|
440
|
-
}
|
|
441
|
-
pushPendingState(ctx);
|
|
442
|
-
current.on({
|
|
443
|
-
next: value => {
|
|
444
|
-
if (ctx.state.alive) {
|
|
445
|
-
const parsed = parseWithError(ctx, depth, value);
|
|
446
|
-
if (parsed) {
|
|
447
|
-
onParse(ctx, createStreamNextNode(id, parsed));
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
},
|
|
451
|
-
throw: value => {
|
|
452
|
-
if (ctx.state.alive) {
|
|
453
|
-
const parsed = parseWithError(ctx, depth, value);
|
|
454
|
-
if (parsed) {
|
|
455
|
-
onParse(ctx, createStreamThrowNode(id, parsed));
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
popPendingState(ctx);
|
|
459
|
-
},
|
|
460
|
-
return: value => {
|
|
461
|
-
if (ctx.state.alive) {
|
|
462
|
-
const parsed = parseWithError(ctx, depth, value);
|
|
463
|
-
if (parsed) {
|
|
464
|
-
onParse(ctx, createStreamReturnNode(id, parsed));
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
popPendingState(ctx);
|
|
468
|
-
},
|
|
469
|
-
});
|
|
470
|
-
return result;
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
function handlePromiseSuccess(
|
|
474
|
-
this: StreamParserContext,
|
|
475
|
-
id: number,
|
|
476
|
-
depth: number,
|
|
477
|
-
data: unknown,
|
|
478
|
-
): void {
|
|
479
|
-
if (this.state.alive) {
|
|
480
|
-
const parsed = parseWithError(this, depth, data);
|
|
481
|
-
if (parsed) {
|
|
482
|
-
onParse(
|
|
483
|
-
this,
|
|
484
|
-
createSerovalNode(
|
|
485
|
-
SerovalNodeType.PromiseSuccess,
|
|
486
|
-
id,
|
|
487
|
-
NIL,
|
|
488
|
-
NIL,
|
|
489
|
-
NIL,
|
|
490
|
-
NIL,
|
|
491
|
-
NIL,
|
|
492
|
-
[
|
|
493
|
-
parseSpecialReference(this.base, SpecialReference.PromiseSuccess),
|
|
494
|
-
parsed,
|
|
495
|
-
],
|
|
496
|
-
NIL,
|
|
497
|
-
NIL,
|
|
498
|
-
NIL,
|
|
499
|
-
NIL,
|
|
500
|
-
),
|
|
501
|
-
);
|
|
502
|
-
}
|
|
503
|
-
popPendingState(this);
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
function handlePromiseFailure(
|
|
508
|
-
this: StreamParserContext,
|
|
509
|
-
id: number,
|
|
510
|
-
depth: number,
|
|
511
|
-
data: unknown,
|
|
512
|
-
): void {
|
|
513
|
-
if (this.state.alive) {
|
|
514
|
-
const parsed = parseWithError(this, depth, data);
|
|
515
|
-
if (parsed) {
|
|
516
|
-
onParse(
|
|
517
|
-
this,
|
|
518
|
-
createSerovalNode(
|
|
519
|
-
SerovalNodeType.PromiseFailure,
|
|
520
|
-
id,
|
|
521
|
-
NIL,
|
|
522
|
-
NIL,
|
|
523
|
-
NIL,
|
|
524
|
-
NIL,
|
|
525
|
-
NIL,
|
|
526
|
-
[
|
|
527
|
-
parseSpecialReference(this.base, SpecialReference.PromiseFailure),
|
|
528
|
-
parsed,
|
|
529
|
-
],
|
|
530
|
-
NIL,
|
|
531
|
-
NIL,
|
|
532
|
-
NIL,
|
|
533
|
-
NIL,
|
|
534
|
-
),
|
|
535
|
-
);
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
popPendingState(this);
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
function parsePromise(
|
|
542
|
-
ctx: SOSParserContext,
|
|
543
|
-
depth: number,
|
|
544
|
-
id: number,
|
|
545
|
-
current: Promise<unknown>,
|
|
546
|
-
): SerovalPromiseConstructorNode {
|
|
547
|
-
// Creates a unique reference for the promise resolver
|
|
548
|
-
const resolver = createIndexForValue(ctx.base, {});
|
|
549
|
-
if (ctx.type === ParserMode.Stream) {
|
|
550
|
-
pushPendingState(ctx);
|
|
551
|
-
current.then(
|
|
552
|
-
handlePromiseSuccess.bind(ctx, resolver, depth),
|
|
553
|
-
handlePromiseFailure.bind(ctx, resolver, depth),
|
|
554
|
-
);
|
|
555
|
-
}
|
|
556
|
-
return createPromiseConstructorNode(ctx.base, id, resolver);
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
function parsePluginSync(
|
|
560
|
-
ctx: SyncParserContext,
|
|
561
|
-
depth: number,
|
|
562
|
-
id: number,
|
|
563
|
-
current: unknown,
|
|
564
|
-
currentPlugins: Plugin<any, any>[],
|
|
565
|
-
): SerovalPluginNode | undefined {
|
|
566
|
-
for (let i = 0, len = currentPlugins.length; i < len; i++) {
|
|
567
|
-
const plugin = currentPlugins[i];
|
|
568
|
-
if (plugin.parse.sync && plugin.test(current)) {
|
|
569
|
-
return createPluginNode(
|
|
570
|
-
id,
|
|
571
|
-
plugin.tag,
|
|
572
|
-
plugin.parse.sync(current, new SyncParsePluginContext(ctx, depth), {
|
|
573
|
-
id,
|
|
574
|
-
}),
|
|
575
|
-
);
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
return NIL;
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
function parsePluginStream(
|
|
582
|
-
ctx: StreamParserContext,
|
|
583
|
-
depth: number,
|
|
584
|
-
id: number,
|
|
585
|
-
current: unknown,
|
|
586
|
-
currentPlugins: Plugin<any, any>[],
|
|
587
|
-
): SerovalPluginNode | undefined {
|
|
588
|
-
for (let i = 0, len = currentPlugins.length; i < len; i++) {
|
|
589
|
-
const plugin = currentPlugins[i];
|
|
590
|
-
if (plugin.parse.stream && plugin.test(current)) {
|
|
591
|
-
return createPluginNode(
|
|
592
|
-
id,
|
|
593
|
-
plugin.tag,
|
|
594
|
-
plugin.parse.stream(current, new StreamParsePluginContext(ctx, depth), {
|
|
595
|
-
id,
|
|
596
|
-
}),
|
|
597
|
-
);
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
return NIL;
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
function parsePlugin(
|
|
604
|
-
ctx: SOSParserContext,
|
|
605
|
-
depth: number,
|
|
606
|
-
id: number,
|
|
607
|
-
current: unknown,
|
|
608
|
-
): SerovalPluginNode | undefined {
|
|
609
|
-
const currentPlugins = ctx.base.plugins;
|
|
610
|
-
if (currentPlugins) {
|
|
611
|
-
return ctx.type === ParserMode.Sync
|
|
612
|
-
? parsePluginSync(ctx, depth, id, current, currentPlugins)
|
|
613
|
-
: parsePluginStream(ctx, depth, id, current, currentPlugins);
|
|
614
|
-
}
|
|
615
|
-
return NIL;
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
function parseSequence(
|
|
619
|
-
ctx: SOSParserContext,
|
|
620
|
-
depth: number,
|
|
621
|
-
id: number,
|
|
622
|
-
current: Sequence,
|
|
623
|
-
): SerovalSequenceNode {
|
|
624
|
-
const nodes: SerovalNode[] = [];
|
|
625
|
-
for (let i = 0, len = current.v.length; i < len; i++) {
|
|
626
|
-
nodes[i] = parseSOS(ctx, depth, current.v[i]);
|
|
627
|
-
}
|
|
628
|
-
return createSequenceNode(id, nodes, current.t, current.d);
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
function parseObjectPhase2(
|
|
632
|
-
ctx: SOSParserContext,
|
|
633
|
-
depth: number,
|
|
634
|
-
id: number,
|
|
635
|
-
current: object,
|
|
636
|
-
currentClass: unknown,
|
|
637
|
-
): SerovalNode {
|
|
638
|
-
switch (currentClass) {
|
|
639
|
-
case Object:
|
|
640
|
-
return parsePlainObject(
|
|
641
|
-
ctx,
|
|
642
|
-
depth,
|
|
643
|
-
id,
|
|
644
|
-
current as Record<string, unknown>,
|
|
645
|
-
false,
|
|
646
|
-
);
|
|
647
|
-
case NIL:
|
|
648
|
-
return parsePlainObject(
|
|
649
|
-
ctx,
|
|
650
|
-
depth,
|
|
651
|
-
id,
|
|
652
|
-
current as Record<string, unknown>,
|
|
653
|
-
true,
|
|
654
|
-
);
|
|
655
|
-
case Date:
|
|
656
|
-
return createDateNode(id, current as unknown as Date);
|
|
657
|
-
case Error:
|
|
658
|
-
case EvalError:
|
|
659
|
-
case RangeError:
|
|
660
|
-
case ReferenceError:
|
|
661
|
-
case SyntaxError:
|
|
662
|
-
case TypeError:
|
|
663
|
-
case URIError:
|
|
664
|
-
return parseError(ctx, depth, id, current as unknown as Error);
|
|
665
|
-
case Number:
|
|
666
|
-
case Boolean:
|
|
667
|
-
case String:
|
|
668
|
-
case BigInt:
|
|
669
|
-
return parseBoxed(ctx, depth, id, current);
|
|
670
|
-
case ArrayBuffer:
|
|
671
|
-
return createArrayBufferNode(
|
|
672
|
-
ctx.base,
|
|
673
|
-
id,
|
|
674
|
-
current as unknown as ArrayBuffer,
|
|
675
|
-
);
|
|
676
|
-
case Int8Array:
|
|
677
|
-
case Int16Array:
|
|
678
|
-
case Int32Array:
|
|
679
|
-
case Uint8Array:
|
|
680
|
-
case Uint16Array:
|
|
681
|
-
case Uint32Array:
|
|
682
|
-
case Uint8ClampedArray:
|
|
683
|
-
case Float32Array:
|
|
684
|
-
case Float64Array:
|
|
685
|
-
return parseTypedArray(
|
|
686
|
-
ctx,
|
|
687
|
-
depth,
|
|
688
|
-
id,
|
|
689
|
-
current as unknown as TypedArrayValue,
|
|
690
|
-
);
|
|
691
|
-
case DataView:
|
|
692
|
-
return parseDataView(ctx, depth, id, current as unknown as DataView);
|
|
693
|
-
case Map:
|
|
694
|
-
return parseMap(
|
|
695
|
-
ctx,
|
|
696
|
-
depth,
|
|
697
|
-
id,
|
|
698
|
-
current as unknown as Map<unknown, unknown>,
|
|
699
|
-
);
|
|
700
|
-
case Set:
|
|
701
|
-
return parseSet(ctx, depth, id, current as unknown as Set<unknown>);
|
|
702
|
-
default:
|
|
703
|
-
break;
|
|
704
|
-
}
|
|
705
|
-
// Promises
|
|
706
|
-
if (currentClass === Promise || current instanceof Promise) {
|
|
707
|
-
return parsePromise(ctx, depth, id, current as unknown as Promise<unknown>);
|
|
708
|
-
}
|
|
709
|
-
const currentFeatures = ctx.base.features;
|
|
710
|
-
if (currentFeatures & Feature.RegExp && currentClass === RegExp) {
|
|
711
|
-
return createRegExpNode(id, current as unknown as RegExp);
|
|
712
|
-
}
|
|
713
|
-
// BigInt Typed Arrays
|
|
714
|
-
if (currentFeatures & Feature.BigIntTypedArray) {
|
|
715
|
-
switch (currentClass) {
|
|
716
|
-
case BigInt64Array:
|
|
717
|
-
case BigUint64Array:
|
|
718
|
-
return parseBigIntTypedArray(
|
|
719
|
-
ctx,
|
|
720
|
-
depth,
|
|
721
|
-
id,
|
|
722
|
-
current as unknown as BigIntTypedArrayValue,
|
|
723
|
-
);
|
|
724
|
-
default:
|
|
725
|
-
break;
|
|
726
|
-
}
|
|
727
|
-
}
|
|
728
|
-
if (
|
|
729
|
-
currentFeatures & Feature.AggregateError &&
|
|
730
|
-
typeof AggregateError !== 'undefined' &&
|
|
731
|
-
(currentClass === AggregateError || current instanceof AggregateError)
|
|
732
|
-
) {
|
|
733
|
-
return parseAggregateError(
|
|
734
|
-
ctx,
|
|
735
|
-
depth,
|
|
736
|
-
id,
|
|
737
|
-
current as unknown as AggregateError,
|
|
738
|
-
);
|
|
739
|
-
}
|
|
740
|
-
// Slow path. We only need to handle Errors and Iterators
|
|
741
|
-
// since they have very broad implementations.
|
|
742
|
-
if (current instanceof Error) {
|
|
743
|
-
return parseError(ctx, depth, id, current);
|
|
744
|
-
}
|
|
745
|
-
// Generator functions don't have a global constructor
|
|
746
|
-
// despite existing
|
|
747
|
-
if (SYM_ITERATOR in current || SYM_ASYNC_ITERATOR in current) {
|
|
748
|
-
return parsePlainObject(ctx, depth, id, current, !!currentClass);
|
|
749
|
-
}
|
|
750
|
-
throw new SerovalUnsupportedTypeError(current);
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
function parseObject(
|
|
754
|
-
ctx: SOSParserContext,
|
|
755
|
-
depth: number,
|
|
756
|
-
id: number,
|
|
757
|
-
current: object,
|
|
758
|
-
): SerovalNode {
|
|
759
|
-
if (Array.isArray(current)) {
|
|
760
|
-
return parseArray(ctx, depth, id, current);
|
|
761
|
-
}
|
|
762
|
-
if (isStream(current)) {
|
|
763
|
-
return parseStream(ctx, depth, id, current);
|
|
764
|
-
}
|
|
765
|
-
if (isSequence(current)) {
|
|
766
|
-
return parseSequence(ctx, depth, id, current);
|
|
767
|
-
}
|
|
768
|
-
const currentClass = current.constructor;
|
|
769
|
-
if (currentClass === OpaqueReference) {
|
|
770
|
-
return parseSOS(
|
|
771
|
-
ctx,
|
|
772
|
-
depth,
|
|
773
|
-
(current as OpaqueReference<unknown, unknown>).replacement,
|
|
774
|
-
);
|
|
775
|
-
}
|
|
776
|
-
const parsed = parsePlugin(ctx, depth, id, current);
|
|
777
|
-
if (parsed) {
|
|
778
|
-
return parsed;
|
|
779
|
-
}
|
|
780
|
-
return parseObjectPhase2(ctx, depth, id, current, currentClass);
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
function parseFunction(
|
|
784
|
-
ctx: SOSParserContext,
|
|
785
|
-
depth: number,
|
|
786
|
-
current: unknown,
|
|
787
|
-
): SerovalNode {
|
|
788
|
-
const ref = getReferenceNode(ctx.base, current);
|
|
789
|
-
if (ref.type !== ParserNodeType.Fresh) {
|
|
790
|
-
return ref.value;
|
|
791
|
-
}
|
|
792
|
-
const plugin = parsePlugin(ctx, depth, ref.value, current);
|
|
793
|
-
if (plugin) {
|
|
794
|
-
return plugin;
|
|
795
|
-
}
|
|
796
|
-
throw new SerovalUnsupportedTypeError(current);
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
export function parseSOS<T>(
|
|
800
|
-
ctx: SOSParserContext,
|
|
801
|
-
depth: number,
|
|
802
|
-
current: T,
|
|
803
|
-
): SerovalNode {
|
|
804
|
-
if (depth >= ctx.base.depthLimit) {
|
|
805
|
-
throw new SerovalDepthLimitError(ctx.base.depthLimit);
|
|
806
|
-
}
|
|
807
|
-
switch (typeof current) {
|
|
808
|
-
case 'boolean':
|
|
809
|
-
return current ? TRUE_NODE : FALSE_NODE;
|
|
810
|
-
case 'undefined':
|
|
811
|
-
return UNDEFINED_NODE;
|
|
812
|
-
case 'string':
|
|
813
|
-
return createStringNode(current as string);
|
|
814
|
-
case 'number':
|
|
815
|
-
return createNumberNode(current as number);
|
|
816
|
-
case 'bigint':
|
|
817
|
-
return createBigIntNode(current as bigint);
|
|
818
|
-
case 'object': {
|
|
819
|
-
if (current) {
|
|
820
|
-
const ref = getReferenceNode(ctx.base, current);
|
|
821
|
-
return ref.type === ParserNodeType.Fresh
|
|
822
|
-
? parseObject(ctx, depth + 1, ref.value, current as object)
|
|
823
|
-
: ref.value;
|
|
824
|
-
}
|
|
825
|
-
return NULL_NODE;
|
|
826
|
-
}
|
|
827
|
-
case 'symbol':
|
|
828
|
-
return parseWellKnownSymbol(ctx.base, current);
|
|
829
|
-
case 'function': {
|
|
830
|
-
return parseFunction(ctx, depth, current);
|
|
831
|
-
}
|
|
832
|
-
default:
|
|
833
|
-
throw new SerovalUnsupportedTypeError(current);
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
|
|
837
|
-
export function parseTop<T>(ctx: SyncParserContext, current: T): SerovalNode {
|
|
838
|
-
try {
|
|
839
|
-
return parseSOS(ctx, 0, current);
|
|
840
|
-
} catch (error) {
|
|
841
|
-
throw error instanceof SerovalParserError
|
|
842
|
-
? error
|
|
843
|
-
: new SerovalParserError(error);
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
function onParse(ctx: StreamParserContext, node: SerovalNode): void {
|
|
848
|
-
// If the value emitted happens to be during parsing, we push to the
|
|
849
|
-
// buffer and emit after the initial parsing is done.
|
|
850
|
-
if (ctx.state.initial) {
|
|
851
|
-
ctx.state.buffer.push(node);
|
|
852
|
-
} else {
|
|
853
|
-
onParseInternal(ctx, node, false);
|
|
854
|
-
}
|
|
855
|
-
}
|
|
856
|
-
|
|
857
|
-
function onError(ctx: StreamParserContext, error: unknown): void {
|
|
858
|
-
if (ctx.state.onError) {
|
|
859
|
-
ctx.state.onError(error);
|
|
860
|
-
} else {
|
|
861
|
-
throw error instanceof SerovalParserError
|
|
862
|
-
? error
|
|
863
|
-
: new SerovalParserError(error);
|
|
864
|
-
}
|
|
865
|
-
}
|
|
866
|
-
|
|
867
|
-
function onDone(ctx: StreamParserContext): void {
|
|
868
|
-
if (ctx.state.onDone) {
|
|
869
|
-
ctx.state.onDone();
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
for (let i = 0, len = ctx.state.cleanups.length; i < len; i++) {
|
|
873
|
-
ctx.state.cleanups[i]();
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
function onParseInternal(
|
|
878
|
-
ctx: StreamParserContext,
|
|
879
|
-
node: SerovalNode,
|
|
880
|
-
initial: boolean,
|
|
881
|
-
): void {
|
|
882
|
-
try {
|
|
883
|
-
ctx.state.onParse(node, initial);
|
|
884
|
-
} catch (error) {
|
|
885
|
-
onError(ctx, error);
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
|
|
889
|
-
function pushPendingState(ctx: StreamParserContext): void {
|
|
890
|
-
ctx.state.pending++;
|
|
891
|
-
}
|
|
892
|
-
|
|
893
|
-
function popPendingState(ctx: StreamParserContext): void {
|
|
894
|
-
if (--ctx.state.pending <= 0) {
|
|
895
|
-
onDone(ctx);
|
|
896
|
-
}
|
|
897
|
-
}
|
|
898
|
-
|
|
899
|
-
function parseWithError<T>(
|
|
900
|
-
ctx: StreamParserContext,
|
|
901
|
-
depth: number,
|
|
902
|
-
current: T,
|
|
903
|
-
): SerovalNode | undefined {
|
|
904
|
-
try {
|
|
905
|
-
return parseSOS(ctx, depth, current);
|
|
906
|
-
} catch (err) {
|
|
907
|
-
onError(ctx, err);
|
|
908
|
-
return NIL;
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
|
|
912
|
-
export function startStreamParse<T>(
|
|
913
|
-
ctx: StreamParserContext,
|
|
914
|
-
current: T,
|
|
915
|
-
): void {
|
|
916
|
-
const parsed = parseWithError(ctx, 0, current);
|
|
917
|
-
if (parsed) {
|
|
918
|
-
onParseInternal(ctx, parsed, true);
|
|
919
|
-
ctx.state.initial = false;
|
|
920
|
-
flushStreamParse(ctx, ctx.state);
|
|
921
|
-
|
|
922
|
-
// Check if there's any pending pushes
|
|
923
|
-
if (ctx.state.pending <= 0) {
|
|
924
|
-
destroyStreamParse(ctx);
|
|
925
|
-
}
|
|
926
|
-
}
|
|
927
|
-
}
|
|
928
|
-
|
|
929
|
-
function flushStreamParse(
|
|
930
|
-
ctx: StreamParserContext,
|
|
931
|
-
state: StreamParserState,
|
|
932
|
-
): void {
|
|
933
|
-
for (let i = 0, len = state.buffer.length; i < len; i++) {
|
|
934
|
-
onParseInternal(ctx, state.buffer[i], false);
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
export function destroyStreamParse(ctx: StreamParserContext): void {
|
|
939
|
-
if (ctx.state.alive) {
|
|
940
|
-
onDone(ctx);
|
|
941
|
-
ctx.state.alive = false;
|
|
942
|
-
}
|
|
943
|
-
}
|