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.
Files changed (91) hide show
  1. package/README.md +4 -287
  2. package/dist/cjs/development/index.cjs +3858 -1385
  3. package/dist/cjs/development/index.cjs.map +4 -4
  4. package/dist/cjs/production/index.cjs +12 -3
  5. package/dist/esm/development/index.mjs +3611 -1136
  6. package/dist/esm/development/index.mjs.map +4 -4
  7. package/dist/esm/production/index.mjs +12 -3
  8. package/dist/types/core/Serializer.d.ts +14 -0
  9. package/dist/types/{tree → core}/UnsupportedTypeError.d.ts +4 -3
  10. package/dist/types/{assert.d.ts → core/assert.d.ts} +1 -1
  11. package/dist/types/core/assignments.d.ts +33 -0
  12. package/dist/types/core/base-primitives.d.ts +12 -0
  13. package/dist/types/{compat.d.ts → core/compat.d.ts} +22 -22
  14. package/dist/types/core/constants.d.ts +89 -0
  15. package/dist/types/core/context.d.ts +9 -0
  16. package/dist/types/core/cross/async.d.ts +3 -0
  17. package/dist/types/core/cross/context.d.ts +30 -0
  18. package/dist/types/core/cross/index.d.ts +7 -0
  19. package/dist/types/core/cross/primitives.d.ts +9 -0
  20. package/dist/types/core/cross/serialize.d.ts +5 -0
  21. package/dist/types/core/cross/stream.d.ts +3 -0
  22. package/dist/types/core/cross/sync.d.ts +3 -0
  23. package/dist/types/core/cross/web-api.d.ts +4 -0
  24. package/dist/types/{get-identifier.d.ts → core/get-identifier.d.ts} +1 -1
  25. package/dist/types/core/keys.d.ts +12 -0
  26. package/dist/types/{tree/constants.d.ts → core/literals.d.ts} +9 -11
  27. package/dist/types/core/promise-to-result.d.ts +1 -0
  28. package/dist/types/{tree → core}/reference.d.ts +5 -6
  29. package/dist/types/{tree → core}/shared.d.ts +13 -11
  30. package/dist/types/{string.d.ts → core/string.d.ts} +3 -3
  31. package/dist/types/core/tree/async.d.ts +3 -0
  32. package/dist/types/core/tree/context.d.ts +45 -0
  33. package/dist/types/core/tree/deserialize.d.ts +3 -0
  34. package/dist/types/core/tree/index.d.ts +15 -0
  35. package/dist/types/core/tree/primitives.d.ts +9 -0
  36. package/dist/types/core/tree/serialize.d.ts +4 -0
  37. package/dist/types/core/tree/sync.d.ts +3 -0
  38. package/dist/types/core/tree/web-api.d.ts +4 -0
  39. package/dist/types/{tree → core}/types.d.ts +228 -228
  40. package/dist/types/core/web-api.d.ts +4 -0
  41. package/dist/types/index.d.ts +9 -19
  42. package/dist/types/types.d.ts +20 -20
  43. package/package.json +7 -7
  44. package/src/core/Serializer.ts +46 -0
  45. package/src/{tree → core}/UnsupportedTypeError.ts +1 -1
  46. package/src/core/assignments.ts +159 -0
  47. package/src/{tree/primitives.ts → core/base-primitives.ts} +42 -133
  48. package/src/core/constants.ts +169 -0
  49. package/src/core/context.ts +15 -0
  50. package/src/core/cross/async.ts +614 -0
  51. package/src/core/cross/context.ts +79 -0
  52. package/src/core/cross/index.ts +154 -0
  53. package/src/core/cross/primitives.ts +137 -0
  54. package/src/core/cross/serialize.ts +846 -0
  55. package/src/core/cross/stream.ts +740 -0
  56. package/src/core/cross/sync.ts +561 -0
  57. package/src/core/cross/web-api.ts +55 -0
  58. package/src/core/header.js +65 -0
  59. package/src/core/keys.ts +33 -0
  60. package/src/core/literals.ts +28 -0
  61. package/src/core/promise-to-result.ts +9 -0
  62. package/src/{tree → core}/reference.ts +6 -8
  63. package/src/{tree → core}/shared.ts +17 -3
  64. package/src/{tree → core/tree}/async.ts +57 -34
  65. package/src/core/tree/context.ts +136 -0
  66. package/src/{tree → core/tree}/deserialize.ts +83 -54
  67. package/src/core/tree/index.ts +146 -0
  68. package/src/core/tree/primitives.ts +132 -0
  69. package/src/{tree → core/tree}/serialize.ts +124 -178
  70. package/src/{tree → core/tree}/sync.ts +60 -39
  71. package/src/{tree → core/tree}/web-api.ts +10 -50
  72. package/src/{tree → core}/types.ts +82 -54
  73. package/src/core/web-api.ts +51 -0
  74. package/src/index.ts +7 -141
  75. package/src/types.ts +1 -1
  76. package/dist/types/context.d.ts +0 -61
  77. package/dist/types/tree/async.d.ts +0 -3
  78. package/dist/types/tree/deserialize.d.ts +0 -3
  79. package/dist/types/tree/primitives.d.ts +0 -19
  80. package/dist/types/tree/serialize.d.ts +0 -4
  81. package/dist/types/tree/symbols.d.ts +0 -33
  82. package/dist/types/tree/sync.d.ts +0 -3
  83. package/dist/types/tree/web-api.d.ts +0 -6
  84. package/src/context.ts +0 -154
  85. package/src/tree/constants.ts +0 -72
  86. package/src/tree/iterator.ts +0 -14
  87. package/src/tree/symbols.ts +0 -65
  88. /package/src/{assert.ts → core/assert.ts} +0 -0
  89. /package/src/{compat.ts → core/compat.ts} +0 -0
  90. /package/src/{get-identifier.ts → core/get-identifier.ts} +0 -0
  91. /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
