seroval 1.3.2 → 1.4.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 (112) hide show
  1. package/dist/cjs/development/index.cjs +2640 -2683
  2. package/dist/cjs/development/index.cjs.map +4 -4
  3. package/dist/cjs/production/index.cjs +3 -17
  4. package/dist/esm/development/index.mjs +2640 -2683
  5. package/dist/esm/development/index.mjs.map +4 -4
  6. package/dist/esm/production/index.mjs +3 -17
  7. package/dist/types/core/base-primitives.d.ts +1 -2
  8. package/dist/types/core/base-primitives.d.ts.map +1 -1
  9. package/dist/types/core/compat.d.ts +1 -1
  10. package/dist/types/core/compat.d.ts.map +1 -1
  11. package/dist/types/core/constants.d.ts +1 -0
  12. package/dist/types/core/constants.d.ts.map +1 -1
  13. package/dist/types/core/constructors.d.ts +54 -0
  14. package/dist/types/core/constructors.d.ts.map +1 -0
  15. package/dist/types/core/context/async-parser.d.ts +19 -0
  16. package/dist/types/core/context/async-parser.d.ts.map +1 -0
  17. package/dist/types/core/context/deserializer.d.ts +35 -38
  18. package/dist/types/core/context/deserializer.d.ts.map +1 -1
  19. package/dist/types/core/context/parser.d.ts +32 -19
  20. package/dist/types/core/context/parser.d.ts.map +1 -1
  21. package/dist/types/core/context/serializer.d.ts +38 -99
  22. package/dist/types/core/context/serializer.d.ts.map +1 -1
  23. package/dist/types/core/context/sync-parser.d.ts +59 -0
  24. package/dist/types/core/context/sync-parser.d.ts.map +1 -0
  25. package/dist/types/core/cross/index.d.ts +12 -13
  26. package/dist/types/core/cross/index.d.ts.map +1 -1
  27. package/dist/types/core/errors.d.ts.map +1 -1
  28. package/dist/types/core/function-string.d.ts +2 -2
  29. package/dist/types/core/function-string.d.ts.map +1 -1
  30. package/dist/types/core/plugin.d.ts +13 -11
  31. package/dist/types/core/plugin.d.ts.map +1 -1
  32. package/dist/types/core/reference.d.ts.map +1 -1
  33. package/dist/types/core/special-reference.d.ts +3 -2
  34. package/dist/types/core/special-reference.d.ts.map +1 -1
  35. package/dist/types/core/stream.d.ts +1 -2
  36. package/dist/types/core/stream.d.ts.map +1 -1
  37. package/dist/types/core/symbols.d.ts +14 -0
  38. package/dist/types/core/symbols.d.ts.map +1 -0
  39. package/dist/types/core/tree/index.d.ts +3 -2
  40. package/dist/types/core/tree/index.d.ts.map +1 -1
  41. package/dist/types/core/types.d.ts +3 -1
  42. package/dist/types/core/types.d.ts.map +1 -1
  43. package/dist/types/core/utils/iterator-to-sequence.d.ts.map +1 -1
  44. package/dist/types/index.d.ts +10 -5
  45. package/dist/types/index.d.ts.map +1 -1
  46. package/package.json +17 -19
  47. package/src/core/base-primitives.ts +0 -27
  48. package/src/core/compat.ts +2 -1
  49. package/src/core/constants.ts +28 -26
  50. package/src/core/constructors.ts +269 -0
  51. package/src/core/context/async-parser.ts +586 -0
  52. package/src/core/context/deserializer.ts +506 -316
  53. package/src/core/context/parser.ts +243 -180
  54. package/src/core/context/serializer.ts +1058 -827
  55. package/src/core/context/sync-parser.ts +833 -0
  56. package/src/core/cross/index.ts +63 -47
  57. package/src/core/errors.ts +73 -12
  58. package/src/core/function-string.ts +11 -10
  59. package/src/core/plugin.ts +20 -11
  60. package/src/core/reference.ts +8 -5
  61. package/src/core/special-reference.ts +18 -90
  62. package/src/core/stream.ts +18 -152
  63. package/src/core/symbols.ts +18 -0
  64. package/src/core/tree/index.ts +45 -31
  65. package/src/core/types.ts +7 -2
  66. package/src/core/utils/iterator-to-sequence.ts +6 -28
  67. package/src/index.ts +29 -11
  68. package/dist/types/core/context/parser/async.d.ts +0 -24
  69. package/dist/types/core/context/parser/async.d.ts.map +0 -1
  70. package/dist/types/core/context/parser/stream.d.ts +0 -43
  71. package/dist/types/core/context/parser/stream.d.ts.map +0 -1
  72. package/dist/types/core/context/parser/sync.d.ts +0 -30
  73. package/dist/types/core/context/parser/sync.d.ts.map +0 -1
  74. package/dist/types/core/cross/async.d.ts +0 -8
  75. package/dist/types/core/cross/async.d.ts.map +0 -1
  76. package/dist/types/core/cross/deserializer.d.ts +0 -9
  77. package/dist/types/core/cross/deserializer.d.ts.map +0 -1
  78. package/dist/types/core/cross/parser.d.ts +0 -6
  79. package/dist/types/core/cross/parser.d.ts.map +0 -1
  80. package/dist/types/core/cross/serializer.d.ts +0 -16
  81. package/dist/types/core/cross/serializer.d.ts.map +0 -1
  82. package/dist/types/core/cross/stream.d.ts +0 -8
  83. package/dist/types/core/cross/stream.d.ts.map +0 -1
  84. package/dist/types/core/cross/sync.d.ts +0 -8
  85. package/dist/types/core/cross/sync.d.ts.map +0 -1
  86. package/dist/types/core/tree/async.d.ts +0 -8
  87. package/dist/types/core/tree/async.d.ts.map +0 -1
  88. package/dist/types/core/tree/deserializer.d.ts +0 -13
  89. package/dist/types/core/tree/deserializer.d.ts.map +0 -1
  90. package/dist/types/core/tree/serializer.d.ts +0 -29
  91. package/dist/types/core/tree/serializer.d.ts.map +0 -1
  92. package/dist/types/core/tree/sync.d.ts +0 -8
  93. package/dist/types/core/tree/sync.d.ts.map +0 -1
  94. package/dist/types/core/utils/assert.d.ts +0 -2
  95. package/dist/types/core/utils/assert.d.ts.map +0 -1
  96. package/dist/types/core/utils/deferred.d.ts +0 -7
  97. package/dist/types/core/utils/deferred.d.ts.map +0 -1
  98. package/src/core/context/parser/async.ts +0 -495
  99. package/src/core/context/parser/stream.ts +0 -323
  100. package/src/core/context/parser/sync.ts +0 -404
  101. package/src/core/cross/async.ts +0 -9
  102. package/src/core/cross/deserializer.ts +0 -16
  103. package/src/core/cross/parser.ts +0 -7
  104. package/src/core/cross/serializer.ts +0 -72
  105. package/src/core/cross/stream.ts +0 -9
  106. package/src/core/cross/sync.ts +0 -9
  107. package/src/core/tree/async.ts +0 -9
  108. package/src/core/tree/deserializer.ts +0 -26
  109. package/src/core/tree/serializer.ts +0 -98
  110. package/src/core/tree/sync.ts +0 -9
  111. package/src/core/utils/assert.ts +0 -5
  112. package/src/core/utils/deferred.ts +0 -22
