seroval 0.5.1 → 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,7 @@ import {
6
6
  getRefParam,
7
7
  markRef,
8
8
  } from '../context';
9
- import quote from '../quote';
9
+ import { GLOBAL_KEY } from './reference';
10
10
  import { isValidIdentifier } from './shared';
11
11
  import { SYMBOL_STRING } from './symbols';
12
12
  import {
@@ -22,19 +22,32 @@ import {
22
22
  SerovalObjectNode,
23
23
  SerovalObjectRecordNode,
24
24
  SerovalPromiseNode,
25
- SerovalReferenceNode,
25
+ SerovalIndexedValueNode,
26
26
  SerovalSetNode,
27
27
  SerovalTypedArrayNode,
28
+ SerovalArrayBufferNode,
29
+ SerovalDataViewNode,
30
+ SerovalBlobNode,
31
+ SerovalFileNode,
32
+ SerovalHeadersNode,
33
+ SerovalRegExpNode,
34
+ SerovalDateNode,
35
+ SerovalURLNode,
36
+ SerovalURLSearchParamsNode,
37
+ SerovalReferenceNode,
38
+ SerovalFormDataNode,
28
39
  } from './types';
29
40
 
30
41
  function getAssignmentExpression(assignment: Assignment): string {
31
42
  switch (assignment.t) {
32
43
  case 'index':
33
44
  return assignment.s + '=' + assignment.v;
34
- case 'map':
35
- return assignment.s + '.set(' + assignment.k + ',' + assignment.v + ')';
36
45
  case 'set':
46
+ return assignment.s + '.set(' + assignment.k + ',' + assignment.v + ')';
47
+ case 'add':
37
48
  return assignment.s + '.add(' + assignment.v + ')';
49
+ case 'append':
50
+ return assignment.s + '.append(' + assignment.k + ',' + assignment.v + ')';
38
51
  default:
39
52
  return '';
40
53
  }
@@ -65,11 +78,11 @@ function mergeAssignments(assignments: Assignment[]) {
65
78
  current = item;
66
79
  }
67
80
  break;
68
- case 'map':
81
+ case 'set':
69
82
  if (item.s === prev.s) {
70
83
  // Maps has chaining methods, merge if source is the same
71
84
  current = {
72
- t: 'map',
85
+ t: 'set',
73
86
  s: getAssignmentExpression(current),
74
87
  k: item.k,
75
88
  v: item.v,
@@ -80,11 +93,11 @@ function mergeAssignments(assignments: Assignment[]) {
80
93
  current = item;
81
94
  }
82
95
  break;
83
- case 'set':
96
+ case 'add':
84
97
  if (item.s === prev.s) {
85
98
  // Sets has chaining methods too
86
99
  current = {
87
- t: 'set',
100
+ t: 'add',
88
101
  s: getAssignmentExpression(current),
89
102
  k: undefined,
90
103
  v: item.v,
@@ -95,6 +108,11 @@ function mergeAssignments(assignments: Assignment[]) {
95
108
  current = item;
96
109
  }
97
110
  break;
111
+ case 'append':
112
+ // Different assignment, push current
113
+ newAssignments.push(current);
114
+ current = item;
115
+ break;
98
116
  default:
99
117
  break;
100
118
  }
@@ -145,29 +163,41 @@ function createAssignment(
145
163
  });
146
164
  }
147
165
 
148
- function createSetAdd(
166
+ function createAddAssignment(
149
167
  ctx: SerializationContext,
150
168
  ref: number,
151
169
  value: string,
152
170
  ) {
153
- markRef(ctx, ref);
154
171
  ctx.assignments.push({
155
- t: 'set',
172
+ t: 'add',
156
173
  s: getRefParam(ctx, ref),
157
174
  k: undefined,
158
175
  v: value,
159
176
  });
160
177
  }
161
178
 
162
- 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(
163
194
  ctx: SerializationContext,
164
195
  ref: number,
165
196
  key: string,
166
197
  value: string,
167
198
  ) {
168
- markRef(ctx, ref);
169
199
  ctx.assignments.push({
170
- t: 'map',
200
+ t: 'append',
171
201
  s: getRefParam(ctx, ref),
172
202
  k: key,
173
203
  v: value,
@@ -180,7 +210,6 @@ function createArrayAssign(
180
210
  index: number | string,
181
211
  value: string,
182
212
  ) {
183
- markRef(ctx, ref);
184
213
  createAssignment(ctx, getRefParam(ctx, ref) + '[' + index + ']', value);
185
214
  }
186
215
 
@@ -194,7 +223,7 @@ function createObjectAssign(
194
223
  createAssignment(ctx, getRefParam(ctx, ref) + '.' + key, value);
195
224
  }
196
225
 
197
- function assignRef(
226
+ function assignIndexedValue(
198
227
  ctx: SerializationContext,
199
228
  index: number,
200
229
  value: string,
@@ -205,16 +234,20 @@ function assignRef(
205
234
  return value;
206
235
  }
207
236
 
208
- function isReferenceInStack(
237
+ function isIndexedValueInStack(
209
238
  ctx: SerializationContext,
210
239
  node: SerovalNode,
211
- ): node is SerovalReferenceNode {
212
- return node.t === SerovalNodeType.Reference && ctx.stack.includes(node.i);
240
+ ): node is SerovalIndexedValueNode {
241
+ return node.t === SerovalNodeType.IndexedValue && ctx.stack.includes(node.i);
213
242
  }
214
243
 
244
+ type SerovalNodeListNode =
245
+ | SerovalArrayNode
246
+ | SerovalIterableNode;
247
+
215
248
  function serializeNodeList(
216
249
  ctx: SerializationContext,
217
- node: SerovalArrayNode | SerovalIterableNode | SerovalAggregateErrorNode,
250
+ node: SerovalNodeListNode,
218
251
  ) {
219
252
  // This is different than Map and Set
220
253
  // because we also need to serialize
@@ -232,7 +265,8 @@ function serializeNodeList(
232
265
  // Check if index is a hole
233
266
  if (item) {
234
267
  // Check if item is a parent
235
- if (isReferenceInStack(ctx, item)) {
268
+ if (isIndexedValueInStack(ctx, item)) {
269
+ markRef(ctx, node.i);
236
270
  createArrayAssign(ctx, node.i, i, getRefParam(ctx, item.i));
237
271
  isHoley = true;
238
272
  } else {
@@ -253,7 +287,7 @@ function serializeArray(
253
287
  ctx.stack.push(node.i);
254
288
  const result = serializeNodeList(ctx, node);
255
289
  ctx.stack.pop();
256
- return assignRef(ctx, node.i, result);
290
+ return assignIndexedValue(ctx, node.i, result);
257
291
  }
258
292
 
259
293
  function serializeProperties(
@@ -272,23 +306,27 @@ function serializeProperties(
272
306
  let isIdentifier: boolean;
273
307
  let refParam: string;
274
308
  let hasPrev = false;
275
- for (let i = 0; i < node.s; i++) {
276
- key = node.k[i];
277
- 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];
278
314
  check = Number(key);
279
315
  // Test if key is a valid number or JS identifier
280
316
  // so that we don't have to serialize the key and wrap with brackets
281
317
  isIdentifier = check >= 0 || isValidIdentifier(key);
282
- if (isReferenceInStack(ctx, val)) {
318
+ if (isIndexedValueInStack(ctx, val)) {
283
319
  refParam = getRefParam(ctx, val.i);
284
320
  if (isIdentifier && Number.isNaN(check)) {
321
+ markRef(ctx, sourceID);
285
322
  createObjectAssign(ctx, sourceID, key, refParam);
286
323
  } else {
287
- createArrayAssign(ctx, sourceID, isIdentifier ? key : ('"' + quote(key) + '"'), refParam);
324
+ markRef(ctx, sourceID);
325
+ createArrayAssign(ctx, sourceID, isIdentifier ? key : ('"' + key + '"'), refParam);
288
326
  }
289
327
  } else {
290
328
  result += (hasPrev ? ',' : '')
291
- + (isIdentifier ? key : ('"' + quote(key) + '"'))
329
+ + (isIdentifier ? key : ('"' + key + '"'))
292
330
  + ':' + serializeTree(ctx, val);
293
331
  hasPrev = true;
294
332
  }
@@ -323,12 +361,14 @@ function serializeAssignments(
323
361
  let check: number;
324
362
  let parentAssignment: Assignment[];
325
363
  let isIdentifier: boolean;
326
- 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++) {
327
367
  parentStack = ctx.stack;
328
368
  ctx.stack = [];
329
- refParam = serializeTree(ctx, node.v[i]);
369
+ refParam = serializeTree(ctx, values[i]);
330
370
  ctx.stack = parentStack;
331
- key = node.k[i];
371
+ key = keys[i];
332
372
  check = Number(key);
333
373
  parentAssignment = ctx.assignments;
334
374
  ctx.assignments = mainAssignments;
@@ -338,7 +378,7 @@ function serializeAssignments(
338
378
  if (isIdentifier && Number.isNaN(check)) {
339
379
  createObjectAssign(ctx, sourceID, key, refParam);
340
380
  } else {
341
- createArrayAssign(ctx, sourceID, isIdentifier ? key : ('"' + quote(key) + '"'), refParam);
381
+ createArrayAssign(ctx, sourceID, isIdentifier ? key : ('"' + key + '"'), refParam);
342
382
  }
343
383
  ctx.assignments = parentAssignment;
344
384
  }
@@ -359,11 +399,11 @@ function serializeDictionary(
359
399
  markRef(ctx, i);
360
400
  const assignments = serializeAssignments(ctx, i, d);
361
401
  if (assignments) {
362
- return '(' + assignRef(ctx, i, init) + ',' + assignments + getRefParam(ctx, i) + ')';
402
+ return '(' + assignIndexedValue(ctx, i, init) + ',' + assignments + getRefParam(ctx, i) + ')';
363
403
  }
364
404
  }
365
405
  }
366
- return assignRef(ctx, i, init);
406
+ return assignIndexedValue(ctx, i, init);
367
407
  }
368
408
 
369
409
  function serializeNullConstructor(
@@ -377,7 +417,7 @@ function serializeObject(
377
417
  ctx: SerializationContext,
378
418
  node: SerovalObjectNode,
379
419
  ) {
380
- return assignRef(ctx, node.i, serializeProperties(ctx, node.i, node.d));
420
+ return assignIndexedValue(ctx, node.i, serializeProperties(ctx, node.i, node.d));
381
421
  }
382
422
 
383
423
  function serializeSet(
@@ -393,8 +433,9 @@ function serializeSet(
393
433
  let hasPrev = false;
394
434
  for (let i = 0; i < size; i++) {
395
435
  item = node.a[i];
396
- if (isReferenceInStack(ctx, item)) {
397
- createSetAdd(ctx, node.i, getRefParam(ctx, item.i));
436
+ if (isIndexedValueInStack(ctx, item)) {
437
+ markRef(ctx, node.i);
438
+ createAddAssignment(ctx, node.i, getRefParam(ctx, item.i));
398
439
  } else {
399
440
  // Push directly
400
441
  result += (hasPrev ? ',' : '') + serializeTree(ctx, item);
@@ -406,7 +447,7 @@ function serializeSet(
406
447
  serialized += '([' + result + '])';
407
448
  }
408
449
  }
409
- return assignRef(ctx, node.i, serialized);
450
+ return assignIndexedValue(ctx, node.i, serialized);
410
451
  }
411
452
 
412
453
  function serializeMap(
@@ -427,16 +468,17 @@ function serializeMap(
427
468
  // Check if key is a parent
428
469
  key = node.d.k[i];
429
470
  val = node.d.v[i];
430
- if (isReferenceInStack(ctx, key)) {
471
+ if (isIndexedValueInStack(ctx, key)) {
431
472
  // Create reference for the map instance
432
473
  keyRef = getRefParam(ctx, key.i);
474
+ markRef(ctx, node.i);
433
475
  // Check if value is a parent
434
- if (isReferenceInStack(ctx, val)) {
476
+ if (isIndexedValueInStack(ctx, val)) {
435
477
  valueRef = getRefParam(ctx, val.i);
436
478
  // Register an assignment since
437
479
  // both key and value are a parent of this
438
480
  // Map instance
439
- createMapSet(ctx, node.i, keyRef, valueRef);
481
+ createSetAssignment(ctx, node.i, keyRef, valueRef);
440
482
  } else {
441
483
  // Reset the stack
442
484
  // This is required because the serialized
@@ -445,16 +487,17 @@ function serializeMap(
445
487
  // assignment
446
488
  parent = ctx.stack;
447
489
  ctx.stack = [];
448
- createMapSet(ctx, node.i, keyRef, serializeTree(ctx, val));
490
+ createSetAssignment(ctx, node.i, keyRef, serializeTree(ctx, val));
449
491
  ctx.stack = parent;
450
492
  }
451
- } else if (isReferenceInStack(ctx, val)) {
493
+ } else if (isIndexedValueInStack(ctx, val)) {
452
494
  // Create ref for the Map instance
453
495
  valueRef = getRefParam(ctx, val.i);
496
+ markRef(ctx, node.i);
454
497
  // Reset stack for the key serialization
455
498
  parent = ctx.stack;
456
499
  ctx.stack = [];
457
- createMapSet(ctx, node.i, serializeTree(ctx, key), valueRef);
500
+ createSetAssignment(ctx, node.i, serializeTree(ctx, key), valueRef);
458
501
  ctx.stack = parent;
459
502
  } else {
460
503
  result += (hasPrev ? ',[' : '[') + serializeTree(ctx, key) + ',' + serializeTree(ctx, val) + ']';
@@ -469,7 +512,7 @@ function serializeMap(
469
512
  serialized += '([' + result + '])';
470
513
  }
471
514
  }
472
- return assignRef(ctx, node.i, serialized);
515
+ return assignIndexedValue(ctx, node.i, serialized);
473
516
  }
474
517
 
475
518
  function serializeAggregateError(
@@ -478,7 +521,7 @@ function serializeAggregateError(
478
521
  ) {
479
522
  // Serialize the required arguments
480
523
  ctx.stack.push(node.i);
481
- const serialized = 'new AggregateError(' + serializeNodeList(ctx, node) + ',"' + quote(node.m) + '")';
524
+ const serialized = 'new AggregateError([],"' + node.m + '")';
482
525
  ctx.stack.pop();
483
526
  // `AggregateError` might've been extended
484
527
  // either through class or custom properties
@@ -490,7 +533,7 @@ function serializeError(
490
533
  ctx: SerializationContext,
491
534
  node: SerovalErrorNode,
492
535
  ) {
493
- const serialized = 'new ' + node.c + '("' + quote(node.m) + '")';
536
+ const serialized = 'new ' + node.c + '("' + node.m + '")';
494
537
  return serializeDictionary(ctx, node.i, node.d, serialized);
495
538
  }
496
539
 
@@ -500,7 +543,7 @@ function serializePromise(
500
543
  ) {
501
544
  let serialized: string;
502
545
  // Check if resolved value is a parent expression
503
- if (isReferenceInStack(ctx, node.f)) {
546
+ if (isIndexedValueInStack(ctx, node.f)) {
504
547
  // A Promise trick, reference the value
505
548
  // inside the `then` expression so that
506
549
  // the Promise evaluates after the parent
@@ -518,20 +561,30 @@ function serializePromise(
518
561
  // just inline the value/reference here
519
562
  serialized = 'Promise.resolve(' + result + ')';
520
563
  }
521
- return assignRef(ctx, node.i, serialized);
564
+ return assignIndexedValue(ctx, node.i, serialized);
565
+ }
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');
522
580
  }
523
581
 
524
582
  function serializeTypedArray(
525
583
  ctx: SerializationContext,
526
584
  node: SerovalTypedArrayNode | SerovalBigIntTypedArrayNode,
527
585
  ) {
528
- let result = '';
529
- const isBigInt = node.t === SerovalNodeType.BigIntTypedArray;
530
- for (let i = 0, len = node.s.length; i < len; i++) {
531
- result += (i !== 0 ? ',' : '') + node.s[i] + (isBigInt ? 'n' : '');
532
- }
533
- const args = '[' + result + ']' + (node.l !== 0 ? (',' + node.l) : '');
534
- return assignRef(ctx, node.i, 'new ' + node.c + '(' + args + ')');
586
+ const args = serializeTree(ctx, node.f) + ',' + node.b + ',' + node.l;
587
+ return assignIndexedValue(ctx, node.i, 'new ' + node.c + '(' + args + ')');
535
588
  }
536
589
 
537
590
  function serializeIterable(
@@ -558,6 +611,112 @@ function serializeIterable(
558
611
  return serializeDictionary(ctx, node.i, node.d, serialized);
559
612
  }
560
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
+
561
720
  export default function serializeTree(
562
721
  ctx: SerializationContext,
563
722
  node: SerovalNode,
@@ -583,7 +742,7 @@ export default function serializeTree(
583
742
  return 'NaN';
584
743
  case SerovalNodeType.BigInt:
585
744
  return node.s + 'n';
586
- case SerovalNodeType.Reference:
745
+ case SerovalNodeType.IndexedValue:
587
746
  return getRefParam(ctx, node.i);
588
747
  case SerovalNodeType.Array:
589
748
  return serializeArray(ctx, node);
@@ -592,16 +751,20 @@ export default function serializeTree(
592
751
  case SerovalNodeType.NullConstructor:
593
752
  return serializeNullConstructor(ctx, node);
594
753
  case SerovalNodeType.Date:
595
- return assignRef(ctx, node.i, 'new Date("' + node.s + '")');
754
+ return serializeDate(ctx, node);
596
755
  case SerovalNodeType.RegExp:
597
- return assignRef(ctx, node.i, '/' + node.c + '/' + node.m);
756
+ return serializeRegExp(ctx, node);
598
757
  case SerovalNodeType.Set:
599
758
  return serializeSet(ctx, node);
600
759
  case SerovalNodeType.Map:
601
760
  return serializeMap(ctx, node);
761
+ case SerovalNodeType.ArrayBuffer:
762
+ return serializeArrayBuffer(ctx, node);
602
763
  case SerovalNodeType.BigIntTypedArray:
603
764
  case SerovalNodeType.TypedArray:
604
765
  return serializeTypedArray(ctx, node);
766
+ case SerovalNodeType.DataView:
767
+ return serializeDataView(ctx, node);
605
768
  case SerovalNodeType.AggregateError:
606
769
  return serializeAggregateError(ctx, node);
607
770
  case SerovalNodeType.Error:
@@ -612,6 +775,20 @@ export default function serializeTree(
612
775
  return serializePromise(ctx, node);
613
776
  case SerovalNodeType.WKSymbol:
614
777
  return SYMBOL_STRING[node.s];
778
+ case SerovalNodeType.URL:
779
+ return serializeURL(ctx, node);
780
+ case SerovalNodeType.URLSearchParams:
781
+ return serializeURLSearchParams(ctx, node);
782
+ case SerovalNodeType.Reference:
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);
615
792
  default:
616
793
  throw new Error('Unsupported type');
617
794
  }