seroval 0.9.0 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -287
- package/dist/cjs/development/index.cjs +3500 -1135
- package/dist/cjs/development/index.cjs.map +4 -4
- package/dist/cjs/production/index.cjs +12 -3
- package/dist/esm/development/index.mjs +3502 -1135
- package/dist/esm/development/index.mjs.map +4 -4
- package/dist/esm/production/index.mjs +12 -3
- package/dist/types/core/Serializer.d.ts +14 -0
- package/dist/types/{tree → core}/UnsupportedTypeError.d.ts +4 -3
- package/dist/types/{assert.d.ts → core/assert.d.ts} +1 -1
- package/dist/types/core/assignments.d.ts +33 -0
- package/dist/types/core/base-primitives.d.ts +12 -0
- package/dist/types/{compat.d.ts → core/compat.d.ts} +22 -22
- package/dist/types/core/constants.d.ts +89 -0
- package/dist/types/core/context.d.ts +9 -0
- package/dist/types/core/cross/async.d.ts +3 -0
- package/dist/types/core/cross/context.d.ts +30 -0
- package/dist/types/core/cross/index.d.ts +7 -0
- package/dist/types/core/cross/primitives.d.ts +9 -0
- package/dist/types/core/cross/serialize.d.ts +5 -0
- package/dist/types/core/cross/stream.d.ts +3 -0
- package/dist/types/core/cross/sync.d.ts +3 -0
- package/dist/types/core/cross/web-api.d.ts +4 -0
- package/dist/types/{get-identifier.d.ts → core/get-identifier.d.ts} +1 -1
- package/dist/types/core/keys.d.ts +12 -0
- package/dist/types/{tree/constants.d.ts → core/literals.d.ts} +9 -11
- package/dist/types/core/promise-to-result.d.ts +1 -0
- package/dist/types/{tree → core}/reference.d.ts +5 -6
- package/dist/types/{tree → core}/shared.d.ts +13 -13
- package/dist/types/{string.d.ts → core/string.d.ts} +3 -3
- package/dist/types/core/tree/async.d.ts +3 -0
- package/dist/types/core/tree/context.d.ts +45 -0
- package/dist/types/core/tree/deserialize.d.ts +3 -0
- package/dist/types/core/tree/index.d.ts +15 -0
- package/dist/types/core/tree/primitives.d.ts +9 -0
- package/dist/types/core/tree/serialize.d.ts +4 -0
- package/dist/types/core/tree/sync.d.ts +3 -0
- package/dist/types/core/tree/web-api.d.ts +4 -0
- package/dist/types/{tree → core}/types.d.ts +228 -238
- package/dist/types/core/web-api.d.ts +4 -0
- package/dist/types/index.d.ts +9 -19
- package/dist/types/types.d.ts +20 -20
- package/package.json +5 -5
- package/src/core/Serializer.ts +46 -0
- package/src/{tree → core}/UnsupportedTypeError.ts +1 -1
- package/src/core/assignments.ts +159 -0
- package/src/{tree/primitives.ts → core/base-primitives.ts} +33 -136
- package/src/core/constants.ts +169 -0
- package/src/core/context.ts +15 -0
- package/src/core/cross/async.ts +614 -0
- package/src/core/cross/context.ts +79 -0
- package/src/core/cross/index.ts +154 -0
- package/src/core/cross/primitives.ts +137 -0
- package/src/core/cross/serialize.ts +846 -0
- package/src/core/cross/stream.ts +740 -0
- package/src/core/cross/sync.ts +561 -0
- package/src/core/cross/web-api.ts +55 -0
- package/src/core/header.js +65 -0
- package/src/core/keys.ts +33 -0
- package/src/core/literals.ts +28 -0
- package/src/core/promise-to-result.ts +9 -0
- package/src/{tree → core}/reference.ts +6 -7
- package/src/{tree → core}/shared.ts +4 -4
- package/src/{tree → core/tree}/async.ts +46 -34
- package/src/core/tree/context.ts +136 -0
- package/src/{tree → core/tree}/deserialize.ts +68 -55
- package/src/core/tree/index.ts +146 -0
- package/src/core/tree/primitives.ts +132 -0
- package/src/{tree → core/tree}/serialize.ts +87 -193
- package/src/{tree → core/tree}/sync.ts +50 -39
- package/src/{tree → core/tree}/web-api.ts +8 -52
- package/src/{tree → core}/types.ts +76 -60
- package/src/core/web-api.ts +51 -0
- package/src/index.ts +7 -141
- package/src/types.ts +1 -1
- package/dist/types/context.d.ts +0 -67
- package/dist/types/tree/async.d.ts +0 -3
- package/dist/types/tree/deserialize.d.ts +0 -3
- package/dist/types/tree/primitives.d.ts +0 -19
- package/dist/types/tree/serialize.d.ts +0 -4
- package/dist/types/tree/symbols.d.ts +0 -33
- package/dist/types/tree/sync.d.ts +0 -3
- package/dist/types/tree/web-api.d.ts +0 -6
- package/src/context.ts +0 -164
- package/src/tree/constants.ts +0 -73
- package/src/tree/symbols.ts +0 -65
- /package/src/{assert.ts → core/assert.ts} +0 -0
- /package/src/{compat.ts → core/compat.ts} +0 -0
- /package/src/{get-identifier.ts → core/get-identifier.ts} +0 -0
- /package/src/{string.ts → core/string.ts} +0 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { SerovalConstant, SerovalNodeType } from './constants';
|
|
2
|
+
import type { SerovalConstantNode } from './types';
|
|
3
|
+
|
|
4
|
+
function createConstantNode(value: SerovalConstant): SerovalConstantNode {
|
|
5
|
+
return {
|
|
6
|
+
t: SerovalNodeType.Constant,
|
|
7
|
+
i: undefined,
|
|
8
|
+
s: value,
|
|
9
|
+
l: undefined,
|
|
10
|
+
c: undefined,
|
|
11
|
+
m: undefined,
|
|
12
|
+
p: undefined,
|
|
13
|
+
e: undefined,
|
|
14
|
+
a: undefined,
|
|
15
|
+
f: undefined,
|
|
16
|
+
b: undefined,
|
|
17
|
+
o: undefined,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const TRUE_NODE = createConstantNode(SerovalConstant.True);
|
|
22
|
+
export const FALSE_NODE = createConstantNode(SerovalConstant.False);
|
|
23
|
+
export const UNDEFINED_NODE = createConstantNode(SerovalConstant.Undefined);
|
|
24
|
+
export const NULL_NODE = createConstantNode(SerovalConstant.Null);
|
|
25
|
+
export const NEG_ZERO_NODE = createConstantNode(SerovalConstant.NegativeZero);
|
|
26
|
+
export const INFINITY_NODE = createConstantNode(SerovalConstant.Infinity);
|
|
27
|
+
export const NEG_INFINITY_NODE = createConstantNode(SerovalConstant.NegativeInfinity);
|
|
28
|
+
export const NAN_NODE = createConstantNode(SerovalConstant.NaN);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* eslint-disable no-restricted-globals */
|
|
2
|
-
import assert from '
|
|
2
|
+
import assert from './assert';
|
|
3
|
+
import { REFERENCES_KEY } from './keys';
|
|
3
4
|
|
|
4
5
|
const REFERENCE = new Map<unknown, string>();
|
|
5
6
|
const INV_REFERENCE = new Map<string, unknown>();
|
|
@@ -28,31 +29,29 @@ export function getReference<T>(id: string): T {
|
|
|
28
29
|
return INV_REFERENCE.get(id) as T;
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
export const GLOBAL_KEY = '__SEROVAL__';
|
|
32
|
-
|
|
33
32
|
if (typeof globalThis !== undefined) {
|
|
34
|
-
Object.defineProperty(globalThis,
|
|
33
|
+
Object.defineProperty(globalThis, REFERENCES_KEY, {
|
|
35
34
|
value: INV_REFERENCE,
|
|
36
35
|
configurable: true,
|
|
37
36
|
writable: false,
|
|
38
37
|
enumerable: false,
|
|
39
38
|
});
|
|
40
39
|
} else if (typeof window !== undefined) {
|
|
41
|
-
Object.defineProperty(window,
|
|
40
|
+
Object.defineProperty(window, REFERENCES_KEY, {
|
|
42
41
|
value: INV_REFERENCE,
|
|
43
42
|
configurable: true,
|
|
44
43
|
writable: false,
|
|
45
44
|
enumerable: false,
|
|
46
45
|
});
|
|
47
46
|
} else if (typeof self !== undefined) {
|
|
48
|
-
Object.defineProperty(self,
|
|
47
|
+
Object.defineProperty(self, REFERENCES_KEY, {
|
|
49
48
|
value: INV_REFERENCE,
|
|
50
49
|
configurable: true,
|
|
51
50
|
writable: false,
|
|
52
51
|
enumerable: false,
|
|
53
52
|
});
|
|
54
53
|
} else if (typeof global !== undefined) {
|
|
55
|
-
Object.defineProperty(global,
|
|
54
|
+
Object.defineProperty(global, REFERENCES_KEY, {
|
|
56
55
|
value: INV_REFERENCE,
|
|
57
56
|
configurable: true,
|
|
58
57
|
writable: false,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Feature } from '
|
|
2
|
-
import type { ParserContext } from '../context';
|
|
1
|
+
import { Feature } from './compat';
|
|
3
2
|
import type {
|
|
4
3
|
ErrorValue,
|
|
5
4
|
} from '../types';
|
|
6
|
-
import { SerovalObjectFlags } from './
|
|
5
|
+
import { SerovalObjectFlags } from './constants';
|
|
6
|
+
import type { BaseParserContext } from './context';
|
|
7
7
|
|
|
8
8
|
export function getErrorConstructorName(error: ErrorValue): string {
|
|
9
9
|
if (error instanceof EvalError) {
|
|
@@ -51,7 +51,7 @@ export function getErrorConstructor(errorName: string): ErrorConstructors {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
export function getErrorOptions(
|
|
54
|
-
ctx:
|
|
54
|
+
ctx: BaseParserContext,
|
|
55
55
|
error: Error,
|
|
56
56
|
): Record<string, unknown> | undefined {
|
|
57
57
|
let options: Record<string, unknown> | undefined;
|
|
@@ -2,44 +2,36 @@
|
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
3
3
|
import assert from '../assert';
|
|
4
4
|
import { Feature } from '../compat';
|
|
5
|
-
import type { ParserContext } from '
|
|
5
|
+
import type { ParserContext } from './context';
|
|
6
6
|
import {
|
|
7
7
|
createIndexedValue,
|
|
8
|
-
} from '
|
|
8
|
+
} from './context';
|
|
9
9
|
import { serializeString } from '../string';
|
|
10
10
|
import type {
|
|
11
11
|
BigIntTypedArrayValue,
|
|
12
12
|
TypedArrayValue,
|
|
13
|
-
} from '
|
|
14
|
-
import UnsupportedTypeError from '
|
|
13
|
+
} from '../../types';
|
|
14
|
+
import UnsupportedTypeError from '../UnsupportedTypeError';
|
|
15
15
|
import {
|
|
16
16
|
TRUE_NODE,
|
|
17
17
|
FALSE_NODE,
|
|
18
18
|
UNDEFINED_NODE,
|
|
19
19
|
NULL_NODE,
|
|
20
|
-
} from '
|
|
20
|
+
} from '../literals';
|
|
21
21
|
import {
|
|
22
|
-
createBigIntNode,
|
|
23
22
|
createBigIntTypedArrayNode,
|
|
24
|
-
createDateNode,
|
|
25
|
-
createNumberNode,
|
|
26
|
-
createIndexedValueNode,
|
|
27
|
-
createRegExpNode,
|
|
28
|
-
createStringNode,
|
|
29
23
|
createTypedArrayNode,
|
|
30
|
-
createReferenceNode,
|
|
31
|
-
createArrayBufferNode,
|
|
32
24
|
createDataViewNode,
|
|
33
25
|
createSymbolNode,
|
|
34
26
|
createFunctionNode,
|
|
35
27
|
} from './primitives';
|
|
36
|
-
import { hasReferenceID } from '
|
|
28
|
+
import { hasReferenceID } from '../reference';
|
|
37
29
|
import {
|
|
38
30
|
getErrorConstructorName,
|
|
39
31
|
getErrorOptions,
|
|
40
32
|
getObjectFlag,
|
|
41
33
|
isIterable,
|
|
42
|
-
} from '
|
|
34
|
+
} from '../shared';
|
|
43
35
|
import type {
|
|
44
36
|
SerovalAggregateErrorNode,
|
|
45
37
|
SerovalArrayNode,
|
|
@@ -56,17 +48,27 @@ import type {
|
|
|
56
48
|
SerovalPlainRecordNode,
|
|
57
49
|
SerovalPromiseNode,
|
|
58
50
|
SerovalSetNode,
|
|
59
|
-
} from '
|
|
51
|
+
} from '../types';
|
|
60
52
|
import {
|
|
61
|
-
SerovalNodeType,
|
|
62
53
|
SerovalObjectRecordSpecialKey,
|
|
63
|
-
} from '
|
|
54
|
+
} from '../types';
|
|
64
55
|
import {
|
|
65
56
|
createBlobNode,
|
|
66
57
|
createFileNode,
|
|
67
|
-
createURLNode,
|
|
68
|
-
createURLSearchParamsNode,
|
|
69
58
|
} from './web-api';
|
|
59
|
+
import { SerovalNodeType } from '../constants';
|
|
60
|
+
import {
|
|
61
|
+
createArrayBufferNode,
|
|
62
|
+
createBigIntNode,
|
|
63
|
+
createDateNode,
|
|
64
|
+
createIndexedValueNode,
|
|
65
|
+
createNumberNode,
|
|
66
|
+
createReferenceNode,
|
|
67
|
+
createRegExpNode,
|
|
68
|
+
createStringNode,
|
|
69
|
+
} from '../base-primitives';
|
|
70
|
+
import { createURLNode, createURLSearchParamsNode } from '../web-api';
|
|
71
|
+
import promiseToResult from '../promise-to-result';
|
|
70
72
|
|
|
71
73
|
type ObjectLikeNode =
|
|
72
74
|
| SerovalObjectNode
|
|
@@ -111,7 +113,8 @@ async function generateArrayNode(
|
|
|
111
113
|
l: current.length,
|
|
112
114
|
c: undefined,
|
|
113
115
|
m: undefined,
|
|
114
|
-
|
|
116
|
+
p: undefined,
|
|
117
|
+
e: undefined,
|
|
115
118
|
a: await generateNodeList(ctx, current),
|
|
116
119
|
f: undefined,
|
|
117
120
|
b: undefined,
|
|
@@ -155,7 +158,8 @@ async function generateMapNode(
|
|
|
155
158
|
l: undefined,
|
|
156
159
|
c: undefined,
|
|
157
160
|
m: undefined,
|
|
158
|
-
|
|
161
|
+
p: undefined,
|
|
162
|
+
e: { k: keyNodes, v: valueNodes, s: len },
|
|
159
163
|
a: undefined,
|
|
160
164
|
f: undefined,
|
|
161
165
|
b: undefined,
|
|
@@ -193,7 +197,8 @@ async function generateSetNode(
|
|
|
193
197
|
l: len,
|
|
194
198
|
c: undefined,
|
|
195
199
|
m: undefined,
|
|
196
|
-
|
|
200
|
+
p: undefined,
|
|
201
|
+
e: undefined,
|
|
197
202
|
a: nodes,
|
|
198
203
|
f: undefined,
|
|
199
204
|
b: undefined,
|
|
@@ -295,17 +300,18 @@ async function generatePromiseNode(
|
|
|
295
300
|
current: Promise<unknown>,
|
|
296
301
|
): Promise<SerovalPromiseNode> {
|
|
297
302
|
assert(ctx.features & Feature.Promise, new UnsupportedTypeError(current));
|
|
303
|
+
const [status, result] = await promiseToResult(current);
|
|
298
304
|
return {
|
|
299
305
|
t: SerovalNodeType.Promise,
|
|
300
306
|
i: id,
|
|
301
|
-
s:
|
|
307
|
+
s: status,
|
|
302
308
|
l: undefined,
|
|
303
309
|
c: undefined,
|
|
304
310
|
m: undefined,
|
|
305
|
-
|
|
306
|
-
|
|
311
|
+
p: undefined,
|
|
312
|
+
e: undefined,
|
|
307
313
|
a: undefined,
|
|
308
|
-
f: await parseAsync(ctx,
|
|
314
|
+
f: await parseAsync(ctx, result),
|
|
309
315
|
b: undefined,
|
|
310
316
|
o: undefined,
|
|
311
317
|
};
|
|
@@ -324,7 +330,8 @@ async function generateObjectNode(
|
|
|
324
330
|
l: undefined,
|
|
325
331
|
c: undefined,
|
|
326
332
|
m: undefined,
|
|
327
|
-
|
|
333
|
+
p: await generateProperties(ctx, current),
|
|
334
|
+
e: undefined,
|
|
328
335
|
a: undefined,
|
|
329
336
|
f: undefined,
|
|
330
337
|
b: undefined,
|
|
@@ -348,7 +355,8 @@ async function generateAggregateErrorNode(
|
|
|
348
355
|
l: undefined,
|
|
349
356
|
c: undefined,
|
|
350
357
|
m: serializeString(current.message),
|
|
351
|
-
|
|
358
|
+
p: optionsNode,
|
|
359
|
+
e: undefined,
|
|
352
360
|
a: undefined,
|
|
353
361
|
f: undefined,
|
|
354
362
|
b: undefined,
|
|
@@ -372,7 +380,8 @@ async function generateErrorNode(
|
|
|
372
380
|
l: undefined,
|
|
373
381
|
c: getErrorConstructorName(current),
|
|
374
382
|
m: serializeString(current.message),
|
|
375
|
-
|
|
383
|
+
p: optionsNode,
|
|
384
|
+
e: undefined,
|
|
376
385
|
a: undefined,
|
|
377
386
|
f: undefined,
|
|
378
387
|
b: undefined,
|
|
@@ -397,7 +406,8 @@ async function generateHeadersNode(
|
|
|
397
406
|
l: undefined,
|
|
398
407
|
c: undefined,
|
|
399
408
|
m: undefined,
|
|
400
|
-
|
|
409
|
+
p: undefined,
|
|
410
|
+
e: await generatePlainProperties(ctx, items),
|
|
401
411
|
a: undefined,
|
|
402
412
|
f: undefined,
|
|
403
413
|
b: undefined,
|
|
@@ -422,7 +432,8 @@ async function generateFormDataNode(
|
|
|
422
432
|
l: undefined,
|
|
423
433
|
c: undefined,
|
|
424
434
|
m: undefined,
|
|
425
|
-
|
|
435
|
+
p: undefined,
|
|
436
|
+
e: await generatePlainProperties(ctx, items),
|
|
426
437
|
a: undefined,
|
|
427
438
|
f: undefined,
|
|
428
439
|
b: undefined,
|
|
@@ -442,7 +453,8 @@ async function generateBoxedNode(
|
|
|
442
453
|
l: undefined,
|
|
443
454
|
c: undefined,
|
|
444
455
|
m: undefined,
|
|
445
|
-
|
|
456
|
+
p: undefined,
|
|
457
|
+
e: undefined,
|
|
446
458
|
a: undefined,
|
|
447
459
|
f: await parseAsync(ctx, current.valueOf()),
|
|
448
460
|
b: undefined,
|
|
@@ -460,7 +472,7 @@ async function parseObject(
|
|
|
460
472
|
// Non-primitive values needs a reference ID
|
|
461
473
|
// mostly because the values themselves are stateful
|
|
462
474
|
const id = createIndexedValue(ctx, current);
|
|
463
|
-
if (ctx.
|
|
475
|
+
if (ctx.reference.marked.has(id)) {
|
|
464
476
|
return createIndexedValueNode(id);
|
|
465
477
|
}
|
|
466
478
|
if (hasReferenceID(current)) {
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { ALL_ENABLED } from '../compat';
|
|
2
|
+
import type { BaseParserContext, BaseSerializerContext } from '../context';
|
|
3
|
+
import getIdentifier from '../get-identifier';
|
|
4
|
+
|
|
5
|
+
export interface ParserReference {
|
|
6
|
+
ids: Map<unknown, number>;
|
|
7
|
+
marked: Set<number>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface ParserContext extends BaseParserContext {
|
|
11
|
+
reference: ParserReference;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface ParserOptions {
|
|
15
|
+
disabledFeatures: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function createParserContext(options: Partial<ParserOptions> = {}): ParserContext {
|
|
19
|
+
return {
|
|
20
|
+
reference: {
|
|
21
|
+
ids: new Map(),
|
|
22
|
+
marked: new Set(),
|
|
23
|
+
},
|
|
24
|
+
features: ALL_ENABLED ^ (options.disabledFeatures || 0),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface SerializerReference {
|
|
29
|
+
size: number;
|
|
30
|
+
// Map tree refs to actual refs
|
|
31
|
+
valid: (number | undefined)[];
|
|
32
|
+
// Refs that are...referenced
|
|
33
|
+
marked: Set<number>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface SerializerContext extends BaseSerializerContext {
|
|
37
|
+
reference: SerializerReference;
|
|
38
|
+
// Variables
|
|
39
|
+
vars: (string | undefined)[];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface SerializerOptions {
|
|
43
|
+
markedRefs: number[] | Set<number>;
|
|
44
|
+
features: number;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function createSerializerContext(options: SerializerOptions): SerializerContext {
|
|
48
|
+
return {
|
|
49
|
+
stack: [],
|
|
50
|
+
vars: [],
|
|
51
|
+
assignments: [],
|
|
52
|
+
reference: {
|
|
53
|
+
valid: [],
|
|
54
|
+
size: 0,
|
|
55
|
+
marked: new Set(options.markedRefs),
|
|
56
|
+
},
|
|
57
|
+
features: options.features,
|
|
58
|
+
flags: [],
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Increments the number of references the referenced value has
|
|
64
|
+
*/
|
|
65
|
+
export function markRef(
|
|
66
|
+
ctx: ParserContext | SerializerContext,
|
|
67
|
+
current: number,
|
|
68
|
+
): void {
|
|
69
|
+
ctx.reference.marked.add(current);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Creates the reference param (identifier) from the given reference ID
|
|
73
|
+
* Calling this function means the value has been referenced somewhere
|
|
74
|
+
*/
|
|
75
|
+
export function getRefParam(ctx: SerializerContext, index: number): string {
|
|
76
|
+
/**
|
|
77
|
+
* Creates a new reference ID from a given reference ID
|
|
78
|
+
* This new reference ID means that the reference itself
|
|
79
|
+
* has been referenced at least once, and is used to generate
|
|
80
|
+
* the variables
|
|
81
|
+
*/
|
|
82
|
+
let actualIndex = ctx.reference.valid[index];
|
|
83
|
+
if (actualIndex == null) {
|
|
84
|
+
actualIndex = ctx.reference.size++;
|
|
85
|
+
ctx.reference.valid[index] = actualIndex;
|
|
86
|
+
}
|
|
87
|
+
let identifier = ctx.vars[actualIndex];
|
|
88
|
+
if (identifier == null) {
|
|
89
|
+
identifier = getIdentifier(actualIndex);
|
|
90
|
+
ctx.vars[actualIndex] = identifier;
|
|
91
|
+
}
|
|
92
|
+
return identifier;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function getRootID<T>(
|
|
96
|
+
ctx: ParserContext,
|
|
97
|
+
current: T,
|
|
98
|
+
): number {
|
|
99
|
+
const ref = ctx.reference.ids.get(current);
|
|
100
|
+
if (ref == null) {
|
|
101
|
+
return ctx.reference.ids.size;
|
|
102
|
+
}
|
|
103
|
+
return ref;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function createIndexedValue<T>(
|
|
107
|
+
ctx: ParserContext,
|
|
108
|
+
current: T,
|
|
109
|
+
): number {
|
|
110
|
+
const ref = ctx.reference.ids.get(current);
|
|
111
|
+
if (ref == null) {
|
|
112
|
+
const id = ctx.reference.ids.size;
|
|
113
|
+
ctx.reference.ids.set(current, id);
|
|
114
|
+
return id;
|
|
115
|
+
}
|
|
116
|
+
markRef(ctx, ref);
|
|
117
|
+
return ref;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface DeserializerContext {
|
|
121
|
+
values: Map<number, unknown>;
|
|
122
|
+
refs: Set<number>;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export interface DeserializerOptions {
|
|
126
|
+
markedRefs: number[] | Set<number>;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export function createDeserializerContext(
|
|
130
|
+
options: DeserializerOptions,
|
|
131
|
+
): DeserializerContext {
|
|
132
|
+
return {
|
|
133
|
+
values: new Map(),
|
|
134
|
+
refs: new Set(options.markedRefs),
|
|
135
|
+
};
|
|
136
|
+
}
|