@@ -1,17 +1,23 @@
1
1
  import {
2
2
  CONSTANT_VAL,
3
3
  ERROR_CONSTRUCTOR,
4
- SYMBOL_REF,
5
4
  SerovalNodeType,
6
5
  SerovalObjectFlags,
6
+ SYMBOL_REF,
7
7
  } from '../constants';
8
+ import {
9
+ ARRAY_BUFFER_CONSTRUCTOR,
10
+ PROMISE_CONSTRUCTOR,
11
+ type PromiseConstructorResolver,
12
+ } from '../constructors';
8
13
  import {
9
14
  SerovalDeserializationError,
10
15
  SerovalMissingInstanceError,
11
16
  SerovalMissingPluginError,
12
17
  SerovalUnsupportedNodeError,
13
18
  } from '../errors';
14
- import type { Plugin, PluginAccessOptions, SerovalMode } from '../plugin';
19
+ import type { PluginAccessOptions } from '../plugin';
20
+ import { SerovalMode } from '../plugin';
15
21
  import { getReference } from '../reference';
16
22
  import type { Stream } from '../stream';
17
23
  import { createStream, streamToAsyncIterable } from '../stream';
@@ -49,9 +55,6 @@ import type {
49
55
  SerovalStreamThrowNode,
50
56
  SerovalTypedArrayNode,
51
57
  } from '../types';
52
- import assert from '../utils/assert';
53
- import type { Deferred } from '../utils/deferred';
54
- import { createDeferred } from '../utils/deferred';
55
58
  import type { Sequence } from '../utils/iterator-to-sequence';
56
59
  import { sequenceToIterator } from '../utils/iterator-to-sequence';
