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