seroval 0.9.0 → 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/README.md +4 -287
- package/dist/cjs/development/index.cjs +3529 -1140
- package/dist/cjs/development/index.cjs.map +4 -4
- package/dist/cjs/production/index.cjs +3 -3
- package/dist/esm/development/index.mjs +3533 -1142
- package/dist/esm/development/index.mjs.map +4 -4
- package/dist/esm/production/index.mjs +3 -3
- package/dist/types/core/Serializer.d.ts +15 -0
- package/dist/types/{tree → core}/UnsupportedTypeError.d.ts +4 -3
- package/dist/types/{assert.d.ts → core/assert.d.ts} +1 -1
- package/dist/types/core/assignments.d.ts +33 -0
- package/dist/types/core/base-primitives.d.ts +12 -0
- package/dist/types/{compat.d.ts → core/compat.d.ts} +22 -22
- package/dist/types/core/constants.d.ts +89 -0
- package/dist/types/core/context.d.ts +9 -0
- package/dist/types/core/cross/async.d.ts +3 -0
- package/dist/types/core/cross/context.d.ts +37 -0
- package/dist/types/core/cross/index.d.ts +8 -0
- package/dist/types/core/cross/primitives.d.ts +9 -0
- package/dist/types/core/cross/serialize.d.ts +5 -0
- package/dist/types/core/cross/stream.d.ts +3 -0
- package/dist/types/core/cross/sync.d.ts +3 -0
- package/dist/types/core/cross/web-api.d.ts +4 -0
- package/dist/types/{get-identifier.d.ts → core/get-identifier.d.ts} +1 -1
- package/dist/types/core/keys.d.ts +13 -0
- package/dist/types/{tree/constants.d.ts → core/literals.d.ts} +9 -11
- package/dist/types/core/promise-to-result.d.ts +1 -0
- package/dist/types/{tree → core}/reference.d.ts +5 -6
- package/dist/types/{tree → core}/shared.d.ts +13 -13
- package/dist/types/{string.d.ts → core/string.d.ts} +3 -3
- package/dist/types/core/tree/async.d.ts +3 -0
- package/dist/types/core/tree/context.d.ts +44 -0
- package/dist/types/core/tree/deserialize.d.ts +3 -0
- package/dist/types/core/tree/index.d.ts +14 -0
- package/dist/types/core/tree/primitives.d.ts +9 -0
- package/dist/types/core/tree/serialize.d.ts +4 -0
- package/dist/types/core/tree/sync.d.ts +3 -0
- package/dist/types/core/tree/web-api.d.ts +4 -0
- package/dist/types/{tree → core}/types.d.ts +228 -238
- package/dist/types/core/web-api.d.ts +4 -0
- package/dist/types/index.d.ts +9 -19
- package/dist/types/types.d.ts +20 -20
- package/package.json +5 -5
- package/src/core/Serializer.ts +48 -0
- package/src/{tree → core}/UnsupportedTypeError.ts +1 -1
- package/src/core/assignments.ts +159 -0
- package/src/{tree/primitives.ts → core/base-primitives.ts} +33 -136
- package/src/core/constants.ts +169 -0
- package/src/core/context.ts +15 -0
- package/src/core/cross/async.ts +614 -0
- package/src/core/cross/context.ts +102 -0
- package/src/core/cross/index.ts +169 -0
- package/src/core/cross/primitives.ts +137 -0
- package/src/core/cross/serialize.ts +847 -0
- package/src/core/cross/stream.ts +745 -0
- package/src/core/cross/sync.ts +561 -0
- package/src/core/cross/web-api.ts +55 -0
- package/src/core/header.js +61 -0
- package/src/core/keys.ts +41 -0
- package/src/core/literals.ts +28 -0
- package/src/core/promise-to-result.ts +9 -0
- package/src/{tree → core}/reference.ts +6 -7
- package/src/{tree → core}/shared.ts +4 -4
- package/src/{tree → core/tree}/async.ts +46 -34
- package/src/core/tree/context.ts +125 -0
- package/src/{tree → core/tree}/deserialize.ts +68 -55
- package/src/core/tree/index.ts +142 -0
- package/src/core/tree/primitives.ts +132 -0
- package/src/{tree → core/tree}/serialize.ts +87 -193
- package/src/{tree → core/tree}/sync.ts +50 -39
- package/src/{tree → core/tree}/web-api.ts +8 -52
- package/src/{tree → core}/types.ts +76 -60
- package/src/core/web-api.ts +51 -0
- package/src/index.ts +7 -141
- package/src/types.ts +1 -1
- package/dist/types/context.d.ts +0 -67
- package/dist/types/tree/async.d.ts +0 -3
- package/dist/types/tree/deserialize.d.ts +0 -3
- package/dist/types/tree/primitives.d.ts +0 -19
- package/dist/types/tree/serialize.d.ts +0 -4
- package/dist/types/tree/symbols.d.ts +0 -33
- package/dist/types/tree/sync.d.ts +0 -3
- package/dist/types/tree/web-api.d.ts +0 -6
- package/src/context.ts +0 -164
- package/src/tree/constants.ts +0 -73
- package/src/tree/symbols.ts +0 -65
- /package/src/{assert.ts → core/assert.ts} +0 -0
- /package/src/{compat.ts → core/compat.ts} +0 -0
- /package/src/{get-identifier.ts → core/get-identifier.ts} +0 -0
- /package/src/{string.ts → core/string.ts} +0 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "seroval",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.10.2",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
7
7
|
"src"
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
"pridepack"
|
|
15
15
|
],
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@types/node": "^20.
|
|
18
|
-
"@vitest/ui": "^0.
|
|
19
|
-
"eslint": "^8.
|
|
17
|
+
"@types/node": "^20.6.2",
|
|
18
|
+
"@vitest/ui": "^0.34.4",
|
|
19
|
+
"eslint": "^8.49.0",
|
|
20
20
|
"eslint-config-lxsmnsyc": "^0.6.5",
|
|
21
21
|
"node-fetch-native": "^1.1.0",
|
|
22
22
|
"pridepack": "2.4.4",
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"typesVersions": {
|
|
68
68
|
"*": {}
|
|
69
69
|
},
|
|
70
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "a093a32769a5653f1598d409b404ecae95d2b2f5"
|
|
71
71
|
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { crossSerializeStream } from './cross';
|
|
2
|
+
import { serializeString } from './string';
|
|
3
|
+
|
|
4
|
+
export interface SerializerOptions {
|
|
5
|
+
globalIdentifier: string;
|
|
6
|
+
scopeId?: string;
|
|
7
|
+
disabledFeatures?: number;
|
|
8
|
+
onData: (result: string) => void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default class Serializer {
|
|
12
|
+
private alive = true;
|
|
13
|
+
|
|
14
|
+
private cleanups: (() => void)[] = [];
|
|
15
|
+
|
|
16
|
+
private refs = new Map<unknown, number>();
|
|
17
|
+
|
|
18
|
+
constructor(
|
|
19
|
+
private options: SerializerOptions,
|
|
20
|
+
) {
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
write(key: string, value: unknown): void {
|
|
24
|
+
if (this.alive) {
|
|
25
|
+
this.cleanups.push(crossSerializeStream(value, {
|
|
26
|
+
scopeId: this.options.scopeId,
|
|
27
|
+
refs: this.refs,
|
|
28
|
+
disabledFeatures: this.options.disabledFeatures,
|
|
29
|
+
onSerialize: (data, initial) => {
|
|
30
|
+
this.options.onData(
|
|
31
|
+
initial
|
|
32
|
+
? this.options.globalIdentifier + '["' + serializeString(key) + '"]=' + data
|
|
33
|
+
: data,
|
|
34
|
+
);
|
|
35
|
+
},
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
close(): void {
|
|
41
|
+
if (this.alive) {
|
|
42
|
+
for (let i = 0, len = this.cleanups.length; i < len; i++) {
|
|
43
|
+
this.cleanups[i]();
|
|
44
|
+
}
|
|
45
|
+
this.alive = false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { SerovalObjectFlags } from './constants';
|
|
2
|
+
|
|
3
|
+
interface IndexAssignment {
|
|
4
|
+
t: 'index';
|
|
5
|
+
s: string;
|
|
6
|
+
k: undefined;
|
|
7
|
+
v: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface SetAssignment {
|
|
11
|
+
t: 'set';
|
|
12
|
+
s: string;
|
|
13
|
+
k: string;
|
|
14
|
+
v: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface AddAssignment {
|
|
18
|
+
t: 'add';
|
|
19
|
+
s: string;
|
|
20
|
+
k: undefined;
|
|
21
|
+
v: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface AppendAssignment {
|
|
25
|
+
t: 'append';
|
|
26
|
+
s: string;
|
|
27
|
+
k: string;
|
|
28
|
+
v: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Array of assignments to be done (used for recursion)
|
|
32
|
+
export type Assignment =
|
|
33
|
+
| IndexAssignment
|
|
34
|
+
| AddAssignment
|
|
35
|
+
| SetAssignment
|
|
36
|
+
| AppendAssignment;
|
|
37
|
+
|
|
38
|
+
export interface FlaggedObject {
|
|
39
|
+
type: SerovalObjectFlags;
|
|
40
|
+
value: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function getAssignmentExpression(assignment: Assignment): string {
|
|
44
|
+
switch (assignment.t) {
|
|
45
|
+
case 'index':
|
|
46
|
+
return assignment.s + '=' + assignment.v;
|
|
47
|
+
case 'set':
|
|
48
|
+
return assignment.s + '.set(' + assignment.k + ',' + assignment.v + ')';
|
|
49
|
+
case 'add':
|
|
50
|
+
return assignment.s + '.add(' + assignment.v + ')';
|
|
51
|
+
case 'append':
|
|
52
|
+
return assignment.s + '.append(' + assignment.k + ',' + assignment.v + ')';
|
|
53
|
+
default:
|
|
54
|
+
return '';
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const OBJECT_FLAG_CONSTRUCTOR: Record<SerovalObjectFlags, string | undefined> = {
|
|
59
|
+
[SerovalObjectFlags.Frozen]: 'Object.freeze',
|
|
60
|
+
[SerovalObjectFlags.Sealed]: 'Object.seal',
|
|
61
|
+
[SerovalObjectFlags.NonExtensible]: 'Object.preventExtensions',
|
|
62
|
+
[SerovalObjectFlags.None]: undefined,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
function mergeAssignments(assignments: Assignment[]): Assignment[] {
|
|
66
|
+
const newAssignments: Assignment[] = [];
|
|
67
|
+
let current = assignments[0];
|
|
68
|
+
let prev = current;
|
|
69
|
+
let item: Assignment;
|
|
70
|
+
for (let i = 1, len = assignments.length; i < len; i++) {
|
|
71
|
+
item = assignments[i];
|
|
72
|
+
if (item.t === prev.t) {
|
|
73
|
+
switch (item.t) {
|
|
74
|
+
case 'index':
|
|
75
|
+
if (item.v === prev.v) {
|
|
76
|
+
// Merge if the right-hand value is the same
|
|
77
|
+
// saves at least 2 chars
|
|
78
|
+
current = {
|
|
79
|
+
t: 'index',
|
|
80
|
+
s: item.s,
|
|
81
|
+
k: undefined,
|
|
82
|
+
v: getAssignmentExpression(current),
|
|
83
|
+
};
|
|
84
|
+
} else {
|
|
85
|
+
// Different assignment, push current
|
|
86
|
+
newAssignments.push(current);
|
|
87
|
+
current = item;
|
|
88
|
+
}
|
|
89
|
+
break;
|
|
90
|
+
case 'set':
|
|
91
|
+
if (item.s === prev.s) {
|
|
92
|
+
// Maps has chaining methods, merge if source is the same
|
|
93
|
+
current = {
|
|
94
|
+
t: 'set',
|
|
95
|
+
s: getAssignmentExpression(current),
|
|
96
|
+
k: item.k,
|
|
97
|
+
v: item.v,
|
|
98
|
+
};
|
|
99
|
+
} else {
|
|
100
|
+
// Different assignment, push current
|
|
101
|
+
newAssignments.push(current);
|
|
102
|
+
current = item;
|
|
103
|
+
}
|
|
104
|
+
break;
|
|
105
|
+
case 'add':
|
|
106
|
+
if (item.s === prev.s) {
|
|
107
|
+
// Sets has chaining methods too
|
|
108
|
+
current = {
|
|
109
|
+
t: 'add',
|
|
110
|
+
s: getAssignmentExpression(current),
|
|
111
|
+
k: undefined,
|
|
112
|
+
v: item.v,
|
|
113
|
+
};
|
|
114
|
+
} else {
|
|
115
|
+
// Different assignment, push current
|
|
116
|
+
newAssignments.push(current);
|
|
117
|
+
current = item;
|
|
118
|
+
}
|
|
119
|
+
break;
|
|
120
|
+
case 'append':
|
|
121
|
+
// Different assignment, push current
|
|
122
|
+
newAssignments.push(current);
|
|
123
|
+
current = item;
|
|
124
|
+
break;
|
|
125
|
+
default:
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
} else {
|
|
129
|
+
newAssignments.push(current);
|
|
130
|
+
current = item;
|
|
131
|
+
}
|
|
132
|
+
prev = item;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
newAssignments.push(current);
|
|
136
|
+
|
|
137
|
+
return newAssignments;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export function resolveAssignments(assignments: Assignment[]): string | undefined {
|
|
141
|
+
if (assignments.length) {
|
|
142
|
+
let result = '';
|
|
143
|
+
const merged = mergeAssignments(assignments);
|
|
144
|
+
for (let i = 0, len = merged.length; i < len; i++) {
|
|
145
|
+
result += getAssignmentExpression(merged[i]) + ',';
|
|
146
|
+
}
|
|
147
|
+
return result;
|
|
148
|
+
}
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export function resolveFlags(flags: FlaggedObject[]): string | undefined {
|
|
153
|
+
let result = '';
|
|
154
|
+
for (let i = 0, len = flags.length; i < len; i++) {
|
|
155
|
+
const flag = flags[i];
|
|
156
|
+
result += OBJECT_FLAG_CONSTRUCTOR[flag.type] + '(' + flag.value + '),';
|
|
157
|
+
}
|
|
158
|
+
return result;
|
|
159
|
+
}
|
|
@@ -1,38 +1,31 @@
|
|
|
1
|
-
import assert from '../assert';
|
|
2
|
-
import { Feature } from '../compat';
|
|
3
|
-
import type { ParserContext } from '../context';
|
|
4
|
-
import { createIndexedValue } from '../context';
|
|
5
|
-
import { serializeString } from '../string';
|
|
6
|
-
import type { BigIntTypedArrayValue, TypedArrayValue } from '../types';
|
|
7
1
|
import UnsupportedTypeError from './UnsupportedTypeError';
|
|
2
|
+
import assert from './assert';
|
|
3
|
+
import { Feature } from './compat';
|
|
4
|
+
import type { WellKnownSymbols } from './constants';
|
|
5
|
+
import { INV_SYMBOL_REF, SerovalNodeType } from './constants';
|
|
6
|
+
import type { BaseParserContext } from './context';
|
|
8
7
|
import {
|
|
9
8
|
INFINITY_NODE,
|
|
10
9
|
NEG_INFINITY_NODE,
|
|
11
10
|
NAN_NODE,
|
|
12
11
|
NEG_ZERO_NODE,
|
|
13
|
-
} from './
|
|
14
|
-
import { getReferenceID
|
|
15
|
-
import
|
|
16
|
-
import { INV_SYMBOL_REF } from './symbols';
|
|
12
|
+
} from './literals';
|
|
13
|
+
import { getReferenceID } from './reference';
|
|
14
|
+
import { serializeString } from './string';
|
|
17
15
|
import type {
|
|
16
|
+
SerovalArrayBufferNode,
|
|
18
17
|
SerovalBigIntNode,
|
|
19
|
-
|
|
18
|
+
SerovalConstantNode,
|
|
20
19
|
SerovalDateNode,
|
|
21
20
|
SerovalIndexedValueNode,
|
|
21
|
+
SerovalNumberNode,
|
|
22
|
+
SerovalReferenceNode,
|
|
22
23
|
SerovalRegExpNode,
|
|
23
24
|
SerovalStringNode,
|
|
24
|
-
SerovalTypedArrayNode,
|
|
25
25
|
SerovalWKSymbolNode,
|
|
26
|
-
SerovalReferenceNode,
|
|
27
|
-
SerovalArrayBufferNode,
|
|
28
|
-
SerovalDataViewNode,
|
|
29
|
-
SerovalNode,
|
|
30
|
-
} from './types';
|
|
31
|
-
import {
|
|
32
|
-
SerovalNodeType,
|
|
33
26
|
} from './types';
|
|
34
27
|
|
|
35
|
-
export function createNumberNode(value: number):
|
|
28
|
+
export function createNumberNode(value: number): SerovalConstantNode | SerovalNumberNode {
|
|
36
29
|
switch (value) {
|
|
37
30
|
case Infinity:
|
|
38
31
|
return INFINITY_NODE;
|
|
@@ -53,7 +46,8 @@ export function createNumberNode(value: number): SerovalNode {
|
|
|
53
46
|
l: undefined,
|
|
54
47
|
c: undefined,
|
|
55
48
|
m: undefined,
|
|
56
|
-
|
|
49
|
+
p: undefined,
|
|
50
|
+
e: undefined,
|
|
57
51
|
a: undefined,
|
|
58
52
|
f: undefined,
|
|
59
53
|
b: undefined,
|
|
@@ -70,7 +64,8 @@ export function createStringNode(value: string): SerovalStringNode {
|
|
|
70
64
|
l: undefined,
|
|
71
65
|
c: undefined,
|
|
72
66
|
m: undefined,
|
|
73
|
-
|
|
67
|
+
p: undefined,
|
|
68
|
+
e: undefined,
|
|
74
69
|
a: undefined,
|
|
75
70
|
f: undefined,
|
|
76
71
|
b: undefined,
|
|
@@ -79,7 +74,7 @@ export function createStringNode(value: string): SerovalStringNode {
|
|
|
79
74
|
}
|
|
80
75
|
|
|
81
76
|
export function createBigIntNode(
|
|
82
|
-
ctx:
|
|
77
|
+
ctx: BaseParserContext,
|
|
83
78
|
current: bigint,
|
|
84
79
|
): SerovalBigIntNode {
|
|
85
80
|
assert(ctx.features & Feature.BigInt, new UnsupportedTypeError(current));
|
|
@@ -90,7 +85,8 @@ export function createBigIntNode(
|
|
|
90
85
|
l: undefined,
|
|
91
86
|
c: undefined,
|
|
92
87
|
m: undefined,
|
|
93
|
-
|
|
88
|
+
p: undefined,
|
|
89
|
+
e: undefined,
|
|
94
90
|
a: undefined,
|
|
95
91
|
f: undefined,
|
|
96
92
|
b: undefined,
|
|
@@ -106,7 +102,8 @@ export function createIndexedValueNode(id: number): SerovalIndexedValueNode {
|
|
|
106
102
|
l: undefined,
|
|
107
103
|
c: undefined,
|
|
108
104
|
m: undefined,
|
|
109
|
-
|
|
105
|
+
p: undefined,
|
|
106
|
+
e: undefined,
|
|
110
107
|
a: undefined,
|
|
111
108
|
f: undefined,
|
|
112
109
|
b: undefined,
|
|
@@ -122,7 +119,8 @@ export function createDateNode(id: number, current: Date): SerovalDateNode {
|
|
|
122
119
|
l: undefined,
|
|
123
120
|
c: undefined,
|
|
124
121
|
m: undefined,
|
|
125
|
-
|
|
122
|
+
p: undefined,
|
|
123
|
+
e: undefined,
|
|
126
124
|
f: undefined,
|
|
127
125
|
a: undefined,
|
|
128
126
|
b: undefined,
|
|
@@ -138,7 +136,8 @@ export function createRegExpNode(id: number, current: RegExp): SerovalRegExpNode
|
|
|
138
136
|
l: undefined,
|
|
139
137
|
c: current.source,
|
|
140
138
|
m: current.flags,
|
|
141
|
-
|
|
139
|
+
p: undefined,
|
|
140
|
+
e: undefined,
|
|
142
141
|
a: undefined,
|
|
143
142
|
f: undefined,
|
|
144
143
|
b: undefined,
|
|
@@ -163,7 +162,8 @@ export function createArrayBufferNode(
|
|
|
163
162
|
l: undefined,
|
|
164
163
|
c: undefined,
|
|
165
164
|
m: undefined,
|
|
166
|
-
|
|
165
|
+
p: undefined,
|
|
166
|
+
e: undefined,
|
|
167
167
|
a: undefined,
|
|
168
168
|
f: undefined,
|
|
169
169
|
b: undefined,
|
|
@@ -171,66 +171,8 @@ export function createArrayBufferNode(
|
|
|
171
171
|
};
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
export function serializeArrayBuffer(
|
|
175
|
-
ctx: ParserContext,
|
|
176
|
-
current: ArrayBuffer,
|
|
177
|
-
): SerovalNode {
|
|
178
|
-
const id = createIndexedValue(ctx, current);
|
|
179
|
-
if (ctx.markedRefs.has(id)) {
|
|
180
|
-
return createIndexedValueNode(id);
|
|
181
|
-
}
|
|
182
|
-
return createArrayBufferNode(id, current);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
export function createTypedArrayNode(
|
|
186
|
-
ctx: ParserContext,
|
|
187
|
-
id: number,
|
|
188
|
-
current: TypedArrayValue,
|
|
189
|
-
): SerovalTypedArrayNode {
|
|
190
|
-
assert(ctx.features & Feature.TypedArray, new UnsupportedTypeError(current));
|
|
191
|
-
return {
|
|
192
|
-
t: SerovalNodeType.TypedArray,
|
|
193
|
-
i: id,
|
|
194
|
-
s: undefined,
|
|
195
|
-
l: current.length,
|
|
196
|
-
c: current.constructor.name,
|
|
197
|
-
m: undefined,
|
|
198
|
-
d: undefined,
|
|
199
|
-
a: undefined,
|
|
200
|
-
f: serializeArrayBuffer(ctx, current.buffer),
|
|
201
|
-
b: current.byteOffset,
|
|
202
|
-
o: undefined,
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
const BIGINT_FLAG = Feature.BigIntTypedArray | Feature.BigInt;
|
|
207
|
-
|
|
208
|
-
export function createBigIntTypedArrayNode(
|
|
209
|
-
ctx: ParserContext,
|
|
210
|
-
id: number,
|
|
211
|
-
current: BigIntTypedArrayValue,
|
|
212
|
-
): SerovalBigIntTypedArrayNode {
|
|
213
|
-
assert(
|
|
214
|
-
(ctx.features & BIGINT_FLAG) === BIGINT_FLAG,
|
|
215
|
-
new UnsupportedTypeError(current),
|
|
216
|
-
);
|
|
217
|
-
return {
|
|
218
|
-
t: SerovalNodeType.BigIntTypedArray,
|
|
219
|
-
i: id,
|
|
220
|
-
s: undefined,
|
|
221
|
-
l: current.length,
|
|
222
|
-
c: current.constructor.name,
|
|
223
|
-
m: undefined,
|
|
224
|
-
d: undefined,
|
|
225
|
-
a: undefined,
|
|
226
|
-
f: serializeArrayBuffer(ctx, current.buffer),
|
|
227
|
-
b: current.byteOffset,
|
|
228
|
-
o: undefined,
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
|
|
232
174
|
export function createWKSymbolNode(
|
|
233
|
-
ctx:
|
|
175
|
+
ctx: BaseParserContext,
|
|
234
176
|
id: number,
|
|
235
177
|
current: WellKnownSymbols,
|
|
236
178
|
): SerovalWKSymbolNode {
|
|
@@ -243,7 +185,8 @@ export function createWKSymbolNode(
|
|
|
243
185
|
l: undefined,
|
|
244
186
|
c: undefined,
|
|
245
187
|
m: undefined,
|
|
246
|
-
|
|
188
|
+
p: undefined,
|
|
189
|
+
e: undefined,
|
|
247
190
|
a: undefined,
|
|
248
191
|
f: undefined,
|
|
249
192
|
b: undefined,
|
|
@@ -262,57 +205,11 @@ export function createReferenceNode<T>(
|
|
|
262
205
|
l: undefined,
|
|
263
206
|
c: undefined,
|
|
264
207
|
m: undefined,
|
|
265
|
-
|
|
208
|
+
p: undefined,
|
|
209
|
+
e: undefined,
|
|
266
210
|
a: undefined,
|
|
267
211
|
f: undefined,
|
|
268
212
|
b: undefined,
|
|
269
213
|
o: undefined,
|
|
270
214
|
};
|
|
271
215
|
}
|
|
272
|
-
|
|
273
|
-
export function createDataViewNode(
|
|
274
|
-
ctx: ParserContext,
|
|
275
|
-
id: number,
|
|
276
|
-
current: DataView,
|
|
277
|
-
): SerovalDataViewNode {
|
|
278
|
-
return {
|
|
279
|
-
t: SerovalNodeType.DataView,
|
|
280
|
-
i: id,
|
|
281
|
-
s: undefined,
|
|
282
|
-
l: current.byteLength,
|
|
283
|
-
c: undefined,
|
|
284
|
-
m: undefined,
|
|
285
|
-
d: undefined,
|
|
286
|
-
a: undefined,
|
|
287
|
-
f: serializeArrayBuffer(ctx, current.buffer),
|
|
288
|
-
b: current.byteOffset,
|
|
289
|
-
o: undefined,
|
|
290
|
-
};
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
export function createSymbolNode(
|
|
294
|
-
ctx: ParserContext,
|
|
295
|
-
current: symbol,
|
|
296
|
-
): SerovalNode {
|
|
297
|
-
const id = createIndexedValue(ctx, current);
|
|
298
|
-
if (ctx.markedRefs.has(id)) {
|
|
299
|
-
return createIndexedValueNode(id);
|
|
300
|
-
}
|
|
301
|
-
if (hasReferenceID(current)) {
|
|
302
|
-
return createReferenceNode(id, current);
|
|
303
|
-
}
|
|
304
|
-
return createWKSymbolNode(ctx, id, current as WellKnownSymbols);
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
export function createFunctionNode(
|
|
308
|
-
ctx: ParserContext,
|
|
309
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
310
|
-
current: Function,
|
|
311
|
-
): SerovalNode {
|
|
312
|
-
assert(hasReferenceID(current), new Error('Cannot serialize function without reference ID.'));
|
|
313
|
-
const id = createIndexedValue(ctx, current);
|
|
314
|
-
if (ctx.markedRefs.has(id)) {
|
|
315
|
-
return createIndexedValueNode(id);
|
|
316
|
-
}
|
|
317
|
-
return createReferenceNode(id, current);
|
|
318
|
-
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import type { SerovalConstantNode } from './types';
|
|
2
|
+
|
|
3
|
+
export const enum SerovalConstant {
|
|
4
|
+
Null = 0,
|
|
5
|
+
Undefined = 1,
|
|
6
|
+
True = 2,
|
|
7
|
+
False = 3,
|
|
8
|
+
NegativeZero = 4,
|
|
9
|
+
Infinity = 5,
|
|
10
|
+
NegativeInfinity = 6,
|
|
11
|
+
NaN = 7,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const enum SerovalNodeType {
|
|
15
|
+
Number = 0,
|
|
16
|
+
String = 1,
|
|
17
|
+
Constant = 2,
|
|
18
|
+
BigInt = 3,
|
|
19
|
+
IndexedValue = 4,
|
|
20
|
+
Date = 5,
|
|
21
|
+
RegExp = 6,
|
|
22
|
+
Set = 7,
|
|
23
|
+
Map = 8,
|
|
24
|
+
Array = 9,
|
|
25
|
+
Object = 10,
|
|
26
|
+
NullConstructor = 11,
|
|
27
|
+
Promise = 12,
|
|
28
|
+
Error = 13,
|
|
29
|
+
AggregateError = 14,
|
|
30
|
+
TypedArray = 15,
|
|
31
|
+
BigIntTypedArray = 16,
|
|
32
|
+
WKSymbol = 17,
|
|
33
|
+
URL = 18,
|
|
34
|
+
URLSearchParams = 19,
|
|
35
|
+
Reference = 20,
|
|
36
|
+
ArrayBuffer = 21,
|
|
37
|
+
DataView = 22,
|
|
38
|
+
Blob = 23,
|
|
39
|
+
File = 24,
|
|
40
|
+
Headers = 25,
|
|
41
|
+
FormData = 26,
|
|
42
|
+
Boxed = 27,
|
|
43
|
+
PromiseConstructor = 28,
|
|
44
|
+
PromiseResolve = 29,
|
|
45
|
+
PromiseReject = 30,
|
|
46
|
+
ReadableStreamConstructor = 31,
|
|
47
|
+
ReadableStreamEnqueue = 32,
|
|
48
|
+
ReadableStreamClose = 33,
|
|
49
|
+
ReadableStreamError = 34,
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const enum SerovalObjectFlags {
|
|
53
|
+
None = 0,
|
|
54
|
+
NonExtensible = 1,
|
|
55
|
+
Sealed = 2,
|
|
56
|
+
Frozen = 3,
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export const enum Symbols {
|
|
60
|
+
AsyncIterator = 0,
|
|
61
|
+
HasInstance = 1,
|
|
62
|
+
IsConcatSpreadable = 2,
|
|
63
|
+
Iterator = 3,
|
|
64
|
+
Match = 4,
|
|
65
|
+
MatchAll = 5,
|
|
66
|
+
Replace = 6,
|
|
67
|
+
Search = 7,
|
|
68
|
+
Species = 8,
|
|
69
|
+
Split = 9,
|
|
70
|
+
ToPrimitive = 10,
|
|
71
|
+
ToStringTag = 11,
|
|
72
|
+
Unscopables = 12,
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export const SYMBOL_STRING: Record<Symbols, string> = {
|
|
76
|
+
[Symbols.AsyncIterator]: 'Symbol.asyncIterator',
|
|
77
|
+
[Symbols.HasInstance]: 'Symbol.hasInstance',
|
|
78
|
+
[Symbols.IsConcatSpreadable]: 'Symbol.isConcatSpreadable',
|
|
79
|
+
[Symbols.Iterator]: 'Symbol.iterator',
|
|
80
|
+
[Symbols.Match]: 'Symbol.match',
|
|
81
|
+
[Symbols.MatchAll]: 'Symbol.matchAll',
|
|
82
|
+
[Symbols.Replace]: 'Symbol.replace',
|
|
83
|
+
[Symbols.Search]: 'Symbol.search',
|
|
84
|
+
[Symbols.Species]: 'Symbol.species',
|
|
85
|
+
[Symbols.Split]: 'Symbol.split',
|
|
86
|
+
[Symbols.ToPrimitive]: 'Symbol.toPrimitive',
|
|
87
|
+
[Symbols.ToStringTag]: 'Symbol.toStringTag',
|
|
88
|
+
[Symbols.Unscopables]: 'Symbol.unscopables',
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export const INV_SYMBOL_REF = {
|
|
92
|
+
[Symbol.asyncIterator]: Symbols.AsyncIterator,
|
|
93
|
+
[Symbol.hasInstance]: Symbols.HasInstance,
|
|
94
|
+
[Symbol.isConcatSpreadable]: Symbols.IsConcatSpreadable,
|
|
95
|
+
[Symbol.iterator]: Symbols.Iterator,
|
|
96
|
+
[Symbol.match]: Symbols.Match,
|
|
97
|
+
[Symbol.matchAll]: Symbols.MatchAll,
|
|
98
|
+
[Symbol.replace]: Symbols.Replace,
|
|
99
|
+
[Symbol.search]: Symbols.Search,
|
|
100
|
+
[Symbol.species]: Symbols.Species,
|
|
101
|
+
[Symbol.split]: Symbols.Split,
|
|
102
|
+
[Symbol.toPrimitive]: Symbols.ToPrimitive,
|
|
103
|
+
[Symbol.toStringTag]: Symbols.ToStringTag,
|
|
104
|
+
[Symbol.unscopables]: Symbols.Unscopables,
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export type WellKnownSymbols = keyof typeof INV_SYMBOL_REF;
|
|
108
|
+
|
|
109
|
+
export const SYMBOL_REF: Record<Symbols, WellKnownSymbols> = {
|
|
110
|
+
[Symbols.AsyncIterator]: Symbol.asyncIterator,
|
|
111
|
+
[Symbols.HasInstance]: Symbol.hasInstance,
|
|
112
|
+
[Symbols.IsConcatSpreadable]: Symbol.isConcatSpreadable,
|
|
113
|
+
[Symbols.Iterator]: Symbol.iterator,
|
|
114
|
+
[Symbols.Match]: Symbol.match,
|
|
115
|
+
[Symbols.MatchAll]: Symbol.matchAll,
|
|
116
|
+
[Symbols.Replace]: Symbol.replace,
|
|
117
|
+
[Symbols.Search]: Symbol.search,
|
|
118
|
+
[Symbols.Species]: Symbol.species,
|
|
119
|
+
[Symbols.Split]: Symbol.split,
|
|
120
|
+
[Symbols.ToPrimitive]: Symbol.toPrimitive,
|
|
121
|
+
[Symbols.ToStringTag]: Symbol.toStringTag,
|
|
122
|
+
[Symbols.Unscopables]: Symbol.unscopables,
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export function serializeConstant(node: SerovalConstantNode): string {
|
|
126
|
+
switch (node.s) {
|
|
127
|
+
case SerovalConstant.True:
|
|
128
|
+
return '!0';
|
|
129
|
+
case SerovalConstant.False:
|
|
130
|
+
return '!1';
|
|
131
|
+
case SerovalConstant.Undefined:
|
|
132
|
+
return 'void 0';
|
|
133
|
+
case SerovalConstant.Null:
|
|
134
|
+
return 'null';
|
|
135
|
+
case SerovalConstant.NegativeZero:
|
|
136
|
+
return '-0';
|
|
137
|
+
case SerovalConstant.Infinity:
|
|
138
|
+
return '1/0';
|
|
139
|
+
case SerovalConstant.NegativeInfinity:
|
|
140
|
+
return '-1/0';
|
|
141
|
+
case SerovalConstant.NaN:
|
|
142
|
+
return 'NaN';
|
|
143
|
+
default:
|
|
144
|
+
throw new Error('invariant');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export function deserializeConstant(node: SerovalConstantNode): unknown {
|
|
149
|
+
switch (node.s) {
|
|
150
|
+
case SerovalConstant.True:
|
|
151
|
+
return true;
|
|
152
|
+
case SerovalConstant.False:
|
|
153
|
+
return false;
|
|
154
|
+
case SerovalConstant.Undefined:
|
|
155
|
+
return undefined;
|
|
156
|
+
case SerovalConstant.Null:
|
|
157
|
+
return null;
|
|
158
|
+
case SerovalConstant.NegativeZero:
|
|
159
|
+
return -0;
|
|
160
|
+
case SerovalConstant.Infinity:
|
|
161
|
+
return Infinity;
|
|
162
|
+
case SerovalConstant.NegativeInfinity:
|
|
163
|
+
return -Infinity;
|
|
164
|
+
case SerovalConstant.NaN:
|
|
165
|
+
return NaN;
|
|
166
|
+
default:
|
|
167
|
+
throw new Error('invariant');
|
|
168
|
+
}
|
|
169
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Assignment, FlaggedObject } from './assignments';
|
|
2
|
+
|
|
3
|
+
export interface BaseParserContext {
|
|
4
|
+
// Supported features
|
|
5
|
+
features: number;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface BaseSerializerContext extends BaseParserContext {
|
|
9
|
+
// To check if an object is synchronously referencing itself
|
|
10
|
+
stack: number[];
|
|
11
|
+
// Array of object mutations
|
|
12
|
+
flags: FlaggedObject[];
|
|
13
|
+
// Array of assignments to be done (used for recursion)
|
|
14
|
+
assignments: Assignment[];
|
|
15
|
+
}
|