seroval 0.6.0 → 0.7.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.
@@ -6,7 +6,6 @@ import {
6
6
  getRefParam,
7
7
  markRef,
8
8
  } from '../context';
9
- import quote from '../quote';
10
9
  import { GLOBAL_KEY } from './reference';
11
10
  import { isValidIdentifier } from './shared';
12
11
  import { SYMBOL_STRING } from './symbols';
@@ -26,16 +25,29 @@ import {
26
25
  SerovalIndexedValueNode,
27
26
  SerovalSetNode,
28
27
  SerovalTypedArrayNode,
28
+ SerovalArrayBufferNode,
29
+ SerovalDataViewNode,
30
+ SerovalBlobNode,
31
+ SerovalFileNode,
32
+ SerovalHeadersNode,
33
+ SerovalRegExpNode,
34
+ SerovalDateNode,
35
+ SerovalURLNode,
36
+ SerovalURLSearchParamsNode,
37
+ SerovalReferenceNode,
38
+ SerovalFormDataNode,
29
39
  } from './types';
30
40
 
31
41
  function getAssignmentExpression(assignment: Assignment): string {
32
42
  switch (assignment.t) {
33
43
  case 'index':
34
44
  return assignment.s + '=' + assignment.v;
35
- case 'map':
36
- return assignment.s + '.set(' + assignment.k + ',' + assignment.v + ')';
37
45
  case 'set':
46
+ return assignment.s + '.set(' + assignment.k + ',' + assignment.v + ')';
47
+ case 'add':
38
48
  return assignment.s + '.add(' + assignment.v + ')';
49
+ case 'append':
50
+ return assignment.s + '.append(' + assignment.k + ',' + assignment.v + ')';
39
51
  default:
40
52
  return '';
41
53
  }
@@ -66,11 +78,11 @@ function mergeAssignments(assignments: Assignment[]) {
66
78
  current = item;
67
79
  }
68
80
  break;
69
- case 'map':
81
+ case 'set':
70
82
  if (item.s === prev.s) {
71
83
  // Maps has chaining methods, merge if source is the same
72
84
  current = {
73
- t: 'map',
85
+ t: 'set',
74
86
  s: getAssignmentExpression(current),
75
87
  k: item.k,
76
88
  v: item.v,
@@ -81,11 +93,11 @@ function mergeAssignments(assignments: Assignment[]) {
81
93
  current = item;
82
94
  }
83
95
  break;
84
- case 'set':
96
+ case 'add':
85
97
  if (item.s === prev.s) {
86
98
  // Sets has chaining methods too
87
99
  current = {
88
- t: 'set',
100
+ t: 'add',
89
101
  s: getAssignmentExpression(current),
90
102
  k: undefined,
91
103
  v: item.v,
@@ -96,6 +108,11 @@ function mergeAssignments(assignments: Assignment[]) {
96
108
  current = item;
97
109
  }
98
110
  break;
111
+ case 'append':
112
+ // Different assignment, push current
113
+ newAssignments.push(current);
114
+ current = item;
115
+ break;
99
116
  default:
100
117
  break;
101
118
  }
@@ -146,29 +163,41 @@ function createAssignment(
146
163
  });
147
164
  }
148
165
 
149
- function createSetAdd(
166
+ function createAddAssignment(
150
167
  ctx: SerializationContext,
151
168
  ref: number,
152
169
  value: string,
153
170
  ) {
154
- markRef(ctx, ref);
155
171
  ctx.assignments.push({
156
- t: 'set',
172
+ t: 'add',
157
173
  s: getRefParam(ctx, ref),
158
174
  k: undefined,
159
175
  v: value,
160
176
  });
161
177
  }
162
178
 
163
- function createMapSet(
179
+ function createSetAssignment(
180
+ ctx: SerializationContext,
181
+ ref: number,
182
+ key: string,
183
+ value: string,
184
+ ) {
185
+ ctx.assignments.push({
186
+ t: 'set',
187
+ s: getRefParam(ctx, ref),
188
+ k: key,
189
+ v: value,
190
+ });
191
+ }
192
+
193
+ function createAppendAssignment(
164
194
  ctx: SerializationContext,
165
195
  ref: number,
166
196
  key: string,
167
197
  value: string,
168
198
  ) {
169
- markRef(ctx, ref);
170
199
  ctx.assignments.push({
171
- t: 'map',
200
+ t: 'append',
172
201
  s: getRefParam(ctx, ref),
173
202
  k: key,
174
203
  v: value,
@@ -181,7 +210,6 @@ function createArrayAssign(
181
210
  index: number | string,
182
211
  value: string,
183
212
  ) {
184
- markRef(ctx, ref);
185
213
  createAssignment(ctx, getRefParam(ctx, ref) + '[' + index + ']', value);
186
214
  }
187
215
 
@@ -213,9 +241,13 @@ function isIndexedValueInStack(
213
241
  return node.t === SerovalNodeType.IndexedValue && ctx.stack.includes(node.i);
214
242
  }
215
243
 
244
+ type SerovalNodeListNode =
245
+ | SerovalArrayNode
246
+ | SerovalIterableNode;
247
+
216
248
  function serializeNodeList(
217
249
  ctx: SerializationContext,
218
- node: SerovalArrayNode | SerovalIterableNode | SerovalAggregateErrorNode,
250
+ node: SerovalNodeListNode,
219
251
  ) {
220
252
  // This is different than Map and Set
221
253
  // because we also need to serialize
@@ -234,6 +266,7 @@ function serializeNodeList(
234
266
  if (item) {
235
267
  // Check if item is a parent
236
268
  if (isIndexedValueInStack(ctx, item)) {
269
+ markRef(ctx, node.i);
237
270
  createArrayAssign(ctx, node.i, i, getRefParam(ctx, item.i));
238
271
  isHoley = true;
239
272
  } else {
@@ -273,9 +306,11 @@ function serializeProperties(
273
306
  let isIdentifier: boolean;
274
307
  let refParam: string;
275
308
  let hasPrev = false;
276
- for (let i = 0; i < node.s; i++) {
277
- key = node.k[i];
278
- val = node.v[i];
309
+ const keys = node.k;
310
+ const values = node.v;
311
+ for (let i = 0, len = node.s; i < len; i++) {
312
+ key = keys[i];
313
+ val = values[i];
279
314
  check = Number(key);
280
315
  // Test if key is a valid number or JS identifier
281
316
  // so that we don't have to serialize the key and wrap with brackets
@@ -283,13 +318,15 @@ function serializeProperties(
283
318
  if (isIndexedValueInStack(ctx, val)) {
284
319
  refParam = getRefParam(ctx, val.i);
285
320
  if (isIdentifier && Number.isNaN(check)) {
321
+ markRef(ctx, sourceID);
286
322
  createObjectAssign(ctx, sourceID, key, refParam);
287
323
  } else {
288
- createArrayAssign(ctx, sourceID, isIdentifier ? key : ('"' + quote(key) + '"'), refParam);
324
+ markRef(ctx, sourceID);
325
+ createArrayAssign(ctx, sourceID, isIdentifier ? key : ('"' + key + '"'), refParam);
289
326
  }
290
327
  } else {
291
328
  result += (hasPrev ? ',' : '')
292
- + (isIdentifier ? key : ('"' + quote(key) + '"'))
329
+ + (isIdentifier ? key : ('"' + key + '"'))
293
330
  + ':' + serializeTree(ctx, val);
294
331
  hasPrev = true;
295
332
  }
@@ -324,12 +361,14 @@ function serializeAssignments(
324
361
  let check: number;
325
362
  let parentAssignment: Assignment[];
326
363
  let isIdentifier: boolean;
327
- for (let i = 0; i < node.s; i++) {
364
+ const keys = node.k;
365
+ const values = node.v;
366
+ for (let i = 0, len = node.s; i < len; i++) {
328
367
  parentStack = ctx.stack;
329
368
  ctx.stack = [];
330
- refParam = serializeTree(ctx, node.v[i]);
369
+ refParam = serializeTree(ctx, values[i]);
331
370
  ctx.stack = parentStack;
332
- key = node.k[i];
371
+ key = keys[i];
333
372
  check = Number(key);
334
373
  parentAssignment = ctx.assignments;
335
374
  ctx.assignments = mainAssignments;
@@ -339,7 +378,7 @@ function serializeAssignments(
339
378
  if (isIdentifier && Number.isNaN(check)) {
340
379
  createObjectAssign(ctx, sourceID, key, refParam);
341
380
  } else {
342
- createArrayAssign(ctx, sourceID, isIdentifier ? key : ('"' + quote(key) + '"'), refParam);
381
+ createArrayAssign(ctx, sourceID, isIdentifier ? key : ('"' + key + '"'), refParam);
343
382
  }
344
383
  ctx.assignments = parentAssignment;
345
384
  }
@@ -395,7 +434,8 @@ function serializeSet(
395
434
  for (let i = 0; i < size; i++) {
396
435
  item = node.a[i];
397
436
  if (isIndexedValueInStack(ctx, item)) {
398
- createSetAdd(ctx, node.i, getRefParam(ctx, item.i));
437
+ markRef(ctx, node.i);
438
+ createAddAssignment(ctx, node.i, getRefParam(ctx, item.i));
399
439
  } else {
400
440
  // Push directly
401
441
  result += (hasPrev ? ',' : '') + serializeTree(ctx, item);
@@ -431,13 +471,14 @@ function serializeMap(
431
471
  if (isIndexedValueInStack(ctx, key)) {
432
472
  // Create reference for the map instance
433
473
  keyRef = getRefParam(ctx, key.i);
474
+ markRef(ctx, node.i);
434
475
  // Check if value is a parent
435
476
  if (isIndexedValueInStack(ctx, val)) {
436
477
  valueRef = getRefParam(ctx, val.i);
437
478
  // Register an assignment since
438
479
  // both key and value are a parent of this
439
480
  // Map instance
440
- createMapSet(ctx, node.i, keyRef, valueRef);
481
+ createSetAssignment(ctx, node.i, keyRef, valueRef);
441
482
  } else {
442
483
  // Reset the stack
443
484
  // This is required because the serialized
@@ -446,16 +487,17 @@ function serializeMap(
446
487
  // assignment
447
488
  parent = ctx.stack;
448
489
  ctx.stack = [];
449
- createMapSet(ctx, node.i, keyRef, serializeTree(ctx, val));
490
+ createSetAssignment(ctx, node.i, keyRef, serializeTree(ctx, val));
450
491
  ctx.stack = parent;
451
492
  }
452
493
  } else if (isIndexedValueInStack(ctx, val)) {
453
494
  // Create ref for the Map instance
454
495
  valueRef = getRefParam(ctx, val.i);
496
+ markRef(ctx, node.i);
455
497
  // Reset stack for the key serialization
456
498
  parent = ctx.stack;
457
499
  ctx.stack = [];
458
- createMapSet(ctx, node.i, serializeTree(ctx, key), valueRef);
500
+ createSetAssignment(ctx, node.i, serializeTree(ctx, key), valueRef);
459
501
  ctx.stack = parent;
460
502
  } else {
461
503
  result += (hasPrev ? ',[' : '[') + serializeTree(ctx, key) + ',' + serializeTree(ctx, val) + ']';
@@ -479,7 +521,7 @@ function serializeAggregateError(
479
521
  ) {
480
522
  // Serialize the required arguments
481
523
  ctx.stack.push(node.i);
482
- const serialized = 'new AggregateError(' + serializeNodeList(ctx, node) + ',"' + quote(node.m) + '")';
524
+ const serialized = 'new AggregateError([],"' + node.m + '")';
483
525
  ctx.stack.pop();
484
526
  // `AggregateError` might've been extended
485
527
  // either through class or custom properties
@@ -491,7 +533,7 @@ function serializeError(
491
533
  ctx: SerializationContext,
492
534
  node: SerovalErrorNode,
493
535
  ) {
494
- const serialized = 'new ' + node.c + '("' + quote(node.m) + '")';
536
+ const serialized = 'new ' + node.c + '("' + node.m + '")';
495
537
  return serializeDictionary(ctx, node.i, node.d, serialized);
496
538
  }
497
539
 
@@ -522,16 +564,26 @@ function serializePromise(
522
564
  return assignIndexedValue(ctx, node.i, serialized);
523
565
  }
524
566
 
567
+ function serializeArrayBuffer(
568
+ ctx: SerializationContext,
569
+ node: SerovalArrayBufferNode,
570
+ ) {
571
+ let result = 'new Uint8Array(';
572
+ if (node.s.length) {
573
+ result += '[';
574
+ for (let i = 0, len = node.s.length; i < len; i++) {
575
+ result += ((i > 0) ? ',' : '') + node.s[i];
576
+ }
577
+ result += ']';
578
+ }
579
+ return assignIndexedValue(ctx, node.i, result + ').buffer');
580
+ }
581
+
525
582
  function serializeTypedArray(
526
583
  ctx: SerializationContext,
527
584
  node: SerovalTypedArrayNode | SerovalBigIntTypedArrayNode,
528
585
  ) {
529
- let result = '';
530
- const isBigInt = node.t === SerovalNodeType.BigIntTypedArray;
531
- for (let i = 0, len = node.s.length; i < len; i++) {
532
- result += (i !== 0 ? ',' : '') + node.s[i] + (isBigInt ? 'n' : '');
533
- }
534
- const args = '[' + result + ']' + (node.l !== 0 ? (',' + node.l) : '');
586
+ const args = serializeTree(ctx, node.f) + ',' + node.b + ',' + node.l;
535
587
  return assignIndexedValue(ctx, node.i, 'new ' + node.c + '(' + args + ')');
536
588
  }
537
589
 
@@ -559,6 +611,112 @@ function serializeIterable(
559
611
  return serializeDictionary(ctx, node.i, node.d, serialized);
560
612
  }
561
613
 
614
+ function serializeDate(
615
+ ctx: SerializationContext,
616
+ node: SerovalDateNode,
617
+ ) {
618
+ return assignIndexedValue(ctx, node.i, 'new Date("' + node.s + '")');
619
+ }
620
+
621
+ function serializeRegExp(
622
+ ctx: SerializationContext,
623
+ node: SerovalRegExpNode,
624
+ ) {
625
+ return assignIndexedValue(ctx, node.i, '/' + node.c + '/' + node.m);
626
+ }
627
+
628
+ function serializeURL(
629
+ ctx: SerializationContext,
630
+ node: SerovalURLNode,
631
+ ) {
632
+ return assignIndexedValue(ctx, node.i, 'new URL("' + node.s + '")');
633
+ }
634
+
635
+ function serializeURLSearchParams(
636
+ ctx: SerializationContext,
637
+ node: SerovalURLSearchParamsNode,
638
+ ) {
639
+ return assignIndexedValue(ctx, node.i, node.s ? 'new URLSearchParams("' + node.s + '")' : 'new URLSearchParams');
640
+ }
641
+
642
+ function serializeReference(
643
+ ctx: SerializationContext,
644
+ node: SerovalReferenceNode,
645
+ ) {
646
+ return assignIndexedValue(ctx, node.i, GLOBAL_KEY + '.get("' + node.s + '")');
647
+ }
648
+
649
+ function serializeDataView(
650
+ ctx: SerializationContext,
651
+ node: SerovalDataViewNode,
652
+ ) {
653
+ const args = serializeTree(ctx, node.f) + ',' + node.b + ',' + node.l;
654
+ return assignIndexedValue(ctx, node.i, 'new DataView(' + args + ')');
655
+ }
656
+
657
+ function serializeBlob(
658
+ ctx: SerializationContext,
659
+ node: SerovalBlobNode,
660
+ ) {
661
+ const args = '[' + serializeTree(ctx, node.f) + '],{type:"' + node.c + '"}';
662
+ return assignIndexedValue(ctx, node.i, 'new Blob(' + args + ')');
663
+ }
664
+
665
+ function serializeFile(
666
+ ctx: SerializationContext,
667
+ node: SerovalFileNode,
668
+ ) {
669
+ const options = '{type:"' + node.c + '",lastModified:' + node.b + '}';
670
+ const args = '[' + serializeTree(ctx, node.f) + '],"' + node.m + '",' + options;
671
+ return assignIndexedValue(ctx, node.i, 'new File(' + args + ')');
672
+ }
673
+
674
+ function serializeHeaders(
675
+ ctx: SerializationContext,
676
+ node: SerovalHeadersNode,
677
+ ) {
678
+ return assignIndexedValue(ctx, node.i, 'new Headers(' + serializeProperties(ctx, node.i, node.d) + ')');
679
+ }
680
+
681
+ function serializeFormDataEntries(
682
+ ctx: SerializationContext,
683
+ node: SerovalFormDataNode,
684
+ ) {
685
+ ctx.stack.push(node.i);
686
+ const mainAssignments: Assignment[] = [];
687
+ let parentStack: number[];
688
+ let value: string;
689
+ let key: string;
690
+ let parentAssignment: Assignment[];
691
+ for (let i = 0; i < node.d.s; i++) {
692
+ parentStack = ctx.stack;
693
+ ctx.stack = [];
694
+ value = serializeTree(ctx, node.d.v[i]);
695
+ key = node.d.k[i];
696
+ ctx.stack = parentStack;
697
+ parentAssignment = ctx.assignments;
698
+ ctx.assignments = mainAssignments;
699
+ createAppendAssignment(ctx, node.i, '"' + key + '"', value);
700
+ ctx.assignments = parentAssignment;
701
+ }
702
+ ctx.stack.pop();
703
+ return resolveAssignments(mainAssignments);
704
+ }
705
+
706
+ function serializeFormData(
707
+ ctx: SerializationContext,
708
+ node: SerovalFormDataNode,
709
+ ) {
710
+ if (node.d.s) {
711
+ markRef(ctx, node.i);
712
+ }
713
+ const result = assignIndexedValue(ctx, node.i, 'new FormData()');
714
+ if (node.d.s) {
715
+ return '(' + result + ',' + serializeFormDataEntries(ctx, node) + getRefParam(ctx, node.i) + ')';
716
+ }
717
+ return result;
718
+ }
719
+
562
720
  export default function serializeTree(
563
721
  ctx: SerializationContext,
564
722
  node: SerovalNode,
@@ -593,16 +751,20 @@ export default function serializeTree(
593
751
  case SerovalNodeType.NullConstructor:
594
752
  return serializeNullConstructor(ctx, node);
595
753
  case SerovalNodeType.Date:
596
- return assignIndexedValue(ctx, node.i, 'new Date("' + node.s + '")');
754
+ return serializeDate(ctx, node);
597
755
  case SerovalNodeType.RegExp:
598
- return assignIndexedValue(ctx, node.i, '/' + node.c + '/' + node.m);
756
+ return serializeRegExp(ctx, node);
599
757
  case SerovalNodeType.Set:
600
758
  return serializeSet(ctx, node);
601
759
  case SerovalNodeType.Map:
602
760
  return serializeMap(ctx, node);
761
+ case SerovalNodeType.ArrayBuffer:
762
+ return serializeArrayBuffer(ctx, node);
603
763
  case SerovalNodeType.BigIntTypedArray:
604
764
  case SerovalNodeType.TypedArray:
605
765
  return serializeTypedArray(ctx, node);
766
+ case SerovalNodeType.DataView:
767
+ return serializeDataView(ctx, node);
606
768
  case SerovalNodeType.AggregateError:
607
769
  return serializeAggregateError(ctx, node);
608
770
  case SerovalNodeType.Error:
@@ -614,11 +776,19 @@ export default function serializeTree(
614
776
  case SerovalNodeType.WKSymbol:
615
777
  return SYMBOL_STRING[node.s];
616
778
  case SerovalNodeType.URL:
617
- return assignIndexedValue(ctx, node.i, 'new URL("' + node.s + '")');
779
+ return serializeURL(ctx, node);
618
780
  case SerovalNodeType.URLSearchParams:
619
- return assignIndexedValue(ctx, node.i, node.s ? 'new URLSearchParams("' + node.s + '")' : 'new URLSearchParams');
781
+ return serializeURLSearchParams(ctx, node);
620
782
  case SerovalNodeType.Reference:
621
- return assignIndexedValue(ctx, node.i, GLOBAL_KEY + '.get("' + node.s + '")');
783
+ return serializeReference(ctx, node);
784
+ case SerovalNodeType.Blob:
785
+ return serializeBlob(ctx, node);
786
+ case SerovalNodeType.File:
787
+ return serializeFile(ctx, node);
788
+ case SerovalNodeType.Headers:
789
+ return serializeHeaders(ctx, node);
790
+ case SerovalNodeType.FormData:
791
+ return serializeFormData(ctx, node);
622
792
  default:
623
793
  throw new Error('Unsupported type');
624
794
  }
package/src/tree/sync.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  import assert from '../assert';
3
3
  import { Feature } from '../compat';
4
4
  import { createIndexedValue, getRootID, ParserContext } from '../context';
5
- import quote from '../quote';
5
+ import { serializeString } from '../string';
6
6
  import { BigIntTypedArrayValue, TypedArrayValue } from '../types';
7
7
  import {
8
8
  createBigIntNode,
@@ -23,6 +23,8 @@ import {
23
23
  TRUE_NODE,
24
24
  UNDEFINED_NODE,
25
25
  createReferenceNode,
26
+ createArrayBufferNode,
27
+ createDataViewNode,
26
28
  } from './primitives';
27
29
  import {
28
30
  hasReferenceID,
@@ -38,6 +40,8 @@ import {
38
40
  SerovalAggregateErrorNode,
39
41
  SerovalArrayNode,
40
42
  SerovalErrorNode,
43
+ SerovalFormDataNode,
44
+ SerovalHeadersNode,
41
45
  SerovalIterableNode,
42
46
  SerovalMapNode,
43
47
  SerovalNode,
@@ -89,6 +93,7 @@ function generateArrayNode(
89
93
  d: undefined,
90
94
  a: generateNodeList(ctx, current),
91
95
  f: undefined,
96
+ b: undefined,
92
97
  };
93
98
  }
94
99
 
@@ -131,6 +136,7 @@ function generateMapNode(
131
136
  d: { k: keyNodes, v: valueNodes, s: len },
132
137
  a: undefined,
133
138
  f: undefined,
139
+ b: undefined,
134
140
  };
135
141
  }
136
142
 
@@ -167,6 +173,7 @@ function generateSetNode(
167
173
  d: undefined,
168
174
  a: nodes,
169
175
  f: undefined,
176
+ b: undefined,
170
177
  };
171
178
  }
172
179
 
@@ -183,14 +190,16 @@ function generateProperties(
183
190
  let deferredSize = 0;
184
191
  let nodesSize = 0;
185
192
  let item: unknown;
193
+ let escaped: string;
186
194
  for (const key of keys) {
187
195
  item = properties[key];
196
+ escaped = serializeString(key);
188
197
  if (isIterable(item)) {
189
- deferredKeys[deferredSize] = key;
198
+ deferredKeys[deferredSize] = escaped;
190
199
  deferredValues[deferredSize] = item;
191
200
  deferredSize++;
192
201
  } else {
193
- keyNodes[nodesSize] = key;
202
+ keyNodes[nodesSize] = escaped;
194
203
  valueNodes[nodesSize] = parse(ctx, item);
195
204
  nodesSize++;
196
205
  }
@@ -227,6 +236,7 @@ function generateIterableNode(
227
236
  : undefined,
228
237
  a: generateNodeList(ctx, array),
229
238
  f: undefined,
239
+ b: undefined,
230
240
  };
231
241
  }
232
242
 
@@ -249,6 +259,7 @@ function generateObjectNode(
249
259
  d: generateProperties(ctx, current),
250
260
  a: undefined,
251
261
  f: undefined,
262
+ b: undefined,
252
263
  };
253
264
  }
254
265
 
@@ -265,12 +276,13 @@ function generateAggregateErrorNode(
265
276
  t: SerovalNodeType.AggregateError,
266
277
  i: id,
267
278
  s: undefined,
268
- l: current.errors.length,
279
+ l: undefined,
269
280
  c: undefined,
270
- m: quote(current.message),
281
+ m: serializeString(current.message),
271
282
  d: optionsNode,
272
- a: generateNodeList(ctx, current.errors as unknown[]),
283
+ a: undefined,
273
284
  f: undefined,
285
+ b: undefined,
274
286
  };
275
287
  }
276
288
 
@@ -289,10 +301,59 @@ function generateErrorNode(
289
301
  s: undefined,
290
302
  l: undefined,
291
303
  c: getErrorConstructorName(current),
292
- m: quote(current.message),
304
+ m: serializeString(current.message),
293
305
  d: optionsNode,
294
306
  a: undefined,
295
307
  f: undefined,
308
+ b: undefined,
309
+ };
310
+ }
311
+
312
+ function generateHeadersNode(
313
+ ctx: ParserContext,
314
+ id: number,
315
+ current: Headers,
316
+ ): SerovalHeadersNode {
317
+ assert(ctx.features & Feature.WebAPI, 'Unsupported type "Headers"');
318
+ const items: Record<string, string> = {};
319
+ current.forEach((value, key) => {
320
+ items[key] = value;
321
+ });
322
+ return {
323
+ t: SerovalNodeType.Headers,
324
+ i: id,
325
+ s: undefined,
326
+ l: undefined,
327
+ c: undefined,
328
+ m: undefined,
329
+ d: generateProperties(ctx, items),
330
+ a: undefined,
331
+ f: undefined,
332
+ b: undefined,
333
+ };
334
+ }
335
+
336
+ function generateFormDataNode(
337
+ ctx: ParserContext,
338
+ id: number,
339
+ current: FormData,
340
+ ): SerovalFormDataNode {
341
+ assert(ctx.features & Feature.WebAPI, 'Unsupported type "FormData"');
342
+ const items: Record<string, FormDataEntryValue> = {};
343
+ current.forEach((value, key) => {
344
+ items[key] = value;
345
+ });
346
+ return {
347
+ t: SerovalNodeType.FormData,
348
+ i: id,
349
+ s: undefined,
350
+ l: undefined,
351
+ c: undefined,
352
+ m: undefined,
353
+ d: generateProperties(ctx, items),
354
+ a: undefined,
355
+ f: undefined,
356
+ b: undefined,
296
357
  };
297
358
  }
298
359
 
@@ -344,6 +405,8 @@ function parse<T>(
344
405
  return createDateNode(id, current as unknown as Date);
345
406
  case RegExp:
346
407
  return createRegExpNode(id, current as unknown as RegExp);
408
+ case ArrayBuffer:
409
+ return createArrayBufferNode(id, current as unknown as ArrayBuffer);
347
410
  case Int8Array:
348
411
  case Int16Array:
349
412
  case Int32Array:
@@ -357,6 +420,8 @@ function parse<T>(
357
420
  case BigInt64Array:
358
421
  case BigUint64Array:
359
422
  return createBigIntTypedArrayNode(ctx, id, current as unknown as BigIntTypedArrayValue);
423
+ case DataView:
424
+ return createDataViewNode(ctx, id, current as unknown as DataView);
360
425
  case Map:
361
426
  return generateMapNode(ctx, id, current as unknown as Map<unknown, unknown>);
362
427
  case Set:
@@ -392,6 +457,10 @@ function parse<T>(
392
457
  return createURLNode(ctx, id, current as unknown as URL);
393
458
  case URLSearchParams:
394
459
  return createURLSearchParamsNode(ctx, id, current as unknown as URLSearchParams);
460
+ case Headers:
461
+ return generateHeadersNode(ctx, id, current as unknown as Headers);
462
+ case FormData:
463
+ return generateFormDataNode(ctx, id, current as unknown as FormData);
395
464
  default:
396
465
  break;
397
466
  }