seroval 1.6.12 → 1.7.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 +10 -3
- package/dist/dev/index.cjs +1572 -1039
- package/dist/dev/index.d.cts +285 -251
- package/dist/dev/index.d.ts +285 -251
- package/dist/dev/index.js +1564 -1040
- package/dist/index.cjs +1562 -1038
- package/dist/index.d.cts +285 -251
- package/dist/index.d.ts +285 -251
- package/dist/index.js +1554 -1039
- package/package.json +19 -11
package/dist/dev/index.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
//#region src/core/compat.ts
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* Public feature bits for `disabledFeatures`. Stays a runtime `enum` so the
|
|
4
|
+
* published declaration is unchanged for consumers. Its values must match
|
|
5
|
+
* the internal bits (checked by test/feature.test.ts).
|
|
6
6
|
*/
|
|
7
7
|
let Feature = /* @__PURE__ */ function(Feature) {
|
|
8
8
|
Feature[Feature["AggregateError"] = 1] = "AggregateError";
|
|
9
|
+
/**
|
|
10
|
+
* @deprecated Has no effect. Output always uses arrow functions.
|
|
11
|
+
*/
|
|
9
12
|
Feature[Feature["ArrowFunction"] = 2] = "ArrowFunction";
|
|
10
13
|
Feature[Feature["ErrorPrototypeStack"] = 4] = "ErrorPrototypeStack";
|
|
11
14
|
Feature[Feature["ObjectAssign"] = 8] = "ObjectAssign";
|
|
@@ -31,35 +34,15 @@ const SYM_TO_STRING_TAG = Symbol.toStringTag;
|
|
|
31
34
|
const SYM_UNSCOPABLES = Symbol.unscopables;
|
|
32
35
|
//#endregion
|
|
33
36
|
//#region src/core/constants.ts
|
|
34
|
-
const
|
|
35
|
-
[0]: "
|
|
36
|
-
[1]: "
|
|
37
|
-
[2]: "
|
|
38
|
-
[3]: "
|
|
39
|
-
[4]: "
|
|
40
|
-
[5]: "
|
|
41
|
-
[6]: "
|
|
42
|
-
[7]: "
|
|
43
|
-
[8]: "Symbol.species",
|
|
44
|
-
[9]: "Symbol.split",
|
|
45
|
-
[10]: "Symbol.toPrimitive",
|
|
46
|
-
[11]: "Symbol.toStringTag",
|
|
47
|
-
[12]: "Symbol.unscopables"
|
|
48
|
-
};
|
|
49
|
-
const INV_SYMBOL_REF = {
|
|
50
|
-
[SYM_ASYNC_ITERATOR]: 0,
|
|
51
|
-
[SYM_HAS_INSTANCE]: 1,
|
|
52
|
-
[SYM_IS_CONCAT_SPREADABLE]: 2,
|
|
53
|
-
[SYM_ITERATOR]: 3,
|
|
54
|
-
[SYM_MATCH]: 4,
|
|
55
|
-
[SYM_MATCH_ALL]: 5,
|
|
56
|
-
[SYM_REPLACE]: 6,
|
|
57
|
-
[SYM_SEARCH]: 7,
|
|
58
|
-
[SYM_SPECIES]: 8,
|
|
59
|
-
[SYM_SPLIT]: 9,
|
|
60
|
-
[SYM_TO_PRIMITIVE]: 10,
|
|
61
|
-
[SYM_TO_STRING_TAG]: 11,
|
|
62
|
-
[SYM_UNSCOPABLES]: 12
|
|
37
|
+
const TEMPORAL_TYPE_NAME = {
|
|
38
|
+
[0]: "Instant",
|
|
39
|
+
[1]: "Duration",
|
|
40
|
+
[2]: "PlainDate",
|
|
41
|
+
[3]: "PlainDateTime",
|
|
42
|
+
[4]: "PlainMonthDay",
|
|
43
|
+
[5]: "PlainTime",
|
|
44
|
+
[6]: "PlainYearMonth",
|
|
45
|
+
[7]: "ZonedDateTime"
|
|
63
46
|
};
|
|
64
47
|
const SYMBOL_REF = {
|
|
65
48
|
[0]: SYM_ASYNC_ITERATOR,
|
|
@@ -76,6 +59,18 @@ const SYMBOL_REF = {
|
|
|
76
59
|
[11]: SYM_TO_STRING_TAG,
|
|
77
60
|
[12]: SYM_UNSCOPABLES
|
|
78
61
|
};
|
|
62
|
+
function createSymbolStringTable() {
|
|
63
|
+
const result = {};
|
|
64
|
+
for (let i = 0; i <= 12; i++) result[i] = SYMBOL_REF[i].description;
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
const SYMBOL_STRING = /* @__PURE__ */ createSymbolStringTable();
|
|
68
|
+
function createInverseSymbolTable() {
|
|
69
|
+
const result = {};
|
|
70
|
+
for (let i = 0; i <= 12; i++) result[SYMBOL_REF[i]] = i;
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
const INV_SYMBOL_REF = /* @__PURE__ */ createInverseSymbolTable();
|
|
79
74
|
const CONSTANT_STRING = {
|
|
80
75
|
[2]: "!0",
|
|
81
76
|
[3]: "!1",
|
|
@@ -92,19 +87,10 @@ const CONSTANT_VAL = {
|
|
|
92
87
|
[1]: void 0,
|
|
93
88
|
[0]: null,
|
|
94
89
|
[4]: -0,
|
|
95
|
-
[5]:
|
|
96
|
-
[6]:
|
|
90
|
+
[5]: Infinity,
|
|
91
|
+
[6]: -Infinity,
|
|
97
92
|
[7]: NaN
|
|
98
93
|
};
|
|
99
|
-
const ERROR_CONSTRUCTOR_STRING = {
|
|
100
|
-
[0]: "Error",
|
|
101
|
-
[1]: "EvalError",
|
|
102
|
-
[2]: "RangeError",
|
|
103
|
-
[3]: "ReferenceError",
|
|
104
|
-
[4]: "SyntaxError",
|
|
105
|
-
[5]: "TypeError",
|
|
106
|
-
[6]: "URIError"
|
|
107
|
-
};
|
|
108
94
|
const ERROR_CONSTRUCTOR = {
|
|
109
95
|
[0]: Error,
|
|
110
96
|
[1]: EvalError,
|
|
@@ -114,9 +100,20 @@ const ERROR_CONSTRUCTOR = {
|
|
|
114
100
|
[5]: TypeError,
|
|
115
101
|
[6]: URIError
|
|
116
102
|
};
|
|
103
|
+
function createErrorConstructorStringTable() {
|
|
104
|
+
const result = {};
|
|
105
|
+
for (let i = 0; i <= 6; i++) result[i] = ERROR_CONSTRUCTOR[i].name;
|
|
106
|
+
return result;
|
|
107
|
+
}
|
|
108
|
+
const ERROR_CONSTRUCTOR_STRING = /* @__PURE__ */ createErrorConstructorStringTable();
|
|
117
109
|
//#endregion
|
|
118
110
|
//#region src/core/node.ts
|
|
119
111
|
function createSerovalNode(t, i, s, c, m, p, e, a, f, b, o, l) {
|
|
112
|
+
if (c === void 0 && m === void 0 && p === void 0 && e === void 0 && a === void 0 && f === void 0 && b === void 0 && o === void 0 && l === void 0) return {
|
|
113
|
+
t,
|
|
114
|
+
i,
|
|
115
|
+
s
|
|
116
|
+
};
|
|
120
117
|
return {
|
|
121
118
|
t,
|
|
122
119
|
i,
|
|
@@ -135,7 +132,7 @@ function createSerovalNode(t, i, s, c, m, p, e, a, f, b, o, l) {
|
|
|
135
132
|
//#endregion
|
|
136
133
|
//#region src/core/literals.ts
|
|
137
134
|
function createConstantNode(value) {
|
|
138
|
-
return createSerovalNode(2, void 0, value
|
|
135
|
+
return createSerovalNode(2, void 0, value);
|
|
139
136
|
}
|
|
140
137
|
const TRUE_NODE = /* @__PURE__ */ createConstantNode(2);
|
|
141
138
|
const FALSE_NODE = /* @__PURE__ */ createConstantNode(3);
|
|
@@ -148,60 +145,109 @@ const NAN_NODE = /* @__PURE__ */ createConstantNode(7);
|
|
|
148
145
|
//#endregion
|
|
149
146
|
//#region src/core/string.ts
|
|
150
147
|
const MIN_JSON_STRINGIFY_LENGTH = 64;
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
case
|
|
159
|
-
case
|
|
160
|
-
case
|
|
161
|
-
case
|
|
162
|
-
case
|
|
163
|
-
case
|
|
148
|
+
const NEEDS_ESCAPE = /["\\\n\r\b\t\f<\u2028\u2029]/;
|
|
149
|
+
const JSON_ESCAPE_DIFFERENCES = /[\x00-\x07\x0b\x0e-\x1f\ud800-\udfff]/;
|
|
150
|
+
const LESS_THAN = /</g;
|
|
151
|
+
const LINE_SEPARATOR = /\u2028/g;
|
|
152
|
+
const PARAGRAPH_SEPARATOR = /\u2029/g;
|
|
153
|
+
function escapeCharCode(code) {
|
|
154
|
+
switch (code) {
|
|
155
|
+
case 34: return "\\\"";
|
|
156
|
+
case 92: return "\\\\";
|
|
157
|
+
case 10: return "\\n";
|
|
158
|
+
case 13: return "\\r";
|
|
159
|
+
case 8: return "\\b";
|
|
160
|
+
case 9: return "\\t";
|
|
161
|
+
case 12: return "\\f";
|
|
162
|
+
case 60: return "\\x3C";
|
|
163
|
+
case 8232: return "\\u2028";
|
|
164
|
+
case 8233: return "\\u2029";
|
|
164
165
|
default: return;
|
|
165
166
|
}
|
|
166
167
|
}
|
|
167
168
|
function serializeString(str) {
|
|
168
|
-
if (
|
|
169
|
+
if (!NEEDS_ESCAPE.test(str)) return str;
|
|
170
|
+
if (str.length >= MIN_JSON_STRINGIFY_LENGTH && !JSON_ESCAPE_DIFFERENCES.test(str)) {
|
|
171
|
+
let result = JSON.stringify(str).slice(1, -1);
|
|
172
|
+
if (result.includes("<")) result = result.replace(LESS_THAN, "\\x3C");
|
|
173
|
+
if (result.includes("\u2028")) result = result.replace(LINE_SEPARATOR, "\\u2028");
|
|
174
|
+
if (result.includes("\u2029")) result = result.replace(PARAGRAPH_SEPARATOR, "\\u2029");
|
|
175
|
+
return result;
|
|
176
|
+
}
|
|
169
177
|
let result = "";
|
|
170
178
|
let lastPos = 0;
|
|
171
179
|
let replacement;
|
|
172
180
|
for (let i = 0, len = str.length; i < len; i++) {
|
|
173
|
-
replacement =
|
|
181
|
+
replacement = escapeCharCode(str.charCodeAt(i));
|
|
174
182
|
if (replacement) {
|
|
175
183
|
result += str.slice(lastPos, i) + replacement;
|
|
176
184
|
lastPos = i + 1;
|
|
177
185
|
}
|
|
178
186
|
}
|
|
179
|
-
|
|
180
|
-
else result += str.slice(lastPos);
|
|
181
|
-
return result;
|
|
182
|
-
}
|
|
183
|
-
function deserializeReplacer(str) {
|
|
184
|
-
switch (str) {
|
|
185
|
-
case "\\\\": return "\\";
|
|
186
|
-
case "\\\"": return "\"";
|
|
187
|
-
case "\\n": return "\n";
|
|
188
|
-
case "\\r": return "\r";
|
|
189
|
-
case "\\b": return "\b";
|
|
190
|
-
case "\\t": return " ";
|
|
191
|
-
case "\\f": return "\f";
|
|
192
|
-
case "\\x3C": return "<";
|
|
193
|
-
case "\\u2028": return "\u2028";
|
|
194
|
-
case "\\u2029": return "\u2029";
|
|
195
|
-
default: return str;
|
|
196
|
-
}
|
|
187
|
+
return result + str.slice(lastPos);
|
|
197
188
|
}
|
|
189
|
+
const JSON_COMPATIBLE = /^(?:[^"\\\x00-\x1f]|\\["\\nrbtf])*$/;
|
|
190
|
+
const ESCAPE_SEQUENCE = /(\\\\|\\"|\\n|\\r|\\b|\\t|\\f|\\u2028|\\u2029|\\x3C)/g;
|
|
198
191
|
function deserializeString(str) {
|
|
199
|
-
if (typeof str
|
|
200
|
-
|
|
192
|
+
if (typeof str !== "string") return str.replace(ESCAPE_SEQUENCE, deserializeString);
|
|
193
|
+
let index = str.indexOf("\\");
|
|
194
|
+
if (index === -1) return str;
|
|
195
|
+
if (JSON_COMPATIBLE.test(str)) return JSON.parse("\"" + str + "\"");
|
|
196
|
+
let result = "";
|
|
197
|
+
let lastPos = 0;
|
|
198
|
+
const last = str.length - 1;
|
|
199
|
+
while (index !== -1 && index < last) {
|
|
200
|
+
let replacement;
|
|
201
|
+
let length = 2;
|
|
202
|
+
switch (str.charCodeAt(index + 1)) {
|
|
203
|
+
case 92:
|
|
204
|
+
replacement = "\\";
|
|
205
|
+
break;
|
|
206
|
+
case 34:
|
|
207
|
+
replacement = "\"";
|
|
208
|
+
break;
|
|
209
|
+
case 110:
|
|
210
|
+
replacement = "\n";
|
|
211
|
+
break;
|
|
212
|
+
case 114:
|
|
213
|
+
replacement = "\r";
|
|
214
|
+
break;
|
|
215
|
+
case 98:
|
|
216
|
+
replacement = "\b";
|
|
217
|
+
break;
|
|
218
|
+
case 116:
|
|
219
|
+
replacement = " ";
|
|
220
|
+
break;
|
|
221
|
+
case 102:
|
|
222
|
+
replacement = "\f";
|
|
223
|
+
break;
|
|
224
|
+
case 120:
|
|
225
|
+
if (str.startsWith("3C", index + 2)) {
|
|
226
|
+
replacement = "<";
|
|
227
|
+
length = 4;
|
|
228
|
+
}
|
|
229
|
+
break;
|
|
230
|
+
case 117: if (str.startsWith("2028", index + 2)) {
|
|
231
|
+
replacement = "\u2028";
|
|
232
|
+
length = 6;
|
|
233
|
+
} else if (str.startsWith("2029", index + 2)) {
|
|
234
|
+
replacement = "\u2029";
|
|
235
|
+
length = 6;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
if (replacement) {
|
|
239
|
+
result += str.slice(lastPos, index) + replacement;
|
|
240
|
+
lastPos = index + length;
|
|
241
|
+
index = str.indexOf("\\", lastPos);
|
|
242
|
+
} else index = str.indexOf("\\", index + 1);
|
|
243
|
+
}
|
|
244
|
+
return result + str.slice(lastPos);
|
|
201
245
|
}
|
|
202
246
|
//#endregion
|
|
203
247
|
//#region src/core/errors.ts
|
|
204
|
-
|
|
248
|
+
function objectToString(value) {
|
|
249
|
+
return Object.prototype.toString.call(value);
|
|
250
|
+
}
|
|
205
251
|
function getErrorMessageDev(type, cause) {
|
|
206
252
|
if (cause instanceof Error) return `Seroval caught an error during the ${type} process.
|
|
207
253
|
|
|
@@ -212,14 +258,13 @@ ${cause.message}
|
|
|
212
258
|
- If you believe this is an error in Seroval, please submit an issue at https://github.com/lxsmnsyc/seroval/issues/new`;
|
|
213
259
|
return `Seroval caught an error during the ${type} process.
|
|
214
260
|
|
|
215
|
-
"${objectToString
|
|
261
|
+
"${objectToString(cause)}"
|
|
216
262
|
|
|
217
263
|
For more information, please check the "cause" property of this error.`;
|
|
218
264
|
}
|
|
219
|
-
const getErrorMessage = (type, cause) => getErrorMessageDev(type, cause);
|
|
220
265
|
var SerovalError = class extends Error {
|
|
221
266
|
constructor(type, cause) {
|
|
222
|
-
super(
|
|
267
|
+
super(getErrorMessageDev(type, cause));
|
|
223
268
|
this.cause = cause;
|
|
224
269
|
}
|
|
225
270
|
};
|
|
@@ -240,7 +285,7 @@ var SerovalDeserializationError = class extends SerovalError {
|
|
|
240
285
|
};
|
|
241
286
|
var SerovalUnsupportedTypeError = class extends Error {
|
|
242
287
|
constructor(value) {
|
|
243
|
-
super(`The value ${objectToString
|
|
288
|
+
super(`The value ${objectToString(value)} of type "${typeof value}" cannot be parsed/serialized.
|
|
244
289
|
|
|
245
290
|
There are few workarounds for this problem:
|
|
246
291
|
- Transform the value in a way that it can be serialized.
|
|
@@ -263,9 +308,13 @@ var SerovalMissingInstanceError = class extends Error {
|
|
|
263
308
|
super("Missing \"" + tag + "\" instance.");
|
|
264
309
|
}
|
|
265
310
|
};
|
|
311
|
+
/**
|
|
312
|
+
* @deprecated Not thrown by seroval. A missing `createReference` key throws
|
|
313
|
+
* {@link SerovalMissingReferenceForIdError} instead.
|
|
314
|
+
*/
|
|
266
315
|
var SerovalMissingReferenceError = class extends Error {
|
|
267
316
|
constructor(value) {
|
|
268
|
-
super("Missing reference for the value \"" + objectToString
|
|
317
|
+
super("Missing reference for the value \"" + objectToString(value) + "\" of type \"" + typeof value + "\"");
|
|
269
318
|
this.value = value;
|
|
270
319
|
}
|
|
271
320
|
};
|
|
@@ -294,103 +343,43 @@ var SerovalDepthLimitError = class extends Error {
|
|
|
294
343
|
super("Depth limit of " + limit + " reached");
|
|
295
344
|
}
|
|
296
345
|
};
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
}
|
|
314
|
-
function hasReferenceID(value) {
|
|
315
|
-
return REFERENCE.has(value);
|
|
316
|
-
}
|
|
317
|
-
function hasReference(id) {
|
|
318
|
-
return INV_REFERENCE.has(id);
|
|
319
|
-
}
|
|
320
|
-
function getReferenceID(value) {
|
|
321
|
-
if (hasReferenceID(value)) return REFERENCE.get(value);
|
|
322
|
-
throw new SerovalMissingReferenceError(value);
|
|
323
|
-
}
|
|
324
|
-
function getReference(id) {
|
|
325
|
-
if (hasReference(id)) return INV_REFERENCE.get(id);
|
|
326
|
-
throw new SerovalMissingReferenceForIdError(id);
|
|
327
|
-
}
|
|
328
|
-
if (typeof globalThis !== "undefined") Object.defineProperty(globalThis, REFERENCES_KEY, {
|
|
329
|
-
value: INV_REFERENCE,
|
|
330
|
-
configurable: true,
|
|
331
|
-
writable: false,
|
|
332
|
-
enumerable: false
|
|
333
|
-
});
|
|
334
|
-
else if (typeof window !== "undefined") Object.defineProperty(window, REFERENCES_KEY, {
|
|
335
|
-
value: INV_REFERENCE,
|
|
336
|
-
configurable: true,
|
|
337
|
-
writable: false,
|
|
338
|
-
enumerable: false
|
|
339
|
-
});
|
|
340
|
-
else if (typeof self !== "undefined") Object.defineProperty(self, REFERENCES_KEY, {
|
|
341
|
-
value: INV_REFERENCE,
|
|
342
|
-
configurable: true,
|
|
343
|
-
writable: false,
|
|
344
|
-
enumerable: false
|
|
345
|
-
});
|
|
346
|
-
else if (typeof global !== "undefined") Object.defineProperty(global, REFERENCES_KEY, {
|
|
347
|
-
value: INV_REFERENCE,
|
|
348
|
-
configurable: true,
|
|
349
|
-
writable: false,
|
|
350
|
-
enumerable: false
|
|
351
|
-
});
|
|
346
|
+
var SerovalAbortedError = class extends Error {
|
|
347
|
+
constructor() {
|
|
348
|
+
super("Cross deserializer has been aborted.");
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
const LIVE_STREAM_ERROR_MESSAGES = {
|
|
352
|
+
consumed: "Live stream already has a consumer",
|
|
353
|
+
pending: "Live stream already has a pending event",
|
|
354
|
+
reading: "Live stream already has a pending read",
|
|
355
|
+
closed: "Live stream is closed"
|
|
356
|
+
};
|
|
357
|
+
var SerovalLiveStreamError = class extends Error {
|
|
358
|
+
constructor(reason) {
|
|
359
|
+
super(LIVE_STREAM_ERROR_MESSAGES[reason]);
|
|
360
|
+
this.reason = reason;
|
|
361
|
+
}
|
|
362
|
+
};
|
|
352
363
|
//#endregion
|
|
353
364
|
//#region src/core/utils/error.ts
|
|
354
365
|
function getErrorConstructor(error) {
|
|
355
|
-
if (error instanceof
|
|
356
|
-
if (error instanceof RangeError) return 2;
|
|
357
|
-
if (error instanceof ReferenceError) return 3;
|
|
358
|
-
if (error instanceof SyntaxError) return 4;
|
|
359
|
-
if (error instanceof TypeError) return 5;
|
|
360
|
-
if (error instanceof URIError) return 6;
|
|
366
|
+
for (let i = 1; i <= 6; i++) if (error instanceof ERROR_CONSTRUCTOR[i]) return i;
|
|
361
367
|
return 0;
|
|
362
368
|
}
|
|
363
|
-
function getInitialErrorOptions(error) {
|
|
364
|
-
const construct = ERROR_CONSTRUCTOR_STRING[getErrorConstructor(error)];
|
|
365
|
-
if (error.name !== construct) return { name: error.name };
|
|
366
|
-
if (error.constructor.name !== construct) return { name: error.constructor.name };
|
|
367
|
-
return {};
|
|
368
|
-
}
|
|
369
369
|
function getErrorOptions(error, features) {
|
|
370
|
-
|
|
371
|
-
const
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
if (name === "stack") {
|
|
376
|
-
if (features & 4) {
|
|
377
|
-
options = options || {};
|
|
378
|
-
options[name] = error[name];
|
|
379
|
-
}
|
|
380
|
-
} else {
|
|
381
|
-
options = options || {};
|
|
382
|
-
options[name] = error[name];
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
}
|
|
370
|
+
const options = Object.create(null);
|
|
371
|
+
const construct = ERROR_CONSTRUCTOR_STRING[getErrorConstructor(error)];
|
|
372
|
+
if (error.name !== construct) options.name = error.name;
|
|
373
|
+
else if (error.constructor.name !== construct) options.name = error.constructor.name;
|
|
374
|
+
for (const name of Object.getOwnPropertyNames(error)) if (name !== "name" && name !== "message" && (name !== "stack" || features & 4)) options[name] = error[name];
|
|
386
375
|
return options;
|
|
387
376
|
}
|
|
388
377
|
//#endregion
|
|
389
378
|
//#region src/core/utils/get-object-flag.ts
|
|
390
379
|
function getObjectFlag(obj) {
|
|
380
|
+
if (Object.isExtensible(obj)) return 0;
|
|
391
381
|
if (Object.isFrozen(obj)) return 3;
|
|
392
382
|
if (Object.isSealed(obj)) return 2;
|
|
393
|
-
if (Object.isExtensible(obj)) return 0;
|
|
394
383
|
return 1;
|
|
395
384
|
}
|
|
396
385
|
//#endregion
|
|
@@ -425,86 +414,265 @@ function createNumberNode(value) {
|
|
|
425
414
|
}
|
|
426
415
|
if (value !== value) return NAN_NODE;
|
|
427
416
|
if (Object.is(value, -0)) return NEG_ZERO_NODE;
|
|
428
|
-
return createSerovalNode(0, void 0, value
|
|
417
|
+
return createSerovalNode(0, void 0, value);
|
|
429
418
|
}
|
|
430
419
|
function createStringNode(value) {
|
|
431
|
-
return createSerovalNode(1, void 0, serializeString(value)
|
|
420
|
+
return createSerovalNode(1, void 0, serializeString(value));
|
|
432
421
|
}
|
|
433
422
|
function createBigIntNode(current) {
|
|
434
|
-
return createSerovalNode(3, void 0, "" + current
|
|
423
|
+
return createSerovalNode(3, void 0, "" + current);
|
|
435
424
|
}
|
|
436
425
|
function createIndexedValueNode(id) {
|
|
437
|
-
return createSerovalNode(4, id
|
|
426
|
+
return createSerovalNode(4, id);
|
|
438
427
|
}
|
|
439
428
|
function createDateNode(id, current) {
|
|
440
429
|
const timestamp = current.valueOf();
|
|
441
|
-
return createSerovalNode(5, id, timestamp
|
|
430
|
+
return createSerovalNode(5, id, timestamp === timestamp ? current.toISOString() : "");
|
|
442
431
|
}
|
|
443
432
|
function createTemporalNode(id, type, current) {
|
|
444
|
-
return createSerovalNode(36, id, current.toString(), type
|
|
433
|
+
return createSerovalNode(36, id, current.toString(), type);
|
|
445
434
|
}
|
|
446
435
|
function createRegExpNode(id, current) {
|
|
447
|
-
return createSerovalNode(6, id, void 0, serializeString(current.source), current.flags
|
|
436
|
+
return createSerovalNode(6, id, void 0, serializeString(current.source), current.flags);
|
|
448
437
|
}
|
|
449
438
|
function createWKSymbolNode(id, current) {
|
|
450
|
-
return createSerovalNode(17, id, INV_SYMBOL_REF[current]
|
|
439
|
+
return createSerovalNode(17, id, INV_SYMBOL_REF[current]);
|
|
451
440
|
}
|
|
452
|
-
function createReferenceNode(id,
|
|
453
|
-
return createSerovalNode(18, id, serializeString(
|
|
441
|
+
function createReferenceNode(id, referenceId) {
|
|
442
|
+
return createSerovalNode(18, id, serializeString(referenceId));
|
|
454
443
|
}
|
|
455
444
|
function createPluginNode(id, tag, value) {
|
|
456
|
-
return createSerovalNode(25, id, value, serializeString(tag)
|
|
445
|
+
return createSerovalNode(25, id, value, serializeString(tag));
|
|
457
446
|
}
|
|
458
447
|
function createArrayNode(id, current, parsedItems) {
|
|
459
|
-
return createSerovalNode(9, id, void 0, void 0, void 0, void 0, void 0, parsedItems, void 0, void 0, getObjectFlag(current)
|
|
448
|
+
return createSerovalNode(9, id, void 0, void 0, void 0, void 0, void 0, parsedItems, void 0, void 0, getObjectFlag(current));
|
|
460
449
|
}
|
|
461
450
|
function createBoxedNode(id, boxed) {
|
|
462
|
-
return createSerovalNode(21, id, void 0, void 0, void 0, void 0, void 0, void 0, boxed
|
|
451
|
+
return createSerovalNode(21, id, void 0, void 0, void 0, void 0, void 0, void 0, boxed);
|
|
463
452
|
}
|
|
464
453
|
const MAX_TYPED_ARRAY_LENGTH = 1e6;
|
|
465
|
-
function
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
if (current.length > MAX_TYPED_ARRAY_LENGTH) throw new SerovalUnsupportedTypeError(current);
|
|
471
|
-
return createSerovalNode(16, id, void 0, getTypedArrayName(current), void 0, void 0, void 0, void 0, buffer, current.byteOffset, void 0, current.length);
|
|
472
|
-
}
|
|
473
|
-
function createDataViewNode(id, current, buffer) {
|
|
474
|
-
if (current.byteLength > MAX_TYPED_ARRAY_LENGTH) throw new SerovalUnsupportedTypeError(current);
|
|
475
|
-
return createSerovalNode(20, id, void 0, void 0, void 0, void 0, void 0, void 0, buffer, current.byteOffset, void 0, current.byteLength);
|
|
454
|
+
function createViewNode(type, id, current, buffer) {
|
|
455
|
+
const isDataView = type === 20;
|
|
456
|
+
const size = isDataView ? current.byteLength : current.length;
|
|
457
|
+
if (size > MAX_TYPED_ARRAY_LENGTH) throw new SerovalUnsupportedTypeError(current);
|
|
458
|
+
return createSerovalNode(type, id, void 0, isDataView ? void 0 : getTypedArrayName(current), void 0, void 0, void 0, void 0, buffer, current.byteOffset, void 0, size);
|
|
476
459
|
}
|
|
477
|
-
function createErrorNode(id, current, options) {
|
|
478
|
-
return createSerovalNode(
|
|
479
|
-
}
|
|
480
|
-
function createAggregateErrorNode(id, current, options) {
|
|
481
|
-
return createSerovalNode(14, id, getErrorConstructor(current), void 0, serializeString(current.message), options, void 0, void 0, void 0, void 0, void 0, void 0);
|
|
460
|
+
function createErrorNode(type, id, current, options) {
|
|
461
|
+
return createSerovalNode(type, id, getErrorConstructor(current), void 0, serializeString(current.message), options);
|
|
482
462
|
}
|
|
483
463
|
function createSetNode(id, items) {
|
|
484
|
-
return createSerovalNode(7, id, void 0, void 0, void 0, void 0, void 0, items
|
|
485
|
-
}
|
|
486
|
-
function createIteratorFactoryInstanceNode(factory, items) {
|
|
487
|
-
return createSerovalNode(28, void 0, void 0, void 0, void 0, void 0, void 0, [factory, items], void 0, void 0, void 0, void 0);
|
|
488
|
-
}
|
|
489
|
-
function createAsyncIteratorFactoryInstanceNode(factory, items) {
|
|
490
|
-
return createSerovalNode(30, void 0, void 0, void 0, void 0, void 0, void 0, [factory, items], void 0, void 0, void 0, void 0);
|
|
491
|
-
}
|
|
492
|
-
function createStreamConstructorNode(id, factory, sequence) {
|
|
493
|
-
return createSerovalNode(31, id, void 0, void 0, void 0, void 0, void 0, sequence, factory, void 0, void 0, void 0);
|
|
464
|
+
return createSerovalNode(7, id, void 0, void 0, void 0, void 0, void 0, items);
|
|
494
465
|
}
|
|
495
|
-
function
|
|
496
|
-
return createSerovalNode(
|
|
466
|
+
function createIteratorFactoryInstanceNode(type, factory, items) {
|
|
467
|
+
return createSerovalNode(type, void 0, void 0, void 0, void 0, void 0, void 0, [factory, items]);
|
|
497
468
|
}
|
|
498
|
-
function
|
|
499
|
-
return createSerovalNode(
|
|
469
|
+
function createStreamConstructorNode(id, factory, sequence, live) {
|
|
470
|
+
return createSerovalNode(31, id, void 0, void 0, void 0, void 0, void 0, sequence, factory, void 0, void 0, live);
|
|
500
471
|
}
|
|
501
|
-
function
|
|
502
|
-
return createSerovalNode(
|
|
472
|
+
function createStreamEventNode(type, id, parsed) {
|
|
473
|
+
return createSerovalNode(type, id, void 0, void 0, void 0, void 0, void 0, void 0, parsed);
|
|
503
474
|
}
|
|
504
475
|
function createSequenceNode(id, sequence, throwAt, doneAt) {
|
|
505
476
|
return createSerovalNode(35, id, throwAt, void 0, void 0, void 0, void 0, sequence, void 0, void 0, void 0, doneAt);
|
|
506
477
|
}
|
|
507
478
|
//#endregion
|
|
479
|
+
//#region src/core/live-stream.ts
|
|
480
|
+
function isLiveStream(value) {
|
|
481
|
+
return value instanceof LiveStream;
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* A single-consumer stream for incremental serialization. Unlike
|
|
485
|
+
* `createStream`, it keeps no history: at most one event is held, and the
|
|
486
|
+
* producer operation that sent it settles only when the consumer accepts it.
|
|
487
|
+
*
|
|
488
|
+
* An internal class rather than a tagged POJO: identity is checked with
|
|
489
|
+
* `instanceof`, which untrusted input cannot forge. The class is exported
|
|
490
|
+
* because bundlers cannot drop an unexported top-level class.
|
|
491
|
+
*/
|
|
492
|
+
var LiveStream = class {
|
|
493
|
+
constructor(options) {
|
|
494
|
+
this.consumed = false;
|
|
495
|
+
this.closed = false;
|
|
496
|
+
this.cancelled = false;
|
|
497
|
+
this.options = options;
|
|
498
|
+
}
|
|
499
|
+
deliver(reader, record) {
|
|
500
|
+
record.delivered = true;
|
|
501
|
+
reader.resolve({
|
|
502
|
+
event: record.event,
|
|
503
|
+
accept: () => {
|
|
504
|
+
if (this.pending === record && record.delivered) {
|
|
505
|
+
const terminal = record.event.type !== "next";
|
|
506
|
+
record.event = void 0;
|
|
507
|
+
this.pending = void 0;
|
|
508
|
+
const resolve = record.resolve;
|
|
509
|
+
record.resolve = void 0;
|
|
510
|
+
record.reject = void 0;
|
|
511
|
+
if (terminal) {
|
|
512
|
+
this.closed = true;
|
|
513
|
+
this.options = void 0;
|
|
514
|
+
const waiter = this.waiting;
|
|
515
|
+
this.waiting = void 0;
|
|
516
|
+
waiter?.reject(new SerovalLiveStreamError("closed"));
|
|
517
|
+
}
|
|
518
|
+
resolve?.();
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
/** @internal */
|
|
524
|
+
push(event) {
|
|
525
|
+
if (this.cancelled) return Promise.reject(this.cancelReason);
|
|
526
|
+
if (this.closed) return Promise.reject(new SerovalLiveStreamError("closed"));
|
|
527
|
+
if (this.pending) return Promise.reject(new SerovalLiveStreamError("pending"));
|
|
528
|
+
return new Promise((resolve, reject) => {
|
|
529
|
+
const record = {
|
|
530
|
+
event,
|
|
531
|
+
delivered: false,
|
|
532
|
+
resolve,
|
|
533
|
+
reject
|
|
534
|
+
};
|
|
535
|
+
this.pending = record;
|
|
536
|
+
if (this.waiting) {
|
|
537
|
+
const waiter = this.waiting;
|
|
538
|
+
this.waiting = void 0;
|
|
539
|
+
this.deliver(waiter, record);
|
|
540
|
+
}
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
cancel(reason) {
|
|
544
|
+
if (this.cancelled || this.closed) return;
|
|
545
|
+
this.cancelled = true;
|
|
546
|
+
this.cancelReason = reason;
|
|
547
|
+
const record = this.pending;
|
|
548
|
+
const waiter = this.waiting;
|
|
549
|
+
this.pending = void 0;
|
|
550
|
+
this.waiting = void 0;
|
|
551
|
+
const callbackOwner = this.options;
|
|
552
|
+
this.options = void 0;
|
|
553
|
+
if (record) {
|
|
554
|
+
record.event = void 0;
|
|
555
|
+
const reject = record.reject;
|
|
556
|
+
record.resolve = void 0;
|
|
557
|
+
record.reject = void 0;
|
|
558
|
+
reject?.(reason);
|
|
559
|
+
}
|
|
560
|
+
if (waiter) waiter.reject(reason);
|
|
561
|
+
callbackOwner?.onCancel?.(reason);
|
|
562
|
+
}
|
|
563
|
+
read() {
|
|
564
|
+
if (this.cancelled) return Promise.reject(this.cancelReason);
|
|
565
|
+
if (this.closed) return Promise.reject(new SerovalLiveStreamError("closed"));
|
|
566
|
+
if (this.waiting) return Promise.reject(new SerovalLiveStreamError("reading"));
|
|
567
|
+
return new Promise((resolve, reject) => {
|
|
568
|
+
const next = {
|
|
569
|
+
resolve,
|
|
570
|
+
reject
|
|
571
|
+
};
|
|
572
|
+
if (this.pending && !this.pending.delivered) this.deliver(next, this.pending);
|
|
573
|
+
else this.waiting = next;
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
consume() {
|
|
577
|
+
if (this.consumed) throw new SerovalLiveStreamError("consumed");
|
|
578
|
+
this.consumed = true;
|
|
579
|
+
return {
|
|
580
|
+
read: () => this.read(),
|
|
581
|
+
cancel: (reason) => this.cancel(reason)
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* Consumes the stream through a replay-style listener, accepting each
|
|
586
|
+
* event as soon as it has been delivered. Use `consume` or `pump` when
|
|
587
|
+
* acceptance must wait for processing.
|
|
588
|
+
*/
|
|
589
|
+
on(listener) {
|
|
590
|
+
const wrap = (key) => (value, accept) => {
|
|
591
|
+
listener[key](value);
|
|
592
|
+
accept();
|
|
593
|
+
};
|
|
594
|
+
return this.pump({
|
|
595
|
+
next: wrap("next"),
|
|
596
|
+
throw: wrap("throw"),
|
|
597
|
+
return: wrap("return")
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* Consumes the stream into a sink that controls acceptance. Returns the
|
|
602
|
+
* cancel function.
|
|
603
|
+
* @internal
|
|
604
|
+
*/
|
|
605
|
+
pump(sink) {
|
|
606
|
+
const consumer = this.consume();
|
|
607
|
+
let current = sink;
|
|
608
|
+
function next() {
|
|
609
|
+
consumer.read().then((delivery) => {
|
|
610
|
+
const target = current;
|
|
611
|
+
if (!target) return;
|
|
612
|
+
const event = delivery.event;
|
|
613
|
+
let failure;
|
|
614
|
+
let failed = false;
|
|
615
|
+
try {
|
|
616
|
+
failure = target[event.type](event.type === "throw" ? event.error : event.value, delivery.accept);
|
|
617
|
+
} catch (error) {
|
|
618
|
+
failed = true;
|
|
619
|
+
failure = error;
|
|
620
|
+
}
|
|
621
|
+
if (failed || failure !== void 0) {
|
|
622
|
+
current = void 0;
|
|
623
|
+
try {
|
|
624
|
+
consumer.cancel(failure);
|
|
625
|
+
} finally {
|
|
626
|
+
target.done?.();
|
|
627
|
+
}
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
if (event.type === "next") {
|
|
631
|
+
next();
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
634
|
+
current = void 0;
|
|
635
|
+
target.done?.();
|
|
636
|
+
}, (reason) => {
|
|
637
|
+
const target = current;
|
|
638
|
+
current = void 0;
|
|
639
|
+
target?.error?.(reason);
|
|
640
|
+
});
|
|
641
|
+
}
|
|
642
|
+
next();
|
|
643
|
+
return consumer.cancel;
|
|
644
|
+
}
|
|
645
|
+
};
|
|
646
|
+
/**
|
|
647
|
+
* Creates a live stream and the producer that writes to it.
|
|
648
|
+
*/
|
|
649
|
+
function createLiveStream(options) {
|
|
650
|
+
const stream = new LiveStream(options);
|
|
651
|
+
return {
|
|
652
|
+
stream,
|
|
653
|
+
producer: {
|
|
654
|
+
write(value) {
|
|
655
|
+
return stream.push({
|
|
656
|
+
type: "next",
|
|
657
|
+
value
|
|
658
|
+
});
|
|
659
|
+
},
|
|
660
|
+
close(value) {
|
|
661
|
+
return stream.push({
|
|
662
|
+
type: "return",
|
|
663
|
+
value
|
|
664
|
+
});
|
|
665
|
+
},
|
|
666
|
+
fail(error) {
|
|
667
|
+
return stream.push({
|
|
668
|
+
type: "throw",
|
|
669
|
+
error
|
|
670
|
+
});
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
//#endregion
|
|
508
676
|
//#region src/core/opaque-reference.ts
|
|
509
677
|
/**
|
|
510
678
|
* An opaque reference allows hiding values from the serializer.
|
|
@@ -542,7 +710,7 @@ const PROMISE_FAILURE = (resolver, data) => {
|
|
|
542
710
|
const SERIALIZED_PROMISE_CONSTRUCTOR = /* @__PURE__ */ PROMISE_CONSTRUCTOR.toString();
|
|
543
711
|
const SERIALIZED_PROMISE_SUCCESS = /* @__PURE__ */ PROMISE_SUCCESS.toString();
|
|
544
712
|
const SERIALIZED_PROMISE_FAILURE = /* @__PURE__ */ PROMISE_FAILURE.toString();
|
|
545
|
-
const STREAM_CONSTRUCTOR = () => {
|
|
713
|
+
const STREAM_CONSTRUCTOR = (live) => {
|
|
546
714
|
const buffer = [];
|
|
547
715
|
const listeners = [];
|
|
548
716
|
let alive = true;
|
|
@@ -550,6 +718,7 @@ const STREAM_CONSTRUCTOR = () => {
|
|
|
550
718
|
let count = 0;
|
|
551
719
|
const internal = {
|
|
552
720
|
flush(value, mode, x) {
|
|
721
|
+
live > 1 || buffer.push(value);
|
|
553
722
|
for (x = 0; x < count; x++) {
|
|
554
723
|
const listener = listeners[x];
|
|
555
724
|
if (listener) listener[mode](value);
|
|
@@ -563,6 +732,7 @@ const STREAM_CONSTRUCTOR = () => {
|
|
|
563
732
|
}
|
|
564
733
|
},
|
|
565
734
|
on(listener, temp = 0) {
|
|
735
|
+
if (live > 1) throw new Error("Stream consumed");
|
|
566
736
|
let subscribed = alive;
|
|
567
737
|
if (alive) {
|
|
568
738
|
for (temp = 0; temp < count; temp++) if (!listeners[temp]) break;
|
|
@@ -570,6 +740,10 @@ const STREAM_CONSTRUCTOR = () => {
|
|
|
570
740
|
listeners[temp] = listener;
|
|
571
741
|
}
|
|
572
742
|
internal.up(listener);
|
|
743
|
+
if (live) {
|
|
744
|
+
live = 2;
|
|
745
|
+
buffer.length = 0;
|
|
746
|
+
}
|
|
573
747
|
return () => {
|
|
574
748
|
if (alive && subscribed) {
|
|
575
749
|
subscribed = false;
|
|
@@ -586,14 +760,10 @@ const STREAM_CONSTRUCTOR = () => {
|
|
|
586
760
|
return internal.on(listener);
|
|
587
761
|
},
|
|
588
762
|
next(value) {
|
|
589
|
-
if (alive)
|
|
590
|
-
buffer.push(value);
|
|
591
|
-
internal.flush(value, "next");
|
|
592
|
-
}
|
|
763
|
+
if (alive) internal.flush(value, "next");
|
|
593
764
|
},
|
|
594
765
|
throw(value) {
|
|
595
766
|
if (alive) {
|
|
596
|
-
buffer.push(value);
|
|
597
767
|
internal.flush(value, "throw");
|
|
598
768
|
alive = false;
|
|
599
769
|
success = false;
|
|
@@ -602,7 +772,6 @@ const STREAM_CONSTRUCTOR = () => {
|
|
|
602
772
|
},
|
|
603
773
|
return(value) {
|
|
604
774
|
if (alive) {
|
|
605
|
-
buffer.push(value);
|
|
606
775
|
internal.flush(value, "return");
|
|
607
776
|
alive = false;
|
|
608
777
|
success = true;
|
|
@@ -724,7 +893,8 @@ const SERIALIZED_ARRAY_BUFFER_CONSTRUCTOR = /* @__PURE__ */ ARRAY_BUFFER_CONSTRU
|
|
|
724
893
|
//#region src/core/sequence.ts
|
|
725
894
|
/**
|
|
726
895
|
* An internal class rather than a tagged POJO: identity is checked with
|
|
727
|
-
* `instanceof`, which untrusted input cannot forge
|
|
896
|
+
* `instanceof`, which untrusted input cannot forge. The class is exported
|
|
897
|
+
* because bundlers cannot drop an unexported top-level class.
|
|
728
898
|
* The eval-based `deserialize` path still rebuilds a `{__SEROVAL_SEQUENCE__…}`
|
|
729
899
|
* POJO from embedded source - it has no access to this class - so a value read
|
|
730
900
|
* back through `deserialize` is not an instance and, by design, is not treated
|
|
@@ -748,7 +918,7 @@ function createSequenceFromIterable(source) {
|
|
|
748
918
|
let throwsAt = -1;
|
|
749
919
|
let doneAt = -1;
|
|
750
920
|
const iterator = source[SYM_ITERATOR]();
|
|
751
|
-
|
|
921
|
+
for (;;) try {
|
|
752
922
|
const value = iterator.next();
|
|
753
923
|
values.push(value.value);
|
|
754
924
|
if (value.done) {
|
|
@@ -763,7 +933,7 @@ function createSequenceFromIterable(source) {
|
|
|
763
933
|
}
|
|
764
934
|
return createSequence(values, throwsAt, doneAt);
|
|
765
935
|
}
|
|
766
|
-
const createIterator = ITERATOR_CONSTRUCTOR(SYM_ITERATOR);
|
|
936
|
+
const createIterator = /* @__PURE__ */ ITERATOR_CONSTRUCTOR(SYM_ITERATOR);
|
|
767
937
|
function sequenceToIterator(sequence) {
|
|
768
938
|
return createIterator(sequence);
|
|
769
939
|
}
|
|
@@ -794,7 +964,8 @@ const SPECIAL_REF_STRING = {
|
|
|
794
964
|
//#region src/core/stream.ts
|
|
795
965
|
/**
|
|
796
966
|
* An internal class rather than a tagged POJO: identity is checked with
|
|
797
|
-
* `instanceof`, which untrusted input cannot forge
|
|
967
|
+
* `instanceof`, which untrusted input cannot forge. The class is exported
|
|
968
|
+
* because bundlers cannot drop an unexported top-level class.
|
|
798
969
|
*
|
|
799
970
|
* The behavior is intentionally duplicated from `STREAM_CONSTRUCTOR`. That
|
|
800
971
|
* constructor's source is embedded verbatim into the eval-based `deserialize`
|
|
@@ -804,18 +975,17 @@ const SPECIAL_REF_STRING = {
|
|
|
804
975
|
* implementations in sync.
|
|
805
976
|
*/
|
|
806
977
|
var Stream = class {
|
|
807
|
-
constructor() {
|
|
978
|
+
constructor(live) {
|
|
808
979
|
this.buffer = [];
|
|
809
980
|
this.listeners = [];
|
|
810
981
|
this.alive = true;
|
|
811
982
|
this.success = false;
|
|
812
983
|
this.count = 0;
|
|
984
|
+
this.live = live;
|
|
813
985
|
}
|
|
814
986
|
flush(value, mode) {
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
(_this$listeners$x = this.listeners[x]) === null || _this$listeners$x === void 0 || _this$listeners$x[mode](value);
|
|
818
|
-
}
|
|
987
|
+
this.live > 1 || this.buffer.push(value);
|
|
988
|
+
for (let x = 0; x < this.count; x++) this.listeners[x]?.[mode](value);
|
|
819
989
|
}
|
|
820
990
|
replay(listener) {
|
|
821
991
|
for (let x = 0, z = this.buffer.length; x < z; x++) {
|
|
@@ -825,6 +995,7 @@ var Stream = class {
|
|
|
825
995
|
}
|
|
826
996
|
}
|
|
827
997
|
on(listener) {
|
|
998
|
+
if (this.live > 1) throw new Error("Stream consumed");
|
|
828
999
|
let subscribed = this.alive;
|
|
829
1000
|
let temp = 0;
|
|
830
1001
|
if (subscribed) {
|
|
@@ -833,6 +1004,10 @@ var Stream = class {
|
|
|
833
1004
|
this.listeners[temp] = listener;
|
|
834
1005
|
}
|
|
835
1006
|
this.replay(listener);
|
|
1007
|
+
if (this.live) {
|
|
1008
|
+
this.live = 2;
|
|
1009
|
+
this.buffer.length = 0;
|
|
1010
|
+
}
|
|
836
1011
|
return () => {
|
|
837
1012
|
if (this.alive && subscribed) {
|
|
838
1013
|
subscribed = false;
|
|
@@ -843,14 +1018,10 @@ var Stream = class {
|
|
|
843
1018
|
};
|
|
844
1019
|
}
|
|
845
1020
|
next(value) {
|
|
846
|
-
if (this.alive)
|
|
847
|
-
this.buffer.push(value);
|
|
848
|
-
this.flush(value, "next");
|
|
849
|
-
}
|
|
1021
|
+
if (this.alive) this.flush(value, "next");
|
|
850
1022
|
}
|
|
851
1023
|
throw(value) {
|
|
852
1024
|
if (this.alive) {
|
|
853
|
-
this.buffer.push(value);
|
|
854
1025
|
this.flush(value, "throw");
|
|
855
1026
|
this.alive = false;
|
|
856
1027
|
this.success = false;
|
|
@@ -859,7 +1030,6 @@ var Stream = class {
|
|
|
859
1030
|
}
|
|
860
1031
|
return(value) {
|
|
861
1032
|
if (this.alive) {
|
|
862
|
-
this.buffer.push(value);
|
|
863
1033
|
this.flush(value, "return");
|
|
864
1034
|
this.alive = false;
|
|
865
1035
|
this.success = true;
|
|
@@ -868,46 +1038,12 @@ var Stream = class {
|
|
|
868
1038
|
}
|
|
869
1039
|
};
|
|
870
1040
|
function isStream(value) {
|
|
871
|
-
return value instanceof Stream;
|
|
1041
|
+
return value instanceof Stream || isLiveStream(value);
|
|
872
1042
|
}
|
|
873
1043
|
function createStream() {
|
|
874
1044
|
return new Stream();
|
|
875
1045
|
}
|
|
876
|
-
|
|
877
|
-
const stream = createStream();
|
|
878
|
-
const iterator = iterable[SYM_ASYNC_ITERATOR]();
|
|
879
|
-
let cancelled = false;
|
|
880
|
-
let done = false;
|
|
881
|
-
cleanups === null || cleanups === void 0 || cleanups.push(() => {
|
|
882
|
-
if (!(done || cancelled)) {
|
|
883
|
-
cancelled = true;
|
|
884
|
-
Promise.resolve().then(() => {
|
|
885
|
-
var _iterator$return;
|
|
886
|
-
return (_iterator$return = iterator.return) === null || _iterator$return === void 0 ? void 0 : _iterator$return.call(iterator);
|
|
887
|
-
}).catch(() => {});
|
|
888
|
-
}
|
|
889
|
-
});
|
|
890
|
-
async function push() {
|
|
891
|
-
try {
|
|
892
|
-
while (!cancelled) {
|
|
893
|
-
const value = await iterator.next();
|
|
894
|
-
if (cancelled) return;
|
|
895
|
-
if (value.done) {
|
|
896
|
-
done = true;
|
|
897
|
-
stream.return(value.value);
|
|
898
|
-
break;
|
|
899
|
-
}
|
|
900
|
-
stream.next(value.value);
|
|
901
|
-
}
|
|
902
|
-
} catch (error) {
|
|
903
|
-
done = true;
|
|
904
|
-
if (!cancelled) stream.throw(error);
|
|
905
|
-
}
|
|
906
|
-
}
|
|
907
|
-
push().catch(() => {});
|
|
908
|
-
return stream;
|
|
909
|
-
}
|
|
910
|
-
const createAsyncIterable = ASYNC_ITERATOR_CONSTRUCTOR(SYM_ASYNC_ITERATOR, PROMISE_CONSTRUCTOR);
|
|
1046
|
+
const createAsyncIterable = /* @__PURE__ */ ASYNC_ITERATOR_CONSTRUCTOR(SYM_ASYNC_ITERATOR, PROMISE_CONSTRUCTOR);
|
|
911
1047
|
function streamToAsyncIterable(stream) {
|
|
912
1048
|
return createAsyncIterable(stream);
|
|
913
1049
|
}
|
|
@@ -921,20 +1057,158 @@ async function promiseToResult(current) {
|
|
|
921
1057
|
}
|
|
922
1058
|
}
|
|
923
1059
|
//#endregion
|
|
1060
|
+
//#region src/core/binary-browser.ts
|
|
1061
|
+
function encodeArrayBuffer$1(current) {
|
|
1062
|
+
const bytes = new Uint8Array(current);
|
|
1063
|
+
if (typeof bytes.toBase64 === "function") return bytes.toBase64();
|
|
1064
|
+
let result = "";
|
|
1065
|
+
for (let i = 0, len = bytes.length; i < len; i++) result += String.fromCharCode(bytes[i]);
|
|
1066
|
+
return btoa(result);
|
|
1067
|
+
}
|
|
1068
|
+
//#endregion
|
|
1069
|
+
//#region src/core/binary-neutral.ts
|
|
1070
|
+
const MIN_NATIVE_BASE64_LENGTH = 512;
|
|
1071
|
+
function encodeArrayBuffer(current) {
|
|
1072
|
+
if (typeof Buffer !== "undefined") return Buffer.from(current).toString("base64");
|
|
1073
|
+
return encodeArrayBuffer$1(current);
|
|
1074
|
+
}
|
|
1075
|
+
function decodeArrayBuffer(source) {
|
|
1076
|
+
if (source.length < MIN_NATIVE_BASE64_LENGTH || typeof Buffer === "undefined") return ARRAY_BUFFER_CONSTRUCTOR(source);
|
|
1077
|
+
const decoded = atob(source);
|
|
1078
|
+
const buffer = new ArrayBuffer(decoded.length);
|
|
1079
|
+
Buffer.from(buffer).write(decoded, "latin1");
|
|
1080
|
+
return buffer;
|
|
1081
|
+
}
|
|
1082
|
+
//#endregion
|
|
1083
|
+
//#region src/core/plugin.ts
|
|
1084
|
+
let SerovalMode = /* @__PURE__ */ function(SerovalMode) {
|
|
1085
|
+
SerovalMode[SerovalMode["Vanilla"] = 1] = "Vanilla";
|
|
1086
|
+
SerovalMode[SerovalMode["Cross"] = 2] = "Cross";
|
|
1087
|
+
return SerovalMode;
|
|
1088
|
+
}({});
|
|
1089
|
+
function createPlugin(plugin) {
|
|
1090
|
+
return plugin;
|
|
1091
|
+
}
|
|
1092
|
+
function dedupePlugins(deduped, plugins) {
|
|
1093
|
+
for (let i = 0, len = plugins.length; i < len; i++) {
|
|
1094
|
+
const current = plugins[i];
|
|
1095
|
+
if (!deduped.has(current)) {
|
|
1096
|
+
deduped.add(current);
|
|
1097
|
+
if (current.extends) dedupePlugins(deduped, current.extends);
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
const RESOLVED_PLUGINS = /* @__PURE__ */ new WeakMap();
|
|
1102
|
+
function matchResolved(resolved, plugins, added) {
|
|
1103
|
+
for (let i = 0, len = plugins.length; i < len; i++) {
|
|
1104
|
+
const current = plugins[i];
|
|
1105
|
+
if (current === resolved[added]) {
|
|
1106
|
+
added++;
|
|
1107
|
+
if (current.extends) {
|
|
1108
|
+
added = matchResolved(resolved, current.extends, added);
|
|
1109
|
+
if (added === -1) return -1;
|
|
1110
|
+
}
|
|
1111
|
+
} else {
|
|
1112
|
+
const index = resolved.indexOf(current);
|
|
1113
|
+
if (index === -1 || index >= added) return -1;
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
return added;
|
|
1117
|
+
}
|
|
1118
|
+
function resolvePlugins(plugins) {
|
|
1119
|
+
if (plugins) {
|
|
1120
|
+
const cached = RESOLVED_PLUGINS.get(plugins);
|
|
1121
|
+
if (cached && matchResolved(cached, plugins, 0) === cached.length) return cached;
|
|
1122
|
+
const deduped = /* @__PURE__ */ new Set();
|
|
1123
|
+
dedupePlugins(deduped, plugins);
|
|
1124
|
+
const resolved = [...deduped];
|
|
1125
|
+
RESOLVED_PLUGINS.set(plugins, resolved);
|
|
1126
|
+
return resolved;
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
/**
|
|
1130
|
+
* Returns the plugins that are tested for plain objects. It is the same array
|
|
1131
|
+
* when no plugin sets `skipPlainObjects`.
|
|
1132
|
+
*/
|
|
1133
|
+
function getPlainObjectPlugins(plugins) {
|
|
1134
|
+
if (plugins) {
|
|
1135
|
+
for (let i = 0, len = plugins.length; i < len; i++) if (plugins[i].skipPlainObjects) {
|
|
1136
|
+
const result = plugins.filter((plugin) => !plugin.skipPlainObjects);
|
|
1137
|
+
return result.length ? result : void 0;
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
return plugins;
|
|
1141
|
+
}
|
|
1142
|
+
//#endregion
|
|
1143
|
+
//#region src/core/keys.ts
|
|
1144
|
+
const REFERENCES_KEY = "__SEROVAL_REFS__";
|
|
1145
|
+
const GLOBAL_CONTEXT_R = `self.\$R`;
|
|
1146
|
+
function getCrossReferenceHeader(id) {
|
|
1147
|
+
if (id == null) return `${GLOBAL_CONTEXT_R}=${GLOBAL_CONTEXT_R}||[]`;
|
|
1148
|
+
return `(${GLOBAL_CONTEXT_R}=${GLOBAL_CONTEXT_R}||{})["${serializeString(id)}"]=[]`;
|
|
1149
|
+
}
|
|
1150
|
+
//#endregion
|
|
1151
|
+
//#region src/core/reference.ts
|
|
1152
|
+
const REFERENCE = /* @__PURE__ */ new Map();
|
|
1153
|
+
const INV_REFERENCE = /* @__PURE__ */ new Map();
|
|
1154
|
+
let installed = false;
|
|
1155
|
+
function getGlobalObject() {
|
|
1156
|
+
if (typeof globalThis !== "undefined") return globalThis;
|
|
1157
|
+
if (typeof window !== "undefined") return window;
|
|
1158
|
+
if (typeof self !== "undefined") return self;
|
|
1159
|
+
if (typeof global !== "undefined") return global;
|
|
1160
|
+
}
|
|
1161
|
+
function installReferenceStore() {
|
|
1162
|
+
if (!installed) {
|
|
1163
|
+
installed = true;
|
|
1164
|
+
const globalObject = getGlobalObject();
|
|
1165
|
+
if (globalObject) Object.defineProperty(globalObject, REFERENCES_KEY, {
|
|
1166
|
+
value: INV_REFERENCE,
|
|
1167
|
+
configurable: true,
|
|
1168
|
+
writable: false,
|
|
1169
|
+
enumerable: false
|
|
1170
|
+
});
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
function createReference(id, value) {
|
|
1174
|
+
installReferenceStore();
|
|
1175
|
+
REFERENCE.set(value, id);
|
|
1176
|
+
INV_REFERENCE.set(id, value);
|
|
1177
|
+
return value;
|
|
1178
|
+
}
|
|
1179
|
+
function hasReference(id) {
|
|
1180
|
+
return INV_REFERENCE.has(id);
|
|
1181
|
+
}
|
|
1182
|
+
function getReferenceID(value) {
|
|
1183
|
+
return REFERENCE.get(value);
|
|
1184
|
+
}
|
|
1185
|
+
function getReference(id) {
|
|
1186
|
+
if (hasReference(id)) return INV_REFERENCE.get(id);
|
|
1187
|
+
throw new SerovalMissingReferenceForIdError(id);
|
|
1188
|
+
}
|
|
1189
|
+
//#endregion
|
|
924
1190
|
//#region src/core/context/parser.ts
|
|
925
|
-
function createBaseParserContext(
|
|
926
|
-
var _options$compactArray;
|
|
1191
|
+
function createBaseParserContext(options) {
|
|
927
1192
|
return {
|
|
928
1193
|
plugins: options.plugins,
|
|
929
|
-
|
|
1194
|
+
plainObjectPlugins: getPlainObjectPlugins(options.plugins),
|
|
930
1195
|
marked: /* @__PURE__ */ new Set(),
|
|
931
|
-
features: 127 ^ (options.disabledFeatures
|
|
932
|
-
refs: options.refs
|
|
1196
|
+
features: 127 ^ (options.disabledFeatures ?? 0),
|
|
1197
|
+
refs: options.refs ?? /* @__PURE__ */ new Map(),
|
|
933
1198
|
depthLimit: options.depthLimit || 1e3,
|
|
934
|
-
compactArrayBufferViews:
|
|
1199
|
+
compactArrayBufferViews: options.compactArrayBufferViews ?? false
|
|
935
1200
|
};
|
|
936
1201
|
}
|
|
937
1202
|
/**
|
|
1203
|
+
* Returns the plugins to test for an object. Plain objects, whose prototype is
|
|
1204
|
+
* `Object.prototype`, skip the plugins that set `skipPlainObjects`. Checking
|
|
1205
|
+
* the prototype as well as `constructor` keeps instances whose prototype has
|
|
1206
|
+
* no own `constructor` property from skipping those plugins.
|
|
1207
|
+
*/
|
|
1208
|
+
function getObjectPlugins(ctx, current, currentClass) {
|
|
1209
|
+
return currentClass === Object && Object.getPrototypeOf(current) === Object.prototype ? ctx.plainObjectPlugins : ctx.plugins;
|
|
1210
|
+
}
|
|
1211
|
+
/**
|
|
938
1212
|
* Ensures that the value (based on an identifier) has been visited by the parser.
|
|
939
1213
|
* @param ctx
|
|
940
1214
|
* @param id
|
|
@@ -956,125 +1230,166 @@ function getNodeForIndexedValue(ctx, current) {
|
|
|
956
1230
|
const registeredId = ctx.refs.get(current);
|
|
957
1231
|
if (registeredId != null) {
|
|
958
1232
|
markParserRef(ctx, registeredId);
|
|
959
|
-
return
|
|
960
|
-
type: 1,
|
|
961
|
-
value: createIndexedValueNode(registeredId)
|
|
962
|
-
};
|
|
1233
|
+
return createIndexedValueNode(registeredId);
|
|
963
1234
|
}
|
|
964
|
-
return
|
|
965
|
-
type: 0,
|
|
966
|
-
value: createIndexForValue(ctx, current)
|
|
967
|
-
};
|
|
1235
|
+
return createIndexForValue(ctx, current);
|
|
968
1236
|
}
|
|
969
1237
|
function getReferenceNode(ctx, current) {
|
|
970
1238
|
const indexed = getNodeForIndexedValue(ctx, current);
|
|
971
|
-
if (indexed
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
value: createReferenceNode(indexed.value, current)
|
|
975
|
-
};
|
|
976
|
-
return indexed;
|
|
1239
|
+
if (typeof indexed !== "number") return indexed;
|
|
1240
|
+
const referenceId = getReferenceID(current);
|
|
1241
|
+
return referenceId === void 0 ? indexed : createReferenceNode(indexed, referenceId);
|
|
977
1242
|
}
|
|
978
1243
|
/**
|
|
979
1244
|
* Parsing methods
|
|
980
1245
|
*/
|
|
981
1246
|
function parseWellKnownSymbol(ctx, current) {
|
|
982
1247
|
const ref = getReferenceNode(ctx, current);
|
|
983
|
-
if (ref
|
|
984
|
-
if (current in INV_SYMBOL_REF) return createWKSymbolNode(ref
|
|
1248
|
+
if (typeof ref !== "number") return ref;
|
|
1249
|
+
if (current in INV_SYMBOL_REF) return createWKSymbolNode(ref, current);
|
|
985
1250
|
throw new SerovalUnsupportedTypeError(current);
|
|
986
1251
|
}
|
|
987
1252
|
function parseSpecialReference(ctx, ref) {
|
|
988
1253
|
const result = getNodeForIndexedValue(ctx, SPECIAL_REFS[ref]);
|
|
989
|
-
if (result
|
|
990
|
-
return createSerovalNode(26, result
|
|
1254
|
+
if (typeof result !== "number") return result;
|
|
1255
|
+
return createSerovalNode(26, result, ref);
|
|
991
1256
|
}
|
|
992
1257
|
function parseIteratorFactory(ctx) {
|
|
993
1258
|
const result = getNodeForIndexedValue(ctx, ITERATOR);
|
|
994
|
-
if (result
|
|
995
|
-
return createSerovalNode(27, result
|
|
1259
|
+
if (typeof result !== "number") return result;
|
|
1260
|
+
return createSerovalNode(27, result, void 0, void 0, void 0, void 0, void 0, void 0, parseWellKnownSymbol(ctx, SYM_ITERATOR));
|
|
996
1261
|
}
|
|
997
1262
|
function parseAsyncIteratorFactory(ctx) {
|
|
998
1263
|
const result = getNodeForIndexedValue(ctx, ASYNC_ITERATOR);
|
|
999
|
-
if (result
|
|
1000
|
-
return createSerovalNode(29, result
|
|
1264
|
+
if (typeof result !== "number") return result;
|
|
1265
|
+
return createSerovalNode(29, result, void 0, void 0, void 0, void 0, void 0, [parseSpecialReference(ctx, 1), parseWellKnownSymbol(ctx, SYM_ASYNC_ITERATOR)]);
|
|
1001
1266
|
}
|
|
1002
|
-
function
|
|
1003
|
-
|
|
1267
|
+
function getTemporalType(currentClass) {
|
|
1268
|
+
switch (currentClass) {
|
|
1269
|
+
case Temporal.Instant: return 0;
|
|
1270
|
+
case Temporal.Duration: return 1;
|
|
1271
|
+
case Temporal.PlainDate: return 2;
|
|
1272
|
+
case Temporal.PlainDateTime: return 3;
|
|
1273
|
+
case Temporal.PlainMonthDay: return 4;
|
|
1274
|
+
case Temporal.PlainTime: return 5;
|
|
1275
|
+
case Temporal.PlainYearMonth: return 6;
|
|
1276
|
+
case Temporal.ZonedDateTime: return 7;
|
|
1277
|
+
default: return;
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
function getObjectClass(current) {
|
|
1281
|
+
const currentClass = current.constructor;
|
|
1282
|
+
if (currentClass !== void 0 && typeof currentClass !== "function") {
|
|
1283
|
+
const proto = Object.getPrototypeOf(current);
|
|
1284
|
+
return proto === null ? void 0 : proto.constructor;
|
|
1285
|
+
}
|
|
1286
|
+
return currentClass;
|
|
1004
1287
|
}
|
|
1005
1288
|
/**
|
|
1006
|
-
*
|
|
1007
|
-
*
|
|
1289
|
+
* Decides how an object is parsed. Shared by the sync, stream and async
|
|
1290
|
+
* parsers so the class checks and feature gates live in one place.
|
|
1008
1291
|
*/
|
|
1009
|
-
function
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1292
|
+
function getObjectKind(current, currentClass, features) {
|
|
1293
|
+
switch (currentClass) {
|
|
1294
|
+
case Object: return 1;
|
|
1295
|
+
case void 0: return 2;
|
|
1296
|
+
case Date: return 3;
|
|
1297
|
+
case Error:
|
|
1298
|
+
case EvalError:
|
|
1299
|
+
case RangeError:
|
|
1300
|
+
case ReferenceError:
|
|
1301
|
+
case SyntaxError:
|
|
1302
|
+
case TypeError:
|
|
1303
|
+
case URIError: return 4;
|
|
1304
|
+
case Number:
|
|
1305
|
+
case Boolean:
|
|
1306
|
+
case String:
|
|
1307
|
+
case BigInt: return 6;
|
|
1308
|
+
case ArrayBuffer: return 7;
|
|
1309
|
+
case Int8Array:
|
|
1310
|
+
case Int16Array:
|
|
1311
|
+
case Int32Array:
|
|
1312
|
+
case Uint8Array:
|
|
1313
|
+
case Uint16Array:
|
|
1314
|
+
case Uint32Array:
|
|
1315
|
+
case Uint8ClampedArray:
|
|
1316
|
+
case Float32Array:
|
|
1317
|
+
case Float64Array: return 8;
|
|
1318
|
+
case DataView: return 10;
|
|
1319
|
+
case Map: return 11;
|
|
1320
|
+
case Set: return 12;
|
|
1321
|
+
}
|
|
1322
|
+
if (currentClass === Promise || current instanceof Promise) return 13;
|
|
1323
|
+
if (features & 32 && currentClass === RegExp) return 14;
|
|
1324
|
+
if (features & 16 && (currentClass === BigInt64Array || currentClass === BigUint64Array)) return 9;
|
|
1325
|
+
if (features & 1 && typeof AggregateError !== "undefined" && (currentClass === AggregateError || current instanceof AggregateError)) return 5;
|
|
1326
|
+
if (features & 64 && typeof Temporal !== "undefined" && getTemporalType(currentClass) != null) return 15;
|
|
1327
|
+
if (current instanceof Error) return 4;
|
|
1328
|
+
if (SYM_ITERATOR in current || SYM_ASYNC_ITERATOR in current) return 16;
|
|
1329
|
+
return 0;
|
|
1330
|
+
}
|
|
1331
|
+
function createObjectNode(id, current, empty, record) {
|
|
1332
|
+
return createSerovalNode(empty ? 11 : 10, id, void 0, void 0, void 0, record, void 0, void 0, void 0, void 0, getObjectFlag(current));
|
|
1333
|
+
}
|
|
1334
|
+
/**
|
|
1335
|
+
* Gets the sentinel node for a Map. Call it before parsing the entries, so
|
|
1336
|
+
* that an outer Map declares the sentinel before any Map inside it uses it.
|
|
1337
|
+
*/
|
|
1338
|
+
function parseMapSentinel(ctx) {
|
|
1339
|
+
return parseSpecialReference(ctx, 0);
|
|
1340
|
+
}
|
|
1341
|
+
function createMapNode(id, sentinel, k, v) {
|
|
1342
|
+
return createSerovalNode(8, id, void 0, void 0, void 0, void 0, {
|
|
1343
|
+
k,
|
|
1344
|
+
v
|
|
1345
|
+
}, void 0, sentinel);
|
|
1346
|
+
}
|
|
1018
1347
|
function createPromiseConstructorNode(ctx, id, resolver) {
|
|
1019
|
-
return createSerovalNode(22, id, resolver, void 0, void 0, void 0, void 0, void 0, parseSpecialReference(ctx, 1)
|
|
1348
|
+
return createSerovalNode(22, id, resolver, void 0, void 0, void 0, void 0, void 0, parseSpecialReference(ctx, 1));
|
|
1020
1349
|
}
|
|
1021
1350
|
function getArrayBufferView(ctx, current) {
|
|
1022
1351
|
if (!ctx.compactArrayBufferViews) return current;
|
|
1023
1352
|
const buffer = new Uint8Array(current.buffer, current.byteOffset, current.byteLength).slice().buffer;
|
|
1024
1353
|
return new (current instanceof DataView ? DataView : getTypedArrayConstructor(getTypedArrayName(current)))(buffer);
|
|
1025
1354
|
}
|
|
1026
|
-
function encodeArrayBuffer(current) {
|
|
1027
|
-
if (typeof Buffer !== "undefined") return Buffer.from(current).toString("base64");
|
|
1028
|
-
const bytes = new Uint8Array(current);
|
|
1029
|
-
if (typeof bytes.toBase64 === "function") return bytes.toBase64();
|
|
1030
|
-
let result = "";
|
|
1031
|
-
for (let i = 0, len = bytes.length; i < len; i++) result += String.fromCharCode(bytes[i]);
|
|
1032
|
-
return btoa(result);
|
|
1033
|
-
}
|
|
1034
1355
|
function createArrayBufferNode(ctx, id, current) {
|
|
1035
|
-
return createSerovalNode(19, id, encodeArrayBuffer(current), void 0, void 0, void 0, void 0, void 0, parseSpecialReference(ctx, 5)
|
|
1356
|
+
return createSerovalNode(19, id, encodeArrayBuffer(current), void 0, void 0, void 0, void 0, void 0, parseSpecialReference(ctx, 5));
|
|
1036
1357
|
}
|
|
1037
1358
|
//#endregion
|
|
1038
1359
|
//#region src/core/context/async-parser.ts
|
|
1039
|
-
function createAsyncParserContext(
|
|
1040
|
-
return {
|
|
1041
|
-
base: createBaseParserContext(mode, options),
|
|
1042
|
-
child: void 0
|
|
1043
|
-
};
|
|
1360
|
+
function createAsyncParserContext(options) {
|
|
1361
|
+
return { base: createBaseParserContext(options) };
|
|
1044
1362
|
}
|
|
1045
|
-
var AsyncParsePluginContext = class {
|
|
1046
|
-
constructor(_p, depth) {
|
|
1047
|
-
this._p = _p;
|
|
1048
|
-
this.depth = depth;
|
|
1049
|
-
}
|
|
1050
|
-
parse(current) {
|
|
1051
|
-
return parseAsync(this._p, this.depth, current);
|
|
1052
|
-
}
|
|
1053
|
-
};
|
|
1054
1363
|
async function parseItems$1(ctx, depth, current) {
|
|
1055
|
-
const
|
|
1056
|
-
|
|
1057
|
-
|
|
1364
|
+
const len = current.length;
|
|
1365
|
+
const nodes = new Array(len);
|
|
1366
|
+
for (let i = 0, node; i < len; i++) if (i in current) {
|
|
1367
|
+
node = parseValueAsync(ctx, depth, current[i]);
|
|
1368
|
+
nodes[i] = node instanceof Promise ? await node : node;
|
|
1369
|
+
} else nodes[i] = 0;
|
|
1058
1370
|
return nodes;
|
|
1059
1371
|
}
|
|
1060
1372
|
async function parseArray$1(ctx, depth, id, current) {
|
|
1061
1373
|
return createArrayNode(id, current, await parseItems$1(ctx, depth, current));
|
|
1062
1374
|
}
|
|
1063
1375
|
async function parseProperties$1(ctx, depth, properties) {
|
|
1064
|
-
const
|
|
1065
|
-
const
|
|
1066
|
-
const
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1376
|
+
const keys = Object.keys(properties);
|
|
1377
|
+
const len = keys.length;
|
|
1378
|
+
const keyNodes = new Array(len);
|
|
1379
|
+
const valueNodes = new Array(len);
|
|
1380
|
+
for (let i = 0, key, node; i < len; i++) {
|
|
1381
|
+
key = keys[i];
|
|
1382
|
+
keyNodes[i] = serializeString(key);
|
|
1383
|
+
node = parseValueAsync(ctx, depth, properties[key]);
|
|
1384
|
+
valueNodes[i] = node instanceof Promise ? await node : node;
|
|
1070
1385
|
}
|
|
1071
1386
|
if (SYM_ITERATOR in properties) {
|
|
1072
1387
|
keyNodes.push(parseWellKnownSymbol(ctx.base, SYM_ITERATOR));
|
|
1073
|
-
valueNodes.push(createIteratorFactoryInstanceNode(parseIteratorFactory(ctx.base), await parseAsync(ctx, depth, createSequenceFromIterable(properties))));
|
|
1388
|
+
valueNodes.push(createIteratorFactoryInstanceNode(28, parseIteratorFactory(ctx.base), await parseAsync(ctx, depth, createSequenceFromIterable(properties))));
|
|
1074
1389
|
}
|
|
1075
1390
|
if (SYM_ASYNC_ITERATOR in properties) {
|
|
1076
1391
|
keyNodes.push(parseWellKnownSymbol(ctx.base, SYM_ASYNC_ITERATOR));
|
|
1077
|
-
valueNodes.push(
|
|
1392
|
+
valueNodes.push(createIteratorFactoryInstanceNode(30, parseAsyncIteratorFactory(ctx.base), await parseAsyncIterable$1(ctx, depth, properties)));
|
|
1078
1393
|
}
|
|
1079
1394
|
if (SYM_TO_STRING_TAG in properties) {
|
|
1080
1395
|
keyNodes.push(parseWellKnownSymbol(ctx.base, SYM_TO_STRING_TAG));
|
|
@@ -1095,167 +1410,183 @@ async function parsePlainObject$1(ctx, depth, id, current, empty) {
|
|
|
1095
1410
|
async function parseBoxed$1(ctx, depth, id, current) {
|
|
1096
1411
|
return createBoxedNode(id, await parseAsync(ctx, depth, current.valueOf()));
|
|
1097
1412
|
}
|
|
1098
|
-
async function
|
|
1099
|
-
current = getArrayBufferView(ctx.base, current);
|
|
1100
|
-
return createTypedArrayNode(id, current, await parseAsync(ctx, depth, current.buffer));
|
|
1101
|
-
}
|
|
1102
|
-
async function parseBigIntTypedArray$1(ctx, depth, id, current) {
|
|
1103
|
-
current = getArrayBufferView(ctx.base, current);
|
|
1104
|
-
return createBigIntTypedArrayNode(id, current, await parseAsync(ctx, depth, current.buffer));
|
|
1105
|
-
}
|
|
1106
|
-
async function parseDataView$1(ctx, depth, id, current) {
|
|
1413
|
+
async function parseView$1(ctx, depth, type, id, current) {
|
|
1107
1414
|
current = getArrayBufferView(ctx.base, current);
|
|
1108
|
-
return
|
|
1415
|
+
return createViewNode(type, id, current, await parseAsync(ctx, depth, current.buffer));
|
|
1109
1416
|
}
|
|
1110
|
-
async function parseError$1(ctx, depth, id, current) {
|
|
1417
|
+
async function parseError$1(ctx, depth, type, id, current) {
|
|
1111
1418
|
const options = getErrorOptions(current, ctx.base.features);
|
|
1112
|
-
return createErrorNode(id, current, options ? await parseProperties$1(ctx, depth, options) : void 0);
|
|
1113
|
-
}
|
|
1114
|
-
async function parseAggregateError$1(ctx, depth, id, current) {
|
|
1115
|
-
const options = getErrorOptions(current, ctx.base.features);
|
|
1116
|
-
return createAggregateErrorNode(id, current, options ? await parseProperties$1(ctx, depth, options) : void 0);
|
|
1419
|
+
return createErrorNode(type, id, current, options ? await parseProperties$1(ctx, depth, options) : void 0);
|
|
1117
1420
|
}
|
|
1118
1421
|
async function parseMap$1(ctx, depth, id, current) {
|
|
1119
1422
|
const sentinel = parseMapSentinel(ctx.base);
|
|
1120
|
-
const keyNodes =
|
|
1121
|
-
const valueNodes =
|
|
1423
|
+
const keyNodes = new Array(current.size);
|
|
1424
|
+
const valueNodes = new Array(current.size);
|
|
1425
|
+
let node;
|
|
1426
|
+
let i = 0;
|
|
1122
1427
|
for (const [key, value] of current.entries()) {
|
|
1123
|
-
|
|
1124
|
-
|
|
1428
|
+
node = parseValueAsync(ctx, depth, key);
|
|
1429
|
+
keyNodes[i] = node instanceof Promise ? await node : node;
|
|
1430
|
+
node = parseValueAsync(ctx, depth, value);
|
|
1431
|
+
valueNodes[i] = node instanceof Promise ? await node : node;
|
|
1432
|
+
i++;
|
|
1125
1433
|
}
|
|
1126
1434
|
return createMapNode(id, sentinel, keyNodes, valueNodes);
|
|
1127
1435
|
}
|
|
1128
1436
|
async function parseSet$1(ctx, depth, id, current) {
|
|
1129
|
-
const items =
|
|
1130
|
-
|
|
1437
|
+
const items = new Array(current.size);
|
|
1438
|
+
let node;
|
|
1439
|
+
let i = 0;
|
|
1440
|
+
for (const item of current.keys()) {
|
|
1441
|
+
node = parseValueAsync(ctx, depth, item);
|
|
1442
|
+
items[i++] = node instanceof Promise ? await node : node;
|
|
1443
|
+
}
|
|
1131
1444
|
return createSetNode(id, items);
|
|
1132
1445
|
}
|
|
1133
|
-
async function parsePlugin$1(ctx, depth, id, current) {
|
|
1134
|
-
const currentPlugins = ctx.base.plugins;
|
|
1446
|
+
async function parsePlugin$1(ctx, depth, id, current, currentPlugins) {
|
|
1135
1447
|
if (currentPlugins) for (let i = 0, len = currentPlugins.length; i < len; i++) {
|
|
1136
1448
|
const plugin = currentPlugins[i];
|
|
1137
|
-
if (plugin.parse.async && plugin.test(current)) return createPluginNode(id, plugin.tag, await plugin.parse.async(current,
|
|
1449
|
+
if (plugin.parse.async && plugin.test(current)) return createPluginNode(id, plugin.tag, await plugin.parse.async(current, {
|
|
1450
|
+
parse: (value) => parseAsync(ctx, depth, value),
|
|
1451
|
+
parseStreamSource(source) {
|
|
1452
|
+
if (depth >= ctx.base.depthLimit) throw new SerovalDepthLimitError(ctx.base.depthLimit);
|
|
1453
|
+
return parseAsyncIterable$1(ctx, depth + 1, source);
|
|
1454
|
+
}
|
|
1455
|
+
}, { id }));
|
|
1138
1456
|
}
|
|
1139
1457
|
}
|
|
1140
1458
|
async function parsePromise$1(ctx, depth, id, current) {
|
|
1141
1459
|
const [status, result] = await promiseToResult(current);
|
|
1142
|
-
return createSerovalNode(12, id, status, void 0, void 0, void 0, void 0, void 0, await parseAsync(ctx, depth, result)
|
|
1460
|
+
return createSerovalNode(12, id, status, void 0, void 0, void 0, void 0, void 0, await parseAsync(ctx, depth, result));
|
|
1143
1461
|
}
|
|
1144
1462
|
function parseStreamHandle(depth, id, current, resolve, reject) {
|
|
1145
1463
|
const sequence = [];
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
cleanup();
|
|
1154
|
-
}
|
|
1155
|
-
|
|
1156
|
-
throw: (value) => {
|
|
1157
|
-
markParserRef(this.base, id);
|
|
1158
|
-
parseAsync(this, depth, value).then((data) => {
|
|
1159
|
-
sequence.push(createStreamThrowNode(id, data));
|
|
1160
|
-
resolve(sequence);
|
|
1161
|
-
cleanup();
|
|
1162
|
-
}, (data) => {
|
|
1163
|
-
reject(data);
|
|
1164
|
-
cleanup();
|
|
1165
|
-
});
|
|
1166
|
-
},
|
|
1167
|
-
return: (value) => {
|
|
1168
|
-
markParserRef(this.base, id);
|
|
1169
|
-
parseAsync(this, depth, value).then((data) => {
|
|
1170
|
-
sequence.push(createStreamReturnNode(id, data));
|
|
1171
|
-
resolve(sequence);
|
|
1172
|
-
cleanup();
|
|
1173
|
-
}, (data) => {
|
|
1174
|
-
reject(data);
|
|
1175
|
-
cleanup();
|
|
1176
|
-
});
|
|
1464
|
+
let unparsed = 0;
|
|
1465
|
+
let ended = false;
|
|
1466
|
+
let settled = false;
|
|
1467
|
+
const fail = (error) => {
|
|
1468
|
+
if (!settled) {
|
|
1469
|
+
settled = true;
|
|
1470
|
+
try {
|
|
1471
|
+
cleanup(error);
|
|
1472
|
+
} catch {}
|
|
1473
|
+
reject(error);
|
|
1177
1474
|
}
|
|
1178
|
-
}
|
|
1475
|
+
};
|
|
1476
|
+
const handle = (type) => (value, accept) => {
|
|
1477
|
+
if (settled) return;
|
|
1478
|
+
markParserRef(this.base, id);
|
|
1479
|
+
const slot = sequence.push(void 0) - 1;
|
|
1480
|
+
unparsed++;
|
|
1481
|
+
if (type !== 32) ended = true;
|
|
1482
|
+
parseAsync(this, depth, value).then((data) => {
|
|
1483
|
+
if (!settled) {
|
|
1484
|
+
sequence[slot] = createStreamEventNode(type, id, data);
|
|
1485
|
+
unparsed--;
|
|
1486
|
+
accept?.();
|
|
1487
|
+
if (ended && unparsed === 0) {
|
|
1488
|
+
settled = true;
|
|
1489
|
+
try {
|
|
1490
|
+
cleanup();
|
|
1491
|
+
} catch (error) {
|
|
1492
|
+
reject(error);
|
|
1493
|
+
return;
|
|
1494
|
+
}
|
|
1495
|
+
resolve(sequence);
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
}, fail);
|
|
1499
|
+
};
|
|
1500
|
+
const listener = {
|
|
1501
|
+
next: handle(32),
|
|
1502
|
+
throw: handle(33),
|
|
1503
|
+
return: handle(34)
|
|
1504
|
+
};
|
|
1505
|
+
const cleanup = isLiveStream(current) ? current.pump(listener) : current.on(listener);
|
|
1179
1506
|
}
|
|
1180
1507
|
async function parseStream$1(ctx, depth, id, current) {
|
|
1181
1508
|
return createStreamConstructorNode(id, parseSpecialReference(ctx.base, 4), await new Promise(parseStreamHandle.bind(ctx, depth, id, current)));
|
|
1182
1509
|
}
|
|
1510
|
+
/**
|
|
1511
|
+
* Collects an async iterable into a replay node, one value at a time.
|
|
1512
|
+
*/
|
|
1513
|
+
async function parseAsyncIterable$1(ctx, depth, current) {
|
|
1514
|
+
const id = createIndexForValue(ctx.base, {});
|
|
1515
|
+
const reference = parseSpecialReference(ctx.base, 4);
|
|
1516
|
+
const iterator = current[SYM_ASYNC_ITERATOR]();
|
|
1517
|
+
const sequence = [];
|
|
1518
|
+
for (;;) {
|
|
1519
|
+
let result;
|
|
1520
|
+
try {
|
|
1521
|
+
result = await iterator.next();
|
|
1522
|
+
} catch (error) {
|
|
1523
|
+
markParserRef(ctx.base, id);
|
|
1524
|
+
sequence.push(createStreamEventNode(33, id, await parseAsync(ctx, depth, error)));
|
|
1525
|
+
break;
|
|
1526
|
+
}
|
|
1527
|
+
markParserRef(ctx.base, id);
|
|
1528
|
+
let parsed;
|
|
1529
|
+
try {
|
|
1530
|
+
parsed = await parseAsync(ctx, depth, result.value);
|
|
1531
|
+
} catch (error) {
|
|
1532
|
+
Promise.resolve().then(() => iterator.return?.()).catch(() => {});
|
|
1533
|
+
throw error;
|
|
1534
|
+
}
|
|
1535
|
+
sequence.push(createStreamEventNode(result.done ? 34 : 32, id, parsed));
|
|
1536
|
+
if (result.done) break;
|
|
1537
|
+
}
|
|
1538
|
+
return createStreamConstructorNode(id, reference, sequence);
|
|
1539
|
+
}
|
|
1183
1540
|
async function parseSequence$1(ctx, depth, id, current) {
|
|
1184
|
-
const
|
|
1185
|
-
|
|
1541
|
+
const len = current.v.length;
|
|
1542
|
+
const nodes = new Array(len);
|
|
1543
|
+
for (let i = 0, node; i < len; i++) {
|
|
1544
|
+
node = parseValueAsync(ctx, depth, current.v[i]);
|
|
1545
|
+
nodes[i] = node instanceof Promise ? await node : node;
|
|
1546
|
+
}
|
|
1186
1547
|
return createSequenceNode(id, nodes, current.t, current.d);
|
|
1187
1548
|
}
|
|
1188
1549
|
async function parseObjectAsync(ctx, depth, id, current) {
|
|
1189
1550
|
if (Array.isArray(current)) return parseArray$1(ctx, depth, id, current);
|
|
1190
1551
|
if (isStream(current)) return parseStream$1(ctx, depth, id, current);
|
|
1191
1552
|
if (isSequence(current)) return parseSequence$1(ctx, depth, id, current);
|
|
1192
|
-
|
|
1193
|
-
if (currentClass !== void 0 && typeof currentClass !== "function") {
|
|
1194
|
-
const proto = Object.getPrototypeOf(current);
|
|
1195
|
-
currentClass = proto === null ? void 0 : proto.constructor;
|
|
1196
|
-
}
|
|
1553
|
+
const currentClass = getObjectClass(current);
|
|
1197
1554
|
if (currentClass === OpaqueReference) return parseAsync(ctx, depth, current.replacement);
|
|
1198
|
-
const parsed = await parsePlugin$1(ctx, depth, id, current);
|
|
1555
|
+
const parsed = await parsePlugin$1(ctx, depth, id, current, getObjectPlugins(ctx.base, current, currentClass));
|
|
1199
1556
|
if (parsed) return parsed;
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
case
|
|
1203
|
-
case
|
|
1204
|
-
case
|
|
1205
|
-
case
|
|
1206
|
-
case
|
|
1207
|
-
case
|
|
1208
|
-
case
|
|
1209
|
-
case
|
|
1210
|
-
case
|
|
1211
|
-
case
|
|
1212
|
-
case
|
|
1213
|
-
case
|
|
1214
|
-
case
|
|
1215
|
-
case
|
|
1216
|
-
case
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
case Uint8Array:
|
|
1220
|
-
case Uint16Array:
|
|
1221
|
-
case Uint32Array:
|
|
1222
|
-
case Uint8ClampedArray:
|
|
1223
|
-
case Float32Array:
|
|
1224
|
-
case Float64Array: return parseTypedArray$1(ctx, depth, id, current);
|
|
1225
|
-
case DataView: return parseDataView$1(ctx, depth, id, current);
|
|
1226
|
-
case Map: return parseMap$1(ctx, depth, id, current);
|
|
1227
|
-
case Set: return parseSet$1(ctx, depth, id, current);
|
|
1228
|
-
}
|
|
1229
|
-
if (currentClass === Promise || current instanceof Promise) return parsePromise$1(ctx, depth, id, current);
|
|
1230
|
-
const currentFeatures = ctx.base.features;
|
|
1231
|
-
if (currentFeatures & 32 && currentClass === RegExp) return createRegExpNode(id, current);
|
|
1232
|
-
if (currentFeatures & 16) switch (currentClass) {
|
|
1233
|
-
case BigInt64Array:
|
|
1234
|
-
case BigUint64Array: return parseBigIntTypedArray$1(ctx, depth, id, current);
|
|
1235
|
-
}
|
|
1236
|
-
if (currentFeatures & 1 && typeof AggregateError !== "undefined" && (currentClass === AggregateError || current instanceof AggregateError)) return parseAggregateError$1(ctx, depth, id, current);
|
|
1237
|
-
if (currentFeatures & 64 && typeof Temporal !== "undefined") switch (currentClass) {
|
|
1238
|
-
case Temporal.Instant: return createTemporalNode(id, 0, current);
|
|
1239
|
-
case Temporal.Duration: return createTemporalNode(id, 1, current);
|
|
1240
|
-
case Temporal.PlainDate: return createTemporalNode(id, 2, current);
|
|
1241
|
-
case Temporal.PlainDateTime: return createTemporalNode(id, 3, current);
|
|
1242
|
-
case Temporal.PlainMonthDay: return createTemporalNode(id, 4, current);
|
|
1243
|
-
case Temporal.PlainTime: return createTemporalNode(id, 5, current);
|
|
1244
|
-
case Temporal.PlainYearMonth: return createTemporalNode(id, 6, current);
|
|
1245
|
-
case Temporal.ZonedDateTime: return createTemporalNode(id, 7, current);
|
|
1246
|
-
}
|
|
1247
|
-
if (current instanceof Error) return parseError$1(ctx, depth, id, current);
|
|
1248
|
-
if (SYM_ITERATOR in current || SYM_ASYNC_ITERATOR in current) return parsePlainObject$1(ctx, depth, id, current, !!currentClass);
|
|
1249
|
-
throw new SerovalUnsupportedTypeError(current);
|
|
1557
|
+
if (currentClass === Object) return parsePlainObject$1(ctx, depth, id, current, false);
|
|
1558
|
+
switch (getObjectKind(current, currentClass, ctx.base.features)) {
|
|
1559
|
+
case 2: return parsePlainObject$1(ctx, depth, id, current, true);
|
|
1560
|
+
case 3: return createDateNode(id, current);
|
|
1561
|
+
case 4: return parseError$1(ctx, depth, 13, id, current);
|
|
1562
|
+
case 5: return parseError$1(ctx, depth, 14, id, current);
|
|
1563
|
+
case 6: return parseBoxed$1(ctx, depth, id, current);
|
|
1564
|
+
case 7: return createArrayBufferNode(ctx.base, id, current);
|
|
1565
|
+
case 8: return parseView$1(ctx, depth, 15, id, current);
|
|
1566
|
+
case 9: return parseView$1(ctx, depth, 16, id, current);
|
|
1567
|
+
case 10: return parseView$1(ctx, depth, 20, id, current);
|
|
1568
|
+
case 11: return parseMap$1(ctx, depth, id, current);
|
|
1569
|
+
case 12: return parseSet$1(ctx, depth, id, current);
|
|
1570
|
+
case 13: return parsePromise$1(ctx, depth, id, current);
|
|
1571
|
+
case 14: return createRegExpNode(id, current);
|
|
1572
|
+
case 15: return createTemporalNode(id, getTemporalType(currentClass), current);
|
|
1573
|
+
case 16: return parsePlainObject$1(ctx, depth, id, current, !!currentClass);
|
|
1574
|
+
default: throw new SerovalUnsupportedTypeError(current);
|
|
1575
|
+
}
|
|
1250
1576
|
}
|
|
1251
1577
|
async function parseFunctionAsync(ctx, depth, current) {
|
|
1252
1578
|
const ref = getReferenceNode(ctx.base, current);
|
|
1253
|
-
if (ref
|
|
1254
|
-
const plugin = await parsePlugin$1(ctx, depth, ref
|
|
1579
|
+
if (typeof ref !== "number") return ref;
|
|
1580
|
+
const plugin = await parsePlugin$1(ctx, depth, ref, current, ctx.base.plugins);
|
|
1255
1581
|
if (plugin) return plugin;
|
|
1256
1582
|
throw new SerovalUnsupportedTypeError(current);
|
|
1257
1583
|
}
|
|
1258
|
-
|
|
1584
|
+
/**
|
|
1585
|
+
* Parses primitives and already-seen values synchronously; only objects and
|
|
1586
|
+
* functions come back as a Promise. Errors are thrown synchronously, which
|
|
1587
|
+
* an async caller turns into a rejection as before.
|
|
1588
|
+
*/
|
|
1589
|
+
function parseValueAsync(ctx, depth, current) {
|
|
1259
1590
|
if (depth >= ctx.base.depthLimit) throw new SerovalDepthLimitError(ctx.base.depthLimit);
|
|
1260
1591
|
switch (typeof current) {
|
|
1261
1592
|
case "boolean": return current ? TRUE_NODE : FALSE_NODE;
|
|
@@ -1266,7 +1597,7 @@ async function parseAsync(ctx, depth, current) {
|
|
|
1266
1597
|
case "object":
|
|
1267
1598
|
if (current) {
|
|
1268
1599
|
const ref = getReferenceNode(ctx.base, current);
|
|
1269
|
-
return ref
|
|
1600
|
+
return typeof ref === "number" ? parseObjectAsync(ctx, depth + 1, ref, current) : ref;
|
|
1270
1601
|
}
|
|
1271
1602
|
return NULL_NODE;
|
|
1272
1603
|
case "symbol": return parseWellKnownSymbol(ctx.base, current);
|
|
@@ -1274,6 +1605,9 @@ async function parseAsync(ctx, depth, current) {
|
|
|
1274
1605
|
default: throw new SerovalUnsupportedTypeError(current);
|
|
1275
1606
|
}
|
|
1276
1607
|
}
|
|
1608
|
+
async function parseAsync(ctx, depth, current) {
|
|
1609
|
+
return await parseValueAsync(ctx, depth, current);
|
|
1610
|
+
}
|
|
1277
1611
|
async function parseTopAsync(ctx, current) {
|
|
1278
1612
|
try {
|
|
1279
1613
|
return await parseAsync(ctx, 0, current);
|
|
@@ -1282,32 +1616,6 @@ async function parseTopAsync(ctx, current) {
|
|
|
1282
1616
|
}
|
|
1283
1617
|
}
|
|
1284
1618
|
//#endregion
|
|
1285
|
-
//#region src/core/plugin.ts
|
|
1286
|
-
let SerovalMode = /* @__PURE__ */ function(SerovalMode) {
|
|
1287
|
-
SerovalMode[SerovalMode["Vanilla"] = 1] = "Vanilla";
|
|
1288
|
-
SerovalMode[SerovalMode["Cross"] = 2] = "Cross";
|
|
1289
|
-
return SerovalMode;
|
|
1290
|
-
}({});
|
|
1291
|
-
function createPlugin(plugin) {
|
|
1292
|
-
return plugin;
|
|
1293
|
-
}
|
|
1294
|
-
function dedupePlugins(deduped, plugins) {
|
|
1295
|
-
for (let i = 0, len = plugins.length; i < len; i++) {
|
|
1296
|
-
const current = plugins[i];
|
|
1297
|
-
if (!deduped.has(current)) {
|
|
1298
|
-
deduped.add(current);
|
|
1299
|
-
if (current.extends) dedupePlugins(deduped, current.extends);
|
|
1300
|
-
}
|
|
1301
|
-
}
|
|
1302
|
-
}
|
|
1303
|
-
function resolvePlugins(plugins) {
|
|
1304
|
-
if (plugins) {
|
|
1305
|
-
const deduped = /* @__PURE__ */ new Set();
|
|
1306
|
-
dedupePlugins(deduped, plugins);
|
|
1307
|
-
return [...deduped];
|
|
1308
|
-
}
|
|
1309
|
-
}
|
|
1310
|
-
//#endregion
|
|
1311
1619
|
//#region src/core/utils/valid-properties.ts
|
|
1312
1620
|
function isValidKey(key) {
|
|
1313
1621
|
switch (key) {
|
|
@@ -1333,7 +1641,6 @@ function isValidSymbol(symbol) {
|
|
|
1333
1641
|
//#endregion
|
|
1334
1642
|
//#region src/core/context/deserializer.ts
|
|
1335
1643
|
const DEFAULT_MAX_BASE64_LENGTH = 1e6;
|
|
1336
|
-
const MIN_NATIVE_BASE64_LENGTH = 512;
|
|
1337
1644
|
const MAX_BIGINT_LENGTH = 1e4;
|
|
1338
1645
|
const MAX_REGEXP_SOURCE_LENGTH = 2e4;
|
|
1339
1646
|
function applyObjectFlag(obj, flag) {
|
|
@@ -1345,68 +1652,48 @@ function applyObjectFlag(obj, flag) {
|
|
|
1345
1652
|
}
|
|
1346
1653
|
}
|
|
1347
1654
|
const DEFAULT_DEPTH_LIMIT = 1e3;
|
|
1348
|
-
function createBaseDeserializerContext(
|
|
1349
|
-
|
|
1350
|
-
const maxBase64Length = (_options$maxBase64Len = options.maxBase64Length) !== null && _options$maxBase64Len !== void 0 ? _options$maxBase64Len : DEFAULT_MAX_BASE64_LENGTH;
|
|
1655
|
+
function createBaseDeserializerContext(options) {
|
|
1656
|
+
const maxBase64Length = options.maxBase64Length ?? DEFAULT_MAX_BASE64_LENGTH;
|
|
1351
1657
|
if (!Number.isSafeInteger(maxBase64Length) || maxBase64Length < 0) throw new RangeError("maxBase64Length must be a non-negative safe integer");
|
|
1352
|
-
const refs = options.refs
|
|
1658
|
+
const refs = options.refs ?? /* @__PURE__ */ new Map();
|
|
1353
1659
|
if (!("types" in refs)) Object.assign(refs, { types: /* @__PURE__ */ new Map() });
|
|
1354
1660
|
return {
|
|
1355
|
-
mode,
|
|
1356
1661
|
plugins: options.plugins,
|
|
1357
1662
|
refs,
|
|
1358
|
-
features:
|
|
1663
|
+
features: options.features ?? 127 ^ (options.disabledFeatures ?? 0),
|
|
1359
1664
|
depthLimit: options.depthLimit || DEFAULT_DEPTH_LIMIT,
|
|
1360
1665
|
maxBase64Length
|
|
1361
1666
|
};
|
|
1362
1667
|
}
|
|
1363
1668
|
function createVanillaDeserializerContext(options) {
|
|
1364
1669
|
return {
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
child: void 0,
|
|
1368
|
-
state: { marked: new Set(options.markedRefs) }
|
|
1670
|
+
base: createBaseDeserializerContext(options),
|
|
1671
|
+
marked: new Set(options.markedRefs)
|
|
1369
1672
|
};
|
|
1370
1673
|
}
|
|
1371
1674
|
function createCrossDeserializerContext(options) {
|
|
1372
1675
|
return {
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
child: void 0
|
|
1676
|
+
base: createBaseDeserializerContext(options),
|
|
1677
|
+
marked: void 0
|
|
1376
1678
|
};
|
|
1377
1679
|
}
|
|
1378
|
-
var DeserializePluginContext = class {
|
|
1379
|
-
constructor(_p, depth) {
|
|
1380
|
-
this._p = _p;
|
|
1381
|
-
this.depth = depth;
|
|
1382
|
-
}
|
|
1383
|
-
deserialize(node) {
|
|
1384
|
-
return deserialize$1(this._p, this.depth, node);
|
|
1385
|
-
}
|
|
1386
|
-
};
|
|
1387
1680
|
function guardIndexedValue(ctx, id) {
|
|
1388
|
-
|
|
1681
|
+
const node = {
|
|
1389
1682
|
t: 4,
|
|
1390
1683
|
i: id
|
|
1391
|
-
}
|
|
1392
|
-
if (
|
|
1684
|
+
};
|
|
1685
|
+
if (id < 0 || !Number.isInteger(id)) throw new SerovalMalformedNodeError(node);
|
|
1686
|
+
if (ctx.refs.has(id)) throw new SerovalConflictedNodeIdError(node);
|
|
1393
1687
|
}
|
|
1394
1688
|
function isThennable(value) {
|
|
1395
1689
|
return !!value && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
|
|
1396
1690
|
}
|
|
1397
|
-
function
|
|
1398
|
-
guardIndexedValue(ctx.base, id);
|
|
1399
|
-
if (ctx.state.marked.has(id)) ctx.base.refs.set(id, value);
|
|
1400
|
-
return value;
|
|
1401
|
-
}
|
|
1402
|
-
function assignIndexedValueCross(ctx, id, value) {
|
|
1691
|
+
function assignIndexedValue$1(ctx, id, value) {
|
|
1403
1692
|
guardIndexedValue(ctx.base, id);
|
|
1404
|
-
ctx.
|
|
1693
|
+
const marked = ctx.marked;
|
|
1694
|
+
if (!marked || marked.has(id)) ctx.base.refs.set(id, value);
|
|
1405
1695
|
return value;
|
|
1406
1696
|
}
|
|
1407
|
-
function assignIndexedValue$1(ctx, id, value) {
|
|
1408
|
-
return ctx.mode === 1 ? assignIndexedValueVanilla(ctx, id, value) : assignIndexedValueCross(ctx, id, value);
|
|
1409
|
-
}
|
|
1410
1697
|
function deserializeKnownValue(node, record, key) {
|
|
1411
1698
|
if (Object.hasOwn(record, key)) return record[key];
|
|
1412
1699
|
throw new SerovalMalformedNodeError(node);
|
|
@@ -1463,7 +1750,8 @@ function deserializeProperties(ctx, depth, node, result) {
|
|
|
1463
1750
|
const keys = node.k;
|
|
1464
1751
|
validateNodeList(node, keys);
|
|
1465
1752
|
validateNodeList(node, node.v);
|
|
1466
|
-
|
|
1753
|
+
const len = keys.length;
|
|
1754
|
+
if (len > 0) for (let i = 0, vals = node.v; i < len; i++) assignProperty(ctx, depth, result, keys[i], vals[i]);
|
|
1467
1755
|
return result;
|
|
1468
1756
|
}
|
|
1469
1757
|
function deserializeObject(ctx, depth, node) {
|
|
@@ -1477,35 +1765,8 @@ function deserializeDate(ctx, node) {
|
|
|
1477
1765
|
}
|
|
1478
1766
|
function deserializeTemporal(ctx, node) {
|
|
1479
1767
|
if (!(ctx.base.features & 64)) throw new SerovalUnsupportedNodeError(node);
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
case 0:
|
|
1483
|
-
value = Temporal.Instant.from(node.s);
|
|
1484
|
-
break;
|
|
1485
|
-
case 1:
|
|
1486
|
-
value = Temporal.Duration.from(node.s);
|
|
1487
|
-
break;
|
|
1488
|
-
case 2:
|
|
1489
|
-
value = Temporal.PlainDate.from(node.s);
|
|
1490
|
-
break;
|
|
1491
|
-
case 3:
|
|
1492
|
-
value = Temporal.PlainDateTime.from(node.s);
|
|
1493
|
-
break;
|
|
1494
|
-
case 4:
|
|
1495
|
-
value = Temporal.PlainMonthDay.from(node.s);
|
|
1496
|
-
break;
|
|
1497
|
-
case 5:
|
|
1498
|
-
value = Temporal.PlainTime.from(node.s);
|
|
1499
|
-
break;
|
|
1500
|
-
case 6:
|
|
1501
|
-
value = Temporal.PlainYearMonth.from(node.s);
|
|
1502
|
-
break;
|
|
1503
|
-
case 7:
|
|
1504
|
-
value = Temporal.ZonedDateTime.from(node.s);
|
|
1505
|
-
break;
|
|
1506
|
-
default: throw new SerovalMalformedNodeError(node);
|
|
1507
|
-
}
|
|
1508
|
-
return assignIndexedValue$1(ctx, node.i, value);
|
|
1768
|
+
const construct = Temporal[deserializeKnownValue(node, TEMPORAL_TYPE_NAME, node.c)];
|
|
1769
|
+
return assignIndexedValue$1(ctx, node.i, construct.from(node.s));
|
|
1509
1770
|
}
|
|
1510
1771
|
function deserializeRegExp(ctx, node) {
|
|
1511
1772
|
if (ctx.base.features & 32) {
|
|
@@ -1531,32 +1792,15 @@ function deserializeMap(ctx, depth, node) {
|
|
|
1531
1792
|
function deserializeArrayBuffer(ctx, node) {
|
|
1532
1793
|
if (typeof node.s !== "string") throw new SerovalMalformedNodeError(node);
|
|
1533
1794
|
if (node.s.length > ctx.base.maxBase64Length) throw new RangeError("ArrayBuffer exceeds maxBase64Length (" + ctx.base.maxBase64Length + ")");
|
|
1534
|
-
const
|
|
1535
|
-
let buffer;
|
|
1536
|
-
if (source.length < MIN_NATIVE_BASE64_LENGTH || typeof Buffer === "undefined") buffer = ARRAY_BUFFER_CONSTRUCTOR(source);
|
|
1537
|
-
else {
|
|
1538
|
-
const decoded = atob(source);
|
|
1539
|
-
buffer = new ArrayBuffer(decoded.length);
|
|
1540
|
-
Buffer.from(buffer).write(decoded, "latin1");
|
|
1541
|
-
}
|
|
1795
|
+
const buffer = decodeArrayBuffer(deserializeString(node.s));
|
|
1542
1796
|
return assignIndexedValue$1(ctx, node.i, buffer);
|
|
1543
1797
|
}
|
|
1544
|
-
function
|
|
1545
|
-
var _node$b;
|
|
1546
|
-
const construct = getTypedArrayConstructor(node.c);
|
|
1547
|
-
const source = deserialize$1(ctx, depth, node.f);
|
|
1548
|
-
if (!(source instanceof ArrayBuffer)) throw new SerovalMalformedNodeError(node);
|
|
1549
|
-
const offset = (_node$b = node.b) !== null && _node$b !== void 0 ? _node$b : 0;
|
|
1550
|
-
if (offset < 0 || offset > source.byteLength) throw new SerovalMalformedNodeError(node);
|
|
1551
|
-
return assignIndexedValue$1(ctx, node.i, new construct(source, offset, node.l));
|
|
1552
|
-
}
|
|
1553
|
-
function deserializeDataView(ctx, depth, node) {
|
|
1554
|
-
var _node$b2;
|
|
1798
|
+
function deserializeView(ctx, depth, node, construct) {
|
|
1555
1799
|
const source = deserialize$1(ctx, depth, node.f);
|
|
1556
1800
|
if (!(source instanceof ArrayBuffer)) throw new SerovalMalformedNodeError(node);
|
|
1557
|
-
const offset =
|
|
1801
|
+
const offset = node.b ?? 0;
|
|
1558
1802
|
if (offset < 0 || offset > source.byteLength) throw new SerovalMalformedNodeError(node);
|
|
1559
|
-
return assignIndexedValue$1(ctx, node.i, new DataView(source, offset, node.l));
|
|
1803
|
+
return assignIndexedValue$1(ctx, node.i, construct ? new construct(source, offset, node.l) : new DataView(source, offset, node.l));
|
|
1560
1804
|
}
|
|
1561
1805
|
function deserializeDictionary(ctx, depth, node, result) {
|
|
1562
1806
|
if (node.p) {
|
|
@@ -1590,7 +1834,7 @@ function deserializePlugin(ctx, depth, node) {
|
|
|
1590
1834
|
const tag = deserializeString(node.c);
|
|
1591
1835
|
for (let i = 0, len = currentPlugins.length; i < len; i++) {
|
|
1592
1836
|
const plugin = currentPlugins[i];
|
|
1593
|
-
if (plugin.tag === tag) return assignIndexedValue$1(ctx, node.i, plugin.deserialize(node.s,
|
|
1837
|
+
if (plugin.tag === tag) return assignIndexedValue$1(ctx, node.i, plugin.deserialize(node.s, { deserialize: (current) => deserialize$1(ctx, depth, current) }, { id: node.i }));
|
|
1594
1838
|
}
|
|
1595
1839
|
}
|
|
1596
1840
|
throw new SerovalMissingPluginError(node.c);
|
|
@@ -1598,6 +1842,7 @@ function deserializePlugin(ctx, depth, node) {
|
|
|
1598
1842
|
function deserializePromiseConstructor(ctx, node) {
|
|
1599
1843
|
const value = assignIndexedValue$1(ctx, node.i, assignIndexedValue$1(ctx, node.s, PROMISE_CONSTRUCTOR()).p);
|
|
1600
1844
|
assignNodeType(ctx, node.s, 22);
|
|
1845
|
+
ctx.base.pending?.add(node.s);
|
|
1601
1846
|
return value;
|
|
1602
1847
|
}
|
|
1603
1848
|
function deserializePromiseFulfill(ctx, depth, node) {
|
|
@@ -1608,6 +1853,7 @@ function deserializePromiseFulfill(ctx, depth, node) {
|
|
|
1608
1853
|
if (isThennable(deserialized)) throw new SerovalMalformedNodeError(node.a[1]);
|
|
1609
1854
|
if (node.t === 23) deferred.s(deserialized);
|
|
1610
1855
|
else deferred.f(deserialized);
|
|
1856
|
+
ctx.base.pending?.delete(node.i);
|
|
1611
1857
|
return;
|
|
1612
1858
|
}
|
|
1613
1859
|
throw new SerovalMissingInstanceError("Promise");
|
|
@@ -1625,37 +1871,21 @@ function deserializeAsyncIteratorFactoryInstance(ctx, depth, node) {
|
|
|
1625
1871
|
return streamToAsyncIterable(source);
|
|
1626
1872
|
}
|
|
1627
1873
|
function deserializeStreamConstructor(ctx, depth, node) {
|
|
1628
|
-
const result = assignIndexedValue$1(ctx, node.i,
|
|
1874
|
+
const result = assignIndexedValue$1(ctx, node.i, new Stream(node.l === 1 ? 1 : void 0));
|
|
1629
1875
|
assignNodeType(ctx, node.i, 31);
|
|
1876
|
+
ctx.base.pending?.add(node.i);
|
|
1630
1877
|
const items = node.a;
|
|
1631
1878
|
validateNodeList(node, items);
|
|
1632
1879
|
const len = items.length;
|
|
1633
1880
|
if (len) for (let i = 0; i < len; i++) deserialize$1(ctx, depth, items[i]);
|
|
1634
1881
|
return result;
|
|
1635
1882
|
}
|
|
1636
|
-
function
|
|
1883
|
+
function deserializeStreamCall(ctx, depth, node, method) {
|
|
1637
1884
|
const deferred = ctx.base.refs.get(node.i);
|
|
1638
1885
|
if (deferred) {
|
|
1639
1886
|
validateNodeType(ctx, node, node.i, 31);
|
|
1640
|
-
deferred
|
|
1641
|
-
|
|
1642
|
-
}
|
|
1643
|
-
throw new SerovalMissingInstanceError("Stream");
|
|
1644
|
-
}
|
|
1645
|
-
function deserializeStreamThrow(ctx, depth, node) {
|
|
1646
|
-
const deferred = ctx.base.refs.get(node.i);
|
|
1647
|
-
if (deferred) {
|
|
1648
|
-
validateNodeType(ctx, node, node.i, 31);
|
|
1649
|
-
deferred.throw(deserialize$1(ctx, depth, node.f));
|
|
1650
|
-
return;
|
|
1651
|
-
}
|
|
1652
|
-
throw new SerovalMissingInstanceError("Stream");
|
|
1653
|
-
}
|
|
1654
|
-
function deserializeStreamReturn(ctx, depth, node) {
|
|
1655
|
-
const deferred = ctx.base.refs.get(node.i);
|
|
1656
|
-
if (deferred) {
|
|
1657
|
-
validateNodeType(ctx, node, node.i, 31);
|
|
1658
|
-
deferred.return(deserialize$1(ctx, depth, node.f));
|
|
1887
|
+
deferred[method](deserialize$1(ctx, depth, node.f));
|
|
1888
|
+
if (method !== "next") ctx.base.pending?.delete(node.i);
|
|
1659
1889
|
return;
|
|
1660
1890
|
}
|
|
1661
1891
|
throw new SerovalMissingInstanceError("Stream");
|
|
@@ -1674,6 +1904,7 @@ function deserializeSequence(ctx, depth, node) {
|
|
|
1674
1904
|
const size = node.a.length;
|
|
1675
1905
|
if (!(isSequenceIndex(node.s, size) && isSequenceIndex(node.l, size))) throw new SerovalMalformedNodeError(node);
|
|
1676
1906
|
const result = assignIndexedValue$1(ctx, node.i, createSequence([], node.s, node.l));
|
|
1907
|
+
assignNodeType(ctx, node.i, 35);
|
|
1677
1908
|
for (let i = 0; i < size; i++) result.v[i] = deserialize$1(ctx, depth, node.a[i]);
|
|
1678
1909
|
return result;
|
|
1679
1910
|
}
|
|
@@ -1698,8 +1929,8 @@ function deserialize$1(ctx, depth, node) {
|
|
|
1698
1929
|
case 8: return deserializeMap(ctx, depth, node);
|
|
1699
1930
|
case 19: return deserializeArrayBuffer(ctx, node);
|
|
1700
1931
|
case 16:
|
|
1701
|
-
case 15: return
|
|
1702
|
-
case 20: return
|
|
1932
|
+
case 15: return deserializeView(ctx, depth, node, getTypedArrayConstructor(node.c));
|
|
1933
|
+
case 20: return deserializeView(ctx, depth, node);
|
|
1703
1934
|
case 14: return deserializeAggregateError(ctx, depth, node);
|
|
1704
1935
|
case 13: return deserializeError(ctx, depth, node);
|
|
1705
1936
|
case 12: return deserializePromise(ctx, depth, node);
|
|
@@ -1712,9 +1943,9 @@ function deserialize$1(ctx, depth, node) {
|
|
|
1712
1943
|
case 28: return deserializeIteratorFactoryInstance(ctx, depth, node);
|
|
1713
1944
|
case 30: return deserializeAsyncIteratorFactoryInstance(ctx, depth, node);
|
|
1714
1945
|
case 31: return deserializeStreamConstructor(ctx, depth, node);
|
|
1715
|
-
case 32: return
|
|
1716
|
-
case 33: return
|
|
1717
|
-
case 34: return
|
|
1946
|
+
case 32: return deserializeStreamCall(ctx, depth, node, "next");
|
|
1947
|
+
case 33: return deserializeStreamCall(ctx, depth, node, "throw");
|
|
1948
|
+
case 34: return deserializeStreamCall(ctx, depth, node, "return");
|
|
1718
1949
|
case 27: return deserializeIteratorFactory(ctx, depth, node);
|
|
1719
1950
|
case 29: return deserializeAsyncIteratorFactory(ctx, depth, node);
|
|
1720
1951
|
case 35: return deserializeSequence(ctx, depth, node);
|
|
@@ -1729,11 +1960,31 @@ function deserializeTop(ctx, node) {
|
|
|
1729
1960
|
throw new SerovalDeserializationError(error);
|
|
1730
1961
|
}
|
|
1731
1962
|
}
|
|
1963
|
+
/**
|
|
1964
|
+
* Rejects every pending promise and throws into every open stream tracked
|
|
1965
|
+
* by `ctx.base.pending`, then drops the bookkeeping so the context no longer
|
|
1966
|
+
* accepts deferred values. Does nothing once the bookkeeping is gone.
|
|
1967
|
+
*/
|
|
1968
|
+
function abortDeferred(ctx, reason) {
|
|
1969
|
+
const pending = ctx.base.pending;
|
|
1970
|
+
if (pending) {
|
|
1971
|
+
ctx.base.pending = void 0;
|
|
1972
|
+
const refs = ctx.base.refs;
|
|
1973
|
+
const errors = [];
|
|
1974
|
+
for (const id of pending) try {
|
|
1975
|
+
const value = refs.get(id);
|
|
1976
|
+
if (refs.types.get(id) === 22) value.f(reason);
|
|
1977
|
+
else value.throw(reason);
|
|
1978
|
+
} catch (error) {
|
|
1979
|
+
errors.push(error);
|
|
1980
|
+
}
|
|
1981
|
+
if (errors.length) throw errors[0];
|
|
1982
|
+
}
|
|
1983
|
+
}
|
|
1732
1984
|
//#endregion
|
|
1733
1985
|
//#region src/core/function-string.ts
|
|
1734
1986
|
const RETURN = () => T;
|
|
1735
|
-
const
|
|
1736
|
-
const IS_MODERN = /* @__PURE__ */ /=>/.test(SERIALIZED_RETURN);
|
|
1987
|
+
const IS_MODERN = /* @__PURE__ */ (/* @__PURE__ */ RETURN.toString()).includes("=>");
|
|
1737
1988
|
function createFunction(parameters, body) {
|
|
1738
1989
|
if (IS_MODERN) return (parameters.length === 1 ? parameters[0] : "(" + parameters.join(",") + ")") + "=>" + (body.startsWith("{") ? "(" + body + ")" : body);
|
|
1739
1990
|
return "function(" + parameters.join(",") + "){return " + body + "}";
|
|
@@ -1761,10 +2012,13 @@ function getIdentifier(index) {
|
|
|
1761
2012
|
}
|
|
1762
2013
|
//#endregion
|
|
1763
2014
|
//#region src/core/utils/is-valid-identifier.ts
|
|
1764
|
-
const IDENTIFIER_CHECK = /^[$A-Z_][0-9A-Z_$]*$/i;
|
|
1765
2015
|
function isValidIdentifier(name) {
|
|
1766
|
-
const
|
|
1767
|
-
|
|
2016
|
+
const len = name.length;
|
|
2017
|
+
for (let i = 0; i < len; i++) {
|
|
2018
|
+
const code = name.charCodeAt(i);
|
|
2019
|
+
if (!(code >= 97 && code <= 122 || code >= 65 && code <= 90 || code >= 48 && code <= 57 && i > 0 || code === 95 || code === 36)) return false;
|
|
2020
|
+
}
|
|
2021
|
+
return len > 0;
|
|
1768
2022
|
}
|
|
1769
2023
|
//#endregion
|
|
1770
2024
|
//#region src/core/context/serializer.ts
|
|
@@ -1778,58 +2032,31 @@ function getAssignmentExpression(assignment) {
|
|
|
1778
2032
|
}
|
|
1779
2033
|
}
|
|
1780
2034
|
const MAX_ASSIGNMENT_CHAIN_LENGTH = 100;
|
|
1781
|
-
function
|
|
1782
|
-
|
|
1783
|
-
let
|
|
2035
|
+
function resolveAssignments(assignments) {
|
|
2036
|
+
if (!assignments.length) return void 0;
|
|
2037
|
+
let previous = assignments[0];
|
|
2038
|
+
let expression = getAssignmentExpression(previous);
|
|
2039
|
+
let result = "";
|
|
1784
2040
|
let chainLength = 1;
|
|
1785
|
-
for (let
|
|
1786
|
-
|
|
2041
|
+
for (let index = 1, length = assignments.length; index < length; index++) {
|
|
2042
|
+
const assignment = assignments[index];
|
|
1787
2043
|
if (chainLength === MAX_ASSIGNMENT_CHAIN_LENGTH) {
|
|
1788
|
-
|
|
1789
|
-
|
|
2044
|
+
result += expression + ",";
|
|
2045
|
+
expression = getAssignmentExpression(assignment);
|
|
1790
2046
|
chainLength = 0;
|
|
1791
|
-
} else if (
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
v: getAssignmentExpression(current)
|
|
1796
|
-
};
|
|
1797
|
-
else if (item.t === 2 && prev.t === 2 && item.s === prev.s) current = {
|
|
1798
|
-
t: 2,
|
|
1799
|
-
s: getAssignmentExpression(current),
|
|
1800
|
-
k: item.k,
|
|
1801
|
-
v: item.v
|
|
1802
|
-
};
|
|
1803
|
-
else if (item.t === 1 && prev.t === 1 && item.s === prev.s) current = {
|
|
1804
|
-
t: 1,
|
|
1805
|
-
s: getAssignmentExpression(current),
|
|
1806
|
-
k: void 0,
|
|
1807
|
-
v: item.v
|
|
1808
|
-
};
|
|
1809
|
-
else if (item.t === 3 && prev.t === 2 && item.s === prev.s) current = {
|
|
1810
|
-
t: 3,
|
|
1811
|
-
s: getAssignmentExpression(current),
|
|
1812
|
-
k: item.k,
|
|
1813
|
-
v: void 0
|
|
1814
|
-
};
|
|
2047
|
+
} else if (assignment.t === 0 && previous.t === 0 && assignment.v === previous.v) expression = assignment.s + "=" + expression;
|
|
2048
|
+
else if (assignment.t === 2 && previous.t === 2 && assignment.s === previous.s) expression += ".set(" + assignment.k + "," + assignment.v + ")";
|
|
2049
|
+
else if (assignment.t === 1 && previous.t === 1 && assignment.s === previous.s) expression += ".add(" + assignment.v + ")";
|
|
2050
|
+
else if (assignment.t === 3 && previous.t === 2 && assignment.s === previous.s) expression += ".delete(" + assignment.k + ")";
|
|
1815
2051
|
else {
|
|
1816
|
-
|
|
1817
|
-
|
|
2052
|
+
result += expression + ",";
|
|
2053
|
+
expression = getAssignmentExpression(assignment);
|
|
1818
2054
|
chainLength = 0;
|
|
1819
2055
|
}
|
|
1820
2056
|
chainLength++;
|
|
1821
|
-
|
|
1822
|
-
}
|
|
1823
|
-
newAssignments.push(current);
|
|
1824
|
-
return newAssignments;
|
|
1825
|
-
}
|
|
1826
|
-
function resolveAssignments(assignments) {
|
|
1827
|
-
if (assignments.length) {
|
|
1828
|
-
let result = "";
|
|
1829
|
-
const merged = mergeAssignments(assignments);
|
|
1830
|
-
for (let i = 0, len = merged.length; i < len; i++) result += getAssignmentExpression(merged[i]) + ",";
|
|
1831
|
-
return result;
|
|
2057
|
+
previous = assignment;
|
|
1832
2058
|
}
|
|
2059
|
+
return result + expression + ",";
|
|
1833
2060
|
}
|
|
1834
2061
|
const NULL_CONSTRUCTOR = "Object.create(null)";
|
|
1835
2062
|
const SET_CONSTRUCTOR = "new Set";
|
|
@@ -1847,42 +2074,34 @@ function createBaseSerializerContext(mode, options) {
|
|
|
1847
2074
|
mode,
|
|
1848
2075
|
plugins: options.plugins,
|
|
1849
2076
|
features: options.features,
|
|
1850
|
-
marked: new Set(options.markedRefs),
|
|
2077
|
+
marked: Array.isArray(options.markedRefs) ? new Set(options.markedRefs) : options.markedRefs,
|
|
1851
2078
|
stack: [],
|
|
1852
2079
|
flags: [],
|
|
1853
|
-
assignments: []
|
|
2080
|
+
assignments: [],
|
|
2081
|
+
assignAll: mode === 2 && !options.assignSharedRefsOnly
|
|
1854
2082
|
};
|
|
1855
2083
|
}
|
|
1856
2084
|
function createVanillaSerializerState() {
|
|
1857
2085
|
return {
|
|
1858
2086
|
valid: /* @__PURE__ */ new Map(),
|
|
1859
|
-
vars: []
|
|
2087
|
+
vars: [],
|
|
2088
|
+
sentinels: /* @__PURE__ */ new Set()
|
|
1860
2089
|
};
|
|
1861
2090
|
}
|
|
1862
2091
|
function createVanillaSerializerContext(options) {
|
|
1863
2092
|
return {
|
|
1864
2093
|
mode: 1,
|
|
1865
2094
|
base: createBaseSerializerContext(1, options),
|
|
1866
|
-
state: createVanillaSerializerState()
|
|
1867
|
-
child: void 0
|
|
2095
|
+
state: createVanillaSerializerState()
|
|
1868
2096
|
};
|
|
1869
2097
|
}
|
|
1870
2098
|
function createCrossSerializerContext(options) {
|
|
1871
2099
|
return {
|
|
1872
2100
|
mode: 2,
|
|
1873
2101
|
base: createBaseSerializerContext(2, options),
|
|
1874
|
-
state: options
|
|
1875
|
-
child: void 0
|
|
2102
|
+
state: options
|
|
1876
2103
|
};
|
|
1877
2104
|
}
|
|
1878
|
-
var SerializePluginContext = class {
|
|
1879
|
-
constructor(_p) {
|
|
1880
|
-
this._p = _p;
|
|
1881
|
-
}
|
|
1882
|
-
serialize(node) {
|
|
1883
|
-
return serialize$1(this._p, node);
|
|
1884
|
-
}
|
|
1885
|
-
};
|
|
1886
2105
|
/**
|
|
1887
2106
|
* Creates the reference param (identifier) from the given reference ID
|
|
1888
2107
|
* Calling this function means the value has been referenced somewhere
|
|
@@ -1990,7 +2209,7 @@ function createArrayAssign(ctx, ref, index, value) {
|
|
|
1990
2209
|
createAssignment(ctx.base, getRefParam(ctx, ref) + "[" + index + "]", value);
|
|
1991
2210
|
}
|
|
1992
2211
|
function createObjectAssign(ctx, ref, key, value) {
|
|
1993
|
-
if (
|
|
2212
|
+
if (key === "__proto__") {
|
|
1994
2213
|
ctx.base.assignments.push({
|
|
1995
2214
|
t: 4,
|
|
1996
2215
|
s: getRefParam(ctx, ref),
|
|
@@ -2008,6 +2227,15 @@ function createSequenceAssign(ctx, ref, index, value) {
|
|
|
2008
2227
|
* Checks if the value is in the stack. Stack here is a reference
|
|
2009
2228
|
* structure to know if a object is to be accessed in a TDZ.
|
|
2010
2229
|
*/
|
|
2230
|
+
function getKeyKind(key) {
|
|
2231
|
+
const first = key.charCodeAt(0);
|
|
2232
|
+
if (first >= 48 && first <= 57) {
|
|
2233
|
+
const check = Number(key);
|
|
2234
|
+
return check >= 0 && check.toString() === key ? 2 : 0;
|
|
2235
|
+
}
|
|
2236
|
+
if (key === "Infinity") return 2;
|
|
2237
|
+
return isValidIdentifier(key) ? 1 : 0;
|
|
2238
|
+
}
|
|
2011
2239
|
function isIndexedValueInStack(ctx, node) {
|
|
2012
2240
|
return node.t === 4 && ctx.stack.includes(node.i);
|
|
2013
2241
|
}
|
|
@@ -2034,7 +2262,7 @@ function hasMarkedNode(ctx, node) {
|
|
|
2034
2262
|
* it.
|
|
2035
2263
|
*/
|
|
2036
2264
|
function assignIndexedValue(ctx, index, value) {
|
|
2037
|
-
if (ctx.
|
|
2265
|
+
if (!ctx.base.assignAll && !isSerializerRefMarked(ctx.base, index)) return value;
|
|
2038
2266
|
/**
|
|
2039
2267
|
* In cross-reference, we have to assume that
|
|
2040
2268
|
* every reference are going to be referenced
|
|
@@ -2042,12 +2270,13 @@ function assignIndexedValue(ctx, index, value) {
|
|
|
2042
2270
|
* all of it into the reference array.
|
|
2043
2271
|
*
|
|
2044
2272
|
* otherwise in vanilla, we only do this if it
|
|
2045
|
-
* is actually referenced
|
|
2273
|
+
* is actually referenced. `assignSharedRefsOnly` gives cross-reference
|
|
2274
|
+
* output the vanilla behavior.
|
|
2046
2275
|
*/
|
|
2047
2276
|
return getRefParam(ctx, index) + "=" + value;
|
|
2048
2277
|
}
|
|
2049
2278
|
function serializeReference(node) {
|
|
2050
|
-
return "
|
|
2279
|
+
return REFERENCES_KEY + ".get(\"" + node.s + "\")";
|
|
2051
2280
|
}
|
|
2052
2281
|
function serializeArrayItem(ctx, id, item, index) {
|
|
2053
2282
|
if (item) {
|
|
@@ -2081,16 +2310,15 @@ function serializeArray(ctx, node) {
|
|
|
2081
2310
|
}
|
|
2082
2311
|
function serializeProperty(ctx, source, key, val) {
|
|
2083
2312
|
if (typeof key === "string") {
|
|
2084
|
-
const
|
|
2085
|
-
const isIdentifier = check >= 0 && check.toString() === key || isValidIdentifier(key);
|
|
2313
|
+
const kind = getKeyKind(key);
|
|
2086
2314
|
if (isIndexedValueInStack(ctx.base, val)) {
|
|
2087
2315
|
const refParam = getRefParam(ctx, val.i);
|
|
2088
2316
|
markSerializerRef(ctx.base, source.i);
|
|
2089
|
-
if (
|
|
2090
|
-
else createArrayAssign(ctx, source.i,
|
|
2317
|
+
if (kind === 1) createObjectAssign(ctx, source.i, key, refParam);
|
|
2318
|
+
else createArrayAssign(ctx, source.i, kind === 2 ? key : "\"" + key + "\"", refParam);
|
|
2091
2319
|
return "";
|
|
2092
2320
|
}
|
|
2093
|
-
if (
|
|
2321
|
+
if (key !== "__proto__") return (kind === 0 ? "\"" + key + "\"" : key) + ":" + serialize$1(ctx, val);
|
|
2094
2322
|
return "[\"" + key + "\"]:" + serialize$1(ctx, val);
|
|
2095
2323
|
}
|
|
2096
2324
|
return "[" + serialize$1(ctx, key) + "]:" + serialize$1(ctx, val);
|
|
@@ -2102,7 +2330,7 @@ function serializeProperties(ctx, source, record) {
|
|
|
2102
2330
|
const values = record.v;
|
|
2103
2331
|
ctx.base.stack.push(source.i);
|
|
2104
2332
|
let result = serializeProperty(ctx, source, keys[0], values[0]);
|
|
2105
|
-
for (let i = 1, item
|
|
2333
|
+
for (let i = 1, item; i < len; i++) {
|
|
2106
2334
|
item = serializeProperty(ctx, source, keys[i], values[i]);
|
|
2107
2335
|
result += (item && result && ",") + item;
|
|
2108
2336
|
}
|
|
@@ -2123,18 +2351,14 @@ function serializeWithObjectAssign(ctx, source, value, serialized) {
|
|
|
2123
2351
|
function serializeStringKeyAssignment(ctx, source, mainAssignments, key, value) {
|
|
2124
2352
|
const base = ctx.base;
|
|
2125
2353
|
const serialized = serialize$1(ctx, value);
|
|
2126
|
-
const
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
|
|
2135
|
-
else createArrayAssign(ctx, source.i, isIdentifier ? key : "\"" + key + "\"", serialized);
|
|
2136
|
-
base.assignments = parentAssignment;
|
|
2137
|
-
}
|
|
2354
|
+
const parentAssignment = base.assignments;
|
|
2355
|
+
if (!isIndexedValueInStack(base, value)) base.assignments = mainAssignments;
|
|
2356
|
+
createKeyAssign(ctx, source.i, getKeyKind(key), key, serialized);
|
|
2357
|
+
base.assignments = parentAssignment;
|
|
2358
|
+
}
|
|
2359
|
+
function createKeyAssign(ctx, ref, kind, key, value) {
|
|
2360
|
+
if (kind === 1) createObjectAssign(ctx, ref, key, value);
|
|
2361
|
+
else createArrayAssign(ctx, ref, kind === 2 ? key : "\"" + key + "\"", value);
|
|
2138
2362
|
}
|
|
2139
2363
|
function serializeAssignment(ctx, source, mainAssignments, key, value) {
|
|
2140
2364
|
if (typeof key === "string") serializeStringKeyAssignment(ctx, source, mainAssignments, key, value);
|
|
@@ -2165,7 +2389,7 @@ function serializeAssignments(ctx, source, node) {
|
|
|
2165
2389
|
function serializeDictionary(ctx, node, init) {
|
|
2166
2390
|
if (node.p) {
|
|
2167
2391
|
const base = ctx.base;
|
|
2168
|
-
if (base.features & 8) init = serializeWithObjectAssign(ctx, node, node.p, init);
|
|
2392
|
+
if (base.features & 8 && !node.p.k.includes("__proto__")) init = serializeWithObjectAssign(ctx, node, node.p, init);
|
|
2169
2393
|
else {
|
|
2170
2394
|
markSerializerRef(base, node.i);
|
|
2171
2395
|
const assignments = serializeAssignments(ctx, node, node.p);
|
|
@@ -2181,18 +2405,8 @@ function serializeNullConstructor(ctx, node) {
|
|
|
2181
2405
|
function serializeDate(node) {
|
|
2182
2406
|
return "new Date(\"" + node.s + "\")";
|
|
2183
2407
|
}
|
|
2184
|
-
const TEMPORAL_CONSTRUCTOR = {
|
|
2185
|
-
[0]: "Temporal.Instant",
|
|
2186
|
-
[1]: "Temporal.Duration",
|
|
2187
|
-
[2]: "Temporal.PlainDate",
|
|
2188
|
-
[3]: "Temporal.PlainDateTime",
|
|
2189
|
-
[4]: "Temporal.PlainMonthDay",
|
|
2190
|
-
[5]: "Temporal.PlainTime",
|
|
2191
|
-
[6]: "Temporal.PlainYearMonth",
|
|
2192
|
-
[7]: "Temporal.ZonedDateTime"
|
|
2193
|
-
};
|
|
2194
2408
|
function serializeTemporal(ctx, node) {
|
|
2195
|
-
if (ctx.base.features & 64) return
|
|
2409
|
+
if (ctx.base.features & 64) return "Temporal." + TEMPORAL_TYPE_NAME[node.c] + ".from(\"" + node.s + "\")";
|
|
2196
2410
|
throw new SerovalUnsupportedNodeError(node);
|
|
2197
2411
|
}
|
|
2198
2412
|
function serializeRegExp(ctx, node) {
|
|
@@ -2219,7 +2433,7 @@ function serializeSet(ctx, node) {
|
|
|
2219
2433
|
if (size > 0) {
|
|
2220
2434
|
ctx.base.stack.push(id);
|
|
2221
2435
|
let result = serializeSetItem(ctx, id, items[0]);
|
|
2222
|
-
for (let i = 1, item
|
|
2436
|
+
for (let i = 1, item; i < size; i++) {
|
|
2223
2437
|
item = serializeSetItem(ctx, id, items[i]);
|
|
2224
2438
|
result += (item && result && ",") + item;
|
|
2225
2439
|
}
|
|
@@ -2228,7 +2442,7 @@ function serializeSet(ctx, node) {
|
|
|
2228
2442
|
}
|
|
2229
2443
|
return serialized;
|
|
2230
2444
|
}
|
|
2231
|
-
function serializeMapEntry(ctx, id, key, val,
|
|
2445
|
+
function serializeMapEntry(ctx, id, key, val, getSentinel) {
|
|
2232
2446
|
const base = ctx.base;
|
|
2233
2447
|
if (isIndexedValueInStack(base, key)) {
|
|
2234
2448
|
const keyRef = getRefParam(ctx, key.i);
|
|
@@ -2239,6 +2453,7 @@ function serializeMapEntry(ctx, id, key, val, sentinel) {
|
|
|
2239
2453
|
}
|
|
2240
2454
|
if (val.t !== 4 && val.i != null && hasMarkedNode(base, val)) {
|
|
2241
2455
|
markSerializerRef(base, val.i);
|
|
2456
|
+
const sentinel = getSentinel();
|
|
2242
2457
|
const serialized = "(" + serialize$1(ctx, val) + ",[" + sentinel + "," + sentinel + "])";
|
|
2243
2458
|
createSetAssignment(ctx, id, keyRef, getRefParam(ctx, val.i));
|
|
2244
2459
|
createDeleteAssignment(ctx, id, sentinel);
|
|
@@ -2255,6 +2470,7 @@ function serializeMapEntry(ctx, id, key, val, sentinel) {
|
|
|
2255
2470
|
markSerializerRef(base, id);
|
|
2256
2471
|
if (key.t !== 4 && key.i != null && hasMarkedNode(base, key)) {
|
|
2257
2472
|
markSerializerRef(base, key.i);
|
|
2473
|
+
const sentinel = getSentinel();
|
|
2258
2474
|
const serialized = "(" + serialize$1(ctx, key) + ",[" + sentinel + "," + sentinel + "])";
|
|
2259
2475
|
createSetAssignment(ctx, id, getRefParam(ctx, key.i), valueRef);
|
|
2260
2476
|
createDeleteAssignment(ctx, id, sentinel);
|
|
@@ -2274,20 +2490,27 @@ function serializeMap(ctx, node) {
|
|
|
2274
2490
|
const size = keys.length;
|
|
2275
2491
|
const id = node.i;
|
|
2276
2492
|
const sentinel = node.f;
|
|
2277
|
-
|
|
2493
|
+
let sentinelRef;
|
|
2494
|
+
const getSentinel = () => {
|
|
2495
|
+
if (sentinelRef == null) {
|
|
2496
|
+
sentinelRef = getRefParam(ctx, sentinel.i);
|
|
2497
|
+
if (ctx.mode === 1) ctx.state.sentinels.add(ctx.state.valid.get(sentinel.i));
|
|
2498
|
+
}
|
|
2499
|
+
return sentinelRef;
|
|
2500
|
+
};
|
|
2278
2501
|
const base = ctx.base;
|
|
2279
2502
|
if (size > 0) {
|
|
2280
2503
|
const vals = node.e.v;
|
|
2281
2504
|
base.stack.push(id);
|
|
2282
|
-
let result = serializeMapEntry(ctx, id, keys[0], vals[0],
|
|
2283
|
-
for (let i = 1, item
|
|
2284
|
-
item = serializeMapEntry(ctx, id, keys[i], vals[i],
|
|
2505
|
+
let result = serializeMapEntry(ctx, id, keys[0], vals[0], getSentinel);
|
|
2506
|
+
for (let i = 1, item; i < size; i++) {
|
|
2507
|
+
item = serializeMapEntry(ctx, id, keys[i], vals[i], getSentinel);
|
|
2285
2508
|
result += (item && result && ",") + item;
|
|
2286
2509
|
}
|
|
2287
2510
|
base.stack.pop();
|
|
2288
2511
|
if (result) serialized += "([" + result + "])";
|
|
2289
2512
|
}
|
|
2290
|
-
if (sentinel.t === 26) {
|
|
2513
|
+
if (ctx.mode === 2 && sentinel.t === 26) {
|
|
2291
2514
|
markSerializerRef(base, sentinel.i);
|
|
2292
2515
|
serialized = "(" + serialize$1(ctx, sentinel) + "," + serialized + ")";
|
|
2293
2516
|
}
|
|
@@ -2296,11 +2519,8 @@ function serializeMap(ctx, node) {
|
|
|
2296
2519
|
function serializeArrayBuffer(ctx, node) {
|
|
2297
2520
|
return getConstructor(ctx, node.f) + "(\"" + node.s + "\")";
|
|
2298
2521
|
}
|
|
2299
|
-
function
|
|
2300
|
-
return "new " + node.c + "(" + serialize$1(ctx, node.f) + "," + node.b + "," + node.l + ")";
|
|
2301
|
-
}
|
|
2302
|
-
function serializeDataView(ctx, node) {
|
|
2303
|
-
return "new DataView(" + serialize$1(ctx, node.f) + "," + node.b + "," + node.l + ")";
|
|
2522
|
+
function serializeView(ctx, node) {
|
|
2523
|
+
return "new " + (node.t === 20 ? "DataView" : node.c) + "(" + serialize$1(ctx, node.f) + "," + node.b + "," + node.l + ")";
|
|
2304
2524
|
}
|
|
2305
2525
|
function serializeAggregateError(ctx, node) {
|
|
2306
2526
|
const id = node.i;
|
|
@@ -2340,11 +2560,7 @@ function serializePromiseConstructor(ctx, node) {
|
|
|
2340
2560
|
if (ctx.mode === 1) throw new SerovalUnsupportedNodeError(node);
|
|
2341
2561
|
return "(" + assignIndexedValue(ctx, node.s, getConstructor(ctx, node.f) + "()") + ").p";
|
|
2342
2562
|
}
|
|
2343
|
-
function
|
|
2344
|
-
if (ctx.mode === 1) throw new SerovalUnsupportedNodeError(node);
|
|
2345
|
-
return getConstructor(ctx, node.a[0]) + "(" + getRefParam(ctx, node.i) + "," + serialize$1(ctx, node.a[1]) + ")";
|
|
2346
|
-
}
|
|
2347
|
-
function serializePromiseReject(ctx, node) {
|
|
2563
|
+
function serializePromiseResult(ctx, node) {
|
|
2348
2564
|
if (ctx.mode === 1) throw new SerovalUnsupportedNodeError(node);
|
|
2349
2565
|
return getConstructor(ctx, node.a[0]) + "(" + getRefParam(ctx, node.i) + "," + serialize$1(ctx, node.a[1]) + ")";
|
|
2350
2566
|
}
|
|
@@ -2352,10 +2568,7 @@ function serializePlugin(ctx, node) {
|
|
|
2352
2568
|
const currentPlugins = ctx.base.plugins;
|
|
2353
2569
|
if (currentPlugins) for (let i = 0, len = currentPlugins.length; i < len; i++) {
|
|
2354
2570
|
const plugin = currentPlugins[i];
|
|
2355
|
-
if (plugin.tag === node.c) {
|
|
2356
|
-
if (ctx.child == null) ctx.child = new SerializePluginContext(ctx);
|
|
2357
|
-
return plugin.serialize(node.s, ctx.child, { id: node.i });
|
|
2358
|
-
}
|
|
2571
|
+
if (plugin.tag === node.c) return plugin.serialize(node.s, { serialize: (current) => serialize$1(ctx, current) }, { id: node.i });
|
|
2359
2572
|
}
|
|
2360
2573
|
throw new SerovalMissingPluginError(node.c);
|
|
2361
2574
|
}
|
|
@@ -2392,11 +2605,8 @@ function serializeAsyncIteratorFactory(ctx, node) {
|
|
|
2392
2605
|
if (result) return result + iterator + ")";
|
|
2393
2606
|
return iterator;
|
|
2394
2607
|
}
|
|
2395
|
-
function serializeAsyncIteratorFactoryInstance(ctx, node) {
|
|
2396
|
-
return getConstructor(ctx, node.a[0]) + "(" + serialize$1(ctx, node.a[1]) + ")";
|
|
2397
|
-
}
|
|
2398
2608
|
function serializeStreamConstructor(ctx, node) {
|
|
2399
|
-
const result = assignIndexedValue(ctx, node.i, getConstructor(ctx, node.f) + "()");
|
|
2609
|
+
const result = assignIndexedValue(ctx, node.i, getConstructor(ctx, node.f) + (node.l === 1 ? "(1)" : "()"));
|
|
2400
2610
|
const len = node.a.length;
|
|
2401
2611
|
if (len) {
|
|
2402
2612
|
let values = serialize$1(ctx, node.a[0]);
|
|
@@ -2405,14 +2615,8 @@ function serializeStreamConstructor(ctx, node) {
|
|
|
2405
2615
|
}
|
|
2406
2616
|
return result;
|
|
2407
2617
|
}
|
|
2408
|
-
function
|
|
2409
|
-
return getRefParam(ctx, node.i) + ".
|
|
2410
|
-
}
|
|
2411
|
-
function serializeStreamThrow(ctx, node) {
|
|
2412
|
-
return getRefParam(ctx, node.i) + ".throw(" + serialize$1(ctx, node.f) + ")";
|
|
2413
|
-
}
|
|
2414
|
-
function serializeStreamReturn(ctx, node) {
|
|
2415
|
-
return getRefParam(ctx, node.i) + ".return(" + serialize$1(ctx, node.f) + ")";
|
|
2618
|
+
function serializeStreamCall(ctx, node, method) {
|
|
2619
|
+
return getRefParam(ctx, node.i) + "." + method + "(" + serialize$1(ctx, node.f) + ")";
|
|
2416
2620
|
}
|
|
2417
2621
|
function serializeSequenceItem(ctx, id, index, item) {
|
|
2418
2622
|
const base = ctx.base;
|
|
@@ -2430,7 +2634,7 @@ function serializeSequence(ctx, node) {
|
|
|
2430
2634
|
if (size > 0) {
|
|
2431
2635
|
ctx.base.stack.push(id);
|
|
2432
2636
|
let result = serializeSequenceItem(ctx, id, 0, items[0]);
|
|
2433
|
-
for (let i = 1, item
|
|
2637
|
+
for (let i = 1, item; i < size; i++) {
|
|
2434
2638
|
item = serializeSequenceItem(ctx, id, i, items[i]);
|
|
2435
2639
|
result += (item && result && ",") + item;
|
|
2436
2640
|
}
|
|
@@ -2452,8 +2656,8 @@ function serializeAssignable(ctx, node) {
|
|
|
2452
2656
|
case 8: return serializeMap(ctx, node);
|
|
2453
2657
|
case 19: return serializeArrayBuffer(ctx, node);
|
|
2454
2658
|
case 16:
|
|
2455
|
-
case 15:
|
|
2456
|
-
case 20: return
|
|
2659
|
+
case 15:
|
|
2660
|
+
case 20: return serializeView(ctx, node);
|
|
2457
2661
|
case 14: return serializeAggregateError(ctx, node);
|
|
2458
2662
|
case 13: return serializeError(ctx, node);
|
|
2459
2663
|
case 12: return serializePromise(ctx, node);
|
|
@@ -2473,20 +2677,20 @@ function serialize$1(ctx, node) {
|
|
|
2473
2677
|
case 1: return "\"" + node.s + "\"";
|
|
2474
2678
|
case 3: return node.s + "n";
|
|
2475
2679
|
case 4: return getRefParam(ctx, node.i);
|
|
2476
|
-
case 23:
|
|
2477
|
-
case 24: return
|
|
2680
|
+
case 23:
|
|
2681
|
+
case 24: return serializePromiseResult(ctx, node);
|
|
2478
2682
|
case 27: return serializeIteratorFactory(ctx, node);
|
|
2479
|
-
case 28:
|
|
2683
|
+
case 28:
|
|
2684
|
+
case 30: return serializeIteratorFactoryInstance(ctx, node);
|
|
2480
2685
|
case 29: return serializeAsyncIteratorFactory(ctx, node);
|
|
2481
|
-
case 30: return serializeAsyncIteratorFactoryInstance(ctx, node);
|
|
2482
2686
|
case 31: return serializeStreamConstructor(ctx, node);
|
|
2483
|
-
case 32: return
|
|
2484
|
-
case 33: return
|
|
2485
|
-
case 34: return
|
|
2687
|
+
case 32: return serializeStreamCall(ctx, node, "next");
|
|
2688
|
+
case 33: return serializeStreamCall(ctx, node, "throw");
|
|
2689
|
+
case 34: return serializeStreamCall(ctx, node, "return");
|
|
2486
2690
|
default: return assignIndexedValue(ctx, node.i, serializeAssignable(ctx, node));
|
|
2487
2691
|
}
|
|
2488
2692
|
}
|
|
2489
|
-
function
|
|
2693
|
+
function serializeVanilla(ctx, tree) {
|
|
2490
2694
|
const result = serialize$1(ctx, tree);
|
|
2491
2695
|
if (tree.i != null && ctx.state.vars.length) {
|
|
2492
2696
|
const patches = resolvePatches(ctx.base);
|
|
@@ -2497,12 +2701,18 @@ function serializeTopVanilla(ctx, tree) {
|
|
|
2497
2701
|
if (!result.startsWith(index + "=")) body = index + "=" + body;
|
|
2498
2702
|
body = "(" + body + ")";
|
|
2499
2703
|
}
|
|
2704
|
+
const sentinels = ctx.state.sentinels;
|
|
2705
|
+
if (sentinels.size) {
|
|
2706
|
+
let declarations = "";
|
|
2707
|
+
for (const index of sentinels) declarations += ctx.state.vars[index] + "=[],";
|
|
2708
|
+
body = "(" + declarations + body + ")";
|
|
2709
|
+
}
|
|
2500
2710
|
return "(" + createFunction(ctx.state.vars, body) + ")()";
|
|
2501
2711
|
}
|
|
2502
2712
|
if (tree.t === 10) return "(" + result + ")";
|
|
2503
2713
|
return result;
|
|
2504
2714
|
}
|
|
2505
|
-
function
|
|
2715
|
+
function serializeCross(ctx, tree) {
|
|
2506
2716
|
const result = serialize$1(ctx, tree);
|
|
2507
2717
|
const id = tree.i;
|
|
2508
2718
|
if (id == null) return result;
|
|
@@ -2510,7 +2720,11 @@ function serializeTopCross(ctx, tree) {
|
|
|
2510
2720
|
const ref = getRefParam(ctx, id);
|
|
2511
2721
|
const scopeId = ctx.state.scopeId;
|
|
2512
2722
|
const params = scopeId == null ? "" : "$R";
|
|
2513
|
-
|
|
2723
|
+
let body = result;
|
|
2724
|
+
if (patches) {
|
|
2725
|
+
if (!ctx.base.assignAll && !result.startsWith(ref + "=")) body = ref + "=" + result;
|
|
2726
|
+
body = "(" + body + "," + patches + ref + ")";
|
|
2727
|
+
}
|
|
2514
2728
|
if (params === "") {
|
|
2515
2729
|
if (tree.t === 10 && !patches) return "(" + body + ")";
|
|
2516
2730
|
return body;
|
|
@@ -2518,76 +2732,35 @@ function serializeTopCross(ctx, tree) {
|
|
|
2518
2732
|
const args = scopeId == null ? "()" : "($R[\"" + serializeString(scopeId) + "\"])";
|
|
2519
2733
|
return "(" + createFunction([params], body) + ")" + args;
|
|
2520
2734
|
}
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
function createSyncParserContext(mode, options) {
|
|
2524
|
-
return {
|
|
2525
|
-
type: 1,
|
|
2526
|
-
base: createBaseParserContext(mode, options),
|
|
2527
|
-
child: void 0
|
|
2528
|
-
};
|
|
2735
|
+
function wrapSerializationError(error) {
|
|
2736
|
+
return error instanceof SerovalSerializationError ? error : new SerovalSerializationError(error);
|
|
2529
2737
|
}
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
parse(current) {
|
|
2536
|
-
return parseSOS(this._p, this.depth, current);
|
|
2537
|
-
}
|
|
2538
|
-
};
|
|
2539
|
-
var StreamParsePluginContext = class {
|
|
2540
|
-
constructor(_p, depth) {
|
|
2541
|
-
this._p = _p;
|
|
2542
|
-
this.depth = depth;
|
|
2543
|
-
}
|
|
2544
|
-
parse(current) {
|
|
2545
|
-
return parseSOS(this._p, this.depth, current);
|
|
2546
|
-
}
|
|
2547
|
-
parseWithError(current) {
|
|
2548
|
-
return parseWithError(this._p, this.depth, current);
|
|
2549
|
-
}
|
|
2550
|
-
isAlive() {
|
|
2551
|
-
return this._p.state.alive;
|
|
2552
|
-
}
|
|
2553
|
-
pushPendingState() {
|
|
2554
|
-
pushPendingState(this._p);
|
|
2555
|
-
}
|
|
2556
|
-
popPendingState() {
|
|
2557
|
-
popPendingState(this._p);
|
|
2558
|
-
}
|
|
2559
|
-
onParse(node) {
|
|
2560
|
-
onParse(this._p, node);
|
|
2561
|
-
}
|
|
2562
|
-
onError(error) {
|
|
2563
|
-
onError(this._p, error);
|
|
2738
|
+
function serializeTopVanilla(ctx, tree) {
|
|
2739
|
+
try {
|
|
2740
|
+
return serializeVanilla(ctx, tree);
|
|
2741
|
+
} catch (error) {
|
|
2742
|
+
throw wrapSerializationError(error);
|
|
2564
2743
|
}
|
|
2565
|
-
|
|
2566
|
-
|
|
2744
|
+
}
|
|
2745
|
+
function serializeTopCross(ctx, tree) {
|
|
2746
|
+
try {
|
|
2747
|
+
return serializeCross(ctx, tree);
|
|
2748
|
+
} catch (error) {
|
|
2749
|
+
throw wrapSerializationError(error);
|
|
2567
2750
|
}
|
|
2568
|
-
};
|
|
2569
|
-
function createStreamParserState(options) {
|
|
2570
|
-
return {
|
|
2571
|
-
alive: true,
|
|
2572
|
-
pending: 0,
|
|
2573
|
-
initial: true,
|
|
2574
|
-
buffer: [],
|
|
2575
|
-
onParse: options.onParse,
|
|
2576
|
-
onError: options.onError,
|
|
2577
|
-
onDone: options.onDone,
|
|
2578
|
-
cleanups: []
|
|
2579
|
-
};
|
|
2580
2751
|
}
|
|
2581
|
-
|
|
2752
|
+
//#endregion
|
|
2753
|
+
//#region src/core/context/sync-parser.ts
|
|
2754
|
+
function createSyncParserContext(options) {
|
|
2582
2755
|
return {
|
|
2583
|
-
type:
|
|
2584
|
-
base: createBaseParserContext(
|
|
2585
|
-
state: createStreamParserState(options)
|
|
2756
|
+
type: 1,
|
|
2757
|
+
base: createBaseParserContext(options)
|
|
2586
2758
|
};
|
|
2587
2759
|
}
|
|
2588
2760
|
function parseItems(ctx, depth, current) {
|
|
2589
|
-
const
|
|
2590
|
-
|
|
2761
|
+
const len = current.length;
|
|
2762
|
+
const nodes = new Array(len);
|
|
2763
|
+
for (let i = 0; i < len; i++) if (i in current) nodes[i] = parseSOS(ctx, depth, current[i]);
|
|
2591
2764
|
else nodes[i] = 0;
|
|
2592
2765
|
return nodes;
|
|
2593
2766
|
}
|
|
@@ -2595,20 +2768,22 @@ function parseArray(ctx, depth, id, current) {
|
|
|
2595
2768
|
return createArrayNode(id, current, parseItems(ctx, depth, current));
|
|
2596
2769
|
}
|
|
2597
2770
|
function parseProperties(ctx, depth, properties) {
|
|
2598
|
-
const
|
|
2599
|
-
const
|
|
2600
|
-
const
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2771
|
+
const keys = Object.keys(properties);
|
|
2772
|
+
const len = keys.length;
|
|
2773
|
+
const keyNodes = new Array(len);
|
|
2774
|
+
const valueNodes = new Array(len);
|
|
2775
|
+
for (let i = 0, key; i < len; i++) {
|
|
2776
|
+
key = keys[i];
|
|
2777
|
+
keyNodes[i] = serializeString(key);
|
|
2778
|
+
valueNodes[i] = parseSOS(ctx, depth, properties[key]);
|
|
2604
2779
|
}
|
|
2605
2780
|
if (SYM_ITERATOR in properties) {
|
|
2606
2781
|
keyNodes.push(parseWellKnownSymbol(ctx.base, SYM_ITERATOR));
|
|
2607
|
-
valueNodes.push(createIteratorFactoryInstanceNode(parseIteratorFactory(ctx.base), parseSOS(ctx, depth, createSequenceFromIterable(properties))));
|
|
2782
|
+
valueNodes.push(createIteratorFactoryInstanceNode(28, parseIteratorFactory(ctx.base), parseSOS(ctx, depth, createSequenceFromIterable(properties))));
|
|
2608
2783
|
}
|
|
2609
2784
|
if (SYM_ASYNC_ITERATOR in properties) {
|
|
2610
2785
|
keyNodes.push(parseWellKnownSymbol(ctx.base, SYM_ASYNC_ITERATOR));
|
|
2611
|
-
valueNodes.push(
|
|
2786
|
+
valueNodes.push(createIteratorFactoryInstanceNode(30, parseAsyncIteratorFactory(ctx.base), parseAsyncIterable(ctx, depth, properties)));
|
|
2612
2787
|
}
|
|
2613
2788
|
if (SYM_TO_STRING_TAG in properties) {
|
|
2614
2789
|
keyNodes.push(parseWellKnownSymbol(ctx.base, SYM_TO_STRING_TAG));
|
|
@@ -2623,188 +2798,111 @@ function parseProperties(ctx, depth, properties) {
|
|
|
2623
2798
|
v: valueNodes
|
|
2624
2799
|
};
|
|
2625
2800
|
}
|
|
2801
|
+
function parseAsyncIterable(ctx, depth, current) {
|
|
2802
|
+
const id = createIndexForValue(ctx.base, {});
|
|
2803
|
+
const result = createStreamConstructorNode(id, parseSpecialReference(ctx.base, 4), []);
|
|
2804
|
+
if (ctx.type === 2) ctx.state.iterable(ctx, depth, id, current);
|
|
2805
|
+
return result;
|
|
2806
|
+
}
|
|
2626
2807
|
function parsePlainObject(ctx, depth, id, current, empty) {
|
|
2627
2808
|
return createObjectNode(id, current, empty, parseProperties(ctx, depth, current));
|
|
2628
2809
|
}
|
|
2629
2810
|
function parseBoxed(ctx, depth, id, current) {
|
|
2630
2811
|
return createBoxedNode(id, parseSOS(ctx, depth, current.valueOf()));
|
|
2631
2812
|
}
|
|
2632
|
-
function
|
|
2813
|
+
function parseView(ctx, depth, type, id, current) {
|
|
2633
2814
|
current = getArrayBufferView(ctx.base, current);
|
|
2634
|
-
return
|
|
2815
|
+
return createViewNode(type, id, current, parseSOS(ctx, depth, current.buffer));
|
|
2635
2816
|
}
|
|
2636
|
-
function
|
|
2637
|
-
current = getArrayBufferView(ctx.base, current);
|
|
2638
|
-
return createBigIntTypedArrayNode(id, current, parseSOS(ctx, depth, current.buffer));
|
|
2639
|
-
}
|
|
2640
|
-
function parseDataView(ctx, depth, id, current) {
|
|
2641
|
-
current = getArrayBufferView(ctx.base, current);
|
|
2642
|
-
return createDataViewNode(id, current, parseSOS(ctx, depth, current.buffer));
|
|
2643
|
-
}
|
|
2644
|
-
function parseError(ctx, depth, id, current) {
|
|
2817
|
+
function parseError(ctx, depth, type, id, current) {
|
|
2645
2818
|
const options = getErrorOptions(current, ctx.base.features);
|
|
2646
|
-
return createErrorNode(id, current, options ? parseProperties(ctx, depth, options) : void 0);
|
|
2647
|
-
}
|
|
2648
|
-
function parseAggregateError(ctx, depth, id, current) {
|
|
2649
|
-
const options = getErrorOptions(current, ctx.base.features);
|
|
2650
|
-
return createAggregateErrorNode(id, current, options ? parseProperties(ctx, depth, options) : void 0);
|
|
2819
|
+
return createErrorNode(type, id, current, options ? parseProperties(ctx, depth, options) : void 0);
|
|
2651
2820
|
}
|
|
2652
2821
|
function parseMap(ctx, depth, id, current) {
|
|
2653
2822
|
const sentinel = parseMapSentinel(ctx.base);
|
|
2654
|
-
const keyNodes =
|
|
2655
|
-
const valueNodes =
|
|
2823
|
+
const keyNodes = new Array(current.size);
|
|
2824
|
+
const valueNodes = new Array(current.size);
|
|
2825
|
+
let i = 0;
|
|
2656
2826
|
for (const [key, value] of current.entries()) {
|
|
2657
|
-
keyNodes
|
|
2658
|
-
valueNodes
|
|
2827
|
+
keyNodes[i] = parseSOS(ctx, depth, key);
|
|
2828
|
+
valueNodes[i] = parseSOS(ctx, depth, value);
|
|
2829
|
+
i++;
|
|
2659
2830
|
}
|
|
2660
2831
|
return createMapNode(id, sentinel, keyNodes, valueNodes);
|
|
2661
2832
|
}
|
|
2662
2833
|
function parseSet(ctx, depth, id, current) {
|
|
2663
|
-
const items =
|
|
2664
|
-
|
|
2834
|
+
const items = new Array(current.size);
|
|
2835
|
+
let i = 0;
|
|
2836
|
+
for (const item of current.keys()) items[i++] = parseSOS(ctx, depth, item);
|
|
2665
2837
|
return createSetNode(id, items);
|
|
2666
2838
|
}
|
|
2667
2839
|
function parseStream(ctx, depth, id, current) {
|
|
2668
2840
|
const result = createStreamConstructorNode(id, parseSpecialReference(ctx.base, 4), []);
|
|
2669
|
-
if (ctx.type ===
|
|
2670
|
-
pushPendingState(ctx);
|
|
2671
|
-
current.on({
|
|
2672
|
-
next: (value) => {
|
|
2673
|
-
if (ctx.state.alive) {
|
|
2674
|
-
const parsed = parseWithError(ctx, depth, value);
|
|
2675
|
-
if (parsed) onParse(ctx, createStreamNextNode(id, parsed));
|
|
2676
|
-
}
|
|
2677
|
-
},
|
|
2678
|
-
throw: (value) => {
|
|
2679
|
-
if (ctx.state.alive) {
|
|
2680
|
-
const parsed = parseWithError(ctx, depth, value);
|
|
2681
|
-
if (parsed) onParse(ctx, createStreamThrowNode(id, parsed));
|
|
2682
|
-
}
|
|
2683
|
-
popPendingState(ctx);
|
|
2684
|
-
},
|
|
2685
|
-
return: (value) => {
|
|
2686
|
-
if (ctx.state.alive) {
|
|
2687
|
-
const parsed = parseWithError(ctx, depth, value);
|
|
2688
|
-
if (parsed) onParse(ctx, createStreamReturnNode(id, parsed));
|
|
2689
|
-
}
|
|
2690
|
-
popPendingState(ctx);
|
|
2691
|
-
}
|
|
2692
|
-
});
|
|
2841
|
+
if (ctx.type === 2) ctx.state.stream(ctx, depth, id, current);
|
|
2693
2842
|
return result;
|
|
2694
2843
|
}
|
|
2695
|
-
function
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
}
|
|
2701
|
-
}
|
|
2702
|
-
function handlePromiseFailure(id, depth, data) {
|
|
2703
|
-
if (this.state.alive) {
|
|
2704
|
-
const parsed = parseWithError(this, depth, data);
|
|
2705
|
-
if (parsed) onParse(this, createSerovalNode(24, id, void 0, void 0, void 0, void 0, void 0, [parseSpecialReference(this.base, 3), parsed], void 0, void 0, void 0, void 0));
|
|
2706
|
-
}
|
|
2707
|
-
popPendingState(this);
|
|
2844
|
+
function parseLiveStream(ctx, depth, id, current) {
|
|
2845
|
+
const stream = ctx.type === 2;
|
|
2846
|
+
const result = createStreamConstructorNode(id, parseSpecialReference(ctx.base, 4), [], stream ? 1 : void 0);
|
|
2847
|
+
if (stream) ctx.state.live(ctx, depth, id, current);
|
|
2848
|
+
return result;
|
|
2708
2849
|
}
|
|
2709
2850
|
function parsePromise(ctx, depth, id, current) {
|
|
2851
|
+
if (ctx.type !== 2) throw new SerovalUnsupportedTypeError(current);
|
|
2710
2852
|
const resolver = createIndexForValue(ctx.base, {});
|
|
2711
|
-
|
|
2712
|
-
pushPendingState(ctx);
|
|
2713
|
-
current.then(handlePromiseSuccess.bind(ctx, resolver, depth), handlePromiseFailure.bind(ctx, resolver, depth));
|
|
2714
|
-
}
|
|
2853
|
+
ctx.state.promise(ctx, resolver, depth, current);
|
|
2715
2854
|
return createPromiseConstructorNode(ctx.base, id, resolver);
|
|
2716
2855
|
}
|
|
2717
2856
|
function parsePluginSync(ctx, depth, id, current, currentPlugins) {
|
|
2718
2857
|
for (let i = 0, len = currentPlugins.length; i < len; i++) {
|
|
2719
2858
|
const plugin = currentPlugins[i];
|
|
2720
|
-
if (plugin.parse.sync && plugin.test(current)) return createPluginNode(id, plugin.tag, plugin.parse.sync(current,
|
|
2859
|
+
if (plugin.parse.sync && plugin.test(current)) return createPluginNode(id, plugin.tag, plugin.parse.sync(current, { parse: (value) => parseSOS(ctx, depth, value) }, { id }));
|
|
2721
2860
|
}
|
|
2722
2861
|
}
|
|
2723
|
-
function
|
|
2724
|
-
|
|
2725
|
-
const plugin = currentPlugins[i];
|
|
2726
|
-
if (plugin.parse.stream && plugin.test(current)) return createPluginNode(id, plugin.tag, plugin.parse.stream(current, new StreamParsePluginContext(ctx, depth), { id }));
|
|
2727
|
-
}
|
|
2728
|
-
}
|
|
2729
|
-
function parsePlugin(ctx, depth, id, current) {
|
|
2730
|
-
const currentPlugins = ctx.base.plugins;
|
|
2731
|
-
if (currentPlugins) return ctx.type === 1 ? parsePluginSync(ctx, depth, id, current, currentPlugins) : parsePluginStream(ctx, depth, id, current, currentPlugins);
|
|
2862
|
+
function parsePlugin(ctx, depth, id, current, currentPlugins) {
|
|
2863
|
+
if (currentPlugins) return ctx.type === 1 ? parsePluginSync(ctx, depth, id, current, currentPlugins) : ctx.state.plugin(ctx, depth, id, current, currentPlugins);
|
|
2732
2864
|
}
|
|
2733
2865
|
function parseSequence(ctx, depth, id, current) {
|
|
2734
|
-
const
|
|
2735
|
-
|
|
2866
|
+
const len = current.v.length;
|
|
2867
|
+
const nodes = new Array(len);
|
|
2868
|
+
for (let i = 0; i < len; i++) nodes[i] = parseSOS(ctx, depth, current.v[i]);
|
|
2736
2869
|
return createSequenceNode(id, nodes, current.t, current.d);
|
|
2737
2870
|
}
|
|
2738
2871
|
function parseObjectPhase2(ctx, depth, id, current, currentClass) {
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
case
|
|
2742
|
-
case
|
|
2743
|
-
case
|
|
2744
|
-
case
|
|
2745
|
-
case
|
|
2746
|
-
case
|
|
2747
|
-
case
|
|
2748
|
-
case
|
|
2749
|
-
case
|
|
2750
|
-
case
|
|
2751
|
-
case
|
|
2752
|
-
case
|
|
2753
|
-
case
|
|
2754
|
-
case
|
|
2755
|
-
case
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
case Uint8Array:
|
|
2759
|
-
case Uint16Array:
|
|
2760
|
-
case Uint32Array:
|
|
2761
|
-
case Uint8ClampedArray:
|
|
2762
|
-
case Float32Array:
|
|
2763
|
-
case Float64Array: return parseTypedArray(ctx, depth, id, current);
|
|
2764
|
-
case DataView: return parseDataView(ctx, depth, id, current);
|
|
2765
|
-
case Map: return parseMap(ctx, depth, id, current);
|
|
2766
|
-
case Set: return parseSet(ctx, depth, id, current);
|
|
2767
|
-
}
|
|
2768
|
-
if (currentClass === Promise || current instanceof Promise) return parsePromise(ctx, depth, id, current);
|
|
2769
|
-
const currentFeatures = ctx.base.features;
|
|
2770
|
-
if (currentFeatures & 32 && currentClass === RegExp) return createRegExpNode(id, current);
|
|
2771
|
-
if (currentFeatures & 16) switch (currentClass) {
|
|
2772
|
-
case BigInt64Array:
|
|
2773
|
-
case BigUint64Array: return parseBigIntTypedArray(ctx, depth, id, current);
|
|
2774
|
-
}
|
|
2775
|
-
if (currentFeatures & 1 && typeof AggregateError !== "undefined" && (currentClass === AggregateError || current instanceof AggregateError)) return parseAggregateError(ctx, depth, id, current);
|
|
2776
|
-
if (currentFeatures & 64 && typeof Temporal !== "undefined") switch (currentClass) {
|
|
2777
|
-
case Temporal.Instant: return createTemporalNode(id, 0, current);
|
|
2778
|
-
case Temporal.Duration: return createTemporalNode(id, 1, current);
|
|
2779
|
-
case Temporal.PlainDate: return createTemporalNode(id, 2, current);
|
|
2780
|
-
case Temporal.PlainDateTime: return createTemporalNode(id, 3, current);
|
|
2781
|
-
case Temporal.PlainMonthDay: return createTemporalNode(id, 4, current);
|
|
2782
|
-
case Temporal.PlainTime: return createTemporalNode(id, 5, current);
|
|
2783
|
-
case Temporal.PlainYearMonth: return createTemporalNode(id, 6, current);
|
|
2784
|
-
case Temporal.ZonedDateTime: return createTemporalNode(id, 7, current);
|
|
2785
|
-
}
|
|
2786
|
-
if (current instanceof Error) return parseError(ctx, depth, id, current);
|
|
2787
|
-
if (SYM_ITERATOR in current || SYM_ASYNC_ITERATOR in current) return parsePlainObject(ctx, depth, id, current, !!currentClass);
|
|
2788
|
-
throw new SerovalUnsupportedTypeError(current);
|
|
2872
|
+
if (currentClass === Object) return parsePlainObject(ctx, depth, id, current, false);
|
|
2873
|
+
switch (getObjectKind(current, currentClass, ctx.base.features)) {
|
|
2874
|
+
case 2: return parsePlainObject(ctx, depth, id, current, true);
|
|
2875
|
+
case 3: return createDateNode(id, current);
|
|
2876
|
+
case 4: return parseError(ctx, depth, 13, id, current);
|
|
2877
|
+
case 5: return parseError(ctx, depth, 14, id, current);
|
|
2878
|
+
case 6: return parseBoxed(ctx, depth, id, current);
|
|
2879
|
+
case 7: return createArrayBufferNode(ctx.base, id, current);
|
|
2880
|
+
case 8: return parseView(ctx, depth, 15, id, current);
|
|
2881
|
+
case 9: return parseView(ctx, depth, 16, id, current);
|
|
2882
|
+
case 10: return parseView(ctx, depth, 20, id, current);
|
|
2883
|
+
case 11: return parseMap(ctx, depth, id, current);
|
|
2884
|
+
case 12: return parseSet(ctx, depth, id, current);
|
|
2885
|
+
case 13: return parsePromise(ctx, depth, id, current);
|
|
2886
|
+
case 14: return createRegExpNode(id, current);
|
|
2887
|
+
case 15: return createTemporalNode(id, getTemporalType(currentClass), current);
|
|
2888
|
+
case 16: return parsePlainObject(ctx, depth, id, current, !!currentClass);
|
|
2889
|
+
default: throw new SerovalUnsupportedTypeError(current);
|
|
2890
|
+
}
|
|
2789
2891
|
}
|
|
2790
2892
|
function parseObject(ctx, depth, id, current) {
|
|
2791
2893
|
if (Array.isArray(current)) return parseArray(ctx, depth, id, current);
|
|
2792
|
-
if (isStream(current)) return parseStream(ctx, depth, id, current);
|
|
2894
|
+
if (isStream(current)) return isLiveStream(current) ? parseLiveStream(ctx, depth, id, current) : parseStream(ctx, depth, id, current);
|
|
2793
2895
|
if (isSequence(current)) return parseSequence(ctx, depth, id, current);
|
|
2794
|
-
|
|
2795
|
-
if (currentClass !== void 0 && typeof currentClass !== "function") {
|
|
2796
|
-
const proto = Object.getPrototypeOf(current);
|
|
2797
|
-
currentClass = proto === null ? void 0 : proto.constructor;
|
|
2798
|
-
}
|
|
2896
|
+
const currentClass = getObjectClass(current);
|
|
2799
2897
|
if (currentClass === OpaqueReference) return parseSOS(ctx, depth, current.replacement);
|
|
2800
|
-
const parsed = parsePlugin(ctx, depth, id, current);
|
|
2898
|
+
const parsed = parsePlugin(ctx, depth, id, current, getObjectPlugins(ctx.base, current, currentClass));
|
|
2801
2899
|
if (parsed) return parsed;
|
|
2802
2900
|
return parseObjectPhase2(ctx, depth, id, current, currentClass);
|
|
2803
2901
|
}
|
|
2804
2902
|
function parseFunction(ctx, depth, current) {
|
|
2805
2903
|
const ref = getReferenceNode(ctx.base, current);
|
|
2806
|
-
if (ref
|
|
2807
|
-
const plugin = parsePlugin(ctx, depth, ref
|
|
2904
|
+
if (typeof ref !== "number") return ref;
|
|
2905
|
+
const plugin = parsePlugin(ctx, depth, ref, current, ctx.base.plugins);
|
|
2808
2906
|
if (plugin) return plugin;
|
|
2809
2907
|
throw new SerovalUnsupportedTypeError(current);
|
|
2810
2908
|
}
|
|
@@ -2819,7 +2917,7 @@ function parseSOS(ctx, depth, current) {
|
|
|
2819
2917
|
case "object":
|
|
2820
2918
|
if (current) {
|
|
2821
2919
|
const ref = getReferenceNode(ctx.base, current);
|
|
2822
|
-
return ref
|
|
2920
|
+
return typeof ref === "number" ? parseObject(ctx, depth + 1, ref, current) : ref;
|
|
2823
2921
|
}
|
|
2824
2922
|
return NULL_NODE;
|
|
2825
2923
|
case "symbol": return parseWellKnownSymbol(ctx.base, current);
|
|
@@ -2834,63 +2932,431 @@ function parseTop(ctx, current) {
|
|
|
2834
2932
|
throw error instanceof SerovalParserError ? error : new SerovalParserError(error);
|
|
2835
2933
|
}
|
|
2836
2934
|
}
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2935
|
+
//#endregion
|
|
2936
|
+
//#region src/core/context/stream-parser.ts
|
|
2937
|
+
/**
|
|
2938
|
+
* Streaming parse mode. Everything here is reached through the function
|
|
2939
|
+
* fields of the stream parser state, which only `createStreamParserContext`
|
|
2940
|
+
* sets, so synchronous consumers (`serialize`, `toJSON`) never bundle it.
|
|
2941
|
+
*/
|
|
2942
|
+
function createStreamParsePluginContext(ctx, depth) {
|
|
2943
|
+
const state = ctx.state;
|
|
2944
|
+
function parse(current) {
|
|
2945
|
+
state.parsing++;
|
|
2946
|
+
try {
|
|
2947
|
+
return parseSOS(ctx, depth, current);
|
|
2948
|
+
} finally {
|
|
2949
|
+
state.parsing--;
|
|
2950
|
+
if (!state.alive) releaseParserValues(ctx);
|
|
2951
|
+
}
|
|
2952
|
+
}
|
|
2953
|
+
return {
|
|
2954
|
+
parse,
|
|
2955
|
+
parseStreamSource(current) {
|
|
2956
|
+
state.parsing++;
|
|
2957
|
+
try {
|
|
2958
|
+
if (depth >= ctx.base.depthLimit) throw new SerovalDepthLimitError(ctx.base.depthLimit);
|
|
2959
|
+
const id = createIndexForValue(ctx.base, {});
|
|
2960
|
+
const node = createStreamConstructorNode(id, parseSpecialReference(ctx.base, 4), [], 1);
|
|
2961
|
+
iterateAsync(ctx, depth + 1, id, current, true);
|
|
2962
|
+
return node;
|
|
2963
|
+
} finally {
|
|
2964
|
+
state.parsing--;
|
|
2965
|
+
if (!state.alive) releaseParserValues(ctx);
|
|
2966
|
+
}
|
|
2967
|
+
},
|
|
2968
|
+
parseWithError(current) {
|
|
2969
|
+
try {
|
|
2970
|
+
return parse(current);
|
|
2971
|
+
} catch (error) {
|
|
2972
|
+
stopStreamParse(ctx, 1, error);
|
|
2973
|
+
return;
|
|
2974
|
+
}
|
|
2975
|
+
},
|
|
2976
|
+
isAlive: () => state.alive,
|
|
2977
|
+
pushPendingState: () => {
|
|
2978
|
+
pushPendingState(ctx);
|
|
2979
|
+
},
|
|
2980
|
+
popPendingState: () => {
|
|
2981
|
+
popPendingState(ctx);
|
|
2982
|
+
},
|
|
2983
|
+
onParse(node) {
|
|
2984
|
+
if (state.alive) {
|
|
2985
|
+
state.queue.push({
|
|
2986
|
+
node,
|
|
2987
|
+
initial: false,
|
|
2988
|
+
accept: void 0
|
|
2989
|
+
});
|
|
2990
|
+
drainOutput(ctx);
|
|
2991
|
+
}
|
|
2992
|
+
},
|
|
2993
|
+
onError(error) {
|
|
2994
|
+
stopStreamParse(ctx, 1, error);
|
|
2995
|
+
},
|
|
2996
|
+
addCleanup(callback) {
|
|
2997
|
+
addCleanup(ctx, callback);
|
|
2998
|
+
}
|
|
2999
|
+
};
|
|
3000
|
+
}
|
|
3001
|
+
function getStreamParsePluginContext(ctx, depth) {
|
|
3002
|
+
const contexts = ctx.state.pluginContexts;
|
|
3003
|
+
return contexts[depth] ?? (contexts[depth] = createStreamParsePluginContext(ctx, depth));
|
|
3004
|
+
}
|
|
3005
|
+
function addCleanup(ctx, callback) {
|
|
3006
|
+
if (ctx.state.alive) ctx.state.cleanups.push(callback);
|
|
3007
|
+
else callback();
|
|
2840
3008
|
}
|
|
2841
|
-
function
|
|
2842
|
-
|
|
2843
|
-
|
|
3009
|
+
function parsePluginStream(ctx, depth, id, current, currentPlugins) {
|
|
3010
|
+
for (let i = 0, len = currentPlugins.length; i < len; i++) {
|
|
3011
|
+
const plugin = currentPlugins[i];
|
|
3012
|
+
if (plugin.parse.stream && plugin.test(current)) return createPluginNode(id, plugin.tag, plugin.parse.stream(current, getStreamParsePluginContext(ctx, depth), { id }));
|
|
3013
|
+
}
|
|
2844
3014
|
}
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
3015
|
+
/**
|
|
3016
|
+
* One listener shape serves both `Stream.on` (no accept) and
|
|
3017
|
+
* `LiveStream.pump` (accept tied to record acceptance). Handlers return the
|
|
3018
|
+
* parse error so the pump can stop the source.
|
|
3019
|
+
*/
|
|
3020
|
+
function streamListener(ctx, depth, id, subscription) {
|
|
3021
|
+
const handle = (type, terminal) => (value, accept) => {
|
|
3022
|
+
let failure = void 0;
|
|
3023
|
+
if (ctx.state.alive) try {
|
|
3024
|
+
failure = parseEvent(ctx, depth, value, createStreamEventNode.bind(null, type, id), accept);
|
|
3025
|
+
} catch (error) {
|
|
3026
|
+
if (!subscription?.active) throw error;
|
|
3027
|
+
subscription.failure ?? (subscription.failure = { value: error });
|
|
3028
|
+
failure = error;
|
|
3029
|
+
}
|
|
3030
|
+
if (terminal && !accept) popPendingState(ctx);
|
|
3031
|
+
return failure;
|
|
3032
|
+
};
|
|
3033
|
+
return {
|
|
3034
|
+
next: handle(32, false),
|
|
3035
|
+
throw: handle(33, true),
|
|
3036
|
+
return: handle(34, true),
|
|
3037
|
+
done() {
|
|
3038
|
+
popPendingState(ctx);
|
|
3039
|
+
},
|
|
3040
|
+
error(reason) {
|
|
3041
|
+
if (ctx.state.alive) stopStreamParse(ctx, 1, reason);
|
|
3042
|
+
}
|
|
3043
|
+
};
|
|
2848
3044
|
}
|
|
2849
|
-
function
|
|
3045
|
+
function subscribeStream(ctx, depth, id, current) {
|
|
3046
|
+
pushPendingState(ctx);
|
|
3047
|
+
const subscription = {
|
|
3048
|
+
active: true,
|
|
3049
|
+
failure: void 0
|
|
3050
|
+
};
|
|
3051
|
+
let cleanup;
|
|
3052
|
+
try {
|
|
3053
|
+
cleanup = current.on(streamListener(ctx, depth, id, subscription));
|
|
3054
|
+
} finally {
|
|
3055
|
+
subscription.active = false;
|
|
3056
|
+
}
|
|
2850
3057
|
try {
|
|
2851
|
-
ctx
|
|
3058
|
+
addCleanup(ctx, cleanup);
|
|
2852
3059
|
} catch (error) {
|
|
2853
|
-
|
|
3060
|
+
subscription.failure ?? (subscription.failure = { value: error });
|
|
2854
3061
|
}
|
|
3062
|
+
const failure = subscription.failure;
|
|
3063
|
+
subscription.failure = void 0;
|
|
3064
|
+
if (failure) throw failure.value;
|
|
3065
|
+
}
|
|
3066
|
+
function consumeLiveStream(ctx, depth, id, current) {
|
|
3067
|
+
const cancel = current.pump(streamListener(ctx, depth, id));
|
|
3068
|
+
pushPendingState(ctx);
|
|
3069
|
+
addCleanup(ctx, () => {
|
|
3070
|
+
cancel(ctx.state.reason);
|
|
3071
|
+
});
|
|
3072
|
+
}
|
|
3073
|
+
function wrapPromiseResult(ctx, type, id, node) {
|
|
3074
|
+
return createSerovalNode(type, id, void 0, void 0, void 0, void 0, void 0, [parseSpecialReference(ctx.base, type === 23 ? 2 : 3), node], void 0, void 0, void 0, void 0);
|
|
3075
|
+
}
|
|
3076
|
+
function handlePromise(type, id, depth, data) {
|
|
3077
|
+
if (this.state.alive) parseEvent(this, depth, data, wrapPromiseResult.bind(null, this, type, id), void 0);
|
|
3078
|
+
popPendingState(this);
|
|
3079
|
+
}
|
|
3080
|
+
function watchPromise(ctx, resolver, depth, current) {
|
|
3081
|
+
pushPendingState(ctx);
|
|
3082
|
+
current.then(handlePromise.bind(ctx, 23, resolver, depth), handlePromise.bind(ctx, 24, resolver, depth));
|
|
3083
|
+
}
|
|
3084
|
+
function returnIterator(iterator) {
|
|
3085
|
+
Promise.resolve().then(() => iterator.return?.()).catch(() => {});
|
|
3086
|
+
}
|
|
3087
|
+
/**
|
|
3088
|
+
* Drives an async iterator directly. The next value is pulled only after the
|
|
3089
|
+
* record for the previous one has been accepted, and cancellation returns
|
|
3090
|
+
* the iterator once.
|
|
3091
|
+
*/
|
|
3092
|
+
function iterateAsync(ctx, depth, id, current, forwardReason) {
|
|
3093
|
+
const iterator = current[SYM_ASYNC_ITERATOR]();
|
|
3094
|
+
const listener = streamListener(ctx, depth, id);
|
|
3095
|
+
let active = true;
|
|
3096
|
+
function stop() {
|
|
3097
|
+
if (active) {
|
|
3098
|
+
active = false;
|
|
3099
|
+
if (forwardReason) try {
|
|
3100
|
+
Promise.resolve(iterator.return?.(ctx.state.reason)).catch(() => {});
|
|
3101
|
+
} catch {}
|
|
3102
|
+
else returnIterator(iterator);
|
|
3103
|
+
}
|
|
3104
|
+
}
|
|
3105
|
+
function pull() {
|
|
3106
|
+
if (active) iterator.next().then((result) => {
|
|
3107
|
+
if (active) {
|
|
3108
|
+
if (result.done) {
|
|
3109
|
+
active = false;
|
|
3110
|
+
listener.return(result.value, void 0);
|
|
3111
|
+
} else if (listener.next(result.value, pull) !== void 0) {
|
|
3112
|
+
stop();
|
|
3113
|
+
listener.done();
|
|
3114
|
+
}
|
|
3115
|
+
}
|
|
3116
|
+
}, (error) => {
|
|
3117
|
+
if (active) {
|
|
3118
|
+
active = false;
|
|
3119
|
+
listener.throw(error, void 0);
|
|
3120
|
+
}
|
|
3121
|
+
});
|
|
3122
|
+
}
|
|
3123
|
+
pushPendingState(ctx);
|
|
3124
|
+
addCleanup(ctx, stop);
|
|
3125
|
+
pull();
|
|
3126
|
+
}
|
|
3127
|
+
function createStreamParserState(options) {
|
|
3128
|
+
return {
|
|
3129
|
+
alive: true,
|
|
3130
|
+
pending: 0,
|
|
3131
|
+
parsing: 0,
|
|
3132
|
+
queue: [],
|
|
3133
|
+
writing: false,
|
|
3134
|
+
inFlight: void 0,
|
|
3135
|
+
reason: void 0,
|
|
3136
|
+
onParse: options.onParse,
|
|
3137
|
+
onError: options.onError,
|
|
3138
|
+
onDone: options.onDone,
|
|
3139
|
+
cleanups: [],
|
|
3140
|
+
pluginContexts: [],
|
|
3141
|
+
stream: subscribeStream,
|
|
3142
|
+
live: consumeLiveStream,
|
|
3143
|
+
promise: watchPromise,
|
|
3144
|
+
iterable: iterateAsync,
|
|
3145
|
+
plugin: parsePluginStream
|
|
3146
|
+
};
|
|
3147
|
+
}
|
|
3148
|
+
function createStreamParserContext(options) {
|
|
3149
|
+
return {
|
|
3150
|
+
type: 2,
|
|
3151
|
+
base: createBaseParserContext(options),
|
|
3152
|
+
state: createStreamParserState(options)
|
|
3153
|
+
};
|
|
2855
3154
|
}
|
|
2856
3155
|
function pushPendingState(ctx) {
|
|
2857
|
-
ctx.state.pending++;
|
|
3156
|
+
if (ctx.state.alive) ctx.state.pending++;
|
|
2858
3157
|
}
|
|
2859
3158
|
function popPendingState(ctx) {
|
|
2860
|
-
if (
|
|
3159
|
+
if (ctx.state.alive) {
|
|
3160
|
+
ctx.state.pending--;
|
|
3161
|
+
checkStreamParse(ctx);
|
|
3162
|
+
}
|
|
2861
3163
|
}
|
|
2862
|
-
|
|
3164
|
+
/**
|
|
3165
|
+
* Parses a value that arrived after the root. Its record is queued before
|
|
3166
|
+
* parsing starts so that records discovered inside it follow it, and it is
|
|
3167
|
+
* dropped again if parsing fails. Returns the parse error after reporting
|
|
3168
|
+
* it, or `undefined`.
|
|
3169
|
+
*/
|
|
3170
|
+
function parseEvent(ctx, depth, value, wrap, accept) {
|
|
3171
|
+
const state = ctx.state;
|
|
3172
|
+
const record = {
|
|
3173
|
+
node: void 0,
|
|
3174
|
+
initial: false,
|
|
3175
|
+
accept
|
|
3176
|
+
};
|
|
3177
|
+
let failure;
|
|
3178
|
+
state.queue.push(record);
|
|
3179
|
+
state.parsing++;
|
|
2863
3180
|
try {
|
|
2864
|
-
|
|
2865
|
-
} catch (
|
|
2866
|
-
|
|
2867
|
-
|
|
3181
|
+
record.node = wrap(parseSOS(ctx, depth, value));
|
|
3182
|
+
} catch (error) {
|
|
3183
|
+
failure = { value: error };
|
|
3184
|
+
} finally {
|
|
3185
|
+
state.parsing--;
|
|
3186
|
+
if (!state.alive) releaseParserValues(ctx);
|
|
3187
|
+
}
|
|
3188
|
+
if (failure) stopStreamParse(ctx, 1, failure.value);
|
|
3189
|
+
else drainOutput(ctx);
|
|
3190
|
+
return failure?.value;
|
|
3191
|
+
}
|
|
3192
|
+
/**
|
|
3193
|
+
* Emits queued records one at a time. A callback that returns a promise
|
|
3194
|
+
* pauses emission until it settles; the source event behind the record is
|
|
3195
|
+
* accepted only after that.
|
|
3196
|
+
*/
|
|
3197
|
+
function drainOutput(ctx) {
|
|
3198
|
+
const state = ctx.state;
|
|
3199
|
+
if (state.writing || state.parsing > 0) return;
|
|
3200
|
+
while (state.alive && state.queue.length > 0) {
|
|
3201
|
+
const record = state.queue.shift();
|
|
3202
|
+
if (!record.node) continue;
|
|
3203
|
+
let pending;
|
|
3204
|
+
state.writing = true;
|
|
3205
|
+
state.inFlight = record;
|
|
3206
|
+
state.parsing++;
|
|
3207
|
+
try {
|
|
3208
|
+
if (!state.onParse) throw new Error("Stream output callback is unavailable");
|
|
3209
|
+
const result = state.onParse(record.node, record.initial);
|
|
3210
|
+
if (result !== null && (typeof result === "object" || typeof result === "function")) {
|
|
3211
|
+
const then = Reflect.get(result, "then");
|
|
3212
|
+
if (typeof then === "function") pending = new Promise((resolve, reject) => {
|
|
3213
|
+
Reflect.apply(then, result, [resolve, reject]);
|
|
3214
|
+
});
|
|
3215
|
+
}
|
|
3216
|
+
} catch (error) {
|
|
3217
|
+
releaseRecord(record);
|
|
3218
|
+
stopStreamParse(ctx, 1, error);
|
|
3219
|
+
return;
|
|
3220
|
+
} finally {
|
|
3221
|
+
state.parsing--;
|
|
3222
|
+
if (!state.alive) releaseParserValues(ctx);
|
|
3223
|
+
}
|
|
3224
|
+
record.node = void 0;
|
|
3225
|
+
if (pending) {
|
|
3226
|
+
if (!state.alive) releaseRecord(record);
|
|
3227
|
+
pending.then(() => {
|
|
3228
|
+
state.writing = false;
|
|
3229
|
+
state.inFlight = void 0;
|
|
3230
|
+
if (state.alive) {
|
|
3231
|
+
const accept = record.accept;
|
|
3232
|
+
releaseRecord(record);
|
|
3233
|
+
accept?.();
|
|
3234
|
+
drainOutput(ctx);
|
|
3235
|
+
}
|
|
3236
|
+
}, (error) => {
|
|
3237
|
+
state.writing = false;
|
|
3238
|
+
state.inFlight = void 0;
|
|
3239
|
+
releaseRecord(record);
|
|
3240
|
+
stopStreamParse(ctx, 1, error);
|
|
3241
|
+
});
|
|
3242
|
+
return;
|
|
3243
|
+
}
|
|
3244
|
+
if (!state.alive) {
|
|
3245
|
+
releaseRecord(record);
|
|
3246
|
+
return;
|
|
3247
|
+
}
|
|
3248
|
+
state.writing = false;
|
|
3249
|
+
state.inFlight = void 0;
|
|
3250
|
+
const accept = record.accept;
|
|
3251
|
+
releaseRecord(record);
|
|
3252
|
+
accept?.();
|
|
2868
3253
|
}
|
|
3254
|
+
checkStreamParse(ctx);
|
|
3255
|
+
}
|
|
3256
|
+
function checkStreamParse(ctx) {
|
|
3257
|
+
const state = ctx.state;
|
|
3258
|
+
if (state.alive && state.parsing === 0 && state.pending <= 0 && state.queue.length === 0 && !state.writing) stopStreamParse(ctx, 0);
|
|
2869
3259
|
}
|
|
2870
3260
|
function startStreamParse(ctx, current) {
|
|
2871
|
-
const
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
3261
|
+
const state = ctx.state;
|
|
3262
|
+
let parsed;
|
|
3263
|
+
let failure;
|
|
3264
|
+
state.parsing++;
|
|
3265
|
+
try {
|
|
3266
|
+
parsed = parseSOS(ctx, 0, current);
|
|
3267
|
+
} catch (error) {
|
|
3268
|
+
failure = { value: error };
|
|
3269
|
+
} finally {
|
|
3270
|
+
state.parsing--;
|
|
3271
|
+
if (!state.alive) releaseParserValues(ctx);
|
|
3272
|
+
}
|
|
3273
|
+
if (failure) {
|
|
3274
|
+
if (state.alive) stopStreamParse(ctx, 1, failure.value);
|
|
3275
|
+
else throw failure.value;
|
|
3276
|
+
} else if (parsed && state.alive) {
|
|
3277
|
+
state.queue.unshift({
|
|
3278
|
+
node: parsed,
|
|
3279
|
+
initial: true,
|
|
3280
|
+
accept: void 0
|
|
3281
|
+
});
|
|
3282
|
+
drainOutput(ctx);
|
|
3283
|
+
}
|
|
3284
|
+
}
|
|
3285
|
+
function runCleanups(state) {
|
|
3286
|
+
const cleanups = state.cleanups;
|
|
3287
|
+
let failure;
|
|
3288
|
+
state.cleanups = [];
|
|
3289
|
+
for (const record of state.queue) releaseRecord(record);
|
|
3290
|
+
state.queue.length = 0;
|
|
3291
|
+
if (state.inFlight) releaseRecord(state.inFlight);
|
|
3292
|
+
state.inFlight = void 0;
|
|
3293
|
+
for (let i = 0, len = cleanups.length; i < len; i++) try {
|
|
3294
|
+
cleanups[i]();
|
|
3295
|
+
} catch (error) {
|
|
3296
|
+
failure ?? (failure = { value: error });
|
|
2877
3297
|
}
|
|
3298
|
+
if (failure) throw failure.value;
|
|
2878
3299
|
}
|
|
2879
|
-
function
|
|
2880
|
-
|
|
3300
|
+
function releaseRecord(record) {
|
|
3301
|
+
record.node = void 0;
|
|
3302
|
+
record.accept = void 0;
|
|
2881
3303
|
}
|
|
2882
|
-
function
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
3304
|
+
function releaseParserValues(ctx) {
|
|
3305
|
+
ctx.base.refs = /* @__PURE__ */ new Map();
|
|
3306
|
+
ctx.base.marked.clear();
|
|
3307
|
+
ctx.base.plugins = void 0;
|
|
3308
|
+
ctx.base.plainObjectPlugins = void 0;
|
|
3309
|
+
ctx.state.pluginContexts = [];
|
|
3310
|
+
if (ctx.state.parsing === 0) ctx.state.reason = void 0;
|
|
3311
|
+
}
|
|
3312
|
+
/**
|
|
3313
|
+
* Ends the parse once: `onDone` on success, `onError` on failure, and every
|
|
3314
|
+
* cleanup either way.
|
|
3315
|
+
*/
|
|
3316
|
+
function stopStreamParse(ctx, mode, reason) {
|
|
3317
|
+
const state = ctx.state;
|
|
3318
|
+
if (state.alive) {
|
|
3319
|
+
state.alive = false;
|
|
3320
|
+
const onError = state.onError;
|
|
3321
|
+
const onDone = state.onDone;
|
|
3322
|
+
if (mode === 1 && !onError && !(reason instanceof SerovalParserError)) reason = new SerovalParserError(reason);
|
|
3323
|
+
state.reason = reason;
|
|
3324
|
+
state.onParse = void 0;
|
|
3325
|
+
state.onError = void 0;
|
|
3326
|
+
state.onDone = void 0;
|
|
3327
|
+
state.writing = false;
|
|
3328
|
+
state.parsing++;
|
|
3329
|
+
let failure;
|
|
3330
|
+
try {
|
|
3331
|
+
if (mode === 1) {
|
|
3332
|
+
if (onError) onError(reason);
|
|
3333
|
+
else throw reason;
|
|
3334
|
+
} else if (mode === 0) onDone?.();
|
|
3335
|
+
} catch (error) {
|
|
3336
|
+
failure = { value: error };
|
|
3337
|
+
}
|
|
3338
|
+
try {
|
|
3339
|
+
runCleanups(state);
|
|
3340
|
+
} catch (error) {
|
|
3341
|
+
failure ?? (failure = { value: error });
|
|
3342
|
+
} finally {
|
|
3343
|
+
state.parsing--;
|
|
3344
|
+
releaseParserValues(ctx);
|
|
3345
|
+
state.pending = 0;
|
|
3346
|
+
}
|
|
3347
|
+
if (failure) throw failure.value;
|
|
2886
3348
|
}
|
|
2887
3349
|
}
|
|
3350
|
+
function destroyStreamParse(ctx, reason) {
|
|
3351
|
+
stopStreamParse(ctx, 2, reason);
|
|
3352
|
+
}
|
|
2888
3353
|
//#endregion
|
|
2889
3354
|
//#region src/core/cross/index.ts
|
|
2890
3355
|
function crossSerialize(source, options = {}) {
|
|
2891
3356
|
const plugins = resolvePlugins(options.plugins);
|
|
2892
|
-
const ctx = createSyncParserContext(
|
|
3357
|
+
const ctx = createSyncParserContext({
|
|
2893
3358
|
compactArrayBufferViews: options.compactArrayBufferViews,
|
|
3359
|
+
depthLimit: options.depthLimit,
|
|
2894
3360
|
plugins,
|
|
2895
3361
|
disabledFeatures: options.disabledFeatures,
|
|
2896
3362
|
refs: options.refs
|
|
@@ -2900,13 +3366,15 @@ function crossSerialize(source, options = {}) {
|
|
|
2900
3366
|
plugins,
|
|
2901
3367
|
features: ctx.base.features,
|
|
2902
3368
|
scopeId: options.scopeId,
|
|
2903
|
-
markedRefs: ctx.base.marked
|
|
3369
|
+
markedRefs: ctx.base.marked,
|
|
3370
|
+
assignSharedRefsOnly: options.assignSharedRefsOnly
|
|
2904
3371
|
}), tree);
|
|
2905
3372
|
}
|
|
2906
3373
|
async function crossSerializeAsync(source, options = {}) {
|
|
2907
3374
|
const plugins = resolvePlugins(options.plugins);
|
|
2908
|
-
const ctx = createAsyncParserContext(
|
|
3375
|
+
const ctx = createAsyncParserContext({
|
|
2909
3376
|
compactArrayBufferViews: options.compactArrayBufferViews,
|
|
3377
|
+
depthLimit: options.depthLimit,
|
|
2910
3378
|
plugins,
|
|
2911
3379
|
disabledFeatures: options.disabledFeatures,
|
|
2912
3380
|
refs: options.refs
|
|
@@ -2916,13 +3384,15 @@ async function crossSerializeAsync(source, options = {}) {
|
|
|
2916
3384
|
plugins,
|
|
2917
3385
|
features: ctx.base.features,
|
|
2918
3386
|
scopeId: options.scopeId,
|
|
2919
|
-
markedRefs: ctx.base.marked
|
|
3387
|
+
markedRefs: ctx.base.marked,
|
|
3388
|
+
assignSharedRefsOnly: options.assignSharedRefsOnly
|
|
2920
3389
|
}), tree);
|
|
2921
3390
|
}
|
|
2922
3391
|
function toCrossJSON(source, options = {}) {
|
|
2923
3392
|
const plugins = resolvePlugins(options.plugins);
|
|
2924
|
-
return parseTop(createSyncParserContext(
|
|
3393
|
+
return parseTop(createSyncParserContext({
|
|
2925
3394
|
compactArrayBufferViews: options.compactArrayBufferViews,
|
|
3395
|
+
depthLimit: options.depthLimit,
|
|
2926
3396
|
plugins,
|
|
2927
3397
|
disabledFeatures: options.disabledFeatures,
|
|
2928
3398
|
refs: options.refs
|
|
@@ -2930,8 +3400,9 @@ function toCrossJSON(source, options = {}) {
|
|
|
2930
3400
|
}
|
|
2931
3401
|
async function toCrossJSONAsync(source, options = {}) {
|
|
2932
3402
|
const plugins = resolvePlugins(options.plugins);
|
|
2933
|
-
return await parseTopAsync(createAsyncParserContext(
|
|
3403
|
+
return await parseTopAsync(createAsyncParserContext({
|
|
2934
3404
|
compactArrayBufferViews: options.compactArrayBufferViews,
|
|
3405
|
+
depthLimit: options.depthLimit,
|
|
2935
3406
|
plugins,
|
|
2936
3407
|
disabledFeatures: options.disabledFeatures,
|
|
2937
3408
|
refs: options.refs
|
|
@@ -2939,8 +3410,11 @@ async function toCrossJSONAsync(source, options = {}) {
|
|
|
2939
3410
|
}
|
|
2940
3411
|
function crossSerializeStream(source, options) {
|
|
2941
3412
|
const plugins = resolvePlugins(options.plugins);
|
|
3413
|
+
const onSerialize = options.onSerialize;
|
|
3414
|
+
const scopeId = options.scopeId;
|
|
2942
3415
|
const ctx = createStreamParserContext({
|
|
2943
3416
|
compactArrayBufferViews: options.compactArrayBufferViews,
|
|
3417
|
+
depthLimit: options.depthLimit,
|
|
2944
3418
|
plugins,
|
|
2945
3419
|
refs: options.refs,
|
|
2946
3420
|
disabledFeatures: options.disabledFeatures,
|
|
@@ -2948,17 +3422,10 @@ function crossSerializeStream(source, options) {
|
|
|
2948
3422
|
const serial = createCrossSerializerContext({
|
|
2949
3423
|
plugins,
|
|
2950
3424
|
features: ctx.base.features,
|
|
2951
|
-
scopeId
|
|
3425
|
+
scopeId,
|
|
2952
3426
|
markedRefs: ctx.base.marked
|
|
2953
3427
|
});
|
|
2954
|
-
|
|
2955
|
-
try {
|
|
2956
|
-
serialized = serializeTopCross(serial, node);
|
|
2957
|
-
} catch (err) {
|
|
2958
|
-
if (options.onError) options.onError(err);
|
|
2959
|
-
return;
|
|
2960
|
-
}
|
|
2961
|
-
options.onSerialize(serialized, initial);
|
|
3428
|
+
return onSerialize(serializeTopCross(serial, node), initial);
|
|
2962
3429
|
},
|
|
2963
3430
|
onError: options.onError,
|
|
2964
3431
|
onDone: options.onDone
|
|
@@ -2981,22 +3448,39 @@ function toCrossJSONStream(source, options) {
|
|
|
2981
3448
|
startStreamParse(ctx, source);
|
|
2982
3449
|
return destroyStreamParse.bind(null, ctx);
|
|
2983
3450
|
}
|
|
2984
|
-
function
|
|
2985
|
-
|
|
2986
|
-
return deserializeTop(createCrossDeserializerContext({
|
|
3451
|
+
function createFromCrossJSONContext(options) {
|
|
3452
|
+
return createCrossDeserializerContext({
|
|
2987
3453
|
maxBase64Length: options.maxBase64Length,
|
|
2988
|
-
plugins,
|
|
3454
|
+
plugins: resolvePlugins(options.plugins),
|
|
2989
3455
|
refs: options.refs,
|
|
2990
3456
|
features: options.features,
|
|
2991
3457
|
disabledFeatures: options.disabledFeatures,
|
|
2992
3458
|
depthLimit: options.depthLimit
|
|
2993
|
-
})
|
|
3459
|
+
});
|
|
3460
|
+
}
|
|
3461
|
+
function fromCrossJSON(source, options) {
|
|
3462
|
+
return deserializeTop(createFromCrossJSONContext(options), source);
|
|
3463
|
+
}
|
|
3464
|
+
function createCrossDeserializer(options) {
|
|
3465
|
+
const ctx = createFromCrossJSONContext(options);
|
|
3466
|
+
ctx.base.pending = /* @__PURE__ */ new Set();
|
|
3467
|
+
return {
|
|
3468
|
+
deserialize(node) {
|
|
3469
|
+
if (!ctx.base.pending) throw new SerovalAbortedError();
|
|
3470
|
+
return deserializeTop(ctx, node);
|
|
3471
|
+
},
|
|
3472
|
+
get pending() {
|
|
3473
|
+
return ctx.base.pending?.size ?? 0;
|
|
3474
|
+
},
|
|
3475
|
+
abort(reason) {
|
|
3476
|
+
abortDeferred(ctx, reason);
|
|
3477
|
+
}
|
|
3478
|
+
};
|
|
2994
3479
|
}
|
|
2995
3480
|
//#endregion
|
|
2996
3481
|
//#region src/core/Serializer.ts
|
|
2997
3482
|
var Serializer = class {
|
|
2998
3483
|
constructor(options) {
|
|
2999
|
-
this.options = options;
|
|
3000
3484
|
this.alive = true;
|
|
3001
3485
|
this.flushed = false;
|
|
3002
3486
|
this.done = false;
|
|
@@ -3005,32 +3489,52 @@ var Serializer = class {
|
|
|
3005
3489
|
this.refs = /* @__PURE__ */ new Map();
|
|
3006
3490
|
this.keys = /* @__PURE__ */ new Set();
|
|
3007
3491
|
this.ids = 0;
|
|
3492
|
+
this.options = options;
|
|
3008
3493
|
this.plugins = resolvePlugins(options.plugins);
|
|
3009
3494
|
}
|
|
3010
3495
|
write(key, value) {
|
|
3011
|
-
|
|
3496
|
+
const options = this.options;
|
|
3497
|
+
if (this.alive && !this.flushed && options) {
|
|
3012
3498
|
this.pending++;
|
|
3013
3499
|
this.keys.add(key);
|
|
3014
|
-
|
|
3500
|
+
const cleanup = crossSerializeStream(value, {
|
|
3015
3501
|
plugins: this.plugins,
|
|
3016
|
-
scopeId:
|
|
3502
|
+
scopeId: options.scopeId,
|
|
3017
3503
|
refs: this.refs,
|
|
3018
|
-
disabledFeatures:
|
|
3019
|
-
compactArrayBufferViews:
|
|
3020
|
-
|
|
3504
|
+
disabledFeatures: options.disabledFeatures,
|
|
3505
|
+
compactArrayBufferViews: options.compactArrayBufferViews,
|
|
3506
|
+
depthLimit: options.depthLimit,
|
|
3507
|
+
onError: (error) => {
|
|
3508
|
+
let failure;
|
|
3509
|
+
try {
|
|
3510
|
+
if (options.onError) options.onError(error);
|
|
3511
|
+
else throw error instanceof SerovalParserError ? error : new SerovalParserError(error);
|
|
3512
|
+
} catch (handlerError) {
|
|
3513
|
+
failure = { value: handlerError };
|
|
3514
|
+
}
|
|
3515
|
+
try {
|
|
3516
|
+
this.finishWrite();
|
|
3517
|
+
} catch (finishError) {
|
|
3518
|
+
failure ?? (failure = { value: finishError });
|
|
3519
|
+
}
|
|
3520
|
+
if (failure) throw failure.value;
|
|
3521
|
+
},
|
|
3021
3522
|
onSerialize: (data, initial) => {
|
|
3022
|
-
|
|
3523
|
+
const current = this.options;
|
|
3524
|
+
if (this.alive && current) current.onData(initial ? current.globalIdentifier + "[\"" + serializeString(key) + "\"]=" + data : data);
|
|
3023
3525
|
},
|
|
3024
3526
|
onDone: () => {
|
|
3025
|
-
|
|
3026
|
-
this.pending--;
|
|
3027
|
-
if (this.pending <= 0 && this.flushed && !this.done && this.options.onDone) {
|
|
3028
|
-
this.options.onDone();
|
|
3029
|
-
this.done = true;
|
|
3030
|
-
}
|
|
3031
|
-
}
|
|
3527
|
+
this.finishWrite();
|
|
3032
3528
|
}
|
|
3033
|
-
})
|
|
3529
|
+
});
|
|
3530
|
+
if (this.alive) this.cleanups.push(cleanup);
|
|
3531
|
+
else cleanup();
|
|
3532
|
+
}
|
|
3533
|
+
}
|
|
3534
|
+
finishWrite() {
|
|
3535
|
+
if (this.alive) {
|
|
3536
|
+
this.pending--;
|
|
3537
|
+
if (this.pending <= 0 && this.flushed && !this.done) this.close();
|
|
3034
3538
|
}
|
|
3035
3539
|
}
|
|
3036
3540
|
getNextID() {
|
|
@@ -3045,20 +3549,36 @@ var Serializer = class {
|
|
|
3045
3549
|
flush() {
|
|
3046
3550
|
if (this.alive) {
|
|
3047
3551
|
this.flushed = true;
|
|
3048
|
-
if (this.pending <= 0 && !this.done
|
|
3049
|
-
this.options.onDone();
|
|
3050
|
-
this.done = true;
|
|
3051
|
-
}
|
|
3552
|
+
if (this.pending <= 0 && !this.done) this.close();
|
|
3052
3553
|
}
|
|
3053
3554
|
}
|
|
3054
3555
|
close() {
|
|
3556
|
+
this.finish();
|
|
3557
|
+
}
|
|
3558
|
+
finish() {
|
|
3055
3559
|
if (this.alive) {
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3560
|
+
this.alive = false;
|
|
3561
|
+
const options = this.options;
|
|
3562
|
+
this.options = void 0;
|
|
3563
|
+
this.plugins = void 0;
|
|
3564
|
+
const cleanups = this.cleanups;
|
|
3565
|
+
this.cleanups = [];
|
|
3566
|
+
let failure;
|
|
3567
|
+
for (let index = 0, length = cleanups.length; index < length; index++) try {
|
|
3568
|
+
cleanups[index]();
|
|
3569
|
+
} catch (error) {
|
|
3570
|
+
failure ?? (failure = { value: error });
|
|
3571
|
+
}
|
|
3572
|
+
this.refs.clear();
|
|
3573
|
+
if (!this.done) {
|
|
3059
3574
|
this.done = true;
|
|
3575
|
+
try {
|
|
3576
|
+
options?.onDone?.();
|
|
3577
|
+
} catch (error) {
|
|
3578
|
+
failure ?? (failure = { value: error });
|
|
3579
|
+
}
|
|
3060
3580
|
}
|
|
3061
|
-
|
|
3581
|
+
if (failure) throw failure.value;
|
|
3062
3582
|
}
|
|
3063
3583
|
}
|
|
3064
3584
|
};
|
|
@@ -3066,8 +3586,9 @@ var Serializer = class {
|
|
|
3066
3586
|
//#region src/core/tree/index.ts
|
|
3067
3587
|
function serialize(source, options = {}) {
|
|
3068
3588
|
const plugins = resolvePlugins(options.plugins);
|
|
3069
|
-
const ctx = createSyncParserContext(
|
|
3589
|
+
const ctx = createSyncParserContext({
|
|
3070
3590
|
compactArrayBufferViews: options.compactArrayBufferViews,
|
|
3591
|
+
depthLimit: options.depthLimit,
|
|
3071
3592
|
plugins,
|
|
3072
3593
|
disabledFeatures: options.disabledFeatures
|
|
3073
3594
|
});
|
|
@@ -3080,8 +3601,9 @@ function serialize(source, options = {}) {
|
|
|
3080
3601
|
}
|
|
3081
3602
|
async function serializeAsync(source, options = {}) {
|
|
3082
3603
|
const plugins = resolvePlugins(options.plugins);
|
|
3083
|
-
const ctx = createAsyncParserContext(
|
|
3604
|
+
const ctx = createAsyncParserContext({
|
|
3084
3605
|
compactArrayBufferViews: options.compactArrayBufferViews,
|
|
3606
|
+
depthLimit: options.depthLimit,
|
|
3085
3607
|
plugins,
|
|
3086
3608
|
disabledFeatures: options.disabledFeatures
|
|
3087
3609
|
});
|
|
@@ -3097,8 +3619,9 @@ function deserialize(source) {
|
|
|
3097
3619
|
}
|
|
3098
3620
|
function toJSON(source, options = {}) {
|
|
3099
3621
|
const plugins = resolvePlugins(options.plugins);
|
|
3100
|
-
const ctx = createSyncParserContext(
|
|
3622
|
+
const ctx = createSyncParserContext({
|
|
3101
3623
|
compactArrayBufferViews: options.compactArrayBufferViews,
|
|
3624
|
+
depthLimit: options.depthLimit,
|
|
3102
3625
|
plugins,
|
|
3103
3626
|
disabledFeatures: options.disabledFeatures
|
|
3104
3627
|
});
|
|
@@ -3110,8 +3633,9 @@ function toJSON(source, options = {}) {
|
|
|
3110
3633
|
}
|
|
3111
3634
|
async function toJSONAsync(source, options = {}) {
|
|
3112
3635
|
const plugins = resolvePlugins(options.plugins);
|
|
3113
|
-
const ctx = createAsyncParserContext(
|
|
3636
|
+
const ctx = createAsyncParserContext({
|
|
3114
3637
|
compactArrayBufferViews: options.compactArrayBufferViews,
|
|
3638
|
+
depthLimit: options.depthLimit,
|
|
3115
3639
|
plugins,
|
|
3116
3640
|
disabledFeatures: options.disabledFeatures
|
|
3117
3641
|
});
|
|
@@ -3129,11 +3653,11 @@ function compileJSON(source, options = {}) {
|
|
|
3129
3653
|
}), source.t);
|
|
3130
3654
|
}
|
|
3131
3655
|
function fromJSON(source, options = {}) {
|
|
3132
|
-
var _source$f;
|
|
3133
3656
|
const plugins = resolvePlugins(options.plugins);
|
|
3134
|
-
const disabledFeatures = options.disabledFeatures
|
|
3135
|
-
const sourceFeatures =
|
|
3657
|
+
const disabledFeatures = options.disabledFeatures ?? 0;
|
|
3658
|
+
const sourceFeatures = source.f ?? 127;
|
|
3136
3659
|
return deserializeTop(createVanillaDeserializerContext({
|
|
3660
|
+
depthLimit: options.depthLimit,
|
|
3137
3661
|
maxBase64Length: options.maxBase64Length,
|
|
3138
3662
|
plugins,
|
|
3139
3663
|
markedRefs: source.m,
|
|
@@ -3142,4 +3666,4 @@ function fromJSON(source, options = {}) {
|
|
|
3142
3666
|
}), source.t);
|
|
3143
3667
|
}
|
|
3144
3668
|
//#endregion
|
|
3145
|
-
export { Feature, OpaqueReference, Serializer, SerovalConflictedNodeIdError, SerovalDepthLimitError, SerovalDeserializationError, SerovalError, SerovalMalformedNodeError, SerovalMissingInstanceError, SerovalMissingPluginError, SerovalMissingReferenceError, SerovalMissingReferenceForIdError, SerovalMode, SerovalParserError, SerovalSerializationError, SerovalUnknownTypedArrayError, SerovalUnsupportedNodeError, SerovalUnsupportedTypeError, compileJSON, createPlugin, createReference, createStream, crossSerialize, crossSerializeAsync, crossSerializeStream, deserialize, fromCrossJSON, fromJSON, getCrossReferenceHeader, isStream, resolvePlugins, serialize, serializeAsync, toCrossJSON, toCrossJSONAsync, toCrossJSONStream, toJSON, toJSONAsync };
|
|
3669
|
+
export { Feature, LiveStream, OpaqueReference, Sequence, Serializer, SerovalAbortedError, SerovalConflictedNodeIdError, SerovalDepthLimitError, SerovalDeserializationError, SerovalError, SerovalLiveStreamError, SerovalMalformedNodeError, SerovalMissingInstanceError, SerovalMissingPluginError, SerovalMissingReferenceError, SerovalMissingReferenceForIdError, SerovalMode, SerovalParserError, SerovalSerializationError, SerovalUnknownTypedArrayError, SerovalUnsupportedNodeError, SerovalUnsupportedTypeError, Stream, compileJSON, createCrossDeserializer, createLiveStream, createPlugin, createReference, createStream, crossSerialize, crossSerializeAsync, crossSerializeStream, deserialize, fromCrossJSON, fromJSON, getCrossReferenceHeader, getPlainObjectPlugins, isLiveStream, isStream, resolvePlugins, serialize, serializeAsync, toCrossJSON, toCrossJSONAsync, toCrossJSONStream, toJSON, toJSONAsync };
|