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.
Files changed (90) hide show
  1. package/README.md +4 -287
  2. package/dist/cjs/development/index.cjs +3529 -1140
  3. package/dist/cjs/development/index.cjs.map +4 -4
  4. package/dist/cjs/production/index.cjs +3 -3
  5. package/dist/esm/development/index.mjs +3533 -1142
  6. package/dist/esm/development/index.mjs.map +4 -4
  7. package/dist/esm/production/index.mjs +3 -3
  8. package/dist/types/core/Serializer.d.ts +15 -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 +37 -0
  18. package/dist/types/core/cross/index.d.ts +8 -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 +13 -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 -13
  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 +44 -0
  33. package/dist/types/core/tree/deserialize.d.ts +3 -0
  34. package/dist/types/core/tree/index.d.ts +14 -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 -238
  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 +5 -5
  44. package/src/core/Serializer.ts +48 -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} +33 -136
  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 +102 -0
  52. package/src/core/cross/index.ts +169 -0
  53. package/src/core/cross/primitives.ts +137 -0
  54. package/src/core/cross/serialize.ts +847 -0
  55. package/src/core/cross/stream.ts +745 -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 +61 -0
  59. package/src/core/keys.ts +41 -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 -7
  63. package/src/{tree → core}/shared.ts +4 -4
  64. package/src/{tree → core/tree}/async.ts +46 -34
  65. package/src/core/tree/context.ts +125 -0
  66. package/src/{tree → core/tree}/deserialize.ts +68 -55
  67. package/src/core/tree/index.ts +142 -0
  68. package/src/core/tree/primitives.ts +132 -0
  69. package/src/{tree → core/tree}/serialize.ts +87 -193
  70. package/src/{tree → core/tree}/sync.ts +50 -39
  71. package/src/{tree → core/tree}/web-api.ts +8 -52
  72. package/src/{tree → core}/types.ts +76 -60
  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 -67
  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 -164
  85. package/src/tree/constants.ts +0 -73
  86. package/src/tree/symbols.ts +0 -65
  87. /package/src/{assert.ts → core/assert.ts} +0 -0
  88. /package/src/{compat.ts → core/compat.ts} +0 -0
  89. /package/src/{get-identifier.ts → core/get-identifier.ts} +0 -0
  90. /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,12 +33,16 @@ import type {
35
33
  SerovalTypedArrayNode,
36
34
  SerovalURLNode,
37
35
  SerovalURLSearchParamsNode,
38
- } from './types';
36
+ } from '../types';
39
37
  import {
40
- SerovalObjectFlags,
41
- SerovalNodeType,
42
38
  SerovalObjectRecordSpecialKey,
43
- } from './types';
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: SerializationContext,
61
+ ctx: DeserializerContext,
60
62
  index: number,
61
63
  value: T,
62
64
  ): T {
63
- if (ctx.markedRefs.has(index)) {
64
- ctx.valueMap.set(index, value);
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: SerializationContext,
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: SerializationContext,
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: SerializationContext,
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.d, result);
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: SerializationContext,
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: SerializationContext,
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.d.k;
157
- const vals = node.d.v;
158
- 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++) {
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: SerializationContext,
173
+ ctx: DeserializerContext,
172
174
  node: AssignableNode,
173
175
  result: T,
174
176
  ): T {
175
- if (node.d) {
176
- const fields = deserializeProperties(ctx, node.d, {});
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: SerializationContext,
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: SerializationContext,
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 resolver: Deferred['resolve'];
216
+ let resolve: Deferred['resolve'];
217
+ let reject: Deferred['reject'];
214
218
  return {
215
219
  resolve(v): void {
216
- resolver(v);
220
+ resolve(v);
221
+ },
222
+ reject(v): void {
223
+ reject(v);
217
224
  },
218
- promise: new Promise((res) => {
219
- resolver = res as Deferred['resolve'];
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: SerializationContext,
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
- 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
+ }
231
244
  return result;
232
245
  }
233
246
 
234
247
  function deserializeArrayBuffer(
235
- ctx: SerializationContext,
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: SerializationContext,
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: SerializationContext,
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: SerializationContext,
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: SerializationContext,
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: SerializationContext,
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: SerializationContext,
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: SerializationContext,
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: SerializationContext,
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: SerializationContext,
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: SerializationContext,
344
+ ctx: DeserializerContext,
332
345
  node: SerovalHeadersNode,
333
346
  ): Headers {
334
347
  const result = assignIndexedValue(ctx, node.i, new Headers());
335
- const keys = node.d.k;
336
- const vals = node.d.v;
337
- 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++) {
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: SerializationContext,
360
+ ctx: DeserializerContext,
348
361
  node: SerovalFormDataNode,
349
362
  ): FormData {
350
363
  const result = assignIndexedValue(ctx, node.i, new FormData());
351
- const keys = node.d.k;
352
- const vals = node.d.v;
353
- 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++) {
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: SerializationContext,
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: SerializationContext,
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.valueMap.get(node.i);
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
+ }