seroval 0.10.3 → 0.11.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.
package/src/core/keys.ts CHANGED
@@ -30,7 +30,7 @@ export const GLOBAL_CONTEXT_API_SCRIPT = `self.${GLOBAL_CONTEXT_API}=self.${GLOB
30
30
  + `${GLOBAL_CONTEXT_PROMISE_REJECT}:function(p,d){p.${LOCAL_CONTEXT_PROMISE_REJECT}(d),this.uP(p)},`
31
31
  + `uS:function(s){delete s.${LOCAL_CONTEXT_STREAM_CONTROLLER}},`
32
32
  + `${GLOBAL_CONTEXT_STREAM_EMIT}:function(s,t,d,c){switch(c=s.${LOCAL_CONTEXT_STREAM_CONTROLLER},t){case 0:return c.enqueue(d);case 1:return(this.uS(s),c.error(d));case 2:return(this.uS(s),c.close())}},`
33
- + `${GLOBAL_CONTEXT_STREAM_CONSTRUCTOR}:function(s,c){return(s=new ReadableStream({start:function(x){c=x}})).${LOCAL_CONTEXT_STREAM_CONTROLLER}=c,s},`
33
+ + `${GLOBAL_CONTEXT_STREAM_CONSTRUCTOR}:function(s,c){return(s=new ReadableStream({start:function(x){c=x}})).${LOCAL_CONTEXT_STREAM_CONTROLLER}=c,s}`
34
34
  + '}';
35
35
 
36
36
  export function getCrossReferenceHeader(id?: string): string {
@@ -1,7 +1,6 @@
1
1
  /* eslint-disable no-await-in-loop */
2
2
  /* eslint-disable @typescript-eslint/no-use-before-define */
3
- import assert from '../assert';
4
- import { Feature } from '../compat';
3
+ import { BIGINT_FLAG, Feature } from '../compat';
5
4
  import type { ParserContext } from './context';
6
5
  import {
7
6
  createIndexedValue,
@@ -24,6 +23,7 @@ import {
24
23
  createDataViewNode,
25
24
  createSymbolNode,
26
25
  createFunctionNode,
26
+ serializeArrayBuffer,
27
27
  } from './primitives';
28
28
  import { hasReferenceID } from '../reference';
29
29
  import {
@@ -36,7 +36,9 @@ import type {
36
36
  SerovalAggregateErrorNode,
37
37
  SerovalArrayNode,
38
38
  SerovalBoxedNode,
39
+ SerovalCustomEventNode,
39
40
  SerovalErrorNode,
41
+ SerovalEventNode,
40
42
  SerovalFormDataNode,
41
43
  SerovalHeadersNode,
42
44
  SerovalMapNode,
@@ -47,6 +49,8 @@ import type {
47
49
  SerovalObjectRecordNode,
48
50
  SerovalPlainRecordNode,
49
51
  SerovalPromiseNode,
52
+ SerovalRequestNode,
53
+ SerovalResponseNode,
50
54
  SerovalSetNode,
51
55
  } from '../types';
52
56
  import {
@@ -67,8 +71,14 @@ import {
67
71
  createRegExpNode,
68
72
  createStringNode,
69
73
  } from '../base-primitives';
70
- import { createURLNode, createURLSearchParamsNode } from '../web-api';
74
+ import { createDOMExceptionNode, createURLNode, createURLSearchParamsNode } from '../web-api';
71
75
  import promiseToResult from '../promise-to-result';
76
+ import {
77
+ createCustomEventOptions,
78
+ createEventOptions,
79
+ createRequestOptions,
80
+ createResponseOptions,
81
+ } from '../constructors';
72
82
 
73
83
  type ObjectLikeNode =
74
84
  | SerovalObjectNode
@@ -127,7 +137,6 @@ async function generateMapNode(
127
137
  id: number,
128
138
  current: Map<unknown, unknown>,
129
139
  ): Promise<SerovalMapNode> {
130
- assert(ctx.features & Feature.Map, new UnsupportedTypeError(current));
131
140
  const len = current.size;
132
141
  const keyNodes = new Array<SerovalNode>(len);
133
142
  const valueNodes = new Array<SerovalNode>(len);
@@ -172,7 +181,6 @@ async function generateSetNode(
172
181
  id: number,
173
182
  current: Set<unknown>,
174
183
  ): Promise<SerovalSetNode> {
175
- assert(ctx.features & Feature.Set, new UnsupportedTypeError(current));
176
184
  const len = current.size;
177
185
  const nodes = new Array<SerovalNode>(len);
178
186
  const deferred = new Array<unknown>(len);
@@ -299,7 +307,6 @@ async function generatePromiseNode(
299
307
  id: number,
300
308
  current: Promise<unknown>,
301
309
  ): Promise<SerovalPromiseNode> {
302
- assert(ctx.features & Feature.Promise, new UnsupportedTypeError(current));
303
310
  const [status, result] = await promiseToResult(current);
304
311
  return {
305
312
  t: SerovalNodeType.Promise,
@@ -394,7 +401,6 @@ async function generateHeadersNode(
394
401
  id: number,
395
402
  current: Headers,
396
403
  ): Promise<SerovalHeadersNode> {
397
- assert(ctx.features & Feature.WebAPI, new UnsupportedTypeError(current));
398
404
  const items: Record<string, string> = {};
399
405
  current.forEach((value, key) => {
400
406
  items[key] = value;
@@ -420,7 +426,6 @@ async function generateFormDataNode(
420
426
  id: number,
421
427
  current: FormData,
422
428
  ): Promise<SerovalFormDataNode> {
423
- assert(ctx.features & Feature.WebAPI, new UnsupportedTypeError(current));
424
429
  const items: Record<string, FormDataEntryValue> = {};
425
430
  current.forEach((value, key) => {
426
431
  items[key] = value;
@@ -462,6 +467,98 @@ async function generateBoxedNode(
462
467
  };
463
468
  }
464
469
 
470
+ async function generateRequestNode(
471
+ ctx: ParserContext,
472
+ id: number,
473
+ current: Request,
474
+ ): Promise<SerovalRequestNode> {
475
+ return {
476
+ t: SerovalNodeType.Request,
477
+ i: id,
478
+ s: serializeString(current.url),
479
+ l: undefined,
480
+ c: undefined,
481
+ m: undefined,
482
+ p: undefined,
483
+ e: undefined,
484
+ f: await parseObject(
485
+ ctx,
486
+ createRequestOptions(current, current.body ? await current.clone().arrayBuffer() : null),
487
+ ),
488
+ a: undefined,
489
+ b: undefined,
490
+ o: undefined,
491
+ };
492
+ }
493
+
494
+ async function generateResponseNode(
495
+ ctx: ParserContext,
496
+ id: number,
497
+ current: Response,
498
+ ): Promise<SerovalResponseNode> {
499
+ return {
500
+ t: SerovalNodeType.Response,
501
+ i: id,
502
+ s: undefined,
503
+ l: undefined,
504
+ c: undefined,
505
+ m: undefined,
506
+ p: undefined,
507
+ e: undefined,
508
+ f: undefined,
509
+ a: [
510
+ current.body
511
+ ? serializeArrayBuffer(ctx, await current.clone().arrayBuffer())
512
+ : NULL_NODE,
513
+ await parseObject(ctx, createResponseOptions(current)),
514
+ ],
515
+ b: undefined,
516
+ o: undefined,
517
+ };
518
+ }
519
+
520
+ async function generateEventNode(
521
+ ctx: ParserContext,
522
+ id: number,
523
+ current: Event,
524
+ ): Promise<SerovalEventNode> {
525
+ return {
526
+ t: SerovalNodeType.Event,
527
+ i: id,
528
+ s: serializeString(current.type),
529
+ l: undefined,
530
+ c: undefined,
531
+ m: undefined,
532
+ p: undefined,
533
+ e: undefined,
534
+ a: undefined,
535
+ f: await parseObject(ctx, createEventOptions(current)),
536
+ b: undefined,
537
+ o: undefined,
538
+ };
539
+ }
540
+
541
+ async function generateCustomEventNode(
542
+ ctx: ParserContext,
543
+ id: number,
544
+ current: CustomEvent,
545
+ ): Promise<SerovalCustomEventNode> {
546
+ return {
547
+ t: SerovalNodeType.CustomEvent,
548
+ i: id,
549
+ s: serializeString(current.type),
550
+ l: undefined,
551
+ c: undefined,
552
+ m: undefined,
553
+ p: undefined,
554
+ e: undefined,
555
+ a: undefined,
556
+ f: await parseObject(ctx, createCustomEventOptions(current)),
557
+ b: undefined,
558
+ o: undefined,
559
+ };
560
+ }
561
+
465
562
  async function parseObject(
466
563
  ctx: ParserContext,
467
564
  current: object | null,
@@ -481,49 +578,17 @@ async function parseObject(
481
578
  if (Array.isArray(current)) {
482
579
  return generateArrayNode(ctx, id, current);
483
580
  }
484
- switch (current.constructor) {
581
+ const currentClass = current.constructor;
582
+ switch (currentClass) {
485
583
  case Number:
486
584
  case Boolean:
487
585
  case String:
488
586
  case BigInt:
489
- case Function:
490
- case Symbol:
491
587
  return generateBoxedNode(ctx, id, current);
492
588
  case Date:
493
589
  return createDateNode(id, current as unknown as Date);
494
590
  case RegExp:
495
591
  return createRegExpNode(id, current as unknown as RegExp);
496
- case Promise:
497
- return generatePromiseNode(ctx, id, current as unknown as Promise<unknown>);
498
- case ArrayBuffer:
499
- return createArrayBufferNode(id, current as unknown as ArrayBuffer);
500
- case Int8Array:
501
- case Int16Array:
502
- case Int32Array:
503
- case Uint8Array:
504
- case Uint16Array:
505
- case Uint32Array:
506
- case Uint8ClampedArray:
507
- case Float32Array:
508
- case Float64Array:
509
- return createTypedArrayNode(ctx, id, current as unknown as TypedArrayValue);
510
- case BigInt64Array:
511
- case BigUint64Array:
512
- return createBigIntTypedArrayNode(ctx, id, current as unknown as BigIntTypedArrayValue);
513
- case DataView:
514
- return createDataViewNode(ctx, id, current as unknown as DataView);
515
- case Map:
516
- return generateMapNode(
517
- ctx,
518
- id,
519
- current as unknown as Map<unknown, unknown>,
520
- );
521
- case Set:
522
- return generateSetNode(
523
- ctx,
524
- id,
525
- current as unknown as Set<unknown>,
526
- );
527
592
  case Object:
528
593
  return generateObjectNode(
529
594
  ctx,
@@ -538,11 +603,6 @@ async function parseObject(
538
603
  current as Record<string, unknown>,
539
604
  true,
540
605
  );
541
- case AggregateError:
542
- if (ctx.features & Feature.AggregateError) {
543
- return generateAggregateErrorNode(ctx, id, current as unknown as AggregateError);
544
- }
545
- return generateErrorNode(ctx, id, current as unknown as AggregateError);
546
606
  case Error:
547
607
  case EvalError:
548
608
  case RangeError:
@@ -551,36 +611,106 @@ async function parseObject(
551
611
  case TypeError:
552
612
  case URIError:
553
613
  return generateErrorNode(ctx, id, current as unknown as Error);
554
- case URL:
555
- return createURLNode(ctx, id, current as unknown as URL);
556
- case URLSearchParams:
557
- return createURLSearchParamsNode(ctx, id, current as unknown as URLSearchParams);
558
- case Blob:
559
- return createBlobNode(ctx, id, current as unknown as Blob);
560
- case File:
561
- return createFileNode(ctx, id, current as unknown as File);
562
- case Headers:
563
- return generateHeadersNode(ctx, id, current as unknown as Headers);
564
- case FormData:
565
- return generateFormDataNode(ctx, id, current as unknown as FormData);
566
614
  default:
567
615
  break;
568
616
  }
569
- if (current instanceof AggregateError) {
570
- if (ctx.features & Feature.AggregateError) {
571
- return generateAggregateErrorNode(ctx, id, current);
617
+ // Typed Arrays
618
+ if (ctx.features & Feature.TypedArray) {
619
+ switch (currentClass) {
620
+ case ArrayBuffer:
621
+ return createArrayBufferNode(id, current as unknown as ArrayBuffer);
622
+ case Int8Array:
623
+ case Int16Array:
624
+ case Int32Array:
625
+ case Uint8Array:
626
+ case Uint16Array:
627
+ case Uint32Array:
628
+ case Uint8ClampedArray:
629
+ case Float32Array:
630
+ case Float64Array:
631
+ return createTypedArrayNode(ctx, id, current as unknown as TypedArrayValue);
632
+ case DataView:
633
+ return createDataViewNode(ctx, id, current as unknown as DataView);
634
+ default:
635
+ break;
572
636
  }
573
- return generateErrorNode(ctx, id, current);
574
637
  }
638
+ // BigInt Typed Arrays
639
+ if ((ctx.features & BIGINT_FLAG) === BIGINT_FLAG) {
640
+ switch (currentClass) {
641
+ case BigInt64Array:
642
+ case BigUint64Array:
643
+ return createBigIntTypedArrayNode(ctx, id, current as unknown as BigIntTypedArrayValue);
644
+ default:
645
+ break;
646
+ }
647
+ }
648
+ // ES Collection
649
+ if (ctx.features & Feature.Map && currentClass === Map) {
650
+ return generateMapNode(
651
+ ctx,
652
+ id,
653
+ current as unknown as Map<unknown, unknown>,
654
+ );
655
+ }
656
+ if (ctx.features & Feature.Set && currentClass === Set) {
657
+ return generateSetNode(
658
+ ctx,
659
+ id,
660
+ current as unknown as Set<unknown>,
661
+ );
662
+ }
663
+ // Web APIs
664
+ if (ctx.features & Feature.WebAPI) {
665
+ switch (currentClass) {
666
+ case URL:
667
+ return createURLNode(id, current as unknown as URL);
668
+ case URLSearchParams:
669
+ return createURLSearchParamsNode(id, current as unknown as URLSearchParams);
670
+ case Blob:
671
+ return createBlobNode(ctx, id, current as unknown as Blob);
672
+ case File:
673
+ return createFileNode(ctx, id, current as unknown as File);
674
+ case Headers:
675
+ return generateHeadersNode(ctx, id, current as unknown as Headers);
676
+ case FormData:
677
+ return generateFormDataNode(ctx, id, current as unknown as FormData);
678
+ case Request:
679
+ return generateRequestNode(ctx, id, current as unknown as Request);
680
+ case Response:
681
+ return generateResponseNode(ctx, id, current as unknown as Response);
682
+ case Event:
683
+ return generateEventNode(ctx, id, current as unknown as Event);
684
+ case CustomEvent:
685
+ return generateCustomEventNode(ctx, id, current as unknown as CustomEvent);
686
+ case DOMException:
687
+ return createDOMExceptionNode(id, current as unknown as DOMException);
688
+ default:
689
+ break;
690
+ }
691
+ }
692
+ if (
693
+ (ctx.features & Feature.AggregateError)
694
+ && (currentClass === AggregateError || current instanceof AggregateError)
695
+ ) {
696
+ return generateAggregateErrorNode(ctx, id, current as unknown as AggregateError);
697
+ }
698
+ // Promises
699
+ if (
700
+ (ctx.features & Feature.Promise)
701
+ && (currentClass === Promise || current instanceof Promise)
702
+ ) {
703
+ return generatePromiseNode(ctx, id, current as unknown as Promise<unknown>);
704
+ }
705
+ // Slow path. We only need to handle Errors and Iterators
706
+ // since they have very broad implementations.
575
707
  if (current instanceof Error) {
576
708
  return generateErrorNode(ctx, id, current);
577
709
  }
578
- if (current instanceof Promise) {
579
- return generatePromiseNode(ctx, id, current);
580
- }
581
710
  // Generator functions don't have a global constructor
582
- if (Symbol.iterator in current) {
583
- return generateObjectNode(ctx, id, current, !!current.constructor);
711
+ // despite existing
712
+ if (ctx.features & Feature.Symbol && Symbol.iterator in current) {
713
+ return generateObjectNode(ctx, id, current, !!currentClass);
584
714
  }
585
715
  throw new UnsupportedTypeError(current);
586
716
  }
@@ -589,23 +719,26 @@ export default async function parseAsync<T>(
589
719
  ctx: ParserContext,
590
720
  current: T,
591
721
  ): Promise<SerovalNode> {
592
- switch (typeof current) {
722
+ const t = typeof current;
723
+ if (ctx.features & Feature.BigInt && t === 'bigint') {
724
+ return createBigIntNode(ctx, current as bigint);
725
+ }
726
+ switch (t) {
593
727
  case 'boolean':
594
728
  return current ? TRUE_NODE : FALSE_NODE;
595
729
  case 'undefined':
596
730
  return UNDEFINED_NODE;
597
731
  case 'string':
598
- return createStringNode(current);
732
+ return createStringNode(current as string);
599
733
  case 'number':
600
- return createNumberNode(current);
601
- case 'bigint':
602
- return createBigIntNode(ctx, current);
734
+ return createNumberNode(current as number);
603
735
  case 'object':
604
- return parseObject(ctx, current);
736
+ return parseObject(ctx, current as object);
605
737
  case 'symbol':
606
- return createSymbolNode(ctx, current);
738
+ return createSymbolNode(ctx, current as symbol);
607
739
  case 'function':
608
- return createFunctionNode(ctx, current);
740
+ // eslint-disable-next-line @typescript-eslint/ban-types
741
+ return createFunctionNode(ctx, current as Function);
609
742
  default:
610
743
  throw new UnsupportedTypeError(current);
611
744
  }
@@ -14,9 +14,12 @@ import type {
14
14
  SerovalBigIntTypedArrayNode,
15
15
  SerovalBlobNode,
16
16
  SerovalBoxedNode,
17
+ SerovalCustomEventNode,
18
+ SerovalDOMExceptionNode,
17
19
  SerovalDataViewNode,
18
20
  SerovalDateNode,
19
21
  SerovalErrorNode,
22
+ SerovalEventNode,
20
23
  SerovalFileNode,
21
24
  SerovalFormDataNode,
22
25
  SerovalHeadersNode,
@@ -29,6 +32,8 @@ import type {
29
32
  SerovalPromiseNode,
30
33
  SerovalReferenceNode,
31
34
  SerovalRegExpNode,
35
+ SerovalRequestNode,
36
+ SerovalResponseNode,
32
37
  SerovalSetNode,
33
38
  SerovalTypedArrayNode,
34
39
  SerovalURLNode,
@@ -383,6 +388,73 @@ function deserializeBoxed(
383
388
  );
384
389
  }
385
390
 
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
+ }
401
+
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
+ }
415
+
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
+ }
429
+
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
+ }
443
+
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
+ }
457
+
386
458
  export default function deserializeTree(
387
459
  ctx: DeserializerContext,
388
460
  node: SerovalNode,
@@ -442,6 +514,16 @@ export default function deserializeTree(
442
514
  return deserializeFormData(ctx, node);
443
515
  case SerovalNodeType.Boxed:
444
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);
445
527
  default:
446
528
  throw new Error('invariant');
447
529
  }
@@ -1,9 +1,7 @@
1
1
  import assert from '../assert';
2
- import { Feature } from '../compat';
3
2
  import type { ParserContext } from './context';
4
3
  import { createIndexedValue } from './context';
5
4
  import type { BigIntTypedArrayValue, TypedArrayValue } from '../../types';
6
- import UnsupportedTypeError from '../UnsupportedTypeError';
7
5
  import { hasReferenceID } from '../reference';
8
6
  import type {
9
7
  SerovalBigIntTypedArrayNode,
@@ -39,7 +37,6 @@ export function createTypedArrayNode(
39
37
  id: number,
40
38
  current: TypedArrayValue,
41
39
  ): SerovalTypedArrayNode {
42
- assert(ctx.features & Feature.TypedArray, new UnsupportedTypeError(current));
43
40
  return {
44
41
  t: SerovalNodeType.TypedArray,
45
42
  i: id,
@@ -56,17 +53,11 @@ export function createTypedArrayNode(
56
53
  };
57
54
  }
58
55
 
59
- const BIGINT_FLAG = Feature.BigIntTypedArray | Feature.BigInt;
60
-
61
56
  export function createBigIntTypedArrayNode(
62
57
  ctx: ParserContext,
63
58
  id: number,
64
59
  current: BigIntTypedArrayValue,
65
60
  ): SerovalBigIntTypedArrayNode {
66
- assert(
67
- (ctx.features & BIGINT_FLAG) === BIGINT_FLAG,
68
- new UnsupportedTypeError(current),
69
- );
70
61
  return {
71
62
  t: SerovalNodeType.BigIntTypedArray,
72
63
  i: id,
@@ -36,6 +36,11 @@ import type {
36
36
  SerovalObjectRecordKey,
37
37
  SerovalBoxedNode,
38
38
  SerovalWKSymbolNode,
39
+ SerovalRequestNode,
40
+ SerovalResponseNode,
41
+ SerovalEventNode,
42
+ SerovalCustomEventNode,
43
+ SerovalDOMExceptionNode,
39
44
  } from '../types';
40
45
  import {
41
46
  SerovalObjectRecordSpecialKey,
@@ -729,6 +734,53 @@ function serializeWKSymbol(
729
734
  return assignIndexedValue(ctx, node.i, SYMBOL_STRING[node.s]);
730
735
  }
731
736
 
737
+ function serializeRequest(
738
+ ctx: SerializerContext,
739
+ node: SerovalRequestNode,
740
+ ): string {
741
+ return assignIndexedValue(ctx, node.i, 'new Request("' + node.s + '",' + serializeTree(ctx, node.f) + ')');
742
+ }
743
+
744
+ function serializeResponse(
745
+ ctx: SerializerContext,
746
+ node: SerovalResponseNode,
747
+ ): string {
748
+ return assignIndexedValue(ctx, node.i, 'new Response(' + serializeTree(ctx, node.a[0]) + ',' + serializeTree(ctx, node.a[1]) + ')');
749
+ }
750
+
751
+ function serializeEvent(
752
+ ctx: SerializerContext,
753
+ node: SerovalEventNode,
754
+ ): string {
755
+ return assignIndexedValue(
756
+ ctx,
757
+ node.i,
758
+ 'new Event("' + node.s + '",' + serializeTree(ctx, node.f) + ')',
759
+ );
760
+ }
761
+
762
+ function serializeCustomEvent(
763
+ ctx: SerializerContext,
764
+ node: SerovalCustomEventNode,
765
+ ): string {
766
+ return assignIndexedValue(
767
+ ctx,
768
+ node.i,
769
+ 'new CustomEvent("' + node.s + '",' + serializeTree(ctx, node.f) + ')',
770
+ );
771
+ }
772
+
773
+ function serializeDOMException(
774
+ ctx: SerializerContext,
775
+ node: SerovalDOMExceptionNode,
776
+ ): string {
777
+ return assignIndexedValue(
778
+ ctx,
779
+ node.i,
780
+ 'new DOMException("' + node.s + '","' + node.c + '")',
781
+ );
782
+ }
783
+
732
784
  export default function serializeTree(
733
785
  ctx: SerializerContext,
734
786
  node: SerovalNode,
@@ -789,6 +841,16 @@ export default function serializeTree(
789
841
  return serializeFormData(ctx, node);
790
842
  case SerovalNodeType.Boxed:
791
843
  return serializeBoxed(ctx, node);
844
+ case SerovalNodeType.Request:
845
+ return serializeRequest(ctx, node);
846
+ case SerovalNodeType.Response:
847
+ return serializeResponse(ctx, node);
848
+ case SerovalNodeType.Event:
849
+ return serializeEvent(ctx, node);
850
+ case SerovalNodeType.CustomEvent:
851
+ return serializeCustomEvent(ctx, node);
852
+ case SerovalNodeType.DOMException:
853
+ return serializeDOMException(ctx, node);
792
854
  default:
793
855
  throw new Error('invariant');
794
856
  }