seroval 1.2.0 → 1.3.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/LICENSE +1 -1
- package/dist/cjs/development/index.cjs +283 -398
- package/dist/cjs/development/index.cjs.map +3 -3
- package/dist/cjs/production/index.cjs +5 -5
- package/dist/esm/development/index.mjs +283 -398
- package/dist/esm/development/index.mjs.map +3 -3
- package/dist/esm/production/index.mjs +5 -5
- package/dist/types/core/base-primitives.d.ts +1 -2
- package/dist/types/core/base-primitives.d.ts.map +1 -1
- package/dist/types/core/compat.d.ts +2 -3
- package/dist/types/core/compat.d.ts.map +1 -1
- package/dist/types/core/constants.d.ts +3 -6
- package/dist/types/core/constants.d.ts.map +1 -1
- package/dist/types/core/context/deserializer.d.ts +0 -3
- package/dist/types/core/context/deserializer.d.ts.map +1 -1
- package/dist/types/core/context/parser/async.d.ts +2 -2
- package/dist/types/core/context/parser/async.d.ts.map +1 -1
- package/dist/types/core/context/parser/stream.d.ts +8 -7
- package/dist/types/core/context/parser/stream.d.ts.map +1 -1
- package/dist/types/core/context/parser/sync.d.ts +3 -3
- package/dist/types/core/context/parser/sync.d.ts.map +1 -1
- package/dist/types/core/context/parser.d.ts +10 -12
- package/dist/types/core/context/parser.d.ts.map +1 -1
- package/dist/types/core/context/serializer.d.ts +1 -5
- package/dist/types/core/context/serializer.d.ts.map +1 -1
- package/dist/types/core/cross/index.d.ts.map +1 -1
- package/dist/types/core/function-string.d.ts +3 -0
- package/dist/types/core/function-string.d.ts.map +1 -0
- package/dist/types/core/special-reference.d.ts +4 -5
- package/dist/types/core/special-reference.d.ts.map +1 -1
- package/dist/types/core/tree/serializer.d.ts +1 -2
- package/dist/types/core/tree/serializer.d.ts.map +1 -1
- package/dist/types/core/types.d.ts +5 -19
- package/dist/types/core/types.d.ts.map +1 -1
- package/package.json +9 -9
- package/src/core/base-primitives.ts +2 -22
- package/src/core/compat.ts +6 -2
- package/src/core/constants.ts +2 -5
- package/src/core/context/deserializer.ts +2 -35
- package/src/core/context/parser/async.ts +67 -84
- package/src/core/context/parser/stream.ts +64 -109
- package/src/core/context/parser/sync.ts +66 -83
- package/src/core/context/parser.ts +24 -56
- package/src/core/context/serializer.ts +12 -128
- package/src/core/cross/index.ts +2 -6
- package/src/core/function-string.ts +31 -0
- package/src/core/special-reference.ts +96 -8
- package/src/core/tree/serializer.ts +0 -7
- package/src/core/types.ts +5 -27
- package/dist/types/core/abort-signal.d.ts +0 -2
- package/dist/types/core/abort-signal.d.ts.map +0 -1
- package/src/core/abort-signal.ts +0 -13
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
createTypedArrayNode,
|
|
20
20
|
} from '../../base-primitives';
|
|
21
21
|
import { Feature } from '../../compat';
|
|
22
|
-
import { NIL
|
|
22
|
+
import { NIL } from '../../constants';
|
|
23
23
|
import { SerovalParserError, SerovalUnsupportedTypeError } from '../../errors';
|
|
24
24
|
import {
|
|
25
25
|
FALSE_NODE,
|
|
@@ -27,15 +27,12 @@ import {
|
|
|
27
27
|
TRUE_NODE,
|
|
28
28
|
UNDEFINED_NODE,
|
|
29
29
|
} from '../../literals';
|
|
30
|
-
import { createSerovalNode } from '../../node';
|
|
31
30
|
import { OpaqueReference } from '../../opaque-reference';
|
|
32
31
|
import { SpecialReference } from '../../special-reference';
|
|
33
32
|
import type { Stream } from '../../stream';
|
|
34
33
|
import { createStream, isStream } from '../../stream';
|
|
35
34
|
import { serializeString } from '../../string';
|
|
36
35
|
import type {
|
|
37
|
-
SerovalAbortSignalConstructorNode,
|
|
38
|
-
SerovalAbortSignalSyncNode,
|
|
39
36
|
SerovalAggregateErrorNode,
|
|
40
37
|
SerovalArrayNode,
|
|
41
38
|
SerovalBigIntTypedArrayNode,
|
|
@@ -60,7 +57,7 @@ import type {
|
|
|
60
57
|
TypedArrayValue,
|
|
61
58
|
} from '../../utils/typed-array';
|
|
62
59
|
import type { BaseParserContextOptions } from '../parser';
|
|
63
|
-
import { BaseParserContext } from '../parser';
|
|
60
|
+
import { BaseParserContext, ParserNodeType } from '../parser';
|
|
64
61
|
|
|
65
62
|
type ObjectLikeNode = SerovalObjectNode | SerovalNullConstructorNode;
|
|
66
63
|
|
|
@@ -71,7 +68,7 @@ export default abstract class BaseSyncParserContext extends BaseParserContext {
|
|
|
71
68
|
const nodes = [];
|
|
72
69
|
for (let i = 0, len = current.length; i < len; i++) {
|
|
73
70
|
if (i in current) {
|
|
74
|
-
nodes[i] = this.
|
|
71
|
+
nodes[i] = this.parseTop(current[i]);
|
|
75
72
|
}
|
|
76
73
|
}
|
|
77
74
|
return nodes;
|
|
@@ -89,7 +86,7 @@ export default abstract class BaseSyncParserContext extends BaseParserContext {
|
|
|
89
86
|
const valueNodes: SerovalNode[] = [];
|
|
90
87
|
for (let i = 0, len = entries.length; i < len; i++) {
|
|
91
88
|
keyNodes.push(serializeString(entries[i][0]));
|
|
92
|
-
valueNodes.push(this.
|
|
89
|
+
valueNodes.push(this.parseTop(entries[i][1]));
|
|
93
90
|
}
|
|
94
91
|
// Check special properties, symbols in this case
|
|
95
92
|
let symbol = Symbol.iterator;
|
|
@@ -98,7 +95,7 @@ export default abstract class BaseSyncParserContext extends BaseParserContext {
|
|
|
98
95
|
valueNodes.push(
|
|
99
96
|
createIteratorFactoryInstanceNode(
|
|
100
97
|
this.parseIteratorFactory(),
|
|
101
|
-
this.
|
|
98
|
+
this.parseTop(
|
|
102
99
|
iteratorToSequence(properties as unknown as Iterable<unknown>),
|
|
103
100
|
),
|
|
104
101
|
),
|
|
@@ -110,7 +107,7 @@ export default abstract class BaseSyncParserContext extends BaseParserContext {
|
|
|
110
107
|
valueNodes.push(
|
|
111
108
|
createAsyncIteratorFactoryInstanceNode(
|
|
112
109
|
this.parseAsyncIteratorFactory(),
|
|
113
|
-
this.
|
|
110
|
+
this.parseTop(createStream()),
|
|
114
111
|
),
|
|
115
112
|
);
|
|
116
113
|
}
|
|
@@ -145,25 +142,29 @@ export default abstract class BaseSyncParserContext extends BaseParserContext {
|
|
|
145
142
|
}
|
|
146
143
|
|
|
147
144
|
protected parseBoxed(id: number, current: object): SerovalBoxedNode {
|
|
148
|
-
return createBoxedNode(id, this.
|
|
145
|
+
return createBoxedNode(id, this.parseTop(current.valueOf()));
|
|
149
146
|
}
|
|
150
147
|
|
|
151
148
|
protected parseTypedArray(
|
|
152
149
|
id: number,
|
|
153
150
|
current: TypedArrayValue,
|
|
154
151
|
): SerovalTypedArrayNode {
|
|
155
|
-
return createTypedArrayNode(id, current, this.
|
|
152
|
+
return createTypedArrayNode(id, current, this.parseTop(current.buffer));
|
|
156
153
|
}
|
|
157
154
|
|
|
158
155
|
protected parseBigIntTypedArray(
|
|
159
156
|
id: number,
|
|
160
157
|
current: BigIntTypedArrayValue,
|
|
161
158
|
): SerovalBigIntTypedArrayNode {
|
|
162
|
-
return createBigIntTypedArrayNode(
|
|
159
|
+
return createBigIntTypedArrayNode(
|
|
160
|
+
id,
|
|
161
|
+
current,
|
|
162
|
+
this.parseTop(current.buffer),
|
|
163
|
+
);
|
|
163
164
|
}
|
|
164
165
|
|
|
165
166
|
protected parseDataView(id: number, current: DataView): SerovalDataViewNode {
|
|
166
|
-
return createDataViewNode(id, current, this.
|
|
167
|
+
return createDataViewNode(id, current, this.parseTop(current.buffer));
|
|
167
168
|
}
|
|
168
169
|
|
|
169
170
|
protected parseError(id: number, current: Error): SerovalErrorNode {
|
|
@@ -194,8 +195,8 @@ export default abstract class BaseSyncParserContext extends BaseParserContext {
|
|
|
194
195
|
const keyNodes: SerovalNode[] = [];
|
|
195
196
|
const valueNodes: SerovalNode[] = [];
|
|
196
197
|
for (const [key, value] of current.entries()) {
|
|
197
|
-
keyNodes.push(this.
|
|
198
|
-
valueNodes.push(this.
|
|
198
|
+
keyNodes.push(this.parseTop(key));
|
|
199
|
+
valueNodes.push(this.parseTop(value));
|
|
199
200
|
}
|
|
200
201
|
return this.createMapNode(id, keyNodes, valueNodes, current.size);
|
|
201
202
|
}
|
|
@@ -203,7 +204,7 @@ export default abstract class BaseSyncParserContext extends BaseParserContext {
|
|
|
203
204
|
protected parseSet(id: number, current: Set<unknown>): SerovalSetNode {
|
|
204
205
|
const items: SerovalNode[] = [];
|
|
205
206
|
for (const item of current.keys()) {
|
|
206
|
-
items.push(this.
|
|
207
|
+
items.push(this.parseTop(item));
|
|
207
208
|
}
|
|
208
209
|
return createSetNode(id, current.size, items);
|
|
209
210
|
}
|
|
@@ -242,37 +243,7 @@ export default abstract class BaseSyncParserContext extends BaseParserContext {
|
|
|
242
243
|
id: number,
|
|
243
244
|
_current: Promise<unknown>,
|
|
244
245
|
): SerovalPromiseConstructorNode {
|
|
245
|
-
return this.createPromiseConstructorNode(id);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
protected parseAbortSignalSync(
|
|
249
|
-
id: number,
|
|
250
|
-
current: AbortSignal,
|
|
251
|
-
): SerovalAbortSignalSyncNode {
|
|
252
|
-
return createSerovalNode(
|
|
253
|
-
SerovalNodeType.AbortSignalSync,
|
|
254
|
-
id,
|
|
255
|
-
NIL,
|
|
256
|
-
NIL,
|
|
257
|
-
NIL,
|
|
258
|
-
NIL,
|
|
259
|
-
NIL,
|
|
260
|
-
NIL,
|
|
261
|
-
NIL,
|
|
262
|
-
this.parse(current.reason),
|
|
263
|
-
NIL,
|
|
264
|
-
NIL,
|
|
265
|
-
);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
protected parseAbortSignal(
|
|
269
|
-
id: number,
|
|
270
|
-
current: AbortSignal,
|
|
271
|
-
): SerovalAbortSignalConstructorNode | SerovalAbortSignalSyncNode {
|
|
272
|
-
if (current.aborted) {
|
|
273
|
-
return this.parseAbortSignalSync(id, current);
|
|
274
|
-
}
|
|
275
|
-
return this.createAbortSignalConstructorNode(id);
|
|
246
|
+
return this.createPromiseConstructorNode(id, this.createIndex({}));
|
|
276
247
|
}
|
|
277
248
|
|
|
278
249
|
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: ehh
|
|
@@ -285,7 +256,7 @@ export default abstract class BaseSyncParserContext extends BaseParserContext {
|
|
|
285
256
|
}
|
|
286
257
|
const currentClass = current.constructor;
|
|
287
258
|
if (currentClass === OpaqueReference) {
|
|
288
|
-
return this.
|
|
259
|
+
return this.parseTop(
|
|
289
260
|
(current as OpaqueReference<unknown, unknown>).replacement,
|
|
290
261
|
);
|
|
291
262
|
}
|
|
@@ -349,13 +320,6 @@ export default abstract class BaseSyncParserContext extends BaseParserContext {
|
|
|
349
320
|
return this.parsePromise(id, current as unknown as Promise<unknown>);
|
|
350
321
|
}
|
|
351
322
|
const currentFeatures = this.features;
|
|
352
|
-
if (
|
|
353
|
-
currentFeatures & Feature.AbortSignal &&
|
|
354
|
-
typeof AbortSignal !== 'undefined' &&
|
|
355
|
-
currentClass === AbortSignal
|
|
356
|
-
) {
|
|
357
|
-
return this.parseAbortSignal(id, current as unknown as AbortSignal);
|
|
358
|
-
}
|
|
359
323
|
// BigInt Typed Arrays
|
|
360
324
|
if (currentFeatures & Feature.BigIntTypedArray) {
|
|
361
325
|
switch (currentClass) {
|
|
@@ -389,37 +353,56 @@ export default abstract class BaseSyncParserContext extends BaseParserContext {
|
|
|
389
353
|
throw new SerovalUnsupportedTypeError(current);
|
|
390
354
|
}
|
|
391
355
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
356
|
+
protected parseFunction(current: unknown): SerovalNode {
|
|
357
|
+
const ref = this.getReference(current);
|
|
358
|
+
if (ref.type !== ParserNodeType.Fresh) {
|
|
359
|
+
return ref.value;
|
|
360
|
+
}
|
|
361
|
+
const plugin = this.parsePlugin(ref.value, current);
|
|
362
|
+
if (plugin) {
|
|
363
|
+
return plugin;
|
|
364
|
+
}
|
|
365
|
+
throw new SerovalUnsupportedTypeError(current);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
parseTop<T>(current: T): SerovalNode {
|
|
369
|
+
switch (typeof current) {
|
|
370
|
+
case 'boolean':
|
|
371
|
+
return current ? TRUE_NODE : FALSE_NODE;
|
|
372
|
+
case 'undefined':
|
|
373
|
+
return UNDEFINED_NODE;
|
|
374
|
+
case 'string':
|
|
375
|
+
return createStringNode(current as string);
|
|
376
|
+
case 'number':
|
|
377
|
+
return createNumberNode(current as number);
|
|
378
|
+
case 'bigint':
|
|
379
|
+
return createBigIntNode(current as bigint);
|
|
380
|
+
case 'object': {
|
|
381
|
+
if (current) {
|
|
382
|
+
const ref = this.getReference(current);
|
|
383
|
+
return ref.type === ParserNodeType.Fresh
|
|
384
|
+
? this.parseObject(ref.value, current as object)
|
|
385
|
+
: ref.value;
|
|
413
386
|
}
|
|
414
|
-
|
|
415
|
-
return this.parseWellKnownSymbol(current);
|
|
416
|
-
case 'function':
|
|
417
|
-
return this.parseFunction(current as (...args: unknown[]) => unknown);
|
|
418
|
-
default:
|
|
419
|
-
throw new SerovalUnsupportedTypeError(current);
|
|
387
|
+
return NULL_NODE;
|
|
420
388
|
}
|
|
389
|
+
case 'symbol':
|
|
390
|
+
return this.parseWellKnownSymbol(current);
|
|
391
|
+
case 'function': {
|
|
392
|
+
return this.parseFunction(current);
|
|
393
|
+
}
|
|
394
|
+
default:
|
|
395
|
+
throw new SerovalUnsupportedTypeError(current);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
parse<T>(current: T): SerovalNode {
|
|
400
|
+
try {
|
|
401
|
+
return this.parseTop(current);
|
|
421
402
|
} catch (error) {
|
|
422
|
-
throw
|
|
403
|
+
throw error instanceof SerovalParserError
|
|
404
|
+
? error
|
|
405
|
+
: new SerovalParserError(error);
|
|
423
406
|
}
|
|
424
407
|
}
|
|
425
408
|
}
|
|
@@ -17,7 +17,6 @@ import {
|
|
|
17
17
|
SpecialReference,
|
|
18
18
|
} from '../special-reference';
|
|
19
19
|
import type {
|
|
20
|
-
SerovalAbortSignalConstructorNode,
|
|
21
20
|
SerovalAsyncIteratorFactoryNode,
|
|
22
21
|
SerovalIndexedValueNode,
|
|
23
22
|
SerovalIteratorFactoryNode,
|
|
@@ -39,24 +38,24 @@ export interface BaseParserContextOptions extends PluginAccessOptions {
|
|
|
39
38
|
refs?: Map<unknown, number>;
|
|
40
39
|
}
|
|
41
40
|
|
|
42
|
-
const enum
|
|
41
|
+
export const enum ParserNodeType {
|
|
43
42
|
Fresh = 0,
|
|
44
43
|
Indexed = 1,
|
|
45
44
|
Referenced = 2,
|
|
46
45
|
}
|
|
47
46
|
|
|
48
|
-
interface FreshNode {
|
|
49
|
-
type:
|
|
47
|
+
export interface FreshNode {
|
|
48
|
+
type: ParserNodeType.Fresh;
|
|
50
49
|
value: number;
|
|
51
50
|
}
|
|
52
51
|
|
|
53
|
-
interface IndexedNode {
|
|
54
|
-
type:
|
|
52
|
+
export interface IndexedNode {
|
|
53
|
+
type: ParserNodeType.Indexed;
|
|
55
54
|
value: SerovalIndexedValueNode;
|
|
56
55
|
}
|
|
57
56
|
|
|
58
|
-
interface ReferencedNode {
|
|
59
|
-
type:
|
|
57
|
+
export interface ReferencedNode {
|
|
58
|
+
type: ParserNodeType.Referenced;
|
|
60
59
|
value: SerovalReferenceNode;
|
|
61
60
|
}
|
|
62
61
|
|
|
@@ -87,59 +86,46 @@ export abstract class BaseParserContext implements PluginAccessOptions {
|
|
|
87
86
|
return this.marked.has(id);
|
|
88
87
|
}
|
|
89
88
|
|
|
89
|
+
protected createIndex<T>(current: T): number {
|
|
90
|
+
const id = this.refs.size;
|
|
91
|
+
this.refs.set(current, id);
|
|
92
|
+
return id;
|
|
93
|
+
}
|
|
94
|
+
|
|
90
95
|
protected getIndexedValue<T>(current: T): FreshNode | IndexedNode {
|
|
91
96
|
const registeredId = this.refs.get(current);
|
|
92
97
|
if (registeredId != null) {
|
|
93
98
|
this.markRef(registeredId);
|
|
94
99
|
return {
|
|
95
|
-
type:
|
|
100
|
+
type: ParserNodeType.Indexed,
|
|
96
101
|
value: createIndexedValueNode(registeredId),
|
|
97
102
|
};
|
|
98
103
|
}
|
|
99
|
-
const id = this.refs.size;
|
|
100
|
-
this.refs.set(current, id);
|
|
101
104
|
return {
|
|
102
|
-
type:
|
|
103
|
-
value:
|
|
105
|
+
type: ParserNodeType.Fresh,
|
|
106
|
+
value: this.createIndex(current),
|
|
104
107
|
};
|
|
105
108
|
}
|
|
106
109
|
|
|
107
110
|
protected getReference<T>(current: T): ObjectNode {
|
|
108
111
|
const indexed = this.getIndexedValue(current);
|
|
109
|
-
if (indexed.type ===
|
|
112
|
+
if (indexed.type === ParserNodeType.Indexed) {
|
|
110
113
|
return indexed;
|
|
111
114
|
}
|
|
112
115
|
if (hasReferenceID(current)) {
|
|
113
116
|
return {
|
|
114
|
-
type:
|
|
117
|
+
type: ParserNodeType.Referenced,
|
|
115
118
|
value: createReferenceNode(indexed.value, current),
|
|
116
119
|
};
|
|
117
120
|
}
|
|
118
121
|
return indexed;
|
|
119
122
|
}
|
|
120
123
|
|
|
121
|
-
protected getStrictReference<T>(
|
|
122
|
-
current: T,
|
|
123
|
-
): SerovalIndexedValueNode | SerovalReferenceNode {
|
|
124
|
-
assert(hasReferenceID(current), new SerovalUnsupportedTypeError(current));
|
|
125
|
-
const result = this.getIndexedValue(current);
|
|
126
|
-
if (result.type === NodeType.Indexed) {
|
|
127
|
-
return result.value;
|
|
128
|
-
}
|
|
129
|
-
return createReferenceNode(result.value, current);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
protected parseFunction(
|
|
133
|
-
current: (...args: unknown[]) => unknown,
|
|
134
|
-
): SerovalNode {
|
|
135
|
-
return this.getStrictReference(current);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
124
|
protected parseWellKnownSymbol(
|
|
139
125
|
current: symbol,
|
|
140
126
|
): SerovalIndexedValueNode | SerovalWKSymbolNode | SerovalReferenceNode {
|
|
141
127
|
const ref = this.getReference(current);
|
|
142
|
-
if (ref.type !==
|
|
128
|
+
if (ref.type !== ParserNodeType.Fresh) {
|
|
143
129
|
return ref.value;
|
|
144
130
|
}
|
|
145
131
|
assert(current in INV_SYMBOL_REF, new SerovalUnsupportedTypeError(current));
|
|
@@ -150,7 +136,7 @@ export abstract class BaseParserContext implements PluginAccessOptions {
|
|
|
150
136
|
ref: SpecialReference,
|
|
151
137
|
): SerovalIndexedValueNode | SerovalSpecialReferenceNode {
|
|
152
138
|
const result = this.getIndexedValue(SPECIAL_REFS[ref]);
|
|
153
|
-
if (result.type ===
|
|
139
|
+
if (result.type === ParserNodeType.Indexed) {
|
|
154
140
|
return result.value;
|
|
155
141
|
}
|
|
156
142
|
return createSerovalNode(
|
|
@@ -173,7 +159,7 @@ export abstract class BaseParserContext implements PluginAccessOptions {
|
|
|
173
159
|
| SerovalIndexedValueNode
|
|
174
160
|
| SerovalIteratorFactoryNode {
|
|
175
161
|
const result = this.getIndexedValue(ITERATOR);
|
|
176
|
-
if (result.type ===
|
|
162
|
+
if (result.type === ParserNodeType.Indexed) {
|
|
177
163
|
return result.value;
|
|
178
164
|
}
|
|
179
165
|
return createSerovalNode(
|
|
@@ -196,7 +182,7 @@ export abstract class BaseParserContext implements PluginAccessOptions {
|
|
|
196
182
|
| SerovalIndexedValueNode
|
|
197
183
|
| SerovalAsyncIteratorFactoryNode {
|
|
198
184
|
const result = this.getIndexedValue(ASYNC_ITERATOR);
|
|
199
|
-
if (result.type ===
|
|
185
|
+
if (result.type === ParserNodeType.Indexed) {
|
|
200
186
|
return result.value;
|
|
201
187
|
}
|
|
202
188
|
return createSerovalNode(
|
|
@@ -264,11 +250,12 @@ export abstract class BaseParserContext implements PluginAccessOptions {
|
|
|
264
250
|
|
|
265
251
|
protected createPromiseConstructorNode(
|
|
266
252
|
id: number,
|
|
253
|
+
resolver: number,
|
|
267
254
|
): SerovalPromiseConstructorNode {
|
|
268
255
|
return createSerovalNode(
|
|
269
256
|
SerovalNodeType.PromiseConstructor,
|
|
270
257
|
id,
|
|
271
|
-
|
|
258
|
+
resolver,
|
|
272
259
|
NIL,
|
|
273
260
|
NIL,
|
|
274
261
|
NIL,
|
|
@@ -280,23 +267,4 @@ export abstract class BaseParserContext implements PluginAccessOptions {
|
|
|
280
267
|
NIL,
|
|
281
268
|
);
|
|
282
269
|
}
|
|
283
|
-
|
|
284
|
-
protected createAbortSignalConstructorNode(
|
|
285
|
-
id: number,
|
|
286
|
-
): SerovalAbortSignalConstructorNode {
|
|
287
|
-
return createSerovalNode(
|
|
288
|
-
SerovalNodeType.AbortSignalConstructor,
|
|
289
|
-
id,
|
|
290
|
-
NIL,
|
|
291
|
-
NIL,
|
|
292
|
-
NIL,
|
|
293
|
-
NIL,
|
|
294
|
-
NIL,
|
|
295
|
-
NIL,
|
|
296
|
-
NIL,
|
|
297
|
-
this.parseSpecialReference(SpecialReference.AbortSignalConstructor),
|
|
298
|
-
NIL,
|
|
299
|
-
NIL,
|
|
300
|
-
);
|
|
301
|
-
}
|
|
302
270
|
}
|
|
@@ -12,13 +12,11 @@ import {
|
|
|
12
12
|
SerovalSerializationError,
|
|
13
13
|
SerovalUnsupportedNodeError,
|
|
14
14
|
} from '../errors';
|
|
15
|
+
import { createEffectfulFunction, createFunction } from '../function-string';
|
|
15
16
|
import { REFERENCES_KEY } from '../keys';
|
|
16
17
|
import type { Plugin, PluginAccessOptions, SerovalMode } from '../plugin';
|
|
17
|
-
import {
|
|
18
|
+
import { serializeSpecialReferenceValue } from '../special-reference';
|
|
18
19
|
import type {
|
|
19
|
-
SerovalAbortSignalAbortNode,
|
|
20
|
-
SerovalAbortSignalConstructorNode,
|
|
21
|
-
SerovalAbortSignalSyncNode,
|
|
22
20
|
SerovalAggregateErrorNode,
|
|
23
21
|
SerovalArrayBufferNode,
|
|
24
22
|
SerovalArrayNode,
|
|
@@ -253,25 +251,11 @@ export default abstract class BaseSerializerContext
|
|
|
253
251
|
abstract readonly mode: SerovalMode;
|
|
254
252
|
|
|
255
253
|
createFunction(parameters: string[], body: string): string {
|
|
256
|
-
|
|
257
|
-
const joined =
|
|
258
|
-
parameters.length === 1
|
|
259
|
-
? parameters[0]
|
|
260
|
-
: '(' + parameters.join(',') + ')';
|
|
261
|
-
return joined + '=>' + (body.startsWith('{') ? '(' + body + ')' : body);
|
|
262
|
-
}
|
|
263
|
-
return 'function(' + parameters.join(',') + '){return ' + body + '}';
|
|
254
|
+
return createFunction(this.features, parameters, body);
|
|
264
255
|
}
|
|
265
256
|
|
|
266
257
|
createEffectfulFunction(parameters: string[], body: string): string {
|
|
267
|
-
|
|
268
|
-
const joined =
|
|
269
|
-
parameters.length === 1
|
|
270
|
-
? parameters[0]
|
|
271
|
-
: '(' + parameters.join(',') + ')';
|
|
272
|
-
return joined + '=>{' + body + '}';
|
|
273
|
-
}
|
|
274
|
-
return 'function(' + parameters.join(',') + '){' + body + '}';
|
|
258
|
+
return createEffectfulFunction(this.features, parameters, body);
|
|
275
259
|
}
|
|
276
260
|
|
|
277
261
|
/**
|
|
@@ -919,7 +903,11 @@ export default abstract class BaseSerializerContext
|
|
|
919
903
|
protected serializePromiseConstructor(
|
|
920
904
|
node: SerovalPromiseConstructorNode,
|
|
921
905
|
): string {
|
|
922
|
-
|
|
906
|
+
const resolver = this.assignIndexedValue(node.s, '{p:0,s:0,f:0}');
|
|
907
|
+
return this.assignIndexedValue(
|
|
908
|
+
node.i,
|
|
909
|
+
this.getConstructor(node.f) + '(' + resolver + ')',
|
|
910
|
+
);
|
|
923
911
|
}
|
|
924
912
|
|
|
925
913
|
protected serializePromiseResolve(node: SerovalPromiseResolveNode): string {
|
|
@@ -944,84 +932,12 @@ export default abstract class BaseSerializerContext
|
|
|
944
932
|
);
|
|
945
933
|
}
|
|
946
934
|
|
|
947
|
-
private serializeSpecialReferenceValue(ref: SpecialReference): string {
|
|
948
|
-
switch (ref) {
|
|
949
|
-
case SpecialReference.MapSentinel:
|
|
950
|
-
return '[]';
|
|
951
|
-
case SpecialReference.PromiseConstructor:
|
|
952
|
-
return this.createFunction(
|
|
953
|
-
['s', 'f', 'p'],
|
|
954
|
-
'((p=new Promise(' +
|
|
955
|
-
this.createEffectfulFunction(['a', 'b'], 's=a,f=b') +
|
|
956
|
-
')).s=s,p.f=f,p)',
|
|
957
|
-
);
|
|
958
|
-
case SpecialReference.PromiseResolve:
|
|
959
|
-
return this.createEffectfulFunction(
|
|
960
|
-
['p', 'd'],
|
|
961
|
-
'p.s(d),p.status="success",p.value=d;delete p.s;delete p.f',
|
|
962
|
-
);
|
|
963
|
-
case SpecialReference.PromiseReject:
|
|
964
|
-
return this.createEffectfulFunction(
|
|
965
|
-
['p', 'd'],
|
|
966
|
-
'p.f(d),p.status="failure",p.value=d;delete p.s;delete p.f',
|
|
967
|
-
);
|
|
968
|
-
case SpecialReference.StreamConstructor:
|
|
969
|
-
return this.createFunction(
|
|
970
|
-
['b', 'a', 's', 'l', 'p', 'f', 'e', 'n'],
|
|
971
|
-
'(b=[],a=!0,s=!1,l=[],p=0,f=' +
|
|
972
|
-
this.createEffectfulFunction(
|
|
973
|
-
['v', 'm', 'x'],
|
|
974
|
-
'for(x=0;x<p;x++)l[x]&&l[x][m](v)',
|
|
975
|
-
) +
|
|
976
|
-
',n=' +
|
|
977
|
-
this.createEffectfulFunction(
|
|
978
|
-
['o', 'x', 'z', 'c'],
|
|
979
|
-
'for(x=0,z=b.length;x<z;x++)(c=b[x],(!a&&x===z-1)?o[s?"return":"throw"](c):o.next(c))',
|
|
980
|
-
) +
|
|
981
|
-
',e=' +
|
|
982
|
-
this.createFunction(
|
|
983
|
-
['o', 't'],
|
|
984
|
-
'(a&&(l[t=p++]=o),n(o),' +
|
|
985
|
-
this.createEffectfulFunction([], 'a&&(l[t]=void 0)') +
|
|
986
|
-
')',
|
|
987
|
-
) +
|
|
988
|
-
',{__SEROVAL_STREAM__:!0,on:' +
|
|
989
|
-
this.createFunction(['o'], 'e(o)') +
|
|
990
|
-
',next:' +
|
|
991
|
-
this.createEffectfulFunction(['v'], 'a&&(b.push(v),f(v,"next"))') +
|
|
992
|
-
',throw:' +
|
|
993
|
-
this.createEffectfulFunction(
|
|
994
|
-
['v'],
|
|
995
|
-
'a&&(b.push(v),f(v,"throw"),a=s=!1,l.length=0)',
|
|
996
|
-
) +
|
|
997
|
-
',return:' +
|
|
998
|
-
this.createEffectfulFunction(
|
|
999
|
-
['v'],
|
|
1000
|
-
'a&&(b.push(v),f(v,"return"),a=!1,s=!0,l.length=0)',
|
|
1001
|
-
) +
|
|
1002
|
-
'})',
|
|
1003
|
-
);
|
|
1004
|
-
case SpecialReference.AbortSignalConstructor:
|
|
1005
|
-
return this.createFunction(
|
|
1006
|
-
['a', 's'],
|
|
1007
|
-
'((s=(a=new AbortController).signal).a=a,s)',
|
|
1008
|
-
);
|
|
1009
|
-
case SpecialReference.AbortSignalAbort:
|
|
1010
|
-
return this.createEffectfulFunction(
|
|
1011
|
-
['s', 'r'],
|
|
1012
|
-
's.a.abort(r);delete s.a',
|
|
1013
|
-
);
|
|
1014
|
-
default:
|
|
1015
|
-
return '';
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
935
|
protected serializeSpecialReference(
|
|
1020
936
|
node: SerovalSpecialReferenceNode,
|
|
1021
937
|
): string {
|
|
1022
938
|
return this.assignIndexedValue(
|
|
1023
939
|
node.i,
|
|
1024
|
-
this.
|
|
940
|
+
serializeSpecialReferenceValue(this.features, node.s),
|
|
1025
941
|
);
|
|
1026
942
|
}
|
|
1027
943
|
|
|
@@ -1173,32 +1089,6 @@ export default abstract class BaseSerializerContext
|
|
|
1173
1089
|
return this.getRefParam(node.i) + '.return(' + this.serialize(node.f) + ')';
|
|
1174
1090
|
}
|
|
1175
1091
|
|
|
1176
|
-
protected serializeAbortSignalSync(node: SerovalAbortSignalSyncNode): string {
|
|
1177
|
-
return this.assignIndexedValue(
|
|
1178
|
-
node.i,
|
|
1179
|
-
'AbortSignal.abort(' + this.serialize(node.f) + ')',
|
|
1180
|
-
);
|
|
1181
|
-
}
|
|
1182
|
-
|
|
1183
|
-
protected serializeAbortSignalConstructor(
|
|
1184
|
-
node: SerovalAbortSignalConstructorNode,
|
|
1185
|
-
): string {
|
|
1186
|
-
return this.assignIndexedValue(node.i, this.getConstructor(node.f) + '()');
|
|
1187
|
-
}
|
|
1188
|
-
|
|
1189
|
-
protected serializeAbortSignalAbort(
|
|
1190
|
-
node: SerovalAbortSignalAbortNode,
|
|
1191
|
-
): string {
|
|
1192
|
-
return (
|
|
1193
|
-
this.getConstructor(node.a[0]) +
|
|
1194
|
-
'(' +
|
|
1195
|
-
this.getRefParam(node.i) +
|
|
1196
|
-
',' +
|
|
1197
|
-
this.serialize(node.a[1]) +
|
|
1198
|
-
')'
|
|
1199
|
-
);
|
|
1200
|
-
}
|
|
1201
|
-
|
|
1202
1092
|
serialize(node: SerovalNode): string {
|
|
1203
1093
|
try {
|
|
1204
1094
|
switch (node.t) {
|
|
@@ -1247,9 +1137,9 @@ export default abstract class BaseSerializerContext
|
|
|
1247
1137
|
return this.serializeBoxed(node);
|
|
1248
1138
|
case SerovalNodeType.PromiseConstructor:
|
|
1249
1139
|
return this.serializePromiseConstructor(node);
|
|
1250
|
-
case SerovalNodeType.
|
|
1140
|
+
case SerovalNodeType.PromiseSuccess:
|
|
1251
1141
|
return this.serializePromiseResolve(node);
|
|
1252
|
-
case SerovalNodeType.
|
|
1142
|
+
case SerovalNodeType.PromiseFailure:
|
|
1253
1143
|
return this.serializePromiseReject(node);
|
|
1254
1144
|
case SerovalNodeType.Plugin:
|
|
1255
1145
|
return this.serializePlugin(node);
|
|
@@ -1271,12 +1161,6 @@ export default abstract class BaseSerializerContext
|
|
|
1271
1161
|
return this.serializeStreamThrow(node);
|
|
1272
1162
|
case SerovalNodeType.StreamReturn:
|
|
1273
1163
|
return this.serializeStreamReturn(node);
|
|
1274
|
-
case SerovalNodeType.AbortSignalAbort:
|
|
1275
|
-
return this.serializeAbortSignalAbort(node);
|
|
1276
|
-
case SerovalNodeType.AbortSignalConstructor:
|
|
1277
|
-
return this.serializeAbortSignalConstructor(node);
|
|
1278
|
-
case SerovalNodeType.AbortSignalSync:
|
|
1279
|
-
return this.serializeAbortSignalSync(node);
|
|
1280
1164
|
default:
|
|
1281
1165
|
throw new SerovalUnsupportedNodeError(node);
|
|
1282
1166
|
}
|
package/src/core/cross/index.ts
CHANGED
|
@@ -131,9 +131,7 @@ export function crossSerializeStream<T>(
|
|
|
131
131
|
|
|
132
132
|
ctx.start(source);
|
|
133
133
|
|
|
134
|
-
return ()
|
|
135
|
-
ctx.destroy();
|
|
136
|
-
};
|
|
134
|
+
return ctx.destroy.bind(ctx);
|
|
137
135
|
}
|
|
138
136
|
|
|
139
137
|
export type ToCrossJSONStreamOptions = CrossStreamParserContextOptions;
|
|
@@ -154,9 +152,7 @@ export function toCrossJSONStream<T>(
|
|
|
154
152
|
|
|
155
153
|
ctx.start(source);
|
|
156
154
|
|
|
157
|
-
return ()
|
|
158
|
-
ctx.destroy();
|
|
159
|
-
};
|
|
155
|
+
return ctx.destroy.bind(ctx);
|
|
160
156
|
}
|
|
161
157
|
|
|
162
158
|
export type FromCrossJSONOptions = CrossDeserializerContextOptions;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Feature } from './compat';
|
|
2
|
+
|
|
3
|
+
export function createFunction(
|
|
4
|
+
features: number,
|
|
5
|
+
parameters: string[],
|
|
6
|
+
body: string,
|
|
7
|
+
): string {
|
|
8
|
+
if (features & Feature.ArrowFunction) {
|
|
9
|
+
const joined =
|
|
10
|
+
parameters.length === 1
|
|
11
|
+
? parameters[0]
|
|
12
|
+
: '(' + parameters.join(',') + ')';
|
|
13
|
+
return joined + '=>' + (body.startsWith('{') ? '(' + body + ')' : body);
|
|
14
|
+
}
|
|
15
|
+
return 'function(' + parameters.join(',') + '){return ' + body + '}';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function createEffectfulFunction(
|
|
19
|
+
features: number,
|
|
20
|
+
parameters: string[],
|
|
21
|
+
body: string,
|
|
22
|
+
): string {
|
|
23
|
+
if (features & Feature.ArrowFunction) {
|
|
24
|
+
const joined =
|
|
25
|
+
parameters.length === 1
|
|
26
|
+
? parameters[0]
|
|
27
|
+
: '(' + parameters.join(',') + ')';
|
|
28
|
+
return joined + '=>{' + body + '}';
|
|
29
|
+
}
|
|
30
|
+
return 'function(' + parameters.join(',') + '){' + body + '}';
|
|
31
|
+
}
|