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.
- package/dist/cjs/development/index.cjs +79 -55
- package/dist/cjs/development/index.cjs.map +3 -3
- package/dist/cjs/production/index.cjs +3 -12
- package/dist/esm/development/index.mjs +79 -55
- package/dist/esm/development/index.mjs.map +3 -3
- package/dist/esm/production/index.mjs +2 -11
- package/dist/types/core/Serializer.d.ts +1 -0
- package/dist/types/core/cross/context.d.ts +7 -0
- package/dist/types/core/cross/index.d.ts +1 -0
- package/dist/types/core/keys.d.ts +8 -7
- package/dist/types/core/tree/context.d.ts +0 -1
- package/dist/types/core/tree/index.d.ts +0 -1
- package/dist/types/index.d.ts +1 -1
- package/package.json +2 -2
- package/src/core/Serializer.ts +2 -0
- package/src/core/cross/context.ts +23 -0
- package/src/core/cross/index.ts +32 -17
- package/src/core/cross/serialize.ts +8 -7
- package/src/core/cross/stream.ts +7 -2
- package/src/core/header.js +54 -58
- package/src/core/keys.ts +27 -19
- package/src/core/tree/context.ts +0 -11
- package/src/core/tree/index.ts +5 -9
- package/src/index.ts +1 -1
|
@@ -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(
|
package/src/core/cross/stream.ts
CHANGED
|
@@ -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
|
-
|
|
570
|
+
popPendingState(ctx);
|
|
566
571
|
}
|
|
567
572
|
},
|
|
568
573
|
);
|
package/src/core/header.js
CHANGED
|
@@ -4,62 +4,58 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
// Global references array. Global because we (ideally) want <script> elements to share it.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
function
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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 = '
|
|
14
|
+
export const GLOBAL_CONTEXT_PROMISE_CONSTRUCTOR = 'P';
|
|
11
15
|
|
|
12
|
-
export const GLOBAL_CONTEXT_PROMISE_RESOLVE = '
|
|
16
|
+
export const GLOBAL_CONTEXT_PROMISE_RESOLVE = 'Ps';
|
|
13
17
|
|
|
14
|
-
export const GLOBAL_CONTEXT_PROMISE_REJECT = '
|
|
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 = '
|
|
19
|
-
|
|
20
|
-
export const GLOBAL_CONTEXT_STREAM_EMIT = '
|
|
21
|
-
|
|
22
|
-
export const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
function
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
function
|
|
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
|
+
}
|
package/src/core/tree/context.ts
CHANGED
|
@@ -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,
|
package/src/core/tree/index.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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.
|
|
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 {
|
|
17
|
+
export { GLOBAL_CONTEXT_API_SCRIPT, getCrossReferenceHeader } from './core/keys';
|
|
18
18
|
|
|
19
19
|
export { default as Serializer } from './core/Serializer';
|
|
20
20
|
|