seroval 0.11.6 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/README.md +29 -16
  2. package/dist/cjs/development/index.cjs +3072 -4875
  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 +3069 -4874
  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 +2 -0
  9. package/dist/types/core/Serializer.d.ts.map +1 -0
  10. package/dist/types/core/UnsupportedTypeError.d.ts +1 -0
  11. package/dist/types/core/UnsupportedTypeError.d.ts.map +1 -0
  12. package/dist/types/core/assert.d.ts +1 -0
  13. package/dist/types/core/assert.d.ts.map +1 -0
  14. package/dist/types/core/base/async.d.ts +30 -0
  15. package/dist/types/core/base/async.d.ts.map +1 -0
  16. package/dist/types/core/base/stream.d.ts +40 -0
  17. package/dist/types/core/base/stream.d.ts.map +1 -0
  18. package/dist/types/core/base/sync.d.ts +32 -0
  19. package/dist/types/core/base/sync.d.ts.map +1 -0
  20. package/dist/types/core/base-primitives.d.ts +3 -1
  21. package/dist/types/core/base-primitives.d.ts.map +1 -0
  22. package/dist/types/core/compat.d.ts +1 -0
  23. package/dist/types/core/compat.d.ts.map +1 -0
  24. package/dist/types/core/constants.d.ts +19 -4
  25. package/dist/types/core/constants.d.ts.map +1 -0
  26. package/dist/types/core/constructors.d.ts +1 -0
  27. package/dist/types/core/constructors.d.ts.map +1 -0
  28. package/dist/types/core/cross/async.d.ts +8 -3
  29. package/dist/types/core/cross/async.d.ts.map +1 -0
  30. package/dist/types/core/cross/cross-parser.d.ts +8 -0
  31. package/dist/types/core/cross/cross-parser.d.ts.map +1 -0
  32. package/dist/types/core/cross/index.d.ts +12 -5
  33. package/dist/types/core/cross/index.d.ts.map +1 -0
  34. package/dist/types/core/cross/serialize.d.ts +23 -5
  35. package/dist/types/core/cross/serialize.d.ts.map +1 -0
  36. package/dist/types/core/cross/stream.d.ts +8 -3
  37. package/dist/types/core/cross/stream.d.ts.map +1 -0
  38. package/dist/types/core/cross/sync.d.ts +8 -3
  39. package/dist/types/core/cross/sync.d.ts.map +1 -0
  40. package/dist/types/core/get-identifier.d.ts +1 -0
  41. package/dist/types/core/get-identifier.d.ts.map +1 -0
  42. package/dist/types/core/keys.d.ts +1 -0
  43. package/dist/types/core/keys.d.ts.map +1 -0
  44. package/dist/types/core/literals.d.ts +1 -0
  45. package/dist/types/core/literals.d.ts.map +1 -0
  46. package/dist/types/core/parser-context.d.ts +23 -0
  47. package/dist/types/core/parser-context.d.ts.map +1 -0
  48. package/dist/types/core/plugin.d.ts +26 -0
  49. package/dist/types/core/plugin.d.ts.map +1 -0
  50. package/dist/types/core/promise-to-result.d.ts +1 -0
  51. package/dist/types/core/promise-to-result.d.ts.map +1 -0
  52. package/dist/types/core/reference.d.ts +1 -0
  53. package/dist/types/core/reference.d.ts.map +1 -0
  54. package/dist/types/core/serializer-context.old.d.ts +165 -0
  55. package/dist/types/core/serializer-context.old.d.ts.map +1 -0
  56. package/dist/types/core/shared.d.ts +4 -7
  57. package/dist/types/core/shared.d.ts.map +1 -0
  58. package/dist/types/core/string.d.ts +1 -0
  59. package/dist/types/core/string.d.ts.map +1 -0
  60. package/dist/types/core/tree/async.d.ts +8 -3
  61. package/dist/types/core/tree/async.d.ts.map +1 -0
  62. package/dist/types/core/tree/deserialize.d.ts +49 -2
  63. package/dist/types/core/tree/deserialize.d.ts.map +1 -0
  64. package/dist/types/core/tree/index.d.ts +10 -7
  65. package/dist/types/core/tree/index.d.ts.map +1 -0
  66. package/dist/types/core/tree/serialize.d.ts +37 -4
  67. package/dist/types/core/tree/serialize.d.ts.map +1 -0
  68. package/dist/types/core/tree/sync.d.ts +8 -3
  69. package/dist/types/core/tree/sync.d.ts.map +1 -0
  70. package/dist/types/core/types.d.ts +10 -3
  71. package/dist/types/core/types.d.ts.map +1 -0
  72. package/dist/types/core/web-api.d.ts +1 -0
  73. package/dist/types/core/web-api.d.ts.map +1 -0
  74. package/dist/types/index.d.ts +3 -0
  75. package/dist/types/index.d.ts.map +1 -0
  76. package/dist/types/types.d.ts +1 -0
  77. package/dist/types/types.d.ts.map +1 -0
  78. package/package.json +2 -2
  79. package/src/core/Serializer.ts +2 -0
  80. package/src/core/base/async.ts +804 -0
  81. package/src/core/base/stream.ts +496 -0
  82. package/src/core/base/sync.ts +675 -0
  83. package/src/core/base-primitives.ts +22 -0
  84. package/src/core/constants.ts +61 -45
  85. package/src/core/cross/async.ts +6 -751
  86. package/src/core/cross/cross-parser.ts +9 -0
  87. package/src/core/cross/index.ts +62 -84
  88. package/src/core/cross/serialize.ts +71 -862
  89. package/src/core/cross/stream.ts +6 -873
  90. package/src/core/cross/sync.ts +6 -624
  91. package/src/core/is-serializable.new.ts +208 -0
  92. package/src/core/keys.ts +1 -1
  93. package/src/core/parser-context.ts +131 -0
  94. package/src/core/plugin.ts +55 -0
  95. package/src/core/serializer-context.new.ts +1168 -0
  96. package/src/core/serializer-context.old.ts +1126 -0
  97. package/src/core/shared.ts +46 -123
  98. package/src/core/tree/async.ts +6 -750
  99. package/src/core/tree/deserialize.ts +423 -420
  100. package/src/core/tree/index.ts +49 -91
  101. package/src/core/tree/parser.ts +45 -0
  102. package/src/core/tree/serialize.ts +122 -828
  103. package/src/core/tree/sync.ts +6 -624
  104. package/src/core/types.ts +13 -2
  105. package/src/example.ts +28 -0
  106. package/src/index.ts +3 -0
  107. package/dist/types/core/assignments.d.ts +0 -33
  108. package/dist/types/core/context.d.ts +0 -9
  109. package/dist/types/core/cross/context.d.ts +0 -37
  110. package/dist/types/core/cross/primitives.d.ts +0 -9
  111. package/dist/types/core/cross/web-api.d.ts +0 -4
  112. package/dist/types/core/tree/context.d.ts +0 -44
  113. package/dist/types/core/tree/primitives.d.ts +0 -9
  114. package/dist/types/core/tree/web-api.d.ts +0 -4
  115. package/src/core/assignments.ts +0 -159
  116. package/src/core/context.ts +0 -15
  117. package/src/core/cross/context.ts +0 -102
  118. package/src/core/cross/primitives.ts +0 -128
  119. package/src/core/cross/web-api.ts +0 -50
  120. package/src/core/tree/context.ts +0 -125
  121. package/src/core/tree/primitives.ts +0 -123
  122. package/src/core/tree/web-api.ts +0 -50
