seroval 0.8.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 +3858 -1385
- package/dist/cjs/development/index.cjs.map +4 -4
- package/dist/cjs/production/index.cjs +12 -3
- package/dist/esm/development/index.mjs +3611 -1136
- 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 -11
- 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 -228
- 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 +7 -7
- 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} +42 -133
- 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 -8
- package/src/{tree → core}/shared.ts +17 -3
- package/src/{tree → core/tree}/async.ts +57 -34
- package/src/core/tree/context.ts +136 -0
- package/src/{tree → core/tree}/deserialize.ts +83 -54
- package/src/core/tree/index.ts +146 -0
- package/src/core/tree/primitives.ts +132 -0
- package/src/{tree → core/tree}/serialize.ts +124 -178
- package/src/{tree → core/tree}/sync.ts +60 -39
- package/src/{tree → core/tree}/web-api.ts +10 -50
- package/src/{tree → core}/types.ts +82 -54
- 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 -61
- 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 -154
- package/src/tree/constants.ts +0 -72
- package/src/tree/iterator.ts +0 -14
- 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
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
/* eslint-disable prefer-spread */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
3
3
|
import type {
|
|
4
|
-
|
|
5
|
-
} from '
|
|
4
|
+
DeserializerContext,
|
|
5
|
+
} from './context';
|
|
6
6
|
import { deserializeString } from '../string';
|
|
7
|
-
import type { BigIntTypedArrayValue, TypedArrayValue } from '
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { getErrorConstructor, getTypedArrayConstructor } from './shared';
|
|
11
|
-
import { SYMBOL_REF } from './symbols';
|
|
7
|
+
import type { BigIntTypedArrayValue, TypedArrayValue } from '../../types';
|
|
8
|
+
import { getReference } from '../reference';
|
|
9
|
+
import { getErrorConstructor, getTypedArrayConstructor } from '../shared';
|
|
12
10
|
import type {
|
|
13
11
|
SerovalAggregateErrorNode,
|
|
14
12
|
SerovalArrayBufferNode,
|
|
@@ -35,25 +33,43 @@ import type {
|
|
|
35
33
|
SerovalTypedArrayNode,
|
|
36
34
|
SerovalURLNode,
|
|
37
35
|
SerovalURLSearchParamsNode,
|
|
38
|
-
} from '
|
|
36
|
+
} from '../types';
|
|
39
37
|
import {
|
|
40
|
-
SerovalNodeType,
|
|
41
38
|
SerovalObjectRecordSpecialKey,
|
|
42
|
-
} from '
|
|
39
|
+
} from '../types';
|
|
40
|
+
import {
|
|
41
|
+
SYMBOL_REF,
|
|
42
|
+
SerovalNodeType,
|
|
43
|
+
SerovalObjectFlags,
|
|
44
|
+
deserializeConstant,
|
|
45
|
+
} from '../constants';
|
|
46
|
+
|
|
47
|
+
function applyObjectFlag(obj: unknown, flag: SerovalObjectFlags): unknown {
|
|
48
|
+
switch (flag) {
|
|
49
|
+
case SerovalObjectFlags.Frozen:
|
|
50
|
+
return Object.freeze(obj);
|
|
51
|
+
case SerovalObjectFlags.NonExtensible:
|
|
52
|
+
return Object.preventExtensions(obj);
|
|
53
|
+
case SerovalObjectFlags.Sealed:
|
|
54
|
+
return Object.seal(obj);
|
|
55
|
+
default:
|
|
56
|
+
return obj;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
43
59
|
|
|
44
60
|
function assignIndexedValue<T>(
|
|
45
|
-
ctx:
|
|
61
|
+
ctx: DeserializerContext,
|
|
46
62
|
index: number,
|
|
47
63
|
value: T,
|
|
48
64
|
): T {
|
|
49
|
-
if (ctx.
|
|
50
|
-
ctx.
|
|
65
|
+
if (ctx.refs.has(index)) {
|
|
66
|
+
ctx.values.set(index, value);
|
|
51
67
|
}
|
|
52
68
|
return value;
|
|
53
69
|
}
|
|
54
70
|
|
|
55
71
|
function deserializeArray(
|
|
56
|
-
ctx:
|
|
72
|
+
ctx: DeserializerContext,
|
|
57
73
|
node: SerovalArrayNode,
|
|
58
74
|
): unknown[] {
|
|
59
75
|
const len = node.l;
|
|
@@ -69,11 +85,12 @@ function deserializeArray(
|
|
|
69
85
|
result[i] = deserializeTree(ctx, item);
|
|
70
86
|
}
|
|
71
87
|
}
|
|
88
|
+
applyObjectFlag(result, node.o);
|
|
72
89
|
return result;
|
|
73
90
|
}
|
|
74
91
|
|
|
75
92
|
function deserializeProperties(
|
|
76
|
-
ctx:
|
|
93
|
+
ctx: DeserializerContext,
|
|
77
94
|
node: SerovalObjectRecordNode,
|
|
78
95
|
result: Record<string | symbol, unknown>,
|
|
79
96
|
): Record<string | symbol, unknown> {
|
|
@@ -102,7 +119,7 @@ function deserializeProperties(
|
|
|
102
119
|
}
|
|
103
120
|
|
|
104
121
|
function deserializeObject(
|
|
105
|
-
ctx:
|
|
122
|
+
ctx: DeserializerContext,
|
|
106
123
|
node: SerovalObjectNode | SerovalNullConstructorNode,
|
|
107
124
|
): Record<string, unknown> {
|
|
108
125
|
const result = assignIndexedValue(
|
|
@@ -112,12 +129,13 @@ function deserializeObject(
|
|
|
112
129
|
? {}
|
|
113
130
|
: Object.create(null)) as Record<string, unknown>,
|
|
114
131
|
);
|
|
115
|
-
deserializeProperties(ctx, node.
|
|
132
|
+
deserializeProperties(ctx, node.p, result);
|
|
133
|
+
applyObjectFlag(result, node.o);
|
|
116
134
|
return result;
|
|
117
135
|
}
|
|
118
136
|
|
|
119
137
|
function deserializeSet(
|
|
120
|
-
ctx:
|
|
138
|
+
ctx: DeserializerContext,
|
|
121
139
|
node: SerovalSetNode,
|
|
122
140
|
): Set<unknown> {
|
|
123
141
|
const result = assignIndexedValue(ctx, node.i, new Set<unknown>());
|
|
@@ -129,7 +147,7 @@ function deserializeSet(
|
|
|
129
147
|
}
|
|
130
148
|
|
|
131
149
|
function deserializeMap(
|
|
132
|
-
ctx:
|
|
150
|
+
ctx: DeserializerContext,
|
|
133
151
|
node: SerovalMapNode,
|
|
134
152
|
): Map<unknown, unknown> {
|
|
135
153
|
const result = assignIndexedValue(
|
|
@@ -137,9 +155,9 @@ function deserializeMap(
|
|
|
137
155
|
node.i,
|
|
138
156
|
new Map<unknown, unknown>(),
|
|
139
157
|
);
|
|
140
|
-
const keys = node.
|
|
141
|
-
const vals = node.
|
|
142
|
-
for (let i = 0, len = node.
|
|
158
|
+
const keys = node.e.k;
|
|
159
|
+
const vals = node.e.v;
|
|
160
|
+
for (let i = 0, len = node.e.s; i < len; i++) {
|
|
143
161
|
result.set(
|
|
144
162
|
deserializeTree(ctx, keys[i]),
|
|
145
163
|
deserializeTree(ctx, vals[i]),
|
|
@@ -152,19 +170,19 @@ type AssignableValue = AggregateError | Error | Iterable<unknown>
|
|
|
152
170
|
type AssignableNode = SerovalAggregateErrorNode | SerovalErrorNode;
|
|
153
171
|
|
|
154
172
|
function deserializeDictionary<T extends AssignableValue>(
|
|
155
|
-
ctx:
|
|
173
|
+
ctx: DeserializerContext,
|
|
156
174
|
node: AssignableNode,
|
|
157
175
|
result: T,
|
|
158
176
|
): T {
|
|
159
|
-
if (node.
|
|
160
|
-
const fields = deserializeProperties(ctx, node.
|
|
177
|
+
if (node.p) {
|
|
178
|
+
const fields = deserializeProperties(ctx, node.p, {});
|
|
161
179
|
Object.assign(result, fields);
|
|
162
180
|
}
|
|
163
181
|
return result;
|
|
164
182
|
}
|
|
165
183
|
|
|
166
184
|
function deserializeAggregateError(
|
|
167
|
-
ctx:
|
|
185
|
+
ctx: DeserializerContext,
|
|
168
186
|
node: SerovalAggregateErrorNode,
|
|
169
187
|
): AggregateError {
|
|
170
188
|
// Serialize the required arguments
|
|
@@ -180,7 +198,7 @@ function deserializeAggregateError(
|
|
|
180
198
|
}
|
|
181
199
|
|
|
182
200
|
function deserializeError(
|
|
183
|
-
ctx:
|
|
201
|
+
ctx: DeserializerContext,
|
|
184
202
|
node: SerovalErrorNode,
|
|
185
203
|
): Error {
|
|
186
204
|
const ErrorConstructor = getErrorConstructor(node.c);
|
|
@@ -190,33 +208,44 @@ function deserializeError(
|
|
|
190
208
|
|
|
191
209
|
interface Deferred {
|
|
192
210
|
resolve(value: unknown): void;
|
|
211
|
+
reject(value: unknown): void;
|
|
193
212
|
promise: Promise<unknown>;
|
|
194
213
|
}
|
|
195
214
|
|
|
196
215
|
function createDeferred(): Deferred {
|
|
197
|
-
let
|
|
216
|
+
let resolve: Deferred['resolve'];
|
|
217
|
+
let reject: Deferred['reject'];
|
|
198
218
|
return {
|
|
199
219
|
resolve(v): void {
|
|
200
|
-
|
|
220
|
+
resolve(v);
|
|
201
221
|
},
|
|
202
|
-
|
|
203
|
-
|
|
222
|
+
reject(v): void {
|
|
223
|
+
reject(v);
|
|
224
|
+
},
|
|
225
|
+
promise: new Promise((res, rej) => {
|
|
226
|
+
resolve = res as Deferred['resolve'];
|
|
227
|
+
reject = rej as Deferred['reject'];
|
|
204
228
|
}),
|
|
205
229
|
};
|
|
206
230
|
}
|
|
207
231
|
|
|
208
232
|
async function deserializePromise(
|
|
209
|
-
ctx:
|
|
233
|
+
ctx: DeserializerContext,
|
|
210
234
|
node: SerovalPromiseNode,
|
|
211
235
|
): Promise<unknown> {
|
|
212
236
|
const deferred = createDeferred();
|
|
213
237
|
const result = assignIndexedValue(ctx, node.i, deferred.promise);
|
|
214
|
-
|
|
238
|
+
const deserialized = deserializeTree(ctx, node.f);
|
|
239
|
+
if (node.s) {
|
|
240
|
+
deferred.resolve(deserialized);
|
|
241
|
+
} else {
|
|
242
|
+
deferred.reject(deserialized);
|
|
243
|
+
}
|
|
215
244
|
return result;
|
|
216
245
|
}
|
|
217
246
|
|
|
218
247
|
function deserializeArrayBuffer(
|
|
219
|
-
ctx:
|
|
248
|
+
ctx: DeserializerContext,
|
|
220
249
|
node: SerovalArrayBufferNode,
|
|
221
250
|
): ArrayBuffer {
|
|
222
251
|
const bytes = new Uint8Array(node.s);
|
|
@@ -225,7 +254,7 @@ function deserializeArrayBuffer(
|
|
|
225
254
|
}
|
|
226
255
|
|
|
227
256
|
function deserializeTypedArray(
|
|
228
|
-
ctx:
|
|
257
|
+
ctx: DeserializerContext,
|
|
229
258
|
node: SerovalTypedArrayNode | SerovalBigIntTypedArrayNode,
|
|
230
259
|
): TypedArrayValue | BigIntTypedArrayValue {
|
|
231
260
|
const TypedArray = getTypedArrayConstructor(node.c);
|
|
@@ -239,42 +268,42 @@ function deserializeTypedArray(
|
|
|
239
268
|
}
|
|
240
269
|
|
|
241
270
|
function deserializeDate(
|
|
242
|
-
ctx:
|
|
271
|
+
ctx: DeserializerContext,
|
|
243
272
|
node: SerovalDateNode,
|
|
244
273
|
): Date {
|
|
245
274
|
return assignIndexedValue(ctx, node.i, new Date(node.s));
|
|
246
275
|
}
|
|
247
276
|
|
|
248
277
|
function deserializeRegExp(
|
|
249
|
-
ctx:
|
|
278
|
+
ctx: DeserializerContext,
|
|
250
279
|
node: SerovalRegExpNode,
|
|
251
280
|
): RegExp {
|
|
252
281
|
return assignIndexedValue(ctx, node.i, new RegExp(node.c, node.m));
|
|
253
282
|
}
|
|
254
283
|
|
|
255
284
|
function deserializeURL(
|
|
256
|
-
ctx:
|
|
285
|
+
ctx: DeserializerContext,
|
|
257
286
|
node: SerovalURLNode,
|
|
258
287
|
): URL {
|
|
259
288
|
return assignIndexedValue(ctx, node.i, new URL(deserializeString(node.s)));
|
|
260
289
|
}
|
|
261
290
|
|
|
262
291
|
function deserializeURLSearchParams(
|
|
263
|
-
ctx:
|
|
292
|
+
ctx: DeserializerContext,
|
|
264
293
|
node: SerovalURLSearchParamsNode,
|
|
265
294
|
): URLSearchParams {
|
|
266
295
|
return assignIndexedValue(ctx, node.i, new URLSearchParams(deserializeString(node.s)));
|
|
267
296
|
}
|
|
268
297
|
|
|
269
298
|
function deserializeReference(
|
|
270
|
-
ctx:
|
|
299
|
+
ctx: DeserializerContext,
|
|
271
300
|
node: SerovalReferenceNode,
|
|
272
301
|
): unknown {
|
|
273
302
|
return assignIndexedValue(ctx, node.i, getReference(deserializeString(node.s)));
|
|
274
303
|
}
|
|
275
304
|
|
|
276
305
|
function deserializeDataView(
|
|
277
|
-
ctx:
|
|
306
|
+
ctx: DeserializerContext,
|
|
278
307
|
node: SerovalDataViewNode,
|
|
279
308
|
): DataView {
|
|
280
309
|
const source = deserializeTree(ctx, node.f) as ArrayBuffer;
|
|
@@ -287,7 +316,7 @@ function deserializeDataView(
|
|
|
287
316
|
}
|
|
288
317
|
|
|
289
318
|
function deserializeBlob(
|
|
290
|
-
ctx:
|
|
319
|
+
ctx: DeserializerContext,
|
|
291
320
|
node: SerovalBlobNode,
|
|
292
321
|
): Blob {
|
|
293
322
|
const source = deserializeTree(ctx, node.f) as ArrayBuffer;
|
|
@@ -299,7 +328,7 @@ function deserializeBlob(
|
|
|
299
328
|
}
|
|
300
329
|
|
|
301
330
|
function deserializeFile(
|
|
302
|
-
ctx:
|
|
331
|
+
ctx: DeserializerContext,
|
|
303
332
|
node: SerovalFileNode,
|
|
304
333
|
): File {
|
|
305
334
|
const source = deserializeTree(ctx, node.f) as ArrayBuffer;
|
|
@@ -312,13 +341,13 @@ function deserializeFile(
|
|
|
312
341
|
}
|
|
313
342
|
|
|
314
343
|
function deserializeHeaders(
|
|
315
|
-
ctx:
|
|
344
|
+
ctx: DeserializerContext,
|
|
316
345
|
node: SerovalHeadersNode,
|
|
317
346
|
): Headers {
|
|
318
347
|
const result = assignIndexedValue(ctx, node.i, new Headers());
|
|
319
|
-
const keys = node.
|
|
320
|
-
const vals = node.
|
|
321
|
-
for (let i = 0, len = node.
|
|
348
|
+
const keys = node.e.k;
|
|
349
|
+
const vals = node.e.v;
|
|
350
|
+
for (let i = 0, len = node.e.s; i < len; i++) {
|
|
322
351
|
result.set(
|
|
323
352
|
deserializeString(keys[i]),
|
|
324
353
|
deserializeTree(ctx, vals[i]) as string,
|
|
@@ -328,13 +357,13 @@ function deserializeHeaders(
|
|
|
328
357
|
}
|
|
329
358
|
|
|
330
359
|
function deserializeFormData(
|
|
331
|
-
ctx:
|
|
360
|
+
ctx: DeserializerContext,
|
|
332
361
|
node: SerovalFormDataNode,
|
|
333
362
|
): FormData {
|
|
334
363
|
const result = assignIndexedValue(ctx, node.i, new FormData());
|
|
335
|
-
const keys = node.
|
|
336
|
-
const vals = node.
|
|
337
|
-
for (let i = 0, len = node.
|
|
364
|
+
const keys = node.e.k;
|
|
365
|
+
const vals = node.e.v;
|
|
366
|
+
for (let i = 0, len = node.e.s; i < len; i++) {
|
|
338
367
|
result.set(
|
|
339
368
|
deserializeString(keys[i]),
|
|
340
369
|
deserializeTree(ctx, vals[i]) as FormDataEntryValue,
|
|
@@ -344,7 +373,7 @@ function deserializeFormData(
|
|
|
344
373
|
}
|
|
345
374
|
|
|
346
375
|
function deserializeBoxed(
|
|
347
|
-
ctx:
|
|
376
|
+
ctx: DeserializerContext,
|
|
348
377
|
node: SerovalBoxedNode,
|
|
349
378
|
): unknown {
|
|
350
379
|
return assignIndexedValue(
|
|
@@ -355,7 +384,7 @@ function deserializeBoxed(
|
|
|
355
384
|
}
|
|
356
385
|
|
|
357
386
|
export default function deserializeTree(
|
|
358
|
-
ctx:
|
|
387
|
+
ctx: DeserializerContext,
|
|
359
388
|
node: SerovalNode,
|
|
360
389
|
): unknown {
|
|
361
390
|
switch (node.t) {
|
|
@@ -368,7 +397,7 @@ export default function deserializeTree(
|
|
|
368
397
|
case SerovalNodeType.BigInt:
|
|
369
398
|
return BigInt(node.s);
|
|
370
399
|
case SerovalNodeType.IndexedValue:
|
|
371
|
-
return ctx.
|
|
400
|
+
return ctx.values.get(node.i);
|
|
372
401
|
case SerovalNodeType.Array:
|
|
373
402
|
return deserializeArray(ctx, node);
|
|
374
403
|
case SerovalNodeType.Object:
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { Feature } from '../compat';
|
|
2
|
+
import { SerovalNodeType } from '../constants';
|
|
3
|
+
import type { SerovalNode } from '../types';
|
|
4
|
+
import parseAsync from './async';
|
|
5
|
+
import type {
|
|
6
|
+
ParserOptions,
|
|
7
|
+
SerializerContext,
|
|
8
|
+
} from './context';
|
|
9
|
+
import {
|
|
10
|
+
createDeserializerContext,
|
|
11
|
+
createParserContext,
|
|
12
|
+
createSerializerContext,
|
|
13
|
+
getRefParam,
|
|
14
|
+
getRootID,
|
|
15
|
+
} from './context';
|
|
16
|
+
import deserializeTree from './deserialize';
|
|
17
|
+
import serializeTree, { resolvePatches } from './serialize';
|
|
18
|
+
import parseSync from './sync';
|
|
19
|
+
|
|
20
|
+
function finalize(
|
|
21
|
+
ctx: SerializerContext,
|
|
22
|
+
rootID: number,
|
|
23
|
+
isObject: boolean,
|
|
24
|
+
result: string,
|
|
25
|
+
): string {
|
|
26
|
+
// Shared references detected
|
|
27
|
+
if (ctx.vars.length) {
|
|
28
|
+
const patches = resolvePatches(ctx);
|
|
29
|
+
let body = result;
|
|
30
|
+
if (patches) {
|
|
31
|
+
// Get (or create) a ref from the source
|
|
32
|
+
const index = getRefParam(ctx, rootID);
|
|
33
|
+
body = result + ',' + patches + index;
|
|
34
|
+
if (!result.startsWith(index + '=')) {
|
|
35
|
+
body = index + '=' + body;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
let params = ctx.vars.length > 1
|
|
39
|
+
? ctx.vars.join(',')
|
|
40
|
+
: ctx.vars[0];
|
|
41
|
+
// Source is probably already assigned
|
|
42
|
+
if (ctx.features & Feature.ArrowFunction) {
|
|
43
|
+
params = ctx.vars.length > 1 || ctx.vars.length === 0
|
|
44
|
+
? '(' + params + ')'
|
|
45
|
+
: params;
|
|
46
|
+
return '(' + params + '=>(' + body + '))()';
|
|
47
|
+
}
|
|
48
|
+
return '(function(' + params + '){return ' + body + '})()';
|
|
49
|
+
}
|
|
50
|
+
if (isObject) {
|
|
51
|
+
return '(' + result + ')';
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function serialize<T>(
|
|
57
|
+
source: T,
|
|
58
|
+
options?: Partial<ParserOptions>,
|
|
59
|
+
): string {
|
|
60
|
+
const ctx = createParserContext(options);
|
|
61
|
+
const tree = parseSync(ctx, source);
|
|
62
|
+
const serial = createSerializerContext({
|
|
63
|
+
markedRefs: ctx.reference.marked,
|
|
64
|
+
features: ctx.features,
|
|
65
|
+
});
|
|
66
|
+
const result = serializeTree(serial, tree);
|
|
67
|
+
return finalize(
|
|
68
|
+
serial,
|
|
69
|
+
getRootID(ctx, source),
|
|
70
|
+
tree.t === SerovalNodeType.Object,
|
|
71
|
+
result,
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export async function serializeAsync<T>(
|
|
76
|
+
source: T,
|
|
77
|
+
options?: Partial<ParserOptions>,
|
|
78
|
+
): Promise<string> {
|
|
79
|
+
const ctx = createParserContext(options);
|
|
80
|
+
const tree = await parseAsync(ctx, source);
|
|
81
|
+
const serial = createSerializerContext({
|
|
82
|
+
markedRefs: ctx.reference.marked,
|
|
83
|
+
features: ctx.features,
|
|
84
|
+
});
|
|
85
|
+
const result = serializeTree(serial, tree);
|
|
86
|
+
return finalize(
|
|
87
|
+
serial,
|
|
88
|
+
getRootID(ctx, source),
|
|
89
|
+
tree.t === SerovalNodeType.Object,
|
|
90
|
+
result,
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function deserialize<T>(source: string): T {
|
|
95
|
+
// eslint-disable-next-line no-eval
|
|
96
|
+
return (0, eval)(source) as T;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface SerovalJSON {
|
|
100
|
+
t: SerovalNode;
|
|
101
|
+
r: number;
|
|
102
|
+
f: number;
|
|
103
|
+
m: number[];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function toJSON<T>(
|
|
107
|
+
source: T,
|
|
108
|
+
options?: Partial<ParserOptions>,
|
|
109
|
+
): SerovalJSON {
|
|
110
|
+
const ctx = createParserContext(options);
|
|
111
|
+
return {
|
|
112
|
+
t: parseSync(ctx, source),
|
|
113
|
+
r: getRootID(ctx, source),
|
|
114
|
+
f: ctx.features,
|
|
115
|
+
m: Array.from(ctx.reference.marked),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export async function toJSONAsync<T>(
|
|
120
|
+
source: T,
|
|
121
|
+
options?: Partial<ParserOptions>,
|
|
122
|
+
): Promise<SerovalJSON> {
|
|
123
|
+
const ctx = createParserContext(options);
|
|
124
|
+
return {
|
|
125
|
+
t: await parseAsync(ctx, source),
|
|
126
|
+
r: getRootID(ctx, source),
|
|
127
|
+
f: ctx.features,
|
|
128
|
+
m: Array.from(ctx.reference.marked),
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function compileJSON(source: SerovalJSON): string {
|
|
133
|
+
const serial = createSerializerContext({
|
|
134
|
+
features: source.f,
|
|
135
|
+
markedRefs: source.m,
|
|
136
|
+
});
|
|
137
|
+
const result = serializeTree(serial, source.t);
|
|
138
|
+
return finalize(serial, source.r, source.t.i === SerovalNodeType.Object, result);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export function fromJSON<T>(source: SerovalJSON): T {
|
|
142
|
+
const serial = createDeserializerContext({
|
|
143
|
+
markedRefs: source.m,
|
|
144
|
+
});
|
|
145
|
+
return deserializeTree(serial, source.t) as T;
|
|
146
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import assert from '../assert';
|
|
2
|
+
import { Feature } from '../compat';
|
|
3
|
+
import type { ParserContext } from './context';
|
|
4
|
+
import { createIndexedValue } from './context';
|
|
5
|
+
import type { BigIntTypedArrayValue, TypedArrayValue } from '../../types';
|
|
6
|
+
import UnsupportedTypeError from '../UnsupportedTypeError';
|
|
7
|
+
import { hasReferenceID } from '../reference';
|
|
8
|
+
import type {
|
|
9
|
+
SerovalBigIntTypedArrayNode,
|
|
10
|
+
SerovalTypedArrayNode,
|
|
11
|
+
SerovalWKSymbolNode,
|
|
12
|
+
SerovalReferenceNode,
|
|
13
|
+
SerovalDataViewNode,
|
|
14
|
+
SerovalNode,
|
|
15
|
+
SerovalIndexedValueNode,
|
|
16
|
+
} from '../types';
|
|
17
|
+
import type { WellKnownSymbols } from '../constants';
|
|
18
|
+
import { SerovalNodeType } from '../constants';
|
|
19
|
+
import {
|
|
20
|
+
createArrayBufferNode,
|
|
21
|
+
createIndexedValueNode,
|
|
22
|
+
createReferenceNode,
|
|
23
|
+
createWKSymbolNode,
|
|
24
|
+
} from '../base-primitives';
|
|
25
|
+
|
|
26
|
+
export function serializeArrayBuffer(
|
|
27
|
+
ctx: ParserContext,
|
|
28
|
+
current: ArrayBuffer,
|
|
29
|
+
): SerovalNode {
|
|
30
|
+
const id = createIndexedValue(ctx, current);
|
|
31
|
+
if (ctx.reference.marked.has(id)) {
|
|
32
|
+
return createIndexedValueNode(id);
|
|
33
|
+
}
|
|
34
|
+
return createArrayBufferNode(id, current);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function createTypedArrayNode(
|
|
38
|
+
ctx: ParserContext,
|
|
39
|
+
id: number,
|
|
40
|
+
current: TypedArrayValue,
|
|
41
|
+
): SerovalTypedArrayNode {
|
|
42
|
+
assert(ctx.features & Feature.TypedArray, new UnsupportedTypeError(current));
|
|
43
|
+
return {
|
|
44
|
+
t: SerovalNodeType.TypedArray,
|
|
45
|
+
i: id,
|
|
46
|
+
s: undefined,
|
|
47
|
+
l: current.length,
|
|
48
|
+
c: current.constructor.name,
|
|
49
|
+
m: undefined,
|
|
50
|
+
p: undefined,
|
|
51
|
+
e: undefined,
|
|
52
|
+
a: undefined,
|
|
53
|
+
f: serializeArrayBuffer(ctx, current.buffer),
|
|
54
|
+
b: current.byteOffset,
|
|
55
|
+
o: undefined,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const BIGINT_FLAG = Feature.BigIntTypedArray | Feature.BigInt;
|
|
60
|
+
|
|
61
|
+
export function createBigIntTypedArrayNode(
|
|
62
|
+
ctx: ParserContext,
|
|
63
|
+
id: number,
|
|
64
|
+
current: BigIntTypedArrayValue,
|
|
65
|
+
): SerovalBigIntTypedArrayNode {
|
|
66
|
+
assert(
|
|
67
|
+
(ctx.features & BIGINT_FLAG) === BIGINT_FLAG,
|
|
68
|
+
new UnsupportedTypeError(current),
|
|
69
|
+
);
|
|
70
|
+
return {
|
|
71
|
+
t: SerovalNodeType.BigIntTypedArray,
|
|
72
|
+
i: id,
|
|
73
|
+
s: undefined,
|
|
74
|
+
l: current.length,
|
|
75
|
+
c: current.constructor.name,
|
|
76
|
+
m: undefined,
|
|
77
|
+
p: undefined,
|
|
78
|
+
e: undefined,
|
|
79
|
+
a: undefined,
|
|
80
|
+
f: serializeArrayBuffer(ctx, current.buffer),
|
|
81
|
+
b: current.byteOffset,
|
|
82
|
+
o: undefined,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function createDataViewNode(
|
|
87
|
+
ctx: ParserContext,
|
|
88
|
+
id: number,
|
|
89
|
+
current: DataView,
|
|
90
|
+
): SerovalDataViewNode {
|
|
91
|
+
return {
|
|
92
|
+
t: SerovalNodeType.DataView,
|
|
93
|
+
i: id,
|
|
94
|
+
s: undefined,
|
|
95
|
+
l: current.byteLength,
|
|
96
|
+
c: undefined,
|
|
97
|
+
m: undefined,
|
|
98
|
+
p: undefined,
|
|
99
|
+
e: undefined,
|
|
100
|
+
a: undefined,
|
|
101
|
+
f: serializeArrayBuffer(ctx, current.buffer),
|
|
102
|
+
b: current.byteOffset,
|
|
103
|
+
o: undefined,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function createSymbolNode(
|
|
108
|
+
ctx: ParserContext,
|
|
109
|
+
current: symbol,
|
|
110
|
+
): SerovalIndexedValueNode | SerovalReferenceNode | SerovalWKSymbolNode {
|
|
111
|
+
const id = createIndexedValue(ctx, current);
|
|
112
|
+
if (ctx.reference.marked.has(id)) {
|
|
113
|
+
return createIndexedValueNode(id);
|
|
114
|
+
}
|
|
115
|
+
if (hasReferenceID(current)) {
|
|
116
|
+
return createReferenceNode(id, current);
|
|
117
|
+
}
|
|
118
|
+
return createWKSymbolNode(ctx, id, current as WellKnownSymbols);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export function createFunctionNode(
|
|
122
|
+
ctx: ParserContext,
|
|
123
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
124
|
+
current: Function,
|
|
125
|
+
): SerovalIndexedValueNode | SerovalReferenceNode {
|
|
126
|
+
assert(hasReferenceID(current), new Error('Cannot serialize function without reference ID.'));
|
|
127
|
+
const id = createIndexedValue(ctx, current);
|
|
128
|
+
if (ctx.reference.marked.has(id)) {
|
|
129
|
+
return createIndexedValueNode(id);
|
|
130
|
+
}
|
|
131
|
+
return createReferenceNode(id, current);
|
|
132
|
+
}
|