57
60
  import type {
@@ -76,381 +79,568 @@ function applyObjectFlag(obj: unknown, flag: SerovalObjectFlags): unknown {
76
79
  type AssignableValue = AggregateError | Error | Iterable<unknown>;
77
80
  type AssignableNode = SerovalAggregateErrorNode | SerovalErrorNode;
78
81
 
79
- export interface BaseDeserializerOptions extends PluginAccessOptions {
82
+ export interface BaseDeserializerContextOptions extends PluginAccessOptions {
80
83
  refs?: Map<number, unknown>;
81
84
  }
82
85
 
83
- export default abstract class BaseDeserializerContext
84
- implements PluginAccessOptions
85
- {
86
- abstract readonly mode: SerovalMode;
87
-
86
+ export interface BaseDeserializerContext extends PluginAccessOptions {
87
+ readonly mode: SerovalMode;
88
88
  /**
89
89
  * Mapping ids to values
90
- * @private
91
90
  */
92
91
  refs: Map<number, unknown>;
92
+ }
93
93
 
94
- plugins?: Plugin<any, any>[] | undefined;
94
+ export function createBaseDeserializerContext(
95
+ mode: SerovalMode,
96
+ options: BaseDeserializerContextOptions,
97
+ ): BaseDeserializerContext {
98
+ return {
99
+ mode,
100
+ plugins: options.plugins,
101
+ refs: options.refs || new Map(),
102
+ };
103
+ }
95
104
 
96
- constructor(options: BaseDeserializerOptions) {
97
- this.plugins = options.plugins;
98
- this.refs = options.refs || new Map<number, unknown>();
99
- }
105
+ export interface VanillaDeserializerContextOptions
106
+ extends Omit<BaseDeserializerContextOptions, 'refs'> {
107
+ markedRefs: number[] | Set<number>;
108
+ }
100
109
 
101
- protected abstract assignIndexedValue<T>(id: number, value: T): T;
110
+ export interface VanillaDeserializerState {
111
+ marked: Set<number>;
112
+ }
102
113
 
103
- private deserializeReference(node: SerovalReferenceNode): unknown {
104
- return this.assignIndexedValue(
105
- node.i,
106
- getReference(deserializeString(node.s)),
107
- );
108
- }
114
+ export interface VanillaDeserializerContext {
115
+ mode: SerovalMode.Vanilla;
116
+ base: BaseDeserializerContext;
117
+ child: DeserializePluginContext | undefined;
118
+ state: VanillaDeserializerState;
119
+ }
109
120
 
110
- private deserializeArray(node: SerovalArrayNode): unknown[] {
111
- const len = node.l;
112
- const result: unknown[] = this.assignIndexedValue(
113
- node.i,
114
- new Array<unknown>(len),
115
- );
116
- let item: SerovalNode | undefined;
117
- for (let i = 0; i < len; i++) {
118
- item = node.a[i];
119
- if (item) {
120
- result[i] = this.deserialize(item);
121
- }
122
- }
123
- applyObjectFlag(result, node.o);
124
- return result;
125
- }
121
+ export function createVanillaDeserializerContext(
122
+ options: VanillaDeserializerContextOptions,
123
+ ): VanillaDeserializerContext {
124
+ return {
125
+ mode: SerovalMode.Vanilla,
126
+ base: createBaseDeserializerContext(SerovalMode.Vanilla, options),
127
+ child: undefined,
128
+ state: {
129
+ marked: new Set(options.markedRefs),
130
+ },
131
+ };
132
+ }
126
133
 
127
- private deserializeProperties(
128
- node: SerovalObjectRecordNode,
129
- result: Record<string | symbol, unknown>,
130
- ): Record<string | symbol, unknown> {
131
- const len = node.s;
132
- if (len) {
133
- const keys = node.k;
134
- const vals = node.v;
135
- for (let i = 0, key: SerovalObjectRecordKey; i < len; i++) {
136
- key = keys[i];
137
- if (typeof key === 'string') {
138
- result[deserializeString(key)] = this.deserialize(vals[i]);
139
- } else {
140
- result[this.deserialize(key) as symbol] = this.deserialize(vals[i]);
141
- }
142
- }
143
- }
144
- return result;
145
- }
134
+ export interface CrossDeserializerContext {
135
+ mode: SerovalMode.Cross;
136
+ base: BaseDeserializerContext;
137
+ child: DeserializePluginContext | undefined;
138
+ }
139
+
140
+ export type CrossDeserializerContextOptions = BaseDeserializerContextOptions;
146
141
 
147
- private deserializeObject(
148
- node: SerovalObjectNode | SerovalNullConstructorNode,
149
- ): Record<string, unknown> {
150
- const result = this.assignIndexedValue(
151
- node.i,
152
- (node.t === SerovalNodeType.Object ? {} : Object.create(null)) as Record<
153
- string,
154
- unknown
155
- >,
156
- );
157
- this.deserializeProperties(node.p, result);
158
- applyObjectFlag(result, node.o);
159
- return result;
142
+ export function createCrossDeserializerContext(
143
+ options: CrossDeserializerContextOptions,
144
+ ): CrossDeserializerContext {
145
+ return {
146
+ mode: SerovalMode.Cross,
147
+ base: createBaseDeserializerContext(SerovalMode.Cross, options),
148
+ child: undefined,
149
+ };
150
+ }
151
+
152
+ type DeserializerContext =
153
+ | VanillaDeserializerContext
154
+ | CrossDeserializerContext;
155
+
156
+ export class DeserializePluginContext {
157
+ constructor(private _p: DeserializerContext) {}
158
+
159
+ deserialize<T>(node: SerovalNode): T {
160
+ return deserialize(this._p, node) as T;
160
161
  }
162
+ }
161
163
 
162
- private deserializeDate(node: SerovalDateNode): Date {
163
- return this.assignIndexedValue(node.i, new Date(node.s));
164
+ function assignIndexedValueVanilla<T>(
165
+ ctx: VanillaDeserializerContext,
166
+ id: number,
167
+ value: T,
168
+ ): T {
169
+ if (ctx.state.marked.has(id)) {
170
+ ctx.base.refs.set(id, value);
164
171
  }
172
+ return value;
173
+ }
165
174
 
166
- private deserializeRegExp(node: SerovalRegExpNode): RegExp {
167
- return this.assignIndexedValue(
168
- node.i,
169
- new RegExp(deserializeString(node.c), node.m),
170
- );
175
+ function assignIndexedValueCross<T>(
176
+ ctx: CrossDeserializerContext,
177
+ id: number,
178
+ value: T,
179
+ ): T {
180
+ if (!ctx.base.refs.has(id)) {
181
+ ctx.base.refs.set(id, value);
171
182
  }
183
+ return value;
184
+ }
185
+
186
+ function assignIndexedValue<T>(
187
+ ctx: DeserializerContext,
188
+ id: number,
189
+ value: T,
190
+ ): T {
191
+ return ctx.mode === SerovalMode.Vanilla
192
+ ? assignIndexedValueVanilla(ctx, id, value)
193
+ : assignIndexedValueCross(ctx, id, value);
194
+ }
195
+
196
+ function deserializeReference(
197
+ ctx: DeserializerContext,
198
+ node: SerovalReferenceNode,
199
+ ): unknown {
200
+ return assignIndexedValue(
201
+ ctx,
202
+ node.i,
203
+ getReference(deserializeString(node.s)),
204
+ );
205
+ }
172
206
 
173
- private deserializeSet(node: SerovalSetNode): Set<unknown> {
174
- const result = this.assignIndexedValue(node.i, new Set<unknown>());
175
- const items = node.a;
176
- for (let i = 0, len = node.l; i < len; i++) {
177
- result.add(this.deserialize(items[i]));
207
+ function deserializeArray(
208
+ ctx: DeserializerContext,
209
+ node: SerovalArrayNode,
210
+ ): unknown[] {
211
+ const len = node.l;
212
+ const result: unknown[] = assignIndexedValue(
213
+ ctx,
214
+ node.i,
215
+ new Array<unknown>(len),
216
+ );
217
+ let item: SerovalNode | undefined;
218
+ for (let i = 0; i < len; i++) {
219
+ item = node.a[i];
220
+ if (item) {
221
+ result[i] = deserialize(ctx, item);
178
222
  }
179
- return result;
180
223
  }
224
+ applyObjectFlag(result, node.o);
225
+ return result;
226
+ }
181
227
 
182
- private deserializeMap(node: SerovalMapNode): Map<unknown, unknown> {
183
- const result = this.assignIndexedValue(node.i, new Map<unknown, unknown>());
184
- const keys = node.e.k;
185
- const vals = node.e.v;
186
- for (let i = 0, len = node.e.s; i < len; i++) {
187
- result.set(this.deserialize(keys[i]), this.deserialize(vals[i]));
228
+ function deserializeProperties(
229
+ ctx: DeserializerContext,
230
+ node: SerovalObjectRecordNode,
231
+ result: Record<string | symbol, unknown>,
232
+ ): Record<string | symbol, unknown> {
233
+ const len = node.s;
234
+ if (len) {
235
+ const keys = node.k;
236
+ const vals = node.v;
237
+ for (let i = 0, key: SerovalObjectRecordKey; i < len; i++) {
238
+ key = keys[i];
239
+ if (typeof key === 'string') {
240
+ result[deserializeString(key)] = deserialize(ctx, vals[i]);
241
+ } else {
242
+ result[deserialize(ctx, key) as symbol] = deserialize(ctx, vals[i]);
243
+ }
188
244
  }
189
- return result;
190
245
  }
246
+ return result;
247
+ }
191
248
 
192
- private deserializeArrayBuffer(node: SerovalArrayBufferNode): ArrayBuffer {
193
- const bytes = new Uint8Array(node.s);
194
- const result = this.assignIndexedValue(node.i, bytes.buffer);
195
- return result;
196
- }
249
+ function deserializeObject(
250
+ ctx: DeserializerContext,
251
+ node: SerovalObjectNode | SerovalNullConstructorNode,
252
+ ): Record<string, unknown> {
253
+ const result = assignIndexedValue(
254
+ ctx,
255
+ node.i,
256
+ (node.t === SerovalNodeType.Object ? {} : Object.create(null)) as Record<
257
+ string,
258
+ unknown
259
+ >,
260
+ );
261
+ deserializeProperties(ctx, node.p, result);
262
+ applyObjectFlag(result, node.o);
263
+ return result;
264
+ }
197
265
 
198
- private deserializeTypedArray(
199
- node: SerovalTypedArrayNode | SerovalBigIntTypedArrayNode,
200
- ): TypedArrayValue | BigIntTypedArrayValue {
201
- const construct = getTypedArrayConstructor(node.c) as Int8ArrayConstructor;
202
- const source = this.deserialize(node.f) as ArrayBuffer;
203
- const result = this.assignIndexedValue(
204
- node.i,
205
- new construct(source, node.b, node.l),
206
- );
207
- return result;
208
- }
266
+ function deserializeDate(
267
+ ctx: DeserializerContext,
268
+ node: SerovalDateNode,
269
+ ): Date {
270
+ return assignIndexedValue(ctx, node.i, new Date(node.s));
271
+ }
209
272
 
210
- private deserializeDataView(node: SerovalDataViewNode): DataView {
211
- const source = this.deserialize(node.f) as ArrayBuffer;
212
- const result = this.assignIndexedValue(
213
- node.i,
214
- new DataView(source, node.b, node.l),
215
- );
216
- return result;
217
- }
273
+ function deserializeRegExp(
274
+ ctx: DeserializerContext,
275
+ node: SerovalRegExpNode,
276
+ ): RegExp {
277
+ return assignIndexedValue(
278
+ ctx,
279
+ node.i,
280
+ new RegExp(deserializeString(node.c), node.m),
281
+ );
282
+ }
218
283
 
219
- private deserializeDictionary<T extends AssignableValue>(
220
- node: AssignableNode,
221
- result: T,
222
- ): T {
223
- if (node.p) {
224
- const fields = this.deserializeProperties(node.p, {});
225
- Object.assign(result, fields);
226
- }
227
- return result;
284
+ function deserializeSet(
285
+ ctx: DeserializerContext,
286
+ node: SerovalSetNode,
287
+ ): Set<unknown> {
288
+ const result = assignIndexedValue(ctx, node.i, new Set<unknown>());
289
+ const items = node.a;
290
+ for (let i = 0, len = node.l; i < len; i++) {
291
+ result.add(deserialize(ctx, items[i]));
228
292
  }
293
+ return result;
294
+ }
229
295
 
230
- private deserializeAggregateError(
231
- node: SerovalAggregateErrorNode,
232
- ): AggregateError {
233
- // Serialize the required arguments
234
- const result = this.assignIndexedValue(
235
- node.i,
236
- new AggregateError([], deserializeString(node.m)),
237
- );
238
- // `AggregateError` might've been extended
239
- // either through class or custom properties
240
- // Make sure to assign extra properties
241
- return this.deserializeDictionary(node, result);
242
- }
296
+ function deserializeMap(
297
+ ctx: DeserializerContext,
298
+ node: SerovalMapNode,
299
+ ): Map<unknown, unknown> {
300
+ const result = assignIndexedValue(ctx, node.i, new Map<unknown, unknown>());
301
+ const keys = node.e.k;
302
+ const vals = node.e.v;
303
+ for (let i = 0, len = node.e.s; i < len; i++) {
304
+ result.set(deserialize(ctx, keys[i]), deserialize(ctx, vals[i]));
305
+ }
306
+ return result;
307
+ }
243
308
 
244
- private deserializeError(node: SerovalErrorNode): Error {
245
- const construct = ERROR_CONSTRUCTOR[node.s];
246
- const result = this.assignIndexedValue(
247
- node.i,
248
- new construct(deserializeString(node.m)),
249
- );
250
- return this.deserializeDictionary(node, result);
251
- }
309
+ function deserializeArrayBuffer(
310
+ ctx: DeserializerContext,
311
+ node: SerovalArrayBufferNode,
312
+ ): ArrayBuffer {
313
+ const result = assignIndexedValue(
314
+ ctx,
315
+ node.i,
316
+ ARRAY_BUFFER_CONSTRUCTOR(node.l, deserializeString(node.s)),
317
+ );
318
+ return result;
319
+ }
252
320
 
253
- private deserializePromise(node: SerovalPromiseNode): Promise<unknown> {
254
- const deferred = createDeferred();
255
- const result = this.assignIndexedValue(node.i, deferred);
256
- const deserialized = this.deserialize(node.f);
257
- if (node.s) {
258
- deferred.resolve(deserialized);
259
- } else {
260
- deferred.reject(deserialized);
261
- }
262
- return result.promise;
263
- }
321
+ function deserializeTypedArray(
322
+ ctx: DeserializerContext,
323
+ node: SerovalTypedArrayNode | SerovalBigIntTypedArrayNode,
324
+ ): TypedArrayValue | BigIntTypedArrayValue {
325
+ const construct = getTypedArrayConstructor(node.c) as Int8ArrayConstructor;
326
+ const source = deserialize(ctx, node.f) as ArrayBuffer;
327
+ const result = assignIndexedValue(
328
+ ctx,
329
+ node.i,
330
+ new construct(source, node.b, node.l),
331
+ );
332
+ return result;
333
+ }
334
+
335
+ function deserializeDataView(
336
+ ctx: DeserializerContext,
337
+ node: SerovalDataViewNode,
338
+ ): DataView {
339
+ const source = deserialize(ctx, node.f) as ArrayBuffer;
340
+ const result = assignIndexedValue(
341
+ ctx,
342
+ node.i,
343
+ new DataView(source, node.b, node.l),
344
+ );
345
+ return result;
346
+ }
264
347
 
265
- private deserializeBoxed(node: SerovalBoxedNode): unknown {
266
- return this.assignIndexedValue(node.i, Object(this.deserialize(node.f)));
348
+ function deserializeDictionary<T extends AssignableValue>(
349
+ ctx: DeserializerContext,
350
+ node: AssignableNode,
351
+ result: T,
352
+ ): T {
353
+ if (node.p) {
354
+ const fields = deserializeProperties(ctx, node.p, {});
355
+ Object.assign(result, fields);
267
356
  }
357
+ return result;
358
+ }
359
+
360
+ function deserializeAggregateError(
361
+ ctx: DeserializerContext,
362
+ node: SerovalAggregateErrorNode,
363
+ ): AggregateError {
364
+ // Serialize the required arguments
365
+ const result = assignIndexedValue(
366
+ ctx,
367
+ node.i,
368
+ new AggregateError([], deserializeString(node.m)),
369
+ );
370
+ // `AggregateError` might've been extended
371
+ // either through class or custom properties
372
+ // Make sure to assign extra properties
373
+ return deserializeDictionary(ctx, node, result);
374
+ }
375
+
376
+ function deserializeError(
377
+ ctx: DeserializerContext,
378
+ node: SerovalErrorNode,
379
+ ): Error {
380
+ const construct = ERROR_CONSTRUCTOR[node.s];
381
+ const result = assignIndexedValue(
382
+ ctx,
383
+ node.i,
384
+ new construct(deserializeString(node.m)),
385
+ );
386
+ return deserializeDictionary(ctx, node, result);
387
+ }
268
388
 
269
- private deserializePlugin(node: SerovalPluginNode): unknown {
270
- const currentPlugins = this.plugins;
271
- if (currentPlugins) {
272
- const tag = deserializeString(node.c);
273
- for (let i = 0, len = currentPlugins.length; i < len; i++) {
274
- const plugin = currentPlugins[i];
275
- if (plugin.tag === tag) {
276
- return this.assignIndexedValue(
277
- node.i,
278
- plugin.deserialize(node.s, this, {
279
- id: node.i,
280
- }),
281
- );
389
+ function deserializePromise(
390
+ ctx: DeserializerContext,
391
+ node: SerovalPromiseNode,
392
+ ): Promise<unknown> {
393
+ const deferred = PROMISE_CONSTRUCTOR();
394
+ const result = assignIndexedValue(ctx, node.i, deferred.p);
395
+ const deserialized = deserialize(ctx, node.f);
396
+ if (node.s) {
397
+ deferred.s(deserialized);
398
+ } else {
399
+ deferred.f(deserialized);
400
+ }
401
+ return result;
402
+ }
403
+
404
+ function deserializeBoxed(
405
+ ctx: DeserializerContext,
406
+ node: SerovalBoxedNode,
407
+ ): unknown {
408
+ // biome-ignore lint/style/useConsistentBuiltinInstantiation: intended
409
+ return assignIndexedValue(ctx, node.i, Object(deserialize(ctx, node.f)));
410
+ }
411
+
412
+ function deserializePlugin(
413
+ ctx: DeserializerContext,
414
+ node: SerovalPluginNode,
415
+ ): unknown {
416
+ const currentPlugins = ctx.base.plugins;
417
+ if (currentPlugins) {
418
+ const tag = deserializeString(node.c);
419
+ for (let i = 0, len = currentPlugins.length; i < len; i++) {
420
+ const plugin = currentPlugins[i];
421
+ if (plugin.tag === tag) {
422
+ if (ctx.child == null) {
423
+ ctx.child = new DeserializePluginContext(ctx);
282
424
  }
425
+ return assignIndexedValue(
426
+ ctx,
427
+ node.i,
428
+ plugin.deserialize(node.s, ctx.child, {
429
+ id: node.i,
430
+ }),
431
+ );
283
432
  }
284
433
  }
285
- throw new SerovalMissingPluginError(node.c);
286
434
  }
435
+ throw new SerovalMissingPluginError(node.c);
436
+ }
287
437
 
288
- private deserializePromiseConstructor(
289
- node: SerovalPromiseConstructorNode,
290
- ): unknown {
291
- return this.assignIndexedValue(
292
- node.i,
293
- this.assignIndexedValue(node.s, createDeferred()).promise,
294
- );
295
- }
438
+ function deserializePromiseConstructor(
439
+ ctx: DeserializerContext,
440
+ node: SerovalPromiseConstructorNode,
441
+ ): unknown {
442
+ return assignIndexedValue(
443
+ ctx,
444
+ node.i,
445
+ assignIndexedValue(ctx, node.s, PROMISE_CONSTRUCTOR()).p,
446
+ );
447
+ }
296
448
 
297
- private deserializePromiseResolve(node: SerovalPromiseResolveNode): unknown {
298
- const deferred = this.refs.get(node.i) as Deferred | undefined;
299
- assert(deferred, new SerovalMissingInstanceError('Promise'));
300
- deferred.resolve(this.deserialize(node.a[1]));
449
+ function deserializePromiseResolve(
450
+ ctx: DeserializerContext,
451
+ node: SerovalPromiseResolveNode,
452
+ ): unknown {
453
+ const deferred = ctx.base.refs.get(node.i) as
454
+ | PromiseConstructorResolver
455
+ | undefined;
456
+ if (deferred) {
457
+ deferred.s(deserialize(ctx, node.a[1]));
301
458
  return undefined;
302
459
  }
460
+ throw new SerovalMissingInstanceError('Promise');
461
+ }
303
462
 
304
- private deserializePromiseReject(node: SerovalPromiseRejectNode): unknown {
305
- const deferred = this.refs.get(node.i) as Deferred | undefined;
306
- assert(deferred, new SerovalMissingInstanceError('Promise'));
307
- deferred.reject(this.deserialize(node.a[1]));
463
+ function deserializePromiseReject(
464
+ ctx: DeserializerContext,
465
+ node: SerovalPromiseRejectNode,
466
+ ): unknown {
467
+ const deferred = ctx.base.refs.get(node.i) as
468
+ | PromiseConstructorResolver
469
+ | undefined;
470
+ if (deferred) {
471
+ deferred.f(deserialize(ctx, node.a[1]));
308
472
  return undefined;
309
473
  }
474
+ throw new SerovalMissingInstanceError('Promise');
475
+ }
310
476
 
311
- private deserializeIteratorFactoryInstance(
312
- node: SerovalIteratorFactoryInstanceNode,
313
- ): unknown {
314
- this.deserialize(node.a[0]);
315
- const source = this.deserialize(node.a[1]);
316
- return sequenceToIterator(source as Sequence);
317
- }
477
+ function deserializeIteratorFactoryInstance(
478
+ ctx: DeserializerContext,
479
+ node: SerovalIteratorFactoryInstanceNode,
480
+ ): unknown {
481
+ deserialize(ctx, node.a[0]);
482
+ const source = deserialize(ctx, node.a[1]);
483
+ return sequenceToIterator(source as Sequence);
484
+ }
318
485
 
319
- private deserializeAsyncIteratorFactoryInstance(
320
- node: SerovalAsyncIteratorFactoryInstanceNode,
321
- ): unknown {
322
- this.deserialize(node.a[0]);
323
- const source = this.deserialize(node.a[1]);
324
- return streamToAsyncIterable(source as Stream<any>);
325
- }
486
+ function deserializeAsyncIteratorFactoryInstance(
487
+ ctx: DeserializerContext,
488
+ node: SerovalAsyncIteratorFactoryInstanceNode,
489
+ ): unknown {
490
+ deserialize(ctx, node.a[0]);
491
+ const source = deserialize(ctx, node.a[1]);
492
+ return streamToAsyncIterable(source as Stream<any>);
493
+ }
326
494
 
327
- private deserializeStreamConstructor(
328
- node: SerovalStreamConstructorNode,
329
- ): unknown {
330
- const result = this.assignIndexedValue(node.i, createStream());
331
- const len = node.a.length;
332
- if (len) {
333
- for (let i = 0; i < len; i++) {
334
- this.deserialize(node.a[i]);
335
- }
495
+ function deserializeStreamConstructor(
496
+ ctx: DeserializerContext,
497
+ node: SerovalStreamConstructorNode,
498
+ ): unknown {
499
+ const result = assignIndexedValue(ctx, node.i, createStream());
500
+ const len = node.a.length;
501
+ if (len) {
502
+ for (let i = 0; i < len; i++) {
503
+ deserialize(ctx, node.a[i]);
336
504
  }
337
- return result;
338
- }
339
-
340
- private deserializeStreamNext(node: SerovalStreamNextNode): unknown {
341
- const deferred = this.refs.get(node.i) as Stream<unknown> | undefined;
342
- assert(deferred, new SerovalMissingInstanceError('Stream'));
343
- deferred.next(this.deserialize(node.f));
344
- return undefined;
345
505
  }
506
+ return result;
507
+ }
346
508
 
347
- private deserializeStreamThrow(node: SerovalStreamThrowNode): unknown {
348
- const deferred = this.refs.get(node.i) as Stream<unknown> | undefined;
349
- assert(deferred, new SerovalMissingInstanceError('Stream'));
350
- deferred.throw(this.deserialize(node.f));
509
+ function deserializeStreamNext(
510
+ ctx: DeserializerContext,
511
+ node: SerovalStreamNextNode,
512
+ ): unknown {
513
+ const deferred = ctx.base.refs.get(node.i) as Stream<unknown> | undefined;
514
+ if (deferred) {
515
+ deferred.next(deserialize(ctx, node.f));
351
516
  return undefined;
352
517
  }
518
+ throw new SerovalMissingInstanceError('Stream');
519
+ }
353
520
 
354
- private deserializeStreamReturn(node: SerovalStreamReturnNode): unknown {
355
- const deferred = this.refs.get(node.i) as Stream<unknown> | undefined;
356
- assert(deferred, new SerovalMissingInstanceError('Stream'));
357
- deferred.return(this.deserialize(node.f));
521
+ function deserializeStreamThrow(
522
+ ctx: DeserializerContext,
523
+ node: SerovalStreamThrowNode,
524
+ ): unknown {
525
+ const deferred = ctx.base.refs.get(node.i) as Stream<unknown> | undefined;
526
+ if (deferred) {
527
+ deferred.throw(deserialize(ctx, node.f));
358
528
  return undefined;
359
529
  }
530
+ throw new SerovalMissingInstanceError('Stream');
531
+ }
360
532
 
361
- private deserializeIteratorFactory(
362
- node: SerovalIteratorFactoryNode,
363
- ): unknown {
364
- this.deserialize(node.f);
533
+ function deserializeStreamReturn(
534
+ ctx: DeserializerContext,
535
+ node: SerovalStreamReturnNode,
536
+ ): unknown {
537
+ const deferred = ctx.base.refs.get(node.i) as Stream<unknown> | undefined;
538
+ if (deferred) {
539
+ deferred.return(deserialize(ctx, node.f));
365
540
  return undefined;
366
541
  }
542
+ throw new SerovalMissingInstanceError('Stream');
543
+ }
367
544
 
368
- private deserializeAsyncIteratorFactory(
369
- node: SerovalAsyncIteratorFactoryNode,
370
- ): unknown {
371
- this.deserialize(node.a[1]);
372
- return undefined;
373
- }
545
+ function deserializeIteratorFactory(
546
+ ctx: DeserializerContext,
547
+ node: SerovalIteratorFactoryNode,
548
+ ): unknown {
549
+ deserialize(ctx, node.f);
550
+ return undefined;
551
+ }
374
552
 
375
- deserializeTop(node: SerovalNode): unknown {
376
- try {
377
- return this.deserialize(node);
378
- } catch (error) {
379
- throw new SerovalDeserializationError(error);
380
- }
553
+ function deserializeAsyncIteratorFactory(
554
+ ctx: DeserializerContext,
555
+ node: SerovalAsyncIteratorFactoryNode,
556
+ ): unknown {
557
+ deserialize(ctx, node.a[1]);
558
+ return undefined;
559
+ }
560
+ export function deserialize(
561
+ ctx: DeserializerContext,
562
+ node: SerovalNode,
563
+ ): unknown {
564
+ switch (node.t) {
565
+ case SerovalNodeType.Constant:
566
+ return CONSTANT_VAL[node.s];
567
+ case SerovalNodeType.Number:
568
+ return node.s;
569
+ case SerovalNodeType.String:
570
+ return deserializeString(node.s);
571
+ case SerovalNodeType.BigInt:
572
+ return BigInt(node.s);
573
+ case SerovalNodeType.IndexedValue:
574
+ return ctx.base.refs.get(node.i);
575
+ case SerovalNodeType.Reference:
576
+ return deserializeReference(ctx, node);
577
+ case SerovalNodeType.Array:
578
+ return deserializeArray(ctx, node);
579
+ case SerovalNodeType.Object:
580
+ case SerovalNodeType.NullConstructor:
581
+ return deserializeObject(ctx, node);
582
+ case SerovalNodeType.Date:
583
+ return deserializeDate(ctx, node);
584
+ case SerovalNodeType.RegExp:
585
+ return deserializeRegExp(ctx, node);
586
+ case SerovalNodeType.Set:
587
+ return deserializeSet(ctx, node);
588
+ case SerovalNodeType.Map:
589
+ return deserializeMap(ctx, node);
590
+ case SerovalNodeType.ArrayBuffer:
591
+ return deserializeArrayBuffer(ctx, node);
592
+ case SerovalNodeType.BigIntTypedArray:
593
+ case SerovalNodeType.TypedArray:
594
+ return deserializeTypedArray(ctx, node);
595
+ case SerovalNodeType.DataView:
596
+ return deserializeDataView(ctx, node);
597
+ case SerovalNodeType.AggregateError:
598
+ return deserializeAggregateError(ctx, node);
599
+ case SerovalNodeType.Error:
600
+ return deserializeError(ctx, node);
601
+ case SerovalNodeType.Promise:
602
+ return deserializePromise(ctx, node);
603
+ case SerovalNodeType.WKSymbol:
604
+ return SYMBOL_REF[node.s];
605
+ case SerovalNodeType.Boxed:
606
+ return deserializeBoxed(ctx, node);
607
+ case SerovalNodeType.Plugin:
608
+ return deserializePlugin(ctx, node);
609
+ case SerovalNodeType.PromiseConstructor:
610
+ return deserializePromiseConstructor(ctx, node);
611
+ case SerovalNodeType.PromiseSuccess:
612
+ return deserializePromiseResolve(ctx, node);
613
+ case SerovalNodeType.PromiseFailure:
614
+ return deserializePromiseReject(ctx, node);
615
+ case SerovalNodeType.IteratorFactoryInstance:
616
+ return deserializeIteratorFactoryInstance(ctx, node);
617
+ case SerovalNodeType.AsyncIteratorFactoryInstance:
618
+ return deserializeAsyncIteratorFactoryInstance(ctx, node);
619
+ case SerovalNodeType.StreamConstructor:
620
+ return deserializeStreamConstructor(ctx, node);
621
+ case SerovalNodeType.StreamNext:
622
+ return deserializeStreamNext(ctx, node);
623
+ case SerovalNodeType.StreamThrow:
624
+ return deserializeStreamThrow(ctx, node);
625
+ case SerovalNodeType.StreamReturn:
626
+ return deserializeStreamReturn(ctx, node);
627
+ case SerovalNodeType.IteratorFactory:
628
+ return deserializeIteratorFactory(ctx, node);
629
+ case SerovalNodeType.AsyncIteratorFactory:
630
+ return deserializeAsyncIteratorFactory(ctx, node);
631
+ // case SerovalNodeType.SpecialReference:
632
+ default:
633
+ throw new SerovalUnsupportedNodeError(node);
381
634
  }
635
+ }
382
636
 
383
- deserialize(node: SerovalNode): unknown {
384
- switch (node.t) {
385
- case SerovalNodeType.Constant:
386
- return CONSTANT_VAL[node.s];
387
- case SerovalNodeType.Number:
388
- return node.s;
389
- case SerovalNodeType.String:
390
- return deserializeString(node.s);
391
- case SerovalNodeType.BigInt:
392
- return BigInt(node.s);
393
- case SerovalNodeType.IndexedValue:
394
- return this.refs.get(node.i);
395
- case SerovalNodeType.Reference:
396
- return this.deserializeReference(node);
397
- case SerovalNodeType.Array:
398
- return this.deserializeArray(node);
399
- case SerovalNodeType.Object:
400
- case SerovalNodeType.NullConstructor:
401
- return this.deserializeObject(node);
402
- case SerovalNodeType.Date:
403
- return this.deserializeDate(node);
404
- case SerovalNodeType.RegExp:
405
- return this.deserializeRegExp(node);
406
- case SerovalNodeType.Set:
407
- return this.deserializeSet(node);
408
- case SerovalNodeType.Map:
409
- return this.deserializeMap(node);
410
- case SerovalNodeType.ArrayBuffer:
411
- return this.deserializeArrayBuffer(node);
412
- case SerovalNodeType.BigIntTypedArray:
413
- case SerovalNodeType.TypedArray:
414
- return this.deserializeTypedArray(node);
415
- case SerovalNodeType.DataView:
416
- return this.deserializeDataView(node);
417
- case SerovalNodeType.AggregateError:
418
- return this.deserializeAggregateError(node);
419
- case SerovalNodeType.Error:
420
- return this.deserializeError(node);
421
- case SerovalNodeType.Promise:
422
- return this.deserializePromise(node);
423
- case SerovalNodeType.WKSymbol:
424
- return SYMBOL_REF[node.s];
425
- case SerovalNodeType.Boxed:
426
- return this.deserializeBoxed(node);
427
- case SerovalNodeType.Plugin:
428
- return this.deserializePlugin(node);
429
- case SerovalNodeType.PromiseConstructor:
430
- return this.deserializePromiseConstructor(node);
431
- case SerovalNodeType.PromiseSuccess:
432
- return this.deserializePromiseResolve(node);
433
- case SerovalNodeType.PromiseFailure:
434
- return this.deserializePromiseReject(node);
435
- case SerovalNodeType.IteratorFactoryInstance:
436
- return this.deserializeIteratorFactoryInstance(node);
437
- case SerovalNodeType.AsyncIteratorFactoryInstance:
438
- return this.deserializeAsyncIteratorFactoryInstance(node);
439
- case SerovalNodeType.StreamConstructor:
440
- return this.deserializeStreamConstructor(node);
441
- case SerovalNodeType.StreamNext:
442
- return this.deserializeStreamNext(node);
443
- case SerovalNodeType.StreamThrow:
444
- return this.deserializeStreamThrow(node);
445
- case SerovalNodeType.StreamReturn:
446
- return this.deserializeStreamReturn(node);
447
- case SerovalNodeType.IteratorFactory:
448
- return this.deserializeIteratorFactory(node);
449
- case SerovalNodeType.AsyncIteratorFactory:
450
- return this.deserializeAsyncIteratorFactory(node);
451
- // case SerovalNodeType.SpecialReference:
452
- default:
453
- throw new SerovalUnsupportedNodeError(node);
454
- }
637
+ export function deserializeTop(
638
+ ctx: DeserializerContext,
639
+ node: SerovalNode,
640
+ ): unknown {
641
+ try {
642
+ return deserialize(ctx, node);
643
+ } catch (error) {
644
+ throw new SerovalDeserializationError(error);
455
645
  }
456
646
  }