seroval 0.10.1 → 0.10.2

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.
@@ -59,6 +59,7 @@ import {
59
59
  REFERENCES_KEY,
60
60
  GLOBAL_CONTEXT_STREAM_CONSTRUCTOR,
61
61
  GLOBAL_CONTEXT_STREAM_EMIT,
62
+ GLOBAL_CONTEXT_API,
62
63
  } from '../keys';
63
64
 
64
65
  export function getRefExpr(id: number): string {
@@ -724,46 +725,46 @@ function serializePromiseResolve(
724
725
  ctx: CrossSerializerContext,
725
726
  node: SerovalPromiseResolveNode,
726
727
  ): string {
727
- return GLOBAL_CONTEXT_PROMISE_RESOLVE + '(' + node.i + ',' + crossSerializeTree(ctx, node.f) + ')';
728
+ return GLOBAL_CONTEXT_API + '.' + GLOBAL_CONTEXT_PROMISE_RESOLVE + '(' + getRefExpr(node.i) + ',' + crossSerializeTree(ctx, node.f) + ')';
728
729
  }
729
730
 
730
731
  function serializePromiseReject(
731
732
  ctx: CrossSerializerContext,
732
733
  node: SerovalPromiseRejectNode,
733
734
  ): string {
734
- return GLOBAL_CONTEXT_PROMISE_REJECT + '(' + node.i + ',' + crossSerializeTree(ctx, node.f) + ')';
735
+ return GLOBAL_CONTEXT_API + '.' + GLOBAL_CONTEXT_PROMISE_REJECT + '(' + getRefExpr(node.i) + ',' + crossSerializeTree(ctx, node.f) + ')';
735
736
  }
736
737
 
737
738
  function serializePromiseConstructor(
738
739
  node: SerovalPromiseConstructorNode,
739
740
  ): string {
740
- return assignIndexedValue(node.i, GLOBAL_CONTEXT_PROMISE_CONSTRUCTOR + '()');
741
+ return assignIndexedValue(node.i, GLOBAL_CONTEXT_API + '.' + GLOBAL_CONTEXT_PROMISE_CONSTRUCTOR + '()');
741
742
  }
742
743
 
743
744
  function serializeReadableStreamClose(
744
745
  node: SerovalReadableStreamCloseNode,
745
746
  ): string {
746
- return GLOBAL_CONTEXT_STREAM_EMIT + '(' + node.i + ',2)';
747
+ return GLOBAL_CONTEXT_API + '.' + GLOBAL_CONTEXT_STREAM_EMIT + '(' + getRefExpr(node.i) + ',2)';
747
748
  }
748
749
 
749
750
  function serializeReadableStreamEnqueue(
750
751
  ctx: CrossSerializerContext,
751
752
  node: SerovalReadableStreamEnqueueNode,
752
753
  ): string {
753
- return GLOBAL_CONTEXT_STREAM_EMIT + '(' + node.i + ',0,' + crossSerializeTree(ctx, node.f) + ')';
754
+ return GLOBAL_CONTEXT_API + '.' + GLOBAL_CONTEXT_STREAM_EMIT + '(' + getRefExpr(node.i) + ',0,' + crossSerializeTree(ctx, node.f) + ')';
754
755
  }
755
756
 
756
757
  function serializeReadableStreamError(
757
758
  ctx: CrossSerializerContext,
758
759
  node: SerovalReadableStreamErrorNode,
759
760
  ): string {
760
- return GLOBAL_CONTEXT_STREAM_EMIT + '(' + node.i + ',1,' + crossSerializeTree(ctx, node.f) + ')';
761
+ return GLOBAL_CONTEXT_API + '.' + GLOBAL_CONTEXT_STREAM_EMIT + '(' + getRefExpr(node.i) + ',1,' + crossSerializeTree(ctx, node.f) + ')';
761
762
  }
762
763
 
763
764
  function serializeReadableStreamConstructor(
764
765
  node: SerovalReadableStreamConstructorNode,
765
766
  ): string {
766
- return assignIndexedValue(node.i, GLOBAL_CONTEXT_STREAM_CONSTRUCTOR + '()');
767
+ return assignIndexedValue(node.i, GLOBAL_CONTEXT_API + '.' + GLOBAL_CONTEXT_STREAM_CONSTRUCTOR + '()');
767
768
  }
768
769
 
769
770
  export default function crossSerializeTree(
@@ -4,7 +4,7 @@ import assert from '../assert';
4
4
  import { Feature } from '../compat';
5
5
  import type { StreamingCrossParserContext } from './context';
6
6
  import {
7
- createCrossIndexedValue,
7
+ createCrossIndexedValue, popPendingState, pushPendingState,
8
8
  } from './context';
9
9
  import { serializeString } from '../string';
10
10
  import type {
@@ -318,6 +318,7 @@ function generatePromiseNode(
318
318
  b: undefined,
319
319
  o: undefined,
320
320
  }, false);
321
+ popPendingState(ctx);
321
322
  }
322
323
  },
