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