seroval 0.6.0 → 0.8.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/README.md +15 -3
- package/dist/cjs/development/index.cjs +1431 -991
- package/dist/cjs/development/index.cjs.map +4 -4
- package/dist/cjs/production/index.cjs +3 -3
- package/dist/esm/development/index.mjs +1431 -991
- package/dist/esm/development/index.mjs.map +4 -4
- package/dist/esm/production/index.mjs +3 -3
- package/dist/types/assert.d.ts +1 -1
- package/dist/types/compat.d.ts +1 -1
- package/dist/types/context.d.ts +13 -7
- package/dist/types/index.d.ts +3 -4
- package/dist/types/string.d.ts +3 -0
- package/dist/types/tree/UnsupportedTypeError.d.ts +3 -0
- package/dist/types/tree/async.d.ts +3 -3
- package/dist/types/tree/constants.d.ts +11 -0
- package/dist/types/tree/deserialize.d.ts +2 -2
- package/dist/types/tree/primitives.d.ts +11 -14
- package/dist/types/tree/serialize.d.ts +2 -2
- package/dist/types/tree/shared.d.ts +10 -8
- package/dist/types/tree/sync.d.ts +3 -3
- package/dist/types/tree/types.d.ts +106 -70
- package/dist/types/tree/web-api.d.ts +4 -2
- package/dist/types/types.d.ts +4 -4
- package/package.json +11 -8
- package/src/assert.ts +2 -2
- package/src/compat.ts +1 -2
- package/src/context.ts +24 -13
- package/src/get-identifier.ts +1 -1
- package/src/index.ts +35 -26
- package/src/string.ts +53 -0
- package/src/tree/UnsupportedTypeError.ts +8 -0
- package/src/tree/async.ts +313 -222
- package/src/tree/constants.ts +72 -0
- package/src/tree/deserialize.ts +239 -119
- package/src/tree/primitives.ts +154 -143
- package/src/tree/reference.ts +4 -3
- package/src/tree/serialize.ts +394 -170
- package/src/tree/shared.ts +31 -22
- package/src/tree/symbols.ts +13 -13
- package/src/tree/sync.ts +288 -191
- package/src/tree/types.ts +173 -91
- package/src/tree/web-api.ts +59 -6
- package/src/types.ts +7 -3
- package/dist/types/quote.d.ts +0 -2
- package/src/quote.ts +0 -56
package/src/tree/primitives.ts
CHANGED
|
@@ -1,145 +1,78 @@
|
|
|
1
1
|
import assert from '../assert';
|
|
2
2
|
import { Feature } from '../compat';
|
|
3
|
-
import { ParserContext } from '../context';
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
3
|
+
import type { ParserContext } from '../context';
|
|
4
|
+
import { createIndexedValue } from '../context';
|
|
5
|
+
import { serializeString } from '../string';
|
|
6
|
+
import type { BigIntTypedArrayValue, TypedArrayValue } from '../types';
|
|
7
|
+
import UnsupportedTypeError from './UnsupportedTypeError';
|
|
8
8
|
import {
|
|
9
|
+
INFINITY_NODE,
|
|
10
|
+
NEG_INFINITY_NODE,
|
|
11
|
+
NAN_NODE,
|
|
12
|
+
NEG_ZERO_NODE,
|
|
13
|
+
} from './constants';
|
|
14
|
+
import { getReferenceID, hasReferenceID } from './reference';
|
|
15
|
+
import type { WellKnownSymbols } from './symbols';
|
|
16
|
+
import { INV_SYMBOL_REF } from './symbols';
|
|
17
|
+
import type {
|
|
9
18
|
SerovalBigIntNode,
|
|
10
19
|
SerovalBigIntTypedArrayNode,
|
|
11
|
-
SerovalBooleanNode,
|
|
12
20
|
SerovalDateNode,
|
|
13
|
-
SerovalInfinityNode,
|
|
14
|
-
SerovalNaNNode,
|
|
15
|
-
SerovalNegativeInfinityNode,
|
|
16
|
-
SerovalNegativeZeroNode,
|
|
17
|
-
SerovalNodeType,
|
|
18
|
-
SerovalNullNode,
|
|
19
|
-
SerovalNumberNode,
|
|
20
21
|
SerovalIndexedValueNode,
|
|
21
22
|
SerovalRegExpNode,
|
|
22
23
|
SerovalStringNode,
|
|
23
24
|
SerovalTypedArrayNode,
|
|
24
|
-
SerovalUndefinedNode,
|
|
25
25
|
SerovalWKSymbolNode,
|
|
26
26
|
SerovalReferenceNode,
|
|
27
|
+
SerovalArrayBufferNode,
|
|
28
|
+
SerovalDataViewNode,
|
|
29
|
+
SerovalNode,
|
|
30
|
+
} from './types';
|
|
31
|
+
import {
|
|
32
|
+
SerovalNodeType,
|
|
27
33
|
} from './types';
|
|
28
34
|
|
|
29
|
-
export
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
c: undefined,
|
|
57
|
-
m: undefined,
|
|
58
|
-
d: undefined,
|
|
59
|
-
a: undefined,
|
|
60
|
-
f: undefined,
|
|
61
|
-
};
|
|
62
|
-
export const NULL_NODE: SerovalNullNode = {
|
|
63
|
-
t: SerovalNodeType.Null,
|
|
64
|
-
i: undefined,
|
|
65
|
-
s: undefined,
|
|
66
|
-
l: undefined,
|
|
67
|
-
c: undefined,
|
|
68
|
-
m: undefined,
|
|
69
|
-
d: undefined,
|
|
70
|
-
a: undefined,
|
|
71
|
-
f: undefined,
|
|
72
|
-
};
|
|
73
|
-
export const NEG_ZERO_NODE: SerovalNegativeZeroNode = {
|
|
74
|
-
t: SerovalNodeType.NegativeZero,
|
|
75
|
-
i: undefined,
|
|
76
|
-
s: undefined,
|
|
77
|
-
l: undefined,
|
|
78
|
-
c: undefined,
|
|
79
|
-
m: undefined,
|
|
80
|
-
d: undefined,
|
|
81
|
-
a: undefined,
|
|
82
|
-
f: undefined,
|
|
83
|
-
};
|
|
84
|
-
export const INFINITY_NODE: SerovalInfinityNode = {
|
|
85
|
-
t: SerovalNodeType.Infinity,
|
|
86
|
-
i: undefined,
|
|
87
|
-
s: undefined,
|
|
88
|
-
l: undefined,
|
|
89
|
-
c: undefined,
|
|
90
|
-
m: undefined,
|
|
91
|
-
d: undefined,
|
|
92
|
-
a: undefined,
|
|
93
|
-
f: undefined,
|
|
94
|
-
};
|
|
95
|
-
export const NEG_INFINITY_NODE: SerovalNegativeInfinityNode = {
|
|
96
|
-
t: SerovalNodeType.NegativeInfinity,
|
|
97
|
-
i: undefined,
|
|
98
|
-
s: undefined,
|
|
99
|
-
l: undefined,
|
|
100
|
-
c: undefined,
|
|
101
|
-
m: undefined,
|
|
102
|
-
d: undefined,
|
|
103
|
-
a: undefined,
|
|
104
|
-
f: undefined,
|
|
105
|
-
};
|
|
106
|
-
export const NAN_NODE: SerovalNaNNode = {
|
|
107
|
-
t: SerovalNodeType.NaN,
|
|
108
|
-
i: undefined,
|
|
109
|
-
s: undefined,
|
|
110
|
-
l: undefined,
|
|
111
|
-
c: undefined,
|
|
112
|
-
m: undefined,
|
|
113
|
-
d: undefined,
|
|
114
|
-
a: undefined,
|
|
115
|
-
f: undefined,
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
export function createNumberNode(value: number): SerovalNumberNode {
|
|
119
|
-
return {
|
|
120
|
-
t: SerovalNodeType.Number,
|
|
121
|
-
i: undefined,
|
|
122
|
-
s: value,
|
|
123
|
-
l: undefined,
|
|
124
|
-
c: undefined,
|
|
125
|
-
m: undefined,
|
|
126
|
-
d: undefined,
|
|
127
|
-
a: undefined,
|
|
128
|
-
f: undefined,
|
|
129
|
-
};
|
|
35
|
+
export function createNumberNode(value: number): SerovalNode {
|
|
36
|
+
switch (value) {
|
|
37
|
+
case Infinity:
|
|
38
|
+
return INFINITY_NODE;
|
|
39
|
+
case -Infinity:
|
|
40
|
+
return NEG_INFINITY_NODE;
|
|
41
|
+
default:
|
|
42
|
+
// eslint-disable-next-line no-self-compare
|
|
43
|
+
if (value !== value) {
|
|
44
|
+
return NAN_NODE;
|
|
45
|
+
}
|
|
46
|
+
if (Object.is(value, -0)) {
|
|
47
|
+
return NEG_ZERO_NODE;
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
t: SerovalNodeType.Number,
|
|
51
|
+
i: undefined,
|
|
52
|
+
s: value,
|
|
53
|
+
l: undefined,
|
|
54
|
+
c: undefined,
|
|
55
|
+
m: undefined,
|
|
56
|
+
d: undefined,
|
|
57
|
+
a: undefined,
|
|
58
|
+
f: undefined,
|
|
59
|
+
b: undefined,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
130
62
|
}
|
|
131
63
|
|
|
132
64
|
export function createStringNode(value: string): SerovalStringNode {
|
|
133
65
|
return {
|
|
134
66
|
t: SerovalNodeType.String,
|
|
135
67
|
i: undefined,
|
|
136
|
-
s:
|
|
68
|
+
s: serializeString(value),
|
|
137
69
|
l: undefined,
|
|
138
70
|
c: undefined,
|
|
139
71
|
m: undefined,
|
|
140
72
|
d: undefined,
|
|
141
73
|
a: undefined,
|
|
142
74
|
f: undefined,
|
|
75
|
+
b: undefined,
|
|
143
76
|
};
|
|
144
77
|
}
|
|
145
78
|
|
|
@@ -147,7 +80,7 @@ export function createBigIntNode(
|
|
|
147
80
|
ctx: ParserContext,
|
|
148
81
|
current: bigint,
|
|
149
82
|
): SerovalBigIntNode {
|
|
150
|
-
assert(ctx.features & Feature.BigInt,
|
|
83
|
+
assert(ctx.features & Feature.BigInt, new UnsupportedTypeError(current));
|
|
151
84
|
return {
|
|
152
85
|
t: SerovalNodeType.BigInt,
|
|
153
86
|
i: undefined,
|
|
@@ -158,6 +91,7 @@ export function createBigIntNode(
|
|
|
158
91
|
d: undefined,
|
|
159
92
|
a: undefined,
|
|
160
93
|
f: undefined,
|
|
94
|
+
b: undefined,
|
|
161
95
|
};
|
|
162
96
|
}
|
|
163
97
|
|
|
@@ -172,6 +106,7 @@ export function createIndexedValueNode(id: number): SerovalIndexedValueNode {
|
|
|
172
106
|
d: undefined,
|
|
173
107
|
a: undefined,
|
|
174
108
|
f: undefined,
|
|
109
|
+
b: undefined,
|
|
175
110
|
};
|
|
176
111
|
}
|
|
177
112
|
|
|
@@ -186,6 +121,7 @@ export function createDateNode(id: number, current: Date): SerovalDateNode {
|
|
|
186
121
|
d: undefined,
|
|
187
122
|
f: undefined,
|
|
188
123
|
a: undefined,
|
|
124
|
+
b: undefined,
|
|
189
125
|
};
|
|
190
126
|
}
|
|
191
127
|
|
|
@@ -200,31 +136,62 @@ export function createRegExpNode(id: number, current: RegExp): SerovalRegExpNode
|
|
|
200
136
|
d: undefined,
|
|
201
137
|
a: undefined,
|
|
202
138
|
f: undefined,
|
|
139
|
+
b: undefined,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export function createArrayBufferNode(
|
|
144
|
+
id: number,
|
|
145
|
+
current: ArrayBuffer,
|
|
146
|
+
): SerovalArrayBufferNode {
|
|
147
|
+
const bytes = new Uint8Array(current);
|
|
148
|
+
const len = bytes.length;
|
|
149
|
+
const values = new Array<number>(len);
|
|
150
|
+
for (let i = 0; i < len; i++) {
|
|
151
|
+
values[i] = bytes[i];
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
t: SerovalNodeType.ArrayBuffer,
|
|
155
|
+
i: id,
|
|
156
|
+
s: values,
|
|
157
|
+
l: undefined,
|
|
158
|
+
c: undefined,
|
|
159
|
+
m: undefined,
|
|
160
|
+
d: undefined,
|
|
161
|
+
a: undefined,
|
|
162
|
+
f: undefined,
|
|
163
|
+
b: undefined,
|
|
203
164
|
};
|
|
204
165
|
}
|
|
205
166
|
|
|
167
|
+
export function serializeArrayBuffer(
|
|
168
|
+
ctx: ParserContext,
|
|
169
|
+
current: ArrayBuffer,
|
|
170
|
+
): SerovalNode {
|
|
171
|
+
const id = createIndexedValue(ctx, current);
|
|
172
|
+
if (ctx.markedRefs.has(id)) {
|
|
173
|
+
return createIndexedValueNode(id);
|
|
174
|
+
}
|
|
175
|
+
return createArrayBufferNode(id, current);
|
|
176
|
+
}
|
|
177
|
+
|
|
206
178
|
export function createTypedArrayNode(
|
|
207
179
|
ctx: ParserContext,
|
|
208
180
|
id: number,
|
|
209
181
|
current: TypedArrayValue,
|
|
210
182
|
): SerovalTypedArrayNode {
|
|
211
|
-
|
|
212
|
-
assert(ctx.features & Feature.TypedArray, `Unsupported value type "${constructor}"`);
|
|
213
|
-
const len = current.length;
|
|
214
|
-
const values = new Array<string>(len);
|
|
215
|
-
for (let i = 0; i < len; i++) {
|
|
216
|
-
values[i] = '' + current[i];
|
|
217
|
-
}
|
|
183
|
+
assert(ctx.features & Feature.TypedArray, new UnsupportedTypeError(current));
|
|
218
184
|
return {
|
|
219
185
|
t: SerovalNodeType.TypedArray,
|
|
220
186
|
i: id,
|
|
221
|
-
s:
|
|
222
|
-
l: current.
|
|
223
|
-
c: constructor,
|
|
187
|
+
s: undefined,
|
|
188
|
+
l: current.length,
|
|
189
|
+
c: current.constructor.name,
|
|
224
190
|
m: undefined,
|
|
225
191
|
d: undefined,
|
|
226
192
|
a: undefined,
|
|
227
|
-
f:
|
|
193
|
+
f: serializeArrayBuffer(ctx, current.buffer),
|
|
194
|
+
b: current.byteOffset,
|
|
228
195
|
};
|
|
229
196
|
}
|
|
230
197
|
|
|
@@ -235,38 +202,34 @@ export function createBigIntTypedArrayNode(
|
|
|
235
202
|
id: number,
|
|
236
203
|
current: BigIntTypedArrayValue,
|
|
237
204
|
): SerovalBigIntTypedArrayNode {
|
|
238
|
-
const constructor = current.constructor.name;
|
|
239
205
|
assert(
|
|
240
206
|
(ctx.features & BIGINT_FLAG) === BIGINT_FLAG,
|
|
241
|
-
|
|
207
|
+
new UnsupportedTypeError(current),
|
|
242
208
|
);
|
|
243
|
-
const len = current.length;
|
|
244
|
-
const values = new Array<string>(len);
|
|
245
|
-
for (let i = 0; i < len; i++) {
|
|
246
|
-
values[i] = '' + current[i];
|
|
247
|
-
}
|
|
248
209
|
return {
|
|
249
210
|
t: SerovalNodeType.BigIntTypedArray,
|
|
250
211
|
i: id,
|
|
251
|
-
s:
|
|
252
|
-
l: current.
|
|
253
|
-
c: constructor,
|
|
212
|
+
s: undefined,
|
|
213
|
+
l: current.length,
|
|
214
|
+
c: current.constructor.name,
|
|
254
215
|
m: undefined,
|
|
255
216
|
d: undefined,
|
|
256
217
|
a: undefined,
|
|
257
|
-
f:
|
|
218
|
+
f: serializeArrayBuffer(ctx, current.buffer),
|
|
219
|
+
b: current.byteOffset,
|
|
258
220
|
};
|
|
259
221
|
}
|
|
260
222
|
|
|
261
223
|
export function createWKSymbolNode(
|
|
262
224
|
ctx: ParserContext,
|
|
225
|
+
id: number,
|
|
263
226
|
current: WellKnownSymbols,
|
|
264
227
|
): SerovalWKSymbolNode {
|
|
265
|
-
assert(ctx.features & Feature.Symbol,
|
|
266
|
-
assert(current in INV_SYMBOL_REF, '
|
|
228
|
+
assert(ctx.features & Feature.Symbol, new UnsupportedTypeError(current));
|
|
229
|
+
assert(current in INV_SYMBOL_REF, new Error('Only well-known symbols are supported.'));
|
|
267
230
|
return {
|
|
268
231
|
t: SerovalNodeType.WKSymbol,
|
|
269
|
-
i:
|
|
232
|
+
i: id,
|
|
270
233
|
s: INV_SYMBOL_REF[current],
|
|
271
234
|
l: undefined,
|
|
272
235
|
c: undefined,
|
|
@@ -274,6 +237,7 @@ export function createWKSymbolNode(
|
|
|
274
237
|
d: undefined,
|
|
275
238
|
a: undefined,
|
|
276
239
|
f: undefined,
|
|
240
|
+
b: undefined,
|
|
277
241
|
};
|
|
278
242
|
}
|
|
279
243
|
|
|
@@ -284,12 +248,59 @@ export function createReferenceNode<T>(
|
|
|
284
248
|
return {
|
|
285
249
|
t: SerovalNodeType.Reference,
|
|
286
250
|
i: id,
|
|
287
|
-
s:
|
|
251
|
+
s: serializeString(getReferenceID(ref)),
|
|
288
252
|
l: undefined,
|
|
289
253
|
c: undefined,
|
|
290
254
|
m: undefined,
|
|
291
255
|
d: undefined,
|
|
292
256
|
a: undefined,
|
|
293
257
|
f: undefined,
|
|
258
|
+
b: undefined,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export function createDataViewNode(
|
|
263
|
+
ctx: ParserContext,
|
|
264
|
+
id: number,
|
|
265
|
+
current: DataView,
|
|
266
|
+
): SerovalDataViewNode {
|
|
267
|
+
return {
|
|
268
|
+
t: SerovalNodeType.DataView,
|
|
269
|
+
i: id,
|
|
270
|
+
s: undefined,
|
|
271
|
+
l: current.byteLength,
|
|
272
|
+
c: undefined,
|
|
273
|
+
m: undefined,
|
|
274
|
+
d: undefined,
|
|
275
|
+
a: undefined,
|
|
276
|
+
f: serializeArrayBuffer(ctx, current.buffer),
|
|
277
|
+
b: current.byteOffset,
|
|
294
278
|
};
|
|
295
279
|
}
|
|
280
|
+
|
|
281
|
+
export function createSymbolNode(
|
|
282
|
+
ctx: ParserContext,
|
|
283
|
+
current: symbol,
|
|
284
|
+
): SerovalNode {
|
|
285
|
+
const id = createIndexedValue(ctx, current);
|
|
286
|
+
if (ctx.markedRefs.has(id)) {
|
|
287
|
+
return createIndexedValueNode(id);
|
|
288
|
+
}
|
|
289
|
+
if (hasReferenceID(current)) {
|
|
290
|
+
return createReferenceNode(id, current);
|
|
291
|
+
}
|
|
292
|
+
return createWKSymbolNode(ctx, id, current as WellKnownSymbols);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
export function createFunctionNode(
|
|
296
|
+
ctx: ParserContext,
|
|
297
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
298
|
+
current: Function,
|
|
299
|
+
): SerovalNode {
|
|
300
|
+
assert(hasReferenceID(current), new Error('Cannot serialize function without reference ID.'));
|
|
301
|
+
const id = createIndexedValue(ctx, current);
|
|
302
|
+
if (ctx.markedRefs.has(id)) {
|
|
303
|
+
return createIndexedValueNode(id);
|
|
304
|
+
}
|
|
305
|
+
return createReferenceNode(id, current);
|
|
306
|
+
}
|
package/src/tree/reference.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
1
2
|
/* eslint-disable no-restricted-globals */
|
|
2
3
|
import assert from '../assert';
|
|
3
4
|
|
|
@@ -19,12 +20,12 @@ export function hasReference(id: string): boolean {
|
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
export function getReferenceID<T>(value: T): string {
|
|
22
|
-
assert(hasReferenceID(value), 'Missing reference id');
|
|
23
|
-
return REFERENCE.get(value)
|
|
23
|
+
assert(hasReferenceID(value), new Error('Missing reference id'));
|
|
24
|
+
return REFERENCE.get(value)!;
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
export function getReference<T>(id: string): T {
|
|
27
|
-
assert(hasReference(id), 'Missing reference for id:' + id);
|
|
28
|
+
assert(hasReference(id), new Error('Missing reference for id:' + id));
|
|
28
29
|
return INV_REFERENCE.get(id) as T;
|
|
29
30
|
}
|
|
30
31
|
|