323
324
  (data) => {
@@ -336,9 +337,11 @@ function generatePromiseNode(
336
337
  b: undefined,
337
338
  o: undefined,
338
339
  }, false);
340
+ popPendingState(ctx);
339
341
  }
340
342
  },
341
343
  );
344
+ pushPendingState(ctx);
342
345
  return {
343
346
  t: SerovalNodeType.PromiseConstructor,
344
347
  i: id,
@@ -507,6 +510,7 @@ function generateReadableStreamNode(
507
510
  ): SerovalReadableStreamConstructorNode {
508
511
  assert(ctx.features & Feature.WebAPI, new UnsupportedTypeError(current));
509
512
  const reader = current.getReader();
513
+ pushPendingState(ctx);
510
514
 
511
515
  function push(): void {
512
516
  reader.read().then(
@@ -527,6 +531,7 @@ function generateReadableStreamNode(
527
531
  b: undefined,
528
532
  o: undefined,
529
533
  }, false);
534
+ popPendingState(ctx);
530
535
  } else {
531
536
  ctx.onParse({
532
537
  t: SerovalNodeType.ReadableStreamEnqueue,
@@ -562,7 +567,7 @@ function generateReadableStreamNode(
562
567
  b: undefined,
563
568
  o: undefined,
564
569
  }, false);
565
- push();
570
+ popPendingState(ctx);
566
571
  }
567
572
  },
568
573
  );
@@ -4,62 +4,58 @@
4
4
  */
5
5
 
6
6
  // Global references array. Global because we (ideally) want <script> elements to share it.
7
- var $R = [];
8
-
9
- // Promise constructor, used to construct deferred Promises
10
- function $P(success, failure, promise) {
11
- promise = new Promise(function (resolve, reject) {
12
- success = resolve;
13
- failure = reject;
14
- });
15
-
16
- promise.s = success;
17
- promise.f = failure;
18
-
19
- return promise;
20
- }
21
-
22
- // This unsets the custom properties of the Promise instance
23
- function $uP(promise) {
24
- delete promise.s;
25
- delete promise.f;
26
- }
27
-
28
- function $Ps(referenceID, data) {
29
- $R[referenceID].s(data);
30
- }
31
-
32
- function $Pf(referenceID, data) {
33
- $R[referenceID].f(data);
34
- }
35
-
36
- // Unset stream
37
- function $uS(stream) {
38
- delete stream.c;
39
- }
40
-
41
- function $Se(referenceID, type, data, stream, controller) {
42
- stream = $R[referenceID];
43
- controller = stream.c;
44
- switch (type) {
45
- case 0: return controller.enqueue(data);
46
- case 1:
47
- $uS(stream);
48
- return controller.error(data);
49
- case 2:
50
- $uS(stream);
51
- return controller.close();
52
- }
53
- }
54
-
55
- // ReadableStream constructor
56
- function $S(stream, controller) {
57
- stream = new ReadableStream({
58
- start: function (c) {
59
- controller = c;
7
+ self._$ = self._$ || {
8
+ // Promise constructor, used to construct deferred Promises
9
+ P(success, failure, promise) {
10
+ promise = new Promise(function (resolve, reject) {
11
+ success = resolve;
12
+ failure = reject;
13
+ });
14
+
15
+ promise.s = success;
16
+ promise.f = failure;
17
+
18
+ return promise;
19
+ },
20
+ // This unsets the custom properties of the Promise instance
21
+ uP(promise) {
22
+ delete promise.s;
23
+ delete promise.f;
24
+ },
25
+ // Promise resolution
26
+ Ps(promise, data) {
27
+ promise.s(data);
28
+ promise.value = data;
29
+ this.uP(promise);
30
+ },
31
+ Pf(promise, data) {
32
+ promise.f(data);
33
+ this.uP(promise);
34
+ },
35
+ // Unset stream
36
+ uS(stream) {
37
+ delete stream.c;
38
+ },
39
+ Se(stream, type, data, controller) {
40
+ controller = stream.c;
41
+ switch (type) {
42
+ case 0: return controller.enqueue(data);
43
+ case 1:
44
+ this.uS(stream);
45
+ return controller.error(data);
46
+ case 2:
47
+ this.uS(stream);
48
+ return controller.close();
60
49
  }
61
- });
62
- stream.c = controller;
63
-
64
- return stream;
65
- }
50
+ },
51
+ // ReadableStream constructor
52
+ S(stream, controller) {
53
+ stream = new ReadableStream({
54
+ start: function (c) {
55
+ controller = c;
56
+ }
57
+ });
58
+ stream.c = controller;
59
+ return stream;
60
+ },
61
+ };
package/src/core/keys.ts CHANGED
@@ -1,33 +1,41 @@
1
+ import { serializeString } from './string';
2
+
1
3
  // Used for mapping isomorphic references
2
4
  export const REFERENCES_KEY = '__SEROVAL_REFS__';
3
5
 
6
+ export const GLOBAL_CONTEXT_API = '_$';
7
+
4
8
  export const GLOBAL_CONTEXT_REFERENCES = '$R';
5
9
 
6
10
  export const LOCAL_CONTEXT_PROMISE_RESOLVE = 's';
7
11
 
8
12
  export const LOCAL_CONTEXT_PROMISE_REJECT = 'f';
9
13
 
10
- export const GLOBAL_CONTEXT_PROMISE_CONSTRUCTOR = '$P';
14
+ export const GLOBAL_CONTEXT_PROMISE_CONSTRUCTOR = 'P';
11
15
 
12
- export const GLOBAL_CONTEXT_PROMISE_RESOLVE = '$Ps';
16
+ export const GLOBAL_CONTEXT_PROMISE_RESOLVE = 'Ps';
13
17
 
14
- export const GLOBAL_CONTEXT_PROMISE_REJECT = '$Pf';
18
+ export const GLOBAL_CONTEXT_PROMISE_REJECT = 'Pf';
15
19
 
16
20
  export const LOCAL_CONTEXT_STREAM_CONTROLLER = 'c';
17
21
 
18
- export const GLOBAL_CONTEXT_STREAM_CONSTRUCTOR = '$S';
19
-
20
- export const GLOBAL_CONTEXT_STREAM_EMIT = '$Se';
21
-
22
- export const ROOT_REFERENCE = 't';
23
-
24
- export const CROSS_REFERENCE_HEADER = `
25
- var ${GLOBAL_CONTEXT_REFERENCES}=[];
26
- function ${GLOBAL_CONTEXT_PROMISE_CONSTRUCTOR}(s,f,p){return (p=new Promise(function(a,b){s=a,f=b})).${LOCAL_CONTEXT_PROMISE_RESOLVE}=s,p.${LOCAL_CONTEXT_PROMISE_REJECT}=f,p}
27
- function $uP(i,p){delete (p=${GLOBAL_CONTEXT_REFERENCES}[i]).${LOCAL_CONTEXT_PROMISE_RESOLVE};delete p.${LOCAL_CONTEXT_PROMISE_REJECT}}
28
- function ${GLOBAL_CONTEXT_PROMISE_RESOLVE}(i,d){${GLOBAL_CONTEXT_REFERENCES}[i].${LOCAL_CONTEXT_PROMISE_RESOLVE}(d),$uP(i)}
29
- function ${GLOBAL_CONTEXT_PROMISE_REJECT}(i,d){${GLOBAL_CONTEXT_REFERENCES}[i].${LOCAL_CONTEXT_PROMISE_REJECT}(d),$uP(i)}
30
- function $uS(s){delete s.${LOCAL_CONTEXT_STREAM_CONTROLLER}}
31
- function ${GLOBAL_CONTEXT_STREAM_EMIT}(i,t,d,s,c){switch(c=(s=${GLOBAL_CONTEXT_REFERENCES}[i]).${LOCAL_CONTEXT_STREAM_CONTROLLER},t){case 0:return c.enqueue(d);case 1:return c.error(d),$uS(s);case 2:return c.close(),$uS(s)}}
32
- function ${GLOBAL_CONTEXT_STREAM_CONSTRUCTOR}(s,c){return(s=new ReadableStream({start:function(t){c=t}})).c=c,s}
33
- `;
22
+ export const GLOBAL_CONTEXT_STREAM_CONSTRUCTOR = 'S';
23
+
24
+ export const GLOBAL_CONTEXT_STREAM_EMIT = 'Se';
25
+
26
+ export const GLOBAL_CONTEXT_API_SCRIPT = `self.${GLOBAL_CONTEXT_API}=self.${GLOBAL_CONTEXT_API}||{`
27
+ + `${GLOBAL_CONTEXT_PROMISE_CONSTRUCTOR}:function(s,f,p){return(p=new Promise(function(a,b){s=a,f=b})).${LOCAL_CONTEXT_PROMISE_RESOLVE}=s,p.${LOCAL_CONTEXT_PROMISE_REJECT}=f,p},`
28
+ + `uP:function(p){delete p.${LOCAL_CONTEXT_PROMISE_RESOLVE};delete p.${LOCAL_CONTEXT_PROMISE_REJECT}},`
29
+ + `${GLOBAL_CONTEXT_PROMISE_RESOLVE}:function(p,d){p.${LOCAL_CONTEXT_PROMISE_RESOLVE}(d),p.value=d,this.uP(p)},`
30
+ + `${GLOBAL_CONTEXT_PROMISE_REJECT}:function(p,d){p.${LOCAL_CONTEXT_PROMISE_REJECT}(d),this.uP(p)},`
31
+ + `uS:function(s){delete s.${LOCAL_CONTEXT_STREAM_CONTROLLER}},`
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},`
34
+ + '}';
35
+
36
+ export function getCrossReferenceHeader(id?: string): string {
37
+ if (id == null) {
38
+ return `self.${GLOBAL_CONTEXT_REFERENCES}=self.${GLOBAL_CONTEXT_REFERENCES}||[];`;
39
+ }
40
+ return `(self.${GLOBAL_CONTEXT_REFERENCES}=self.${GLOBAL_CONTEXT_REFERENCES}||{})["${serializeString(id)}"]=[]`;
41
+ }
@@ -92,17 +92,6 @@ export function getRefParam(ctx: SerializerContext, index: number): string {
92
92
  return identifier;
93
93
  }
94
94
 
95
- export function getRootID<T>(
96
- ctx: ParserContext,
97
- current: T,
98
- ): number {
99
- const ref = ctx.reference.ids.get(current);
100
- if (ref == null) {
101
- return ctx.reference.ids.size;
102
- }
103
- return ref;
104
- }
105
-
106
95
  export function createIndexedValue<T>(
107
96
  ctx: ParserContext,
108
97
  current: T,
@@ -11,7 +11,6 @@ import {
11
11
  createParserContext,
12
12
  createSerializerContext,
13
13
  getRefParam,
14
- getRootID,
15
14
  } from './context';
16
15
  import deserializeTree from './deserialize';
17
16
  import serializeTree, { resolvePatches } from './serialize';
@@ -19,12 +18,12 @@ import parseSync from './sync';
19
18
 
20
19
  function finalize(
21
20
  ctx: SerializerContext,
22
- rootID: number,
21
+ rootID: number | undefined,
23
22
  isObject: boolean,
24
23
  result: string,
25
24
  ): string {
26
25
  // Shared references detected
27
- if (ctx.vars.length) {
26
+ if (rootID != null && ctx.vars.length) {
28
27
  const patches = resolvePatches(ctx);
29
28
  let body = result;
30
29
  if (patches) {
@@ -66,7 +65,7 @@ export function serialize<T>(
66
65
  const result = serializeTree(serial, tree);
67
66
  return finalize(
68
67
  serial,
69
- getRootID(ctx, source),
68
+ tree.i,
70
69
  tree.t === SerovalNodeType.Object,
71
70
  result,
72
71
  );
@@ -85,7 +84,7 @@ export async function serializeAsync<T>(
85
84
  const result = serializeTree(serial, tree);
86
85
  return finalize(
87
86
  serial,
88
- getRootID(ctx, source),
87
+ tree.i,
89
88
  tree.t === SerovalNodeType.Object,
90
89
  result,
91
90
  );
@@ -98,7 +97,6 @@ export function deserialize<T>(source: string): T {
98
97
 
99
98
  export interface SerovalJSON {
100
99
  t: SerovalNode;
101
- r: number;
102
100
  f: number;
103
101
  m: number[];
104
102
  }
@@ -110,7 +108,6 @@ export function toJSON<T>(
110
108
  const ctx = createParserContext(options);
111
109
  return {
112
110
  t: parseSync(ctx, source),
113
- r: getRootID(ctx, source),
114
111
  f: ctx.features,
115
112
  m: Array.from(ctx.reference.marked),
116
113
  };
@@ -123,7 +120,6 @@ export async function toJSONAsync<T>(
123
120
  const ctx = createParserContext(options);
124
121
  return {
125
122
  t: await parseAsync(ctx, source),
126
- r: getRootID(ctx, source),
127
123
  f: ctx.features,
128
124
  m: Array.from(ctx.reference.marked),
129
125
  };
@@ -135,7 +131,7 @@ export function compileJSON(source: SerovalJSON): string {
135
131
  markedRefs: source.m,
136
132
  });
137
133
  const result = serializeTree(serial, source.t);
138
- return finalize(serial, source.r, source.t.i === SerovalNodeType.Object, result);
134
+ return finalize(serial, source.t.i, source.t.i === SerovalNodeType.Object, result);
139
135
  }
140
136
 
141
137
  export function fromJSON<T>(source: SerovalJSON): T {
package/src/index.ts CHANGED
@@ -14,7 +14,7 @@ export { createReference } from './core/reference';
14
14
  export * from './core/tree';
15
15
  export * from './core/cross';
16
16
 
17
- export { CROSS_REFERENCE_HEADER } from './core/keys';
17
+ export { GLOBAL_CONTEXT_API_SCRIPT, getCrossReferenceHeader } from './core/keys';
18
18
 
19
19
  export { default as Serializer } from './core/Serializer';
20
20