- SerializationContext,
5
- } from '../context';
4
+ DeserializerContext,
5
+ } from './context';
6
6
  import { deserializeString } from '../string';
7
- import type { BigIntTypedArrayValue, TypedArrayValue } from '../types';
8
- import { deserializeConstant } from './constants';
9
- import { getReference } from './reference';
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 './types';
36
+ } from '../types';
39
37
  import {
40
- SerovalNodeType,
41
38
  SerovalObjectRecordSpecialKey,
42
- } from './types';
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: SerializationContext,
61
+ ctx: DeserializerContext,
46
62
  index: number,
47
63
  value: T,
48
64
  ): T {
49
- if (ctx.markedRefs.has(index)) {
50
- ctx.valueMap.set(index, value);
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: SerializationContext,
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: SerializationContext,
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: SerializationContext,
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.d, result);
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: SerializationContext,
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: SerializationContext,
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.d.k;
141
- const vals = node.d.v;
142
- for (let i = 0, len = node.d.s; i < len; i++) {
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: SerializationContext,
173
+ ctx: DeserializerContext,
156
174
  node: AssignableNode,
157
175
  result: T,
158
176
  ): T {
159
- if (node.d) {
160
- const fields = deserializeProperties(ctx, node.d, {});
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: SerializationContext,
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: SerializationContext,
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 resolver: Deferred['resolve'];
216
+ let resolve: Deferred['resolve'];
217
+ let reject: Deferred['reject'];
198
218
  return {
199
219
  resolve(v): void {
200
- resolver(v);
220
+ resolve(v);
201
221
  },
202
- promise: new Promise((res) => {
203
- resolver = res as Deferred['resolve'];
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: SerializationContext,
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
- deferred.resolve(deserializeTree(ctx, node.f));
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: SerializationContext,
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: SerializationContext,
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: SerializationContext,
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: SerializationContext,
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: SerializationContext,
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: SerializationContext,
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: SerializationContext,
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: SerializationContext,
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: SerializationContext,
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: SerializationContext,
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: SerializationContext,
344
+ ctx: DeserializerContext,
316
345
  node: SerovalHeadersNode,
317
346
  ): Headers {
318
347
  const result = assignIndexedValue(ctx, node.i, new Headers());
319
- const keys = node.d.k;
320
- const vals = node.d.v;
321
- for (let i = 0, len = node.d.s; i < len; i++) {
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: SerializationContext,
360
+ ctx: DeserializerContext,
332
361
  node: SerovalFormDataNode,
333
362
  ): FormData {
334
363
  const result = assignIndexedValue(ctx, node.i, new FormData());
335
- const keys = node.d.k;
336
- const vals = node.d.v;
337
- for (let i = 0, len = node.d.s; i < len; i++) {
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: SerializationContext,
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: SerializationContext,
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.valueMap.get(node.i);
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
+ }