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