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