@@ -1,12 +1,8 @@
1
1
  /* eslint-disable prefer-spread */
2
- /* eslint-disable @typescript-eslint/no-use-before-define */
3
- import type {
4
- DeserializerContext,
5
- } from './context';
6
2
  import { deserializeString } from '../string';
7
3
  import type { BigIntTypedArrayValue, TypedArrayValue } from '../../types';
8
4
  import { getReference } from '../reference';
9
- import { getErrorConstructor, getTypedArrayConstructor } from '../shared';
5
+ import { getTypedArrayConstructor } from '../shared';
10
6
  import type {
11
7
  SerovalAggregateErrorNode,
12
8
  SerovalArrayBufferNode,
@@ -29,6 +25,7 @@ import type {
29
25
  SerovalObjectNode,
30
26
  SerovalObjectRecordKey,
31
27
  SerovalObjectRecordNode,
28
+ SerovalPluginNode,
32
29
  SerovalPromiseNode,
33
30
  SerovalReferenceNode,
34
31
  SerovalRegExpNode,
@@ -43,11 +40,13 @@ import {
43
40
  SerovalObjectRecordSpecialKey,
44
41
  } from '../types';
45
42
  import {
43
+ CONSTANT_VAL,
44
+ ERROR_CONSTRUCTOR,
46
45
  SYMBOL_REF,
47
46
  SerovalNodeType,
48
47
  SerovalObjectFlags,
49
- deserializeConstant,
50
48
  } from '../constants';
49
+ import type { Plugin, PluginAccessOptions } from '../plugin';
51
50
 
52
51
  function applyObjectFlag(obj: unknown, flag: SerovalObjectFlags): unknown {
53
52
  switch (flag) {
@@ -62,155 +61,9 @@ function applyObjectFlag(obj: unknown, flag: SerovalObjectFlags): unknown {
62
61
  }
63
62
  }
64
63
 
65
- function assignIndexedValue<T>(
66
- ctx: DeserializerContext,
67
- index: number,
68
- value: T,
69
- ): T {
70
- if (ctx.refs.has(index)) {
71
- ctx.values.set(index, value);
72
- }
73
- return value;
74
- }
75
-
76
- function deserializeArray(
77
- ctx: DeserializerContext,
78
- node: SerovalArrayNode,
79
- ): unknown[] {
80
- const len = node.l;
81
- const result: unknown[] = assignIndexedValue(
82
- ctx,
83
- node.i,
84
- new Array<unknown>(len),
85
- );
86
- let item: SerovalNode | undefined;
87
- for (let i = 0; i < len; i++) {
88
- item = node.a[i];
89
- if (item) {
90
- result[i] = deserializeTree(ctx, item);
91
- }
92
- }
93
- applyObjectFlag(result, node.o);
94
- return result;
95
- }
96
-
97
- function deserializeProperties(
98
- ctx: DeserializerContext,
99
- node: SerovalObjectRecordNode,
100
- result: Record<string | symbol, unknown>,
101
- ): Record<string | symbol, unknown> {
102
- const len = node.s;
103
- if (len) {
104
- let key: SerovalObjectRecordKey;
105
- let value: unknown;
106
- const keys = node.k;
107
- const vals = node.v;
108
- for (let i = 0; i < len; i++) {
109
- key = keys[i];
110
- value = deserializeTree(ctx, vals[i]);
111
- switch (key) {
112
- case SerovalObjectRecordSpecialKey.SymbolIterator: {
113
- const current = value as unknown[];
114
- result[Symbol.iterator] = (): IterableIterator<unknown> => current.values();
115
- }
116
- break;
117
- default:
118
- result[deserializeString(key)] = value;
119
- break;
120
- }
121
- }
122
- }
123
- return result;
124
- }
125
-
126
- function deserializeObject(
127
- ctx: DeserializerContext,
128
- node: SerovalObjectNode | SerovalNullConstructorNode,
129
- ): Record<string, unknown> {
130
- const result = assignIndexedValue(
131
- ctx,
132
- node.i,
133
- (node.t === SerovalNodeType.Object
134
- ? {}
135
- : Object.create(null)) as Record<string, unknown>,
136
- );
137
- deserializeProperties(ctx, node.p, result);
138
- applyObjectFlag(result, node.o);
139
- return result;
140
- }
141
-
142
- function deserializeSet(
143
- ctx: DeserializerContext,
144
- node: SerovalSetNode,
145
- ): Set<unknown> {
146
- const result = assignIndexedValue(ctx, node.i, new Set<unknown>());
147
- const items = node.a;
148
- for (let i = 0, len = node.l; i < len; i++) {
149
- result.add(deserializeTree(ctx, items[i]));
150
- }
151
- return result;
152
- }
153
-
154
- function deserializeMap(
155
- ctx: DeserializerContext,
156
- node: SerovalMapNode,
157
- ): Map<unknown, unknown> {
158
- const result = assignIndexedValue(
159
- ctx,
160
- node.i,
161
- new Map<unknown, unknown>(),
162
- );
163
- const keys = node.e.k;
164
- const vals = node.e.v;
165
- for (let i = 0, len = node.e.s; i < len; i++) {
166
- result.set(
167
- deserializeTree(ctx, keys[i]),
168
- deserializeTree(ctx, vals[i]),
169
- );
170
- }
171
- return result;
172
- }
173
-
174
64
  type AssignableValue = AggregateError | Error | Iterable<unknown>
175
65
  type AssignableNode = SerovalAggregateErrorNode | SerovalErrorNode;
176
66
 
177
- function deserializeDictionary<T extends AssignableValue>(
178
- ctx: DeserializerContext,
179
- node: AssignableNode,
180
- result: T,
181
- ): T {
182
- if (node.p) {
183
- const fields = deserializeProperties(ctx, node.p, {});
184
- Object.assign(result, fields);
185
- }
186
- return result;
187
- }
188
-
189
- function deserializeAggregateError(
190
- ctx: DeserializerContext,
191
- node: SerovalAggregateErrorNode,
192
- ): AggregateError {
193
- // Serialize the required arguments
194
- const result = assignIndexedValue(
195
- ctx,
196
- node.i,
197
- new AggregateError([], deserializeString(node.m)),
198
- );
199
- // `AggregateError` might've been extended
200
- // either through class or custom properties
201
- // Make sure to assign extra properties
202
- return deserializeDictionary(ctx, node, result);
203
- }
204
-
205
- function deserializeError(
206
- ctx: DeserializerContext,
207
- node: SerovalErrorNode,
208
- ): Error {
209
- const ErrorConstructor = getErrorConstructor(node.c);
210
- const result = assignIndexedValue(ctx, node.i, new ErrorConstructor(deserializeString(node.m)));
211
- return deserializeDictionary(ctx, node, result);
212
- }
213
-
214
67
  interface Deferred {
215
68
  resolve(value: unknown): void;
216
69
  reject(value: unknown): void;
@@ -234,297 +87,447 @@ function createDeferred(): Deferred {
234
87
  };
235
88
  }
236
89
 
237
- async function deserializePromise(
238
- ctx: DeserializerContext,
239
- node: SerovalPromiseNode,
240
- ): Promise<unknown> {
241
- const deferred = createDeferred();
242
- const result = assignIndexedValue(ctx, node.i, deferred.promise);
243
- const deserialized = deserializeTree(ctx, node.f);
244
- if (node.s) {
245
- deferred.resolve(deserialized);
246
- } else {
247
- deferred.reject(deserialized);
248
- }
249
- return result;
90
+ export interface DeserializerOptions extends PluginAccessOptions {
91
+ markedRefs: number[] | Set<number>;
250
92
  }
251
93
 
252
- function deserializeArrayBuffer(
253
- ctx: DeserializerContext,
254
- node: SerovalArrayBufferNode,
255
- ): ArrayBuffer {
256
- const bytes = new Uint8Array(node.s);
257
- const result = assignIndexedValue(ctx, node.i, bytes.buffer);
258
- return result;
259
- }
94
+ export default class VanillaDeserializerContext implements PluginAccessOptions {
95
+ /**
96
+ * Mapping ids to values
97
+ * @private
98
+ */
99
+ values: Map<number, unknown> = new Map();
260
100
 
261
- function deserializeTypedArray(
262
- ctx: DeserializerContext,
263
- node: SerovalTypedArrayNode | SerovalBigIntTypedArrayNode,
264
- ): TypedArrayValue | BigIntTypedArrayValue {
265
- const TypedArray = getTypedArrayConstructor(node.c);
266
- const source = deserializeTree(ctx, node.f) as ArrayBuffer;
267
- const result = assignIndexedValue(ctx, node.i, new TypedArray(
268
- source,
269
- node.b,
270
- node.l,
271
- ));
272
- return result;
273
- }
101
+ /**
102
+ * Which refs are pre-marked
103
+ * @private
104
+ */
105
+ refs: Set<number>;
274
106
 
275
- function deserializeDate(
276
- ctx: DeserializerContext,
277
- node: SerovalDateNode,
278
- ): Date {
279
- return assignIndexedValue(ctx, node.i, new Date(node.s));
280
- }
107
+ plugins?: Plugin<any, any>[] | undefined;
281
108
 
282
- function deserializeRegExp(
283
- ctx: DeserializerContext,
284
- node: SerovalRegExpNode,
285
- ): RegExp {
286
- return assignIndexedValue(ctx, node.i, new RegExp(node.c, node.m));
287
- }
109
+ constructor(options: DeserializerOptions) {
110
+ this.plugins = options.plugins;
111
+ this.refs = new Set(options.markedRefs);
112
+ }
288
113
 
289
- function deserializeURL(
290
- ctx: DeserializerContext,
291
- node: SerovalURLNode,
292
- ): URL {
293
- return assignIndexedValue(ctx, node.i, new URL(deserializeString(node.s)));
294
- }
114
+ assignIndexedValue<T>(
115
+ index: number,
116
+ value: T,
117
+ ): T {
118
+ if (this.refs.has(index)) {
119
+ this.values.set(index, value);
120
+ }
121
+ return value;
122
+ }
295
123
 
296
- function deserializeURLSearchParams(
297
- ctx: DeserializerContext,
298
- node: SerovalURLSearchParamsNode,
299
- ): URLSearchParams {
300
- return assignIndexedValue(ctx, node.i, new URLSearchParams(deserializeString(node.s)));
301
- }
124
+ private deserializeReference(
125
+ node: SerovalReferenceNode,
126
+ ): unknown {
127
+ return this.assignIndexedValue(node.i, getReference(deserializeString(node.s)));
128
+ }
302
129
 
303
- function deserializeReference(
304
- ctx: DeserializerContext,
305
- node: SerovalReferenceNode,
306
- ): unknown {
307
- return assignIndexedValue(ctx, node.i, getReference(deserializeString(node.s)));
308
- }
130
+ private deserializeArray(
131
+ node: SerovalArrayNode,
132
+ ): unknown[] {
133
+ const len = node.l;
134
+ const result: unknown[] = this.assignIndexedValue(
135
+ node.i,
136
+ new Array<unknown>(len),
137
+ );
138
+ let item: SerovalNode | undefined;
139
+ for (let i = 0; i < len; i++) {
140
+ item = node.a[i];
141
+ if (item) {
142
+ result[i] = this.deserialize(item);
143
+ }
144
+ }
145
+ applyObjectFlag(result, node.o);
146
+ return result;
147
+ }
309
148
 
310
- function deserializeDataView(
311
- ctx: DeserializerContext,
312
- node: SerovalDataViewNode,
313
- ): DataView {
314
- const source = deserializeTree(ctx, node.f) as ArrayBuffer;
315
- const result = assignIndexedValue(ctx, node.i, new DataView(
316
- source,
317
- node.b,
318
- node.l,
319
- ));
320
- return result;
321
- }
149
+ private deserializeProperties(
150
+ node: SerovalObjectRecordNode,
151
+ result: Record<string | symbol, unknown>,
152
+ ): Record<string | symbol, unknown> {
153
+ const len = node.s;
154
+ if (len) {
155
+ let key: SerovalObjectRecordKey;
156
+ let value: unknown;
157
+ const keys = node.k;
158
+ const vals = node.v;
159
+ for (let i = 0; i < len; i++) {
160
+ key = keys[i];
161
+ value = this.deserialize(vals[i]);
162
+ switch (key) {
163
+ case SerovalObjectRecordSpecialKey.SymbolIterator: {
164
+ const current = value as unknown[];
165
+ result[Symbol.iterator] = (): IterableIterator<unknown> => current.values();
166
+ }
167
+ break;
168
+ default:
169
+ result[deserializeString(key)] = value;
170
+ break;
171
+ }
172
+ }
173
+ }
174
+ return result;
175
+ }
322
176
 
323
- function deserializeBlob(
324
- ctx: DeserializerContext,
325
- node: SerovalBlobNode,
326
- ): Blob {
327
- const source = deserializeTree(ctx, node.f) as ArrayBuffer;
328
- const result = assignIndexedValue(ctx, node.i, new Blob(
329
- [source],
330
- { type: deserializeString(node.c) },
331
- ));
332
- return result;
333
- }
177
+ private deserializeObject(
178
+ node: SerovalObjectNode | SerovalNullConstructorNode,
179
+ ): Record<string, unknown> {
180
+ const result = this.assignIndexedValue(
181
+ node.i,
182
+ (node.t === SerovalNodeType.Object
183
+ ? {}
184
+ : Object.create(null)) as Record<string, unknown>,
185
+ );
186
+ this.deserializeProperties(node.p, result);
187
+ applyObjectFlag(result, node.o);
188
+ return result;
189
+ }
334
190
 
335
- function deserializeFile(
336
- ctx: DeserializerContext,
337
- node: SerovalFileNode,
338
- ): File {
339
- const source = deserializeTree(ctx, node.f) as ArrayBuffer;
340
- const result = assignIndexedValue(ctx, node.i, new File(
341
- [source],
342
- deserializeString(node.m),
343
- { type: deserializeString(node.c), lastModified: node.b },
344
- ));
345
- return result;
346
- }
191
+ private deserializeDate(
192
+ node: SerovalDateNode,
193
+ ): Date {
194
+ return this.assignIndexedValue(node.i, new Date(node.s));
195
+ }
347
196
 
348
- function deserializeHeaders(
349
- ctx: DeserializerContext,
350
- node: SerovalHeadersNode,
351
- ): Headers {
352
- const result = assignIndexedValue(ctx, node.i, new Headers());
353
- const keys = node.e.k;
354
- const vals = node.e.v;
355
- for (let i = 0, len = node.e.s; i < len; i++) {
356
- result.set(
357
- deserializeString(keys[i]),
358
- deserializeTree(ctx, vals[i]) as string,
197
+ private deserializeRegExp(
198
+ node: SerovalRegExpNode,
199
+ ): RegExp {
200
+ return this.assignIndexedValue(node.i, new RegExp(node.c, node.m));
201
+ }
202
+
203
+ private deserializeSet(
204
+ node: SerovalSetNode,
205
+ ): Set<unknown> {
206
+ const result = this.assignIndexedValue(node.i, new Set<unknown>());
207
+ const items = node.a;
208
+ for (let i = 0, len = node.l; i < len; i++) {
209
+ result.add(this.deserialize(items[i]));
210
+ }
211
+ return result;
212
+ }
213
+
214
+ private deserializeMap(
215
+ node: SerovalMapNode,
216
+ ): Map<unknown, unknown> {
217
+ const result = this.assignIndexedValue(
218
+ node.i,
219
+ new Map<unknown, unknown>(),
359
220
  );
221
+ const keys = node.e.k;
222
+ const vals = node.e.v;
223
+ for (let i = 0, len = node.e.s; i < len; i++) {
224
+ result.set(
225
+ this.deserialize(keys[i]),
226
+ this.deserialize(vals[i]),
227
+ );
228
+ }
229
+ return result;
230
+ }
231
+
232
+ private deserializeArrayBuffer(
233
+ node: SerovalArrayBufferNode,
234
+ ): ArrayBuffer {
235
+ const bytes = new Uint8Array(node.s);
236
+ const result = this.assignIndexedValue(node.i, bytes.buffer);
237
+ return result;
238
+ }
239
+
240
+ private deserializeTypedArray(
241
+ node: SerovalTypedArrayNode | SerovalBigIntTypedArrayNode,
242
+ ): TypedArrayValue | BigIntTypedArrayValue {
243
+ const TypedArray = getTypedArrayConstructor(node.c);
244
+ const source = this.deserialize(node.f) as ArrayBuffer;
245
+ const result = this.assignIndexedValue(node.i, new TypedArray(
246
+ source,
247
+ node.b,
248
+ node.l,
249
+ ));
250
+ return result;
360
251
  }
361
- return result;
362
- }
363
252
 
364
- function deserializeFormData(
365
- ctx: DeserializerContext,
366
- node: SerovalFormDataNode,
367
- ): FormData {
368
- const result = assignIndexedValue(ctx, node.i, new FormData());
369
- const keys = node.e.k;
370
- const vals = node.e.v;
371
- for (let i = 0, len = node.e.s; i < len; i++) {
372
- result.set(
373
- deserializeString(keys[i]),
374
- deserializeTree(ctx, vals[i]) as FormDataEntryValue,
253
+ private deserializeDataView(
254
+ node: SerovalDataViewNode,
255
+ ): DataView {
256
+ const source = this.deserialize(node.f) as ArrayBuffer;
257
+ const result = this.assignIndexedValue(node.i, new DataView(
258
+ source,
259
+ node.b,
260
+ node.l,
261
+ ));
262
+ return result;
263
+ }
264
+
265
+ private deserializeDictionary<T extends AssignableValue>(
266
+ node: AssignableNode,
267
+ result: T,
268
+ ): T {
269
+ if (node.p) {
270
+ const fields = this.deserializeProperties(node.p, {});
271
+ Object.assign(result, fields);
272
+ }
273
+ return result;
274
+ }
275
+
276
+ private deserializeAggregateError(
277
+ node: SerovalAggregateErrorNode,
278
+ ): AggregateError {
279
+ // Serialize the required arguments
280
+ const result = this.assignIndexedValue(
281
+ node.i,
282
+ new AggregateError([], deserializeString(node.m)),
375
283
  );
284
+ // `AggregateError` might've been extended
285
+ // either through class or custom properties
286
+ // Make sure to assign extra properties
287
+ return this.deserializeDictionary(node, result);
376
288
  }
377
- return result;
378
- }
379
289
 
380
- function deserializeBoxed(
381
- ctx: DeserializerContext,
382
- node: SerovalBoxedNode,
383
- ): unknown {
384
- return assignIndexedValue(
385
- ctx,
386
- node.i,
387
- Object(deserializeTree(ctx, node.f)),
388
- );
389
- }
290
+ private deserializeError(
291
+ node: SerovalErrorNode,
292
+ ): Error {
293
+ const ErrorConstructor = ERROR_CONSTRUCTOR[node.s];
294
+ const result = this.assignIndexedValue(
295
+ node.i,
296
+ new ErrorConstructor(deserializeString(node.m)),
297
+ );
298
+ return this.deserializeDictionary(node, result);
299
+ }
390
300
 
391
- function deserializeRequest(
392
- ctx: DeserializerContext,
393
- node: SerovalRequestNode,
394
- ): Request {
395
- return assignIndexedValue(
396
- ctx,
397
- node.i,
398
- new Request(deserializeString(node.s), deserializeTree(ctx, node.f) as RequestInit),
399
- );
400
- }
301
+ private async deserializePromise(
302
+ node: SerovalPromiseNode,
303
+ ): Promise<unknown> {
304
+ const deferred = createDeferred();
305
+ const result = this.assignIndexedValue(node.i, deferred.promise);
306
+ const deserialized = this.deserialize(node.f);
307
+ if (node.s) {
308
+ deferred.resolve(deserialized);
309
+ } else {
310
+ deferred.reject(deserialized);
311
+ }
312
+ return result;
313
+ }
401
314
 
402
- function deserializeResponse(
403
- ctx: DeserializerContext,
404
- node: SerovalResponseNode,
405
- ): Response {
406
- return assignIndexedValue(
407
- ctx,
408
- node.i,
409
- new Response(
410
- deserializeTree(ctx, node.a[0]) as BodyInit,
411
- deserializeTree(ctx, node.a[1]) as RequestInit,
412
- ),
413
- );
414
- }
315
+ private deserializeURL(
316
+ node: SerovalURLNode,
317
+ ): URL {
318
+ return this.assignIndexedValue(node.i, new URL(deserializeString(node.s)));
319
+ }
415
320
 
416
- function deserializeEvent(
417
- ctx: DeserializerContext,
418
- node: SerovalEventNode,
419
- ): Event {
420
- return assignIndexedValue(
421
- ctx,
422
- node.i,
423
- new Event(
424
- deserializeString(node.s),
425
- deserializeTree(ctx, node.f) as EventInit,
426
- ),
427
- );
428
- }
321
+ private deserializeURLSearchParams(
322
+ node: SerovalURLSearchParamsNode,
323
+ ): URLSearchParams {
324
+ return this.assignIndexedValue(node.i, new URLSearchParams(deserializeString(node.s)));
325
+ }
429
326
 
430
- function deserializeCustomEvent(
431
- ctx: DeserializerContext,
432
- node: SerovalCustomEventNode,
433
- ): CustomEvent {
434
- return assignIndexedValue(
435
- ctx,
436
- node.i,
437
- new CustomEvent(
438
- deserializeString(node.s),
439
- deserializeTree(ctx, node.f) as CustomEventInit,
440
- ),
441
- );
442
- }
327
+ private deserializeBlob(
328
+ node: SerovalBlobNode,
329
+ ): Blob {
330
+ const source = this.deserialize(node.f) as ArrayBuffer;
331
+ const result = this.assignIndexedValue(node.i, new Blob(
332
+ [source],
333
+ { type: deserializeString(node.c) },
334
+ ));
335
+ return result;
336
+ }
443
337
 
444
- function deserializeDOMException(
445
- ctx: DeserializerContext,
446
- node: SerovalDOMExceptionNode,
447
- ): DOMException {
448
- return assignIndexedValue(
449
- ctx,
450
- node.i,
451
- new DOMException(
452
- deserializeString(node.s),
453
- deserializeString(node.c),
454
- ),
455
- );
456
- }
338
+ private deserializeFile(
339
+ node: SerovalFileNode,
340
+ ): File {
341
+ const source = this.deserialize(node.f) as ArrayBuffer;
342
+ const result = this.assignIndexedValue(node.i, new File(
343
+ [source],
344
+ deserializeString(node.m),
345
+ { type: deserializeString(node.c), lastModified: node.b },
346
+ ));
347
+ return result;
348
+ }
457
349
 
458
- export default function deserializeTree(
459
- ctx: DeserializerContext,
460
- node: SerovalNode,
461
- ): unknown {
462
- switch (node.t) {
463
- case SerovalNodeType.Constant:
464
- return deserializeConstant(node);
465
- case SerovalNodeType.Number:
466
- return node.s;
467
- case SerovalNodeType.String:
468
- return deserializeString(node.s);
469
- case SerovalNodeType.BigInt:
470
- return BigInt(node.s);
471
- case SerovalNodeType.IndexedValue:
472
- return ctx.values.get(node.i);
473
- case SerovalNodeType.Array:
474
- return deserializeArray(ctx, node);
475
- case SerovalNodeType.Object:
476
- case SerovalNodeType.NullConstructor:
477
- return deserializeObject(ctx, node);
478
- case SerovalNodeType.Date:
479
- return deserializeDate(ctx, node);
480
- case SerovalNodeType.RegExp:
481
- return deserializeRegExp(ctx, node);
482
- case SerovalNodeType.Set:
483
- return deserializeSet(ctx, node);
484
- case SerovalNodeType.Map:
485
- return deserializeMap(ctx, node);
486
- case SerovalNodeType.ArrayBuffer:
487
- return deserializeArrayBuffer(ctx, node);
488
- case SerovalNodeType.BigIntTypedArray:
489
- case SerovalNodeType.TypedArray:
490
- return deserializeTypedArray(ctx, node);
491
- case SerovalNodeType.DataView:
492
- return deserializeDataView(ctx, node);
493
- case SerovalNodeType.AggregateError:
494
- return deserializeAggregateError(ctx, node);
495
- case SerovalNodeType.Error:
496
- return deserializeError(ctx, node);
497
- case SerovalNodeType.Promise:
498
- return deserializePromise(ctx, node);
499
- case SerovalNodeType.WKSymbol:
500
- return SYMBOL_REF[node.s];
501
- case SerovalNodeType.URL:
502
- return deserializeURL(ctx, node);
503
- case SerovalNodeType.URLSearchParams:
504
- return deserializeURLSearchParams(ctx, node);
505
- case SerovalNodeType.Reference:
506
- return deserializeReference(ctx, node);
507
- case SerovalNodeType.Blob:
508
- return deserializeBlob(ctx, node);
509
- case SerovalNodeType.File:
510
- return deserializeFile(ctx, node);
511
- case SerovalNodeType.Headers:
512
- return deserializeHeaders(ctx, node);
513
- case SerovalNodeType.FormData:
514
- return deserializeFormData(ctx, node);
515
- case SerovalNodeType.Boxed:
516
- return deserializeBoxed(ctx, node);
517
- case SerovalNodeType.Request:
518
- return deserializeRequest(ctx, node);
519
- case SerovalNodeType.Response:
520
- return deserializeResponse(ctx, node);
521
- case SerovalNodeType.Event:
522
- return deserializeEvent(ctx, node);
523
- case SerovalNodeType.CustomEvent:
524
- return deserializeCustomEvent(ctx, node);
525
- case SerovalNodeType.DOMException:
526
- return deserializeDOMException(ctx, node);
527
- default:
528
- throw new Error('invariant');
350
+ private deserializeHeaders(
351
+ node: SerovalHeadersNode,
352
+ ): Headers {
353
+ const result = this.assignIndexedValue(node.i, new Headers());
354
+ const keys = node.e.k;
355
+ const vals = node.e.v;
356
+ for (let i = 0, len = node.e.s; i < len; i++) {
357
+ result.set(
358
+ deserializeString(keys[i]),
359
+ this.deserialize(vals[i]) as string,
360
+ );
361
+ }
362
+ return result;
363
+ }
364
+
365
+ private deserializeFormData(
366
+ node: SerovalFormDataNode,
367
+ ): FormData {
368
+ const result = this.assignIndexedValue(node.i, new FormData());
369
+ const keys = node.e.k;
370
+ const vals = node.e.v;
371
+ for (let i = 0, len = node.e.s; i < len; i++) {
372
+ result.set(
373
+ deserializeString(keys[i]),
374
+ this.deserialize(vals[i]) as FormDataEntryValue,
375
+ );
376
+ }
377
+ return result;
378
+ }
379
+
380
+ private deserializeBoxed(
381
+ node: SerovalBoxedNode,
382
+ ): unknown {
383
+ return this.assignIndexedValue(
384
+ node.i,
385
+ Object(this.deserialize(node.f)),
386
+ );
387
+ }
388
+
389
+ private deserializeRequest(
390
+ node: SerovalRequestNode,
391
+ ): Request {
392
+ return this.assignIndexedValue(
393
+ node.i,
394
+ new Request(deserializeString(node.s), this.deserialize(node.f) as RequestInit),
395
+ );
396
+ }
397
+
398
+ private deserializeResponse(
399
+ node: SerovalResponseNode,
400
+ ): Response {
401
+ return this.assignIndexedValue(
402
+ node.i,
403
+ new Response(
404
+ this.deserialize(node.a[0]) as BodyInit,
405
+ this.deserialize(node.a[1]) as RequestInit,
406
+ ),
407
+ );
408
+ }
409
+
410
+ private deserializeEvent(
411
+ node: SerovalEventNode,
412
+ ): Event {
413
+ return this.assignIndexedValue(
414
+ node.i,
415
+ new Event(
416
+ deserializeString(node.s),
417
+ this.deserialize(node.f) as EventInit,
418
+ ),
419
+ );
420
+ }
421
+
422
+ private deserializeCustomEvent(
423
+ node: SerovalCustomEventNode,
424
+ ): CustomEvent {
425
+ return this.assignIndexedValue(
426
+ node.i,
427
+ new CustomEvent(
428
+ deserializeString(node.s),
429
+ this.deserialize(node.f) as CustomEventInit,
430
+ ),
431
+ );
432
+ }
433
+
434
+ private deserializeDOMException(
435
+ node: SerovalDOMExceptionNode,
436
+ ): DOMException {
437
+ return this.assignIndexedValue(
438
+ node.i,
439
+ new DOMException(
440
+ deserializeString(node.s),
441
+ deserializeString(node.c),
442
+ ),
443
+ );
444
+ }
445
+
446
+ private deserializePlugin(node: SerovalPluginNode): unknown {
447
+ const currentPlugins = this.plugins;
448
+ if (currentPlugins) {
449
+ for (let i = 0, len = currentPlugins.length; i < len; i++) {
450
+ const plugin = currentPlugins[i];
451
+ if (plugin.tag === node.c) {
452
+ return plugin.deserialize(node.s, this, {
453
+ id: node.i,
454
+ });
455
+ }
456
+ }
457
+ }
458
+ throw new Error('Missing plugin for tag "' + node.c + '".');
459
+ }
460
+
461
+ deserialize(node: SerovalNode): unknown {
462
+ switch (node.t) {
463
+ case SerovalNodeType.Constant:
464
+ return CONSTANT_VAL[node.s];
465
+ case SerovalNodeType.Number:
466
+ return node.s;
467
+ case SerovalNodeType.String:
468
+ return deserializeString(node.s);
469
+ case SerovalNodeType.BigInt:
470
+ return BigInt(node.s);
471
+ case SerovalNodeType.IndexedValue:
472
+ return this.values.get(node.i);
473
+ case SerovalNodeType.Reference:
474
+ return this.deserializeReference(node);
475
+ case SerovalNodeType.Array:
476
+ return this.deserializeArray(node);
477
+ case SerovalNodeType.Object:
478
+ case SerovalNodeType.NullConstructor:
479
+ return this.deserializeObject(node);
480
+ case SerovalNodeType.Date:
481
+ return this.deserializeDate(node);
482
+ case SerovalNodeType.RegExp:
483
+ return this.deserializeRegExp(node);
484
+ case SerovalNodeType.Set:
485
+ return this.deserializeSet(node);
486
+ case SerovalNodeType.Map:
487
+ return this.deserializeMap(node);
488
+ case SerovalNodeType.ArrayBuffer:
489
+ return this.deserializeArrayBuffer(node);
490
+ case SerovalNodeType.BigIntTypedArray:
491
+ case SerovalNodeType.TypedArray:
492
+ return this.deserializeTypedArray(node);
493
+ case SerovalNodeType.DataView:
494
+ return this.deserializeDataView(node);
495
+ case SerovalNodeType.AggregateError:
496
+ return this.deserializeAggregateError(node);
497
+ case SerovalNodeType.Error:
498
+ return this.deserializeError(node);
499
+ case SerovalNodeType.Promise:
500
+ return this.deserializePromise(node);
501
+ case SerovalNodeType.WKSymbol:
502
+ return SYMBOL_REF[node.s];
503
+ case SerovalNodeType.URL:
504
+ return this.deserializeURL(node);
505
+ case SerovalNodeType.URLSearchParams:
506
+ return this.deserializeURLSearchParams(node);
507
+ case SerovalNodeType.Blob:
508
+ return this.deserializeBlob(node);
509
+ case SerovalNodeType.File:
510
+ return this.deserializeFile(node);
511
+ case SerovalNodeType.Headers:
512
+ return this.deserializeHeaders(node);
513
+ case SerovalNodeType.FormData:
514
+ return this.deserializeFormData(node);
515
+ case SerovalNodeType.Boxed:
516
+ return this.deserializeBoxed(node);
517
+ case SerovalNodeType.Request:
518
+ return this.deserializeRequest(node);
519
+ case SerovalNodeType.Response:
520
+ return this.deserializeResponse(node);
521
+ case SerovalNodeType.Event:
522
+ return this.deserializeEvent(node);
523
+ case SerovalNodeType.CustomEvent:
524
+ return this.deserializeCustomEvent(node);
525
+ case SerovalNodeType.DOMException:
526
+ return this.deserializeDOMException(node);
527
+ case SerovalNodeType.Plugin:
528
+ return this.deserializePlugin(node);
529
+ default:
530
+ throw new Error('invariant');
531
+ }
529
532
  }
530
533
  }