const require_shared = require("./shared-u-KYXAax.cjs"); const require_typed_array = require("./typed-array-BkSwWNFI.cjs"); //#region src/core/node.ts function createSerovalNode(t, i, s, c, m, p, e, a, f, b, o, l) { 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 { t, i, s }; return { t, i, s, c, m, p, e, a, f, b, o, l }; } //#endregion //#region src/core/literals.ts function createConstantNode(value) { return createSerovalNode(2, void 0, value); } const TRUE_NODE = /* @__PURE__ */ createConstantNode(2); const FALSE_NODE = /* @__PURE__ */ createConstantNode(3); const UNDEFINED_NODE = /* @__PURE__ */ createConstantNode(1); const NULL_NODE = /* @__PURE__ */ createConstantNode(0); const NEG_ZERO_NODE = /* @__PURE__ */ createConstantNode(4); const INFINITY_NODE = /* @__PURE__ */ createConstantNode(5); const NEG_INFINITY_NODE = /* @__PURE__ */ createConstantNode(6); const NAN_NODE = /* @__PURE__ */ createConstantNode(7); //#endregion //#region src/core/utils/error.ts function getErrorConstructor(error) { for (let i = 1; i <= 6; i++) if (error instanceof require_shared.ERROR_CONSTRUCTOR[i]) return i; return 0; } function getErrorOptions(error, features) { const options = Object.create(null); const construct = require_shared.ERROR_CONSTRUCTOR_STRING[getErrorConstructor(error)]; if (error.name !== construct) options.name = error.name; else if (error.constructor.name !== construct) options.name = error.constructor.name; for (const name of Object.getOwnPropertyNames(error)) if (name !== "name" && name !== "message" && (name !== "stack" || features & 4)) options[name] = error[name]; return options; } //#endregion //#region src/core/utils/get-object-flag.ts function getObjectFlag(obj) { if (Object.isExtensible(obj)) return 0; if (Object.isFrozen(obj)) return 3; if (Object.isSealed(obj)) return 2; return 1; } //#endregion //#region src/core/base-primitives.ts function createNumberNode(value) { switch (value) { case Number.POSITIVE_INFINITY: return INFINITY_NODE; case Number.NEGATIVE_INFINITY: return NEG_INFINITY_NODE; } if (value !== value) return NAN_NODE; if (Object.is(value, -0)) return NEG_ZERO_NODE; return createSerovalNode(0, void 0, value); } function createStringNode(value) { return createSerovalNode(1, void 0, require_shared.serializeString(value)); } function createBigIntNode(current) { return createSerovalNode(3, void 0, "" + current); } function createIndexedValueNode(id) { return createSerovalNode(4, id); } const getDateTime = Date.prototype.getTime; const getDateISOString = Date.prototype.toISOString; function createDateNode(id, current) { const timestamp = getDateTime.call(current); return createSerovalNode(5, id, timestamp === timestamp ? getDateISOString.call(current) : ""); } function createTemporalNode(id, type, temporalClass, current) { return createSerovalNode(36, id, temporalClass.prototype.toString.call(current), type); } const getRegExpSource = Object.getOwnPropertyDescriptor(RegExp.prototype, "source").get; const getRegExpFlags = Object.getOwnPropertyDescriptor(RegExp.prototype, "flags").get; function createRegExpNode(id, current) { return createSerovalNode(6, id, void 0, require_shared.serializeString(getRegExpSource.call(current)), getRegExpFlags.call(current)); } function createWKSymbolNode(id, current) { return createSerovalNode(17, id, require_shared.INV_SYMBOL_REF[current]); } function createReferenceNode(id, referenceId) { return createSerovalNode(18, id, require_shared.serializeString(referenceId)); } function createPluginNode(id, tag, value) { return createSerovalNode(25, id, value, require_shared.serializeString(tag)); } function createArrayNode(id, current, parsedItems) { return createSerovalNode(9, id, void 0, void 0, void 0, void 0, void 0, parsedItems, void 0, void 0, getObjectFlag(current)); } function createBoxedNode(id, boxed) { return createSerovalNode(21, id, void 0, void 0, void 0, void 0, void 0, void 0, boxed); } const MAX_TYPED_ARRAY_LENGTH = 1e6; /** * Rejects a sparse array with more holes than the typed array limit. Each hole * still costs a node and output, however few elements the array holds. */ function assertArrayHoles(current) { const len = current.length; if (len > MAX_TYPED_ARRAY_LENGTH && len - Object.keys(current).length > MAX_TYPED_ARRAY_LENGTH) throw new require_shared.SerovalUnsupportedTypeError(current); } function createViewNode(type, id, current, view, buffer) { const isDataView = type === 20; const size = view.length; if (size > MAX_TYPED_ARRAY_LENGTH) throw new require_shared.SerovalUnsupportedTypeError(current); return createSerovalNode(type, id, void 0, isDataView ? void 0 : require_typed_array.getTypedArrayName(current), void 0, void 0, void 0, void 0, buffer, view.byteOffset, void 0, size); } function createErrorNode(type, id, current, options) { return createSerovalNode(type, id, getErrorConstructor(current), void 0, require_shared.serializeString(current.message), options); } function createSetNode(id, items) { return createSerovalNode(7, id, void 0, void 0, void 0, void 0, void 0, items); } function createIteratorFactoryInstanceNode(type, factory, items) { return createSerovalNode(type, void 0, void 0, void 0, void 0, void 0, void 0, [factory, items]); } function createStreamConstructorNode(id, factory, sequence, live) { return createSerovalNode(31, id, void 0, void 0, void 0, void 0, void 0, sequence, factory, void 0, void 0, live); } function createStreamEventNode(type, id, parsed) { return createSerovalNode(type, id, void 0, void 0, void 0, void 0, void 0, void 0, parsed); } function createSequenceNode(id, sequence, throwAt, doneAt) { return createSerovalNode(35, id, throwAt, void 0, void 0, void 0, void 0, sequence, void 0, void 0, void 0, doneAt); } //#endregion //#region src/core/special-reference.ts const ITERATOR = {}; const ASYNC_ITERATOR = {}; /** * Placeholder references */ const SPECIAL_REFS = { [0]: {}, [1]: {}, [2]: {}, [3]: {}, [4]: {}, [5]: {} }; const SPECIAL_REF_STRING = { [0]: "[]", [1]: require_shared.SERIALIZED_PROMISE_CONSTRUCTOR, [2]: require_shared.SERIALIZED_PROMISE_SUCCESS, [3]: require_shared.SERIALIZED_PROMISE_FAILURE, [4]: require_shared.SERIALIZED_STREAM_CONSTRUCTOR, [5]: require_shared.SERIALIZED_ARRAY_BUFFER_CONSTRUCTOR }; //#endregion //#region src/core/utils/promise-to-result.ts async function promiseToResult(current) { try { return [1, await current]; } catch (e) { return [0, e]; } } //#endregion //#region src/core/context/parser.ts function createBaseParserContext(options) { return { plugins: options.plugins, plainObjectPlugins: require_shared.getPlainObjectPlugins(options.plugins), marked: /* @__PURE__ */ new Set(), features: 127 ^ (options.disabledFeatures ?? 0), refs: options.refs ?? /* @__PURE__ */ new Map(), depthLimit: options.depthLimit || 1e3, compactArrayBufferViews: options.compactArrayBufferViews ?? false }; } /** * Returns the plugins to test for an object. Plain objects, whose prototype is * `Object.prototype`, skip the plugins that set `skipPlainObjects`. Checking * the prototype as well as `constructor` keeps instances whose prototype has * no own `constructor` property from skipping those plugins. */ function getObjectPlugins(ctx, current, currentClass) { return currentClass === Object && Object.getPrototypeOf(current) === Object.prototype ? ctx.plainObjectPlugins : ctx.plugins; } /** * Ensures that the value (based on an identifier) has been visited by the parser. * @param ctx * @param id */ function markParserRef(ctx, id) { ctx.marked.add(id); } /** * Creates an identifier for a value * @param ctx * @param current */ function createIndexForValue(ctx, current) { const id = ctx.refs.size; ctx.refs.set(current, id); return id; } /** * Removes the ids registered from `size` on. A parse that fails emits none of * them, so a caller-owned map must not keep them for later calls. */ function rollbackRefs(refs, size) { if (refs.size > size) { for (const [value, id] of refs) if (id >= size) refs.delete(value); } } function getNodeForIndexedValue(ctx, current) { const registeredId = ctx.refs.get(current); if (registeredId != null) { markParserRef(ctx, registeredId); return createIndexedValueNode(registeredId); } return createIndexForValue(ctx, current); } function getReferenceNode(ctx, current) { const indexed = getNodeForIndexedValue(ctx, current); if (typeof indexed !== "number") return indexed; const referenceId = require_shared.getReferenceID(current); return referenceId === void 0 ? indexed : createReferenceNode(indexed, referenceId); } /** * Parsing methods */ function parseWellKnownSymbol(ctx, current) { const ref = getReferenceNode(ctx, current); if (typeof ref !== "number") return ref; if (current in require_shared.INV_SYMBOL_REF) return createWKSymbolNode(ref, current); throw new require_shared.SerovalUnsupportedTypeError(current); } function parseSpecialReference(ctx, ref) { const result = getNodeForIndexedValue(ctx, SPECIAL_REFS[ref]); if (typeof result !== "number") return result; return createSerovalNode(26, result, ref); } function parseIteratorFactory(ctx) { const result = getNodeForIndexedValue(ctx, ITERATOR); if (typeof result !== "number") return result; return createSerovalNode(27, result, void 0, void 0, void 0, void 0, void 0, void 0, parseWellKnownSymbol(ctx, require_shared.SYM_ITERATOR)); } function parseAsyncIteratorFactory(ctx) { const result = getNodeForIndexedValue(ctx, ASYNC_ITERATOR); if (typeof result !== "number") return result; return createSerovalNode(29, result, void 0, void 0, void 0, void 0, void 0, [parseSpecialReference(ctx, 1), parseWellKnownSymbol(ctx, require_shared.SYM_ASYNC_ITERATOR)]); } function getTemporalType(currentClass) { switch (currentClass) { case Temporal.Instant: return 0; case Temporal.Duration: return 1; case Temporal.PlainDate: return 2; case Temporal.PlainDateTime: return 3; case Temporal.PlainMonthDay: return 4; case Temporal.PlainTime: return 5; case Temporal.PlainYearMonth: return 6; case Temporal.ZonedDateTime: return 7; default: return; } } function getObjectClass(current) { const proto = Object.getPrototypeOf(current); if (proto === null) return void 0; if (proto === Object.prototype) return Object; const currentClass = proto.constructor; if (typeof currentClass !== "function" || currentClass === Object || currentClass.prototype === proto) return currentClass; return proto; } /** * Decides how an object is parsed. Shared by the sync, stream and async * parsers so the class checks and feature gates live in one place. */ function getObjectKind(current, currentClass, features) { switch (currentClass) { case Object: return 1; case void 0: return 2; case Date: return 3; case Error: case EvalError: case RangeError: case ReferenceError: case SyntaxError: case TypeError: case URIError: return 4; case Number: case Boolean: case String: case BigInt: return 6; case ArrayBuffer: return 7; case Int8Array: case Int16Array: case Int32Array: case Uint8Array: case Uint16Array: case Uint32Array: case Uint8ClampedArray: case Float32Array: case Float64Array: return 8; case DataView: return 10; case Map: return 11; case Set: return 12; } if (currentClass === Promise || current instanceof Promise) return 13; if (features & 32 && currentClass === RegExp) return 14; if (features & 16 && (currentClass === BigInt64Array || currentClass === BigUint64Array)) return 9; if (features & 1 && typeof AggregateError !== "undefined" && (currentClass === AggregateError || current instanceof AggregateError)) return 5; if (features & 64 && typeof Temporal !== "undefined" && getTemporalType(currentClass) != null) return 15; if (ArrayBuffer.isView(current)) { const name = require_typed_array.getTypedArrayName(current); if (name === void 0) return 10; if (name !== "BigInt64Array" && name !== "BigUint64Array") return 8; if (features & 16) return 9; } if (current instanceof Error) return 4; if (require_shared.SYM_ITERATOR in current || require_shared.SYM_ASYNC_ITERATOR in current) return 16; return 0; } function createObjectNode(id, current, empty, record) { return createSerovalNode(empty ? 11 : 10, id, void 0, void 0, void 0, record, void 0, void 0, void 0, void 0, getObjectFlag(current)); } /** * Gets the sentinel node for a Map. Call it before parsing the entries, so * that an outer Map declares the sentinel before any Map inside it uses it. */ function parseMapSentinel(ctx) { return parseSpecialReference(ctx, 0); } function createMapNode(id, sentinel, k, v) { return createSerovalNode(8, id, void 0, void 0, void 0, void 0, { k, v }, void 0, sentinel); } function createPromiseConstructorNode(ctx, id, resolver) { return createSerovalNode(22, id, resolver, void 0, void 0, void 0, void 0, void 0, parseSpecialReference(ctx, 1)); } function getArrayBufferView(ctx, view) { if (!ctx.compactArrayBufferViews) return view; return { buffer: new Uint8Array(view.buffer, view.byteOffset, view.byteLength).slice().buffer, byteOffset: 0, byteLength: view.byteLength, length: view.length }; } function createArrayBufferNode(ctx, id, current) { return createSerovalNode(19, id, require_typed_array.encodeArrayBuffer(current), void 0, void 0, void 0, void 0, void 0, parseSpecialReference(ctx, 5)); } //#endregion //#region src/core/context/async-parser.ts function createAsyncParserContext(options) { return { base: createBaseParserContext(options) }; } function ignoreRejection() {} /** * A promise gets its rejection handler only when the walk reaches it. While an * earlier sibling is still pending, a later one that rejects would be an * unhandled rejection, which ends a Node.js process by default. Mark the * promises among the children as handled before walking them. */ function handleChildPromises(values) { for (const value of values) if (value instanceof Promise) Promise.prototype.then.call(value, void 0, ignoreRejection); } async function parseItems$1(ctx, depth, current) { assertArrayHoles(current); const len = current.length; const nodes = new Array(len); const values = new Array(len); const present = new Array(len); for (let i = 0; i < len; i++) { present[i] = i in current; if (present[i]) values[i] = current[i]; } handleChildPromises(values); for (let i = 0, node; i < len; i++) if (present[i]) { node = parseValueAsync(ctx, depth, values[i]); nodes[i] = node instanceof Promise ? await node : node; } else nodes[i] = 0; return nodes; } async function parseArray$1(ctx, depth, id, current) { return createArrayNode(id, current, await parseItems$1(ctx, depth, current)); } async function parseProperties$1(ctx, depth, properties) { const keys = Object.keys(properties); const len = keys.length; const keyNodes = new Array(len); const valueNodes = new Array(len); const values = new Array(len); for (let i = 0; i < len; i++) values[i] = properties[keys[i]]; handleChildPromises(values); for (let i = 0, node; i < len; i++) { keyNodes[i] = require_shared.serializeString(keys[i]); node = parseValueAsync(ctx, depth, values[i]); valueNodes[i] = node instanceof Promise ? await node : node; } if (require_shared.SYM_ITERATOR in properties) { keyNodes.push(parseWellKnownSymbol(ctx.base, require_shared.SYM_ITERATOR)); valueNodes.push(createIteratorFactoryInstanceNode(28, parseIteratorFactory(ctx.base), await parseAsync(ctx, depth, require_shared.createSequenceFromIterable(properties)))); } if (require_shared.SYM_ASYNC_ITERATOR in properties) { keyNodes.push(parseWellKnownSymbol(ctx.base, require_shared.SYM_ASYNC_ITERATOR)); valueNodes.push(createIteratorFactoryInstanceNode(30, parseAsyncIteratorFactory(ctx.base), await parseAsyncIterable$1(ctx, depth, properties))); } if (require_shared.SYM_TO_STRING_TAG in properties) { keyNodes.push(parseWellKnownSymbol(ctx.base, require_shared.SYM_TO_STRING_TAG)); valueNodes.push(createStringNode(properties[require_shared.SYM_TO_STRING_TAG])); } if (require_shared.SYM_IS_CONCAT_SPREADABLE in properties) { keyNodes.push(parseWellKnownSymbol(ctx.base, require_shared.SYM_IS_CONCAT_SPREADABLE)); valueNodes.push(properties[require_shared.SYM_IS_CONCAT_SPREADABLE] ? TRUE_NODE : FALSE_NODE); } return { k: keyNodes, v: valueNodes }; } async function parsePlainObject$1(ctx, depth, id, current, empty) { return createObjectNode(id, current, empty, await parseProperties$1(ctx, depth, current)); } async function parseBoxed$1(ctx, depth, id, current) { const node = parseValueAsync(ctx, depth, current.valueOf()); return createBoxedNode(id, node instanceof Promise ? await node : node); } async function parseView$1(ctx, depth, type, id, current) { const view = getArrayBufferView(ctx.base, require_typed_array.readArrayBufferView(current, type === 20)); return createViewNode(type, id, current, view, await parseAsync(ctx, depth, view.buffer)); } async function parseError$1(ctx, depth, type, id, current) { const options = getErrorOptions(current, ctx.base.features); return createErrorNode(type, id, current, options ? await parseProperties$1(ctx, depth, options) : void 0); } async function parseMap$1(ctx, depth, id, current) { const sentinel = parseMapSentinel(ctx.base); const entries = [...current.entries()]; const keyNodes = new Array(entries.length); const valueNodes = new Array(entries.length); const keys = new Array(entries.length); const values = new Array(entries.length); for (let i = 0; i < entries.length; i++) { keys[i] = entries[i][0]; values[i] = entries[i][1]; } handleChildPromises(keys); handleChildPromises(values); for (let i = 0, node; i < entries.length; i++) { node = parseValueAsync(ctx, depth, keys[i]); keyNodes[i] = node instanceof Promise ? await node : node; node = parseValueAsync(ctx, depth, values[i]); valueNodes[i] = node instanceof Promise ? await node : node; } return createMapNode(id, sentinel, keyNodes, valueNodes); } async function parseSet$1(ctx, depth, id, current) { const values = [...current.keys()]; const items = new Array(values.length); handleChildPromises(values); for (let i = 0, node; i < values.length; i++) { node = parseValueAsync(ctx, depth, values[i]); items[i] = node instanceof Promise ? await node : node; } return createSetNode(id, items); } async function parsePlugin$1(ctx, depth, id, current, currentPlugins) { if (currentPlugins) for (let i = 0, len = currentPlugins.length; i < len; i++) { const plugin = currentPlugins[i]; if (plugin.parse.async && plugin.test(current)) return createPluginNode(id, plugin.tag, await plugin.parse.async(current, { parse: (value) => parseAsync(ctx, depth, value), parseStreamSource(source) { if (depth >= ctx.base.depthLimit) throw new require_shared.SerovalDepthLimitError(ctx.base.depthLimit); return parseAsyncIterable$1(ctx, depth + 1, source); } }, { id })); } } async function parsePromise$1(ctx, depth, id, current) { const [status, result] = await promiseToResult(current); return createSerovalNode(12, id, status, void 0, void 0, void 0, void 0, void 0, await parseAsync(ctx, depth, result)); } function parseStreamHandle(depth, id, current, resolve, reject) { const sequence = []; let unparsed = 0; let ended = false; let settled = false; const fail = (error) => { if (!settled) { settled = true; try { cleanup(error); } catch {} reject(error); } }; const handle = (type) => (value, accept) => { if (settled) return; markParserRef(this.base, id); const slot = sequence.push(void 0) - 1; unparsed++; if (type !== 32) ended = true; parseAsync(this, depth, value).then((data) => { if (!settled) { sequence[slot] = createStreamEventNode(type, id, data); unparsed--; accept?.(); if (ended && unparsed === 0) { settled = true; try { cleanup(); } catch (error) { reject(error); return; } resolve(sequence); } } }, fail); }; const listener = { next: handle(32), throw: handle(33), return: handle(34) }; const cleanup = require_shared.isLiveStream(current) ? current.pump(listener) : current.on(listener); } async function parseStream$1(ctx, depth, id, current) { return createStreamConstructorNode(id, parseSpecialReference(ctx.base, 4), await new Promise(parseStreamHandle.bind(ctx, depth, id, current))); } /** * Collects an async iterable into a replay node, one value at a time. */ async function parseAsyncIterable$1(ctx, depth, current) { const id = createIndexForValue(ctx.base, {}); const reference = parseSpecialReference(ctx.base, 4); const iterator = current[require_shared.SYM_ASYNC_ITERATOR](); const sequence = []; for (;;) { let result; markParserRef(ctx.base, id); try { result = await iterator.next(); } catch (error) { sequence.push(createStreamEventNode(33, id, await parseAsync(ctx, depth, error))); break; } let parsed; try { parsed = await parseAsync(ctx, depth, result.value); } catch (error) { Promise.resolve().then(() => iterator.return?.()).catch(() => {}); throw error; } sequence.push(createStreamEventNode(result.done ? 34 : 32, id, parsed)); if (result.done) break; } return createStreamConstructorNode(id, reference, sequence); } async function parseSequence$1(ctx, depth, id, current) { const len = current.v.length; const nodes = new Array(len); for (let i = 0, node; i < len; i++) { node = parseValueAsync(ctx, depth, current.v[i]); nodes[i] = node instanceof Promise ? await node : node; } return createSequenceNode(id, nodes, current.t, current.d); } async function parseObjectAsync(ctx, depth, id, current) { if (Array.isArray(current)) return parseArray$1(ctx, depth, id, current); if (require_shared.isStream(current)) return parseStream$1(ctx, depth, id, current); if (require_shared.isSequence(current)) return parseSequence$1(ctx, depth, id, current); const currentClass = getObjectClass(current); if (currentClass === require_shared.OpaqueReference) return parseAsync(ctx, depth, current.replacement); const parsed = await parsePlugin$1(ctx, depth, id, current, getObjectPlugins(ctx.base, current, currentClass)); if (parsed) return parsed; if (currentClass === Object) return parsePlainObject$1(ctx, depth, id, current, false); switch (getObjectKind(current, currentClass, ctx.base.features)) { case 2: return parsePlainObject$1(ctx, depth, id, current, true); case 3: return createDateNode(id, current); case 4: return parseError$1(ctx, depth, 13, id, current); case 5: return parseError$1(ctx, depth, 14, id, current); case 6: return parseBoxed$1(ctx, depth, id, current); case 7: return createArrayBufferNode(ctx.base, id, current); case 8: return parseView$1(ctx, depth, 15, id, current); case 9: return parseView$1(ctx, depth, 16, id, current); case 10: return parseView$1(ctx, depth, 20, id, current); case 11: return parseMap$1(ctx, depth, id, current); case 12: return parseSet$1(ctx, depth, id, current); case 13: return parsePromise$1(ctx, depth, id, current); case 14: return createRegExpNode(id, current); case 15: return createTemporalNode(id, getTemporalType(currentClass), currentClass, current); case 16: return parsePlainObject$1(ctx, depth, id, current, !!currentClass); default: throw new require_shared.SerovalUnsupportedTypeError(current); } } async function parseFunctionAsync(ctx, depth, current) { const ref = getReferenceNode(ctx.base, current); if (typeof ref !== "number") return ref; const plugin = await parsePlugin$1(ctx, depth, ref, current, ctx.base.plugins); if (plugin) return plugin; throw new require_shared.SerovalUnsupportedTypeError(current); } /** * Parses primitives and already-seen values synchronously; only objects and * functions come back as a Promise. Errors are thrown synchronously, which * an async caller turns into a rejection as before. */ function parseValueAsync(ctx, depth, current) { if (depth >= ctx.base.depthLimit) throw new require_shared.SerovalDepthLimitError(ctx.base.depthLimit); switch (typeof current) { case "boolean": return current ? TRUE_NODE : FALSE_NODE; case "undefined": return UNDEFINED_NODE; case "string": return createStringNode(current); case "number": return createNumberNode(current); case "bigint": return createBigIntNode(current); case "object": if (current) { const ref = getReferenceNode(ctx.base, current); return typeof ref === "number" ? parseObjectAsync(ctx, depth + 1, ref, current) : ref; } return NULL_NODE; case "symbol": return parseWellKnownSymbol(ctx.base, current); case "function": return parseFunctionAsync(ctx, depth, current); default: throw new require_shared.SerovalUnsupportedTypeError(current); } } async function parseAsync(ctx, depth, current) { return await parseValueAsync(ctx, depth, current); } async function parseTopAsync(ctx, current) { const refs = ctx.base.refs; const size = refs.size; try { return await parseAsync(ctx, 0, current); } catch (error) { rollbackRefs(refs, size); throw error instanceof require_shared.SerovalParserError ? error : new require_shared.SerovalParserError(error); } } //#endregion //#region src/core/function-string.ts const RETURN = () => T; const IS_MODERN = /* @__PURE__ */ (/* @__PURE__ */ RETURN.toString()).includes("=>"); function createFunction(parameters, body) { if (IS_MODERN) return (parameters.length === 1 ? parameters[0] : "(" + parameters.join(",") + ")") + "=>" + (body.startsWith("{") ? "(" + body + ")" : body); return "function(" + parameters.join(",") + "){return " + body + "}"; } function createEffectfulFunction(parameters, body) { if (IS_MODERN) return (parameters.length === 1 ? parameters[0] : "(" + parameters.join(",") + ")") + "=>{" + body + "}"; return "function(" + parameters.join(",") + "){" + body + "}"; } //#endregion //#region src/core/utils/get-identifier.ts const REF_START_CHARS = "hjkmoquxzABCDEFGHIJKLNPQRTUVWXYZ$_"; const REF_START_CHARS_LEN = 34; const REF_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$_"; const REF_CHARS_LEN = 64; function getIdentifier(index) { let mod = index % REF_START_CHARS_LEN; let ref = REF_START_CHARS[mod]; index = (index - mod) / REF_START_CHARS_LEN; while (index > 0) { mod = index % REF_CHARS_LEN; ref += REF_CHARS[mod]; index = (index - mod) / REF_CHARS_LEN; } return ref; } //#endregion //#region src/core/utils/is-valid-identifier.ts function isValidIdentifier(name) { const len = name.length; for (let i = 0; i < len; i++) { const code = name.charCodeAt(i); if (!(code >= 97 && code <= 122 || code >= 65 && code <= 90 || code >= 48 && code <= 57 && i > 0 || code === 95 || code === 36)) return false; } return len > 0; } //#endregion //#region src/core/context/serializer.ts function getAssignmentExpression(assignment) { switch (assignment.t) { case 0: return assignment.s + "=" + assignment.v; case 2: return assignment.s + ".set(" + assignment.k + "," + assignment.v + ")"; case 1: return assignment.s + ".add(" + assignment.v + ")"; case 3: return assignment.s + ".delete(" + assignment.k + ")"; case 4: return "Object.defineProperty(" + assignment.s + ",\"__proto__\",{value:" + assignment.k + ",configurable:!0,enumerable:!0,writable:!0})"; } } const MAX_ASSIGNMENT_CHAIN_LENGTH = 100; function resolveAssignments(assignments, chainValues = true) { if (!assignments.length) return void 0; let previous = assignments[0]; let expression = getAssignmentExpression(previous); let result = ""; let chainLength = 1; for (let index = 1, length = assignments.length; index < length; index++) { const assignment = assignments[index]; if (chainLength === MAX_ASSIGNMENT_CHAIN_LENGTH) { result += expression + ","; expression = getAssignmentExpression(assignment); chainLength = 0; } else if (chainValues && assignment.t === 0 && previous.t === 0 && assignment.v === previous.v) expression = assignment.s + "=" + expression; else if (assignment.t === 2 && previous.t === 2 && assignment.s === previous.s) expression += ".set(" + assignment.k + "," + assignment.v + ")"; else if (assignment.t === 1 && previous.t === 1 && assignment.s === previous.s) expression += ".add(" + assignment.v + ")"; else if (assignment.t === 3 && previous.t === 2 && assignment.s === previous.s) expression += ".delete(" + assignment.k + ")"; else { result += expression + ","; expression = getAssignmentExpression(assignment); chainLength = 0; } chainLength++; previous = assignment; } return result + expression + ","; } const NULL_CONSTRUCTOR = "Object.create(null)"; const SET_CONSTRUCTOR = "new Set"; const MAP_CONSTRUCTOR = "new Map"; const PROMISE_RESOLVE = "Promise.resolve"; const PROMISE_REJECT = "Promise.reject"; const OBJECT_FLAG_CONSTRUCTOR = { [3]: "Object.freeze", [2]: "Object.seal", [1]: "Object.preventExtensions", [0]: void 0 }; function createBaseSerializerContext(mode, options) { return { mode, plugins: options.plugins, features: options.features, marked: Array.isArray(options.markedRefs) ? new Set(options.markedRefs) : options.markedRefs, stack: [], flags: [], assignments: [], assignAll: mode === 2 && !options.assignSharedRefsOnly }; } function createVanillaSerializerState() { return { valid: /* @__PURE__ */ new Map(), vars: [], sentinels: /* @__PURE__ */ new Set() }; } function createVanillaSerializerContext(options) { return { mode: 1, base: createBaseSerializerContext(1, options), state: createVanillaSerializerState() }; } function createCrossSerializerContext(options) { return { mode: 2, base: createBaseSerializerContext(2, options), state: options }; } /** * Creates the reference param (identifier) from the given reference ID * Calling this function means the value has been referenced somewhere */ function getVanillaRefParam(state, index) { /** * Creates a new reference ID from a given reference ID * This new reference ID means that the reference itself * has been referenced at least once, and is used to generate * the variables */ let actualIndex = state.valid.get(index); if (actualIndex == null) { actualIndex = state.valid.size; state.valid.set(index, actualIndex); } let identifier = state.vars[actualIndex]; if (identifier == null) { identifier = getIdentifier(actualIndex); state.vars[actualIndex] = identifier; } return identifier; } function getCrossRefParam(id) { return "$R[" + id + "]"; } /** * Converts the ID of a reference into a identifier string * that is used to refer to the object instance in the * generated script. */ function getRefParam(ctx, id) { return ctx.mode === 1 ? getVanillaRefParam(ctx.state, id) : getCrossRefParam(id); } function markSerializerRef(ctx, id) { ctx.marked.add(id); } function isSerializerRefMarked(ctx, id) { return ctx.marked.has(id); } function pushObjectFlag(ctx, flag, id) { if (flag !== 0) { markSerializerRef(ctx.base, id); ctx.base.flags.push({ type: flag, value: getRefParam(ctx, id) }); } } function resolveFlags(ctx) { let result = ""; for (let i = 0, current = ctx.flags, len = current.length; i < len; i++) { const flag = current[i]; result += OBJECT_FLAG_CONSTRUCTOR[flag.type] + "(" + flag.value + "),"; } return result; } function resolvePatches(ctx) { const assignments = resolveAssignments(ctx.assignments); const flags = resolveFlags(ctx); if (assignments) { if (flags) return assignments + flags; return assignments; } return flags; } /** * Generates the inlined assignment for the reference * This is different from the assignments array as this one * signifies creation rather than mutation */ function createAssignment(ctx, source, value) { ctx.assignments.push({ t: 0, s: source, k: void 0, v: value }); } function createAddAssignment(ctx, ref, value) { ctx.base.assignments.push({ t: 1, s: getRefParam(ctx, ref), k: void 0, v: value }); } function createSetAssignment(ctx, ref, key, value) { ctx.base.assignments.push({ t: 2, s: getRefParam(ctx, ref), k: key, v: value }); } function createDeleteAssignment(ctx, ref, key) { ctx.base.assignments.push({ t: 3, s: getRefParam(ctx, ref), k: key, v: void 0 }); } function createArrayAssign(ctx, ref, index, value) { createAssignment(ctx.base, getRefParam(ctx, ref) + "[" + index + "]", value); } function createObjectAssign(ctx, ref, key, value) { if (key === "__proto__") { ctx.base.assignments.push({ t: 4, s: getRefParam(ctx, ref), k: value, v: void 0 }); return; } createAssignment(ctx.base, getRefParam(ctx, ref) + "." + key, value); } function createSequenceAssign(ctx, ref, index, value) { createAssignment(ctx.base, getRefParam(ctx, ref) + ".v[" + index + "]", value); } function getKeyKind(key) { const first = key.charCodeAt(0); if (first >= 48 && first <= 57) { const check = Number(key); return check >= 0 && check.toString() === key ? 2 : 0; } if (key === "Infinity") return 2; return isValidIdentifier(key) ? 1 : 0; } /** * Checks if the value is in the stack. Stack here is a reference * structure to know if a object is to be accessed in a TDZ. */ function isIndexedValueInStack(ctx, node) { return node.t === 4 && ctx.stack.includes(node.i); } /** * Checks if the node, or any node inside it, is read from more than one * place. Such a node must not be created inside a deferred assignment, * because the places that read it may run before the assignment does. */ function hasMarkedNode(ctx, node) { if (Array.isArray(node)) { for (let i = 0, len = node.length; i < len; i++) if (hasMarkedNode(ctx, node[i])) return true; return false; } if (node == null || typeof node !== "object") return false; const current = node; if (current.t !== 4 && typeof current.i === "number" && isSerializerRefMarked(ctx, current.i)) return true; for (const key in current) if (hasMarkedNode(ctx, current[key])) return true; return false; } /** * Produces an assignment expression. `id` generates a reference * parameter (through `getRefParam`) and has the option to * return the reference parameter directly or assign a value to * it. */ function assignIndexedValue(ctx, index, value) { if (!ctx.base.assignAll && !isSerializerRefMarked(ctx.base, index)) return value; /** * In cross-reference, we have to assume that * every reference are going to be referenced * in the future, and so we need to store * all of it into the reference array. * * otherwise in vanilla, we only do this if it * is actually referenced. `assignSharedRefsOnly` gives cross-reference * output the vanilla behavior. */ return getRefParam(ctx, index) + "=" + value; } function serializeReference(node) { return require_shared.REFERENCES_KEY + ".get(\"" + node.s + "\")"; } function serializeArrayItem(ctx, id, item, index) { if (item) { if (isIndexedValueInStack(ctx.base, item)) { markSerializerRef(ctx.base, id); createArrayAssign(ctx, id, index, getRefParam(ctx, item.i)); return ""; } return serialize$1(ctx, item); } return ""; } function serializeArray(ctx, node) { const id = node.i; const list = node.a; const len = list.length; if (len > 0) { ctx.base.stack.push(id); let values = serializeArrayItem(ctx, id, list[0], 0); let isHoley = values === ""; for (let i = 1, item; i < len; i++) { item = serializeArrayItem(ctx, id, list[i], i); values += "," + item; isHoley = item === ""; } ctx.base.stack.pop(); pushObjectFlag(ctx, node.o, node.i); return "[" + values + (isHoley ? ",]" : "]"); } return "[]"; } function serializeProperty(ctx, source, key, val) { if (typeof key === "string") { const kind = getKeyKind(key); if (isIndexedValueInStack(ctx.base, val)) { const refParam = getRefParam(ctx, val.i); markSerializerRef(ctx.base, source.i); createKeyAssign(ctx, source.i, kind, key, refParam); return ""; } if (key !== "__proto__") return (kind === 0 ? "\"" + key + "\"" : key) + ":" + serialize$1(ctx, val); return "[\"" + key + "\"]:" + serialize$1(ctx, val); } return "[" + serialize$1(ctx, key) + "]:" + serialize$1(ctx, val); } function serializeProperties(ctx, source, record) { const keys = record.k; const len = keys.length; if (len > 0) { const values = record.v; ctx.base.stack.push(source.i); let result = serializeProperty(ctx, source, keys[0], values[0]); for (let i = 1, item; i < len; i++) { item = serializeProperty(ctx, source, keys[i], values[i]); result += (item && result && ",") + item; } ctx.base.stack.pop(); return "{" + result + "}"; } return "{}"; } function serializeObject(ctx, node) { pushObjectFlag(ctx, node.o, node.i); return serializeProperties(ctx, node, node.p); } function serializeWithObjectAssign(ctx, source, value, serialized) { const fields = serializeProperties(ctx, source, value); if (fields !== "{}") return "Object.assign(" + serialized + "," + fields + ")"; return serialized; } function serializeStringKeyAssignment(ctx, source, mainAssignments, key, value) { const base = ctx.base; const serialized = serialize$1(ctx, value); const parentAssignment = base.assignments; if (!isIndexedValueInStack(base, value)) base.assignments = mainAssignments; createKeyAssign(ctx, source.i, getKeyKind(key), key, serialized); base.assignments = parentAssignment; } function createKeyAssign(ctx, ref, kind, key, value) { if (kind === 1) createObjectAssign(ctx, ref, key, value); else createArrayAssign(ctx, ref, kind === 2 ? key : "\"" + key + "\"", value); } function serializeAssignment(ctx, source, mainAssignments, key, value) { if (typeof key === "string") serializeStringKeyAssignment(ctx, source, mainAssignments, key, value); else { const base = ctx.base; const parent = base.stack; base.stack = []; const serialized = serialize$1(ctx, value); base.stack = parent; const parentAssignment = base.assignments; base.assignments = mainAssignments; createArrayAssign(ctx, source.i, serialize$1(ctx, key), serialized); base.assignments = parentAssignment; } } function serializeAssignments(ctx, source, node) { const keys = node.k; const len = keys.length; if (len > 0) { const mainAssignments = []; const values = node.v; ctx.base.stack.push(source.i); for (let i = 0; i < len; i++) serializeAssignment(ctx, source, mainAssignments, keys[i], values[i]); ctx.base.stack.pop(); return resolveAssignments(mainAssignments, false); } } function serializeDictionary(ctx, node, init) { if (node.p) { const base = ctx.base; if (base.features & 8 && !node.p.k.includes("__proto__")) init = serializeWithObjectAssign(ctx, node, node.p, init); else { markSerializerRef(base, node.i); const assignments = serializeAssignments(ctx, node, node.p); if (assignments) return "(" + assignIndexedValue(ctx, node.i, init) + "," + assignments + getRefParam(ctx, node.i) + ")"; } } return init; } function serializeNullConstructor(ctx, node) { pushObjectFlag(ctx, node.o, node.i); return serializeDictionary(ctx, node, NULL_CONSTRUCTOR); } function serializeDate(node) { return "new Date(\"" + require_shared.serializeString(node.s) + "\")"; } function serializeTemporal(ctx, node) { if (ctx.base.features & 64) return "Temporal." + require_shared.TEMPORAL_TYPE_NAME[node.c] + ".from(\"" + require_shared.serializeString(node.s) + "\")"; throw new require_shared.SerovalUnsupportedNodeError(node); } function serializeRegExp(ctx, node) { if (ctx.base.features & 32) { if (node.c.includes("\\x3C")) return "new RegExp(\"" + node.c + "\",\"" + node.m + "\")"; return "/" + require_shared.deserializeString(node.c) + "/" + node.m; } throw new require_shared.SerovalUnsupportedNodeError(node); } function serializeSetItem(ctx, id, item) { const base = ctx.base; if (isIndexedValueInStack(base, item)) { markSerializerRef(base, id); createAddAssignment(ctx, id, getRefParam(ctx, item.i)); return ""; } return serialize$1(ctx, item); } function serializeSet(ctx, node) { let serialized = SET_CONSTRUCTOR; const items = node.a; const size = items.length; const id = node.i; if (size > 0) { ctx.base.stack.push(id); let result = serializeSetItem(ctx, id, items[0]); for (let i = 1, item; i < size; i++) { item = serializeSetItem(ctx, id, items[i]); result += (item && result && ",") + item; } ctx.base.stack.pop(); if (result) serialized += "([" + result + "])"; } return serialized; } function serializeMapEntry(ctx, id, key, val, getSentinel) { const base = ctx.base; if (isIndexedValueInStack(base, key)) { const keyRef = getRefParam(ctx, key.i); markSerializerRef(base, id); if (isIndexedValueInStack(base, val)) { createSetAssignment(ctx, id, keyRef, getRefParam(ctx, val.i)); return ""; } if (val.t !== 4 && val.i != null && hasMarkedNode(base, val)) { markSerializerRef(base, val.i); const sentinel = getSentinel(); const serialized = "(" + serialize$1(ctx, val) + ",[" + sentinel + "," + sentinel + "])"; createSetAssignment(ctx, id, keyRef, getRefParam(ctx, val.i)); createDeleteAssignment(ctx, id, sentinel); return serialized; } const parent = base.stack; base.stack = []; createSetAssignment(ctx, id, keyRef, serialize$1(ctx, val)); base.stack = parent; return ""; } if (isIndexedValueInStack(base, val)) { const valueRef = getRefParam(ctx, val.i); markSerializerRef(base, id); if (key.t !== 4 && key.i != null && hasMarkedNode(base, key)) { markSerializerRef(base, key.i); const sentinel = getSentinel(); const serialized = "(" + serialize$1(ctx, key) + ",[" + sentinel + "," + sentinel + "])"; createSetAssignment(ctx, id, getRefParam(ctx, key.i), valueRef); createDeleteAssignment(ctx, id, sentinel); return serialized; } const parent = base.stack; base.stack = []; createSetAssignment(ctx, id, serialize$1(ctx, key), valueRef); base.stack = parent; return ""; } return "[" + serialize$1(ctx, key) + "," + serialize$1(ctx, val) + "]"; } function serializeMap(ctx, node) { let serialized = MAP_CONSTRUCTOR; const keys = node.e.k; const size = keys.length; const id = node.i; const sentinel = node.f; let sentinelRef; const getSentinel = () => { if (sentinelRef == null) { sentinelRef = getRefParam(ctx, sentinel.i); if (ctx.mode === 1) ctx.state.sentinels.add(ctx.state.valid.get(sentinel.i)); } return sentinelRef; }; const base = ctx.base; if (size > 0) { const vals = node.e.v; base.stack.push(id); let result = serializeMapEntry(ctx, id, keys[0], vals[0], getSentinel); for (let i = 1, item; i < size; i++) { item = serializeMapEntry(ctx, id, keys[i], vals[i], getSentinel); result += (item && result && ",") + item; } base.stack.pop(); if (result) serialized += "([" + result + "])"; } if (ctx.mode === 2 && sentinel.t === 26) { markSerializerRef(base, sentinel.i); serialized = "(" + serialize$1(ctx, sentinel) + "," + serialized + ")"; } return serialized; } function serializeArrayBuffer(ctx, node) { return getConstructor(ctx, node.f) + "(\"" + node.s + "\")"; } function serializeView(ctx, node) { return "new " + (node.t === 20 ? "DataView" : node.c) + "(" + serialize$1(ctx, node.f) + "," + +node.b + "," + +node.l + ")"; } function serializeAggregateError(ctx, node) { const id = node.i; ctx.base.stack.push(id); const serialized = serializeDictionary(ctx, node, "new AggregateError([],\"" + node.m + "\")"); ctx.base.stack.pop(); return serialized; } function serializeError(ctx, node) { return serializeDictionary(ctx, node, "new " + require_shared.ERROR_CONSTRUCTOR_STRING[node.s] + "(\"" + node.m + "\")"); } function serializePromise(ctx, node) { let serialized; const fulfilled = node.f; const id = node.i; const promiseConstructor = node.s ? PROMISE_RESOLVE : PROMISE_REJECT; const base = ctx.base; if (isIndexedValueInStack(base, fulfilled)) { const ref = getRefParam(ctx, fulfilled.i); serialized = promiseConstructor + (node.s ? "().then(" + createFunction([], ref) + ")" : "().catch(" + createEffectfulFunction([], "throw " + ref) + ")"); } else { base.stack.push(id); const result = serialize$1(ctx, fulfilled); base.stack.pop(); serialized = promiseConstructor + "(" + result + ")"; } return serialized; } function serializeBoxed(ctx, node) { return "Object(" + serialize$1(ctx, node.f) + ")"; } function getConstructor(ctx, node) { const current = serialize$1(ctx, node); return node.t === 4 ? current : "(" + current + ")"; } function serializePromiseConstructor(ctx, node) { if (ctx.mode === 1) throw new require_shared.SerovalUnsupportedNodeError(node); return "(" + assignIndexedValue(ctx, node.s, getConstructor(ctx, node.f) + "()") + ").p"; } function serializePromiseResult(ctx, node) { if (ctx.mode === 1) throw new require_shared.SerovalUnsupportedNodeError(node); return getConstructor(ctx, node.a[0]) + "(" + getRefParam(ctx, node.i) + "," + serialize$1(ctx, node.a[1]) + ")"; } function serializePlugin(ctx, node) { const currentPlugins = ctx.base.plugins; if (currentPlugins) for (let i = 0, len = currentPlugins.length; i < len; i++) { const plugin = currentPlugins[i]; if (plugin.tag === node.c) return plugin.serialize(node.s, { serialize: (current) => serialize$1(ctx, current) }, { id: node.i }); } throw new require_shared.SerovalMissingPluginError(node.c); } function serializeIteratorFactory(ctx, node) { let result = ""; let initialized = false; if (node.f.t !== 4) { markSerializerRef(ctx.base, node.f.i); result = "(" + serialize$1(ctx, node.f) + ","; initialized = true; } result += assignIndexedValue(ctx, node.i, "(" + require_shared.SERIALIZED_ITERATOR_CONSTRUCTOR + ")(" + getRefParam(ctx, node.f.i) + ")"); if (initialized) result += ")"; return result; } function serializeIteratorFactoryInstance(ctx, node) { return getConstructor(ctx, node.a[0]) + "(" + serialize$1(ctx, node.a[1]) + ")"; } function serializeAsyncIteratorFactory(ctx, node) { const promise = node.a[0]; const symbol = node.a[1]; const base = ctx.base; let result = ""; if (promise.t !== 4) { markSerializerRef(base, promise.i); result += "(" + serialize$1(ctx, promise); } if (symbol.t !== 4) { markSerializerRef(base, symbol.i); result += (result ? "," : "(") + serialize$1(ctx, symbol); } if (result) result += ","; const iterator = assignIndexedValue(ctx, node.i, "(" + require_shared.SERIALIZED_ASYNC_ITERATOR_CONSTRUCTOR + ")(" + getRefParam(ctx, symbol.i) + "," + getRefParam(ctx, promise.i) + ")"); if (result) return result + iterator + ")"; return iterator; } function serializeStreamConstructor(ctx, node) { const result = assignIndexedValue(ctx, node.i, getConstructor(ctx, node.f) + (node.l === 1 ? "(1)" : "()")); const len = node.a.length; if (len) { let values = serialize$1(ctx, node.a[0]); for (let i = 1; i < len; i++) values += "," + serialize$1(ctx, node.a[i]); return "(" + result + "," + values + "," + getRefParam(ctx, node.i) + ")"; } return result; } function serializeStreamCall(ctx, node, method) { return getRefParam(ctx, node.i) + "." + method + "(" + serialize$1(ctx, node.f) + ")"; } function serializeSequenceItem(ctx, id, index, item) { const base = ctx.base; if (isIndexedValueInStack(base, item)) { markSerializerRef(base, id); createSequenceAssign(ctx, id, index, getRefParam(ctx, item.i)); return ""; } return serialize$1(ctx, item); } function serializeSequence(ctx, node) { const items = node.a; const size = items.length; const id = node.i; if (size > 0) { ctx.base.stack.push(id); let result = serializeSequenceItem(ctx, id, 0, items[0]); for (let i = 1, item; i < size; i++) { item = serializeSequenceItem(ctx, id, i, items[i]); result += (item && result && ",") + item; } ctx.base.stack.pop(); if (result) return "{__SEROVAL_SEQUENCE__:!0,v:[" + result + "],t:" + +node.s + ",d:" + +node.l + "}"; } return "{__SEROVAL_SEQUENCE__:!0,v:[],t:-1,d:0}"; } function serializeAssignable(ctx, node) { switch (node.t) { case 17: return require_shared.SYMBOL_STRING[node.s]; case 18: return serializeReference(node); case 9: return serializeArray(ctx, node); case 10: return serializeObject(ctx, node); case 11: return serializeNullConstructor(ctx, node); case 5: return serializeDate(node); case 6: return serializeRegExp(ctx, node); case 7: return serializeSet(ctx, node); case 8: return serializeMap(ctx, node); case 19: return serializeArrayBuffer(ctx, node); case 16: case 15: case 20: return serializeView(ctx, node); case 14: return serializeAggregateError(ctx, node); case 13: return serializeError(ctx, node); case 12: return serializePromise(ctx, node); case 21: return serializeBoxed(ctx, node); case 22: return serializePromiseConstructor(ctx, node); case 25: return serializePlugin(ctx, node); case 26: return SPECIAL_REF_STRING[node.s]; case 35: return serializeSequence(ctx, node); case 36: return serializeTemporal(ctx, node); default: throw new require_shared.SerovalUnsupportedNodeError(node); } } function serialize$1(ctx, node) { switch (node.t) { case 2: return require_shared.CONSTANT_STRING[node.s]; case 0: return "" + node.s; case 1: return "\"" + node.s + "\""; case 3: return node.s + "n"; case 4: return getRefParam(ctx, node.i); case 23: case 24: return serializePromiseResult(ctx, node); case 27: return serializeIteratorFactory(ctx, node); case 28: case 30: return serializeIteratorFactoryInstance(ctx, node); case 29: return serializeAsyncIteratorFactory(ctx, node); case 31: return serializeStreamConstructor(ctx, node); case 32: return serializeStreamCall(ctx, node, "next"); case 33: return serializeStreamCall(ctx, node, "throw"); case 34: return serializeStreamCall(ctx, node, "return"); default: return assignIndexedValue(ctx, node.i, serializeAssignable(ctx, node)); } } function serializeVanilla(ctx, tree) { const result = serialize$1(ctx, tree); if (tree.i != null && ctx.state.vars.length) { const patches = resolvePatches(ctx.base); let body = result; if (patches) { const index = getRefParam(ctx, tree.i); body = result + "," + patches + index; if (!result.startsWith(index + "=")) body = index + "=" + body; body = "(" + body + ")"; } const sentinels = ctx.state.sentinels; if (sentinels.size) { let declarations = ""; for (const index of sentinels) declarations += ctx.state.vars[index] + "=[],"; body = "(" + declarations + body + ")"; } return "(" + createFunction(ctx.state.vars, body) + ")()"; } if (tree.t === 10) return "(" + result + ")"; return result; } function serializeCross(ctx, tree) { const result = serialize$1(ctx, tree); const id = tree.i; if (id == null) return result; const patches = resolvePatches(ctx.base); const ref = getRefParam(ctx, id); let body = result; if (patches) { if (!ctx.base.assignAll && !result.startsWith(ref + "=")) body = ref + "=" + result; body = "(" + body + "," + patches + ref + ")"; } const scopeId = ctx.state.scopeId; if (scopeId == null) { if (tree.t === 10 && !patches) return "(" + body + ")"; return body; } return "(" + createFunction(["$R"], body) + ")($R[\"" + require_shared.serializeString(scopeId) + "\"])"; } function wrapSerializationError(error) { return error instanceof require_shared.SerovalSerializationError ? error : new require_shared.SerovalSerializationError(error); } function serializeTopVanilla(ctx, tree) { try { return serializeVanilla(ctx, tree); } catch (error) { throw wrapSerializationError(error); } } function serializeTopCross(ctx, tree) { try { return serializeCross(ctx, tree); } catch (error) { throw wrapSerializationError(error); } } //#endregion //#region src/core/context/sync-parser.ts function createSyncParserContext(options) { return { type: 1, base: createBaseParserContext(options) }; } function parseItems(ctx, depth, current) { assertArrayHoles(current); const len = current.length; const nodes = new Array(len); for (let i = 0; i < len; i++) if (i in current) nodes[i] = parseSOS(ctx, depth, current[i]); else nodes[i] = 0; return nodes; } function parseArray(ctx, depth, id, current) { return createArrayNode(id, current, parseItems(ctx, depth, current)); } function parseProperties(ctx, depth, properties) { const keys = Object.keys(properties); const len = keys.length; const keyNodes = new Array(len); const valueNodes = new Array(len); for (let i = 0, key; i < len; i++) { key = keys[i]; keyNodes[i] = require_shared.serializeString(key); valueNodes[i] = parseSOS(ctx, depth, properties[key]); } if (require_shared.SYM_ITERATOR in properties) { keyNodes.push(parseWellKnownSymbol(ctx.base, require_shared.SYM_ITERATOR)); valueNodes.push(createIteratorFactoryInstanceNode(28, parseIteratorFactory(ctx.base), parseSOS(ctx, depth, require_shared.createSequenceFromIterable(properties)))); } if (require_shared.SYM_ASYNC_ITERATOR in properties) { keyNodes.push(parseWellKnownSymbol(ctx.base, require_shared.SYM_ASYNC_ITERATOR)); valueNodes.push(createIteratorFactoryInstanceNode(30, parseAsyncIteratorFactory(ctx.base), parseAsyncIterable(ctx, depth, properties))); } if (require_shared.SYM_TO_STRING_TAG in properties) { keyNodes.push(parseWellKnownSymbol(ctx.base, require_shared.SYM_TO_STRING_TAG)); valueNodes.push(createStringNode(properties[require_shared.SYM_TO_STRING_TAG])); } if (require_shared.SYM_IS_CONCAT_SPREADABLE in properties) { keyNodes.push(parseWellKnownSymbol(ctx.base, require_shared.SYM_IS_CONCAT_SPREADABLE)); valueNodes.push(properties[require_shared.SYM_IS_CONCAT_SPREADABLE] ? TRUE_NODE : FALSE_NODE); } return { k: keyNodes, v: valueNodes }; } function parseAsyncIterable(ctx, depth, current) { if (ctx.type !== 2) throw new require_shared.SerovalUnsupportedTypeError(current); const id = createIndexForValue(ctx.base, {}); const result = createStreamConstructorNode(id, parseSpecialReference(ctx.base, 4), []); ctx.state.iterable(ctx, depth, id, current); return result; } function parsePlainObject(ctx, depth, id, current, empty) { return createObjectNode(id, current, empty, parseProperties(ctx, depth, current)); } function parseBoxed(ctx, depth, id, current) { return createBoxedNode(id, parseSOS(ctx, depth, current.valueOf())); } function parseView(ctx, depth, type, id, current) { const view = getArrayBufferView(ctx.base, require_typed_array.readArrayBufferView(current, type === 20)); return createViewNode(type, id, current, view, parseSOS(ctx, depth, view.buffer)); } function parseError(ctx, depth, type, id, current) { const options = getErrorOptions(current, ctx.base.features); return createErrorNode(type, id, current, options ? parseProperties(ctx, depth, options) : void 0); } function parseMap(ctx, depth, id, current) { const sentinel = parseMapSentinel(ctx.base); const keyNodes = new Array(current.size); const valueNodes = new Array(current.size); let i = 0; for (const [key, value] of current.entries()) { keyNodes[i] = parseSOS(ctx, depth, key); valueNodes[i] = parseSOS(ctx, depth, value); i++; } return createMapNode(id, sentinel, keyNodes, valueNodes); } function parseSet(ctx, depth, id, current) { const items = new Array(current.size); let i = 0; for (const item of current.keys()) items[i++] = parseSOS(ctx, depth, item); return createSetNode(id, items); } /** * Sends the events of a stream that has ended, so the copy gets all of them. * A stream that is still open throws, because the other sync modes cannot * send its later events. */ function parseEndedStream(ctx, depth, id, current) { const events = current.endedEvents(); if (!events) throw new require_shared.SerovalUnsupportedTypeError(current); const values = events.values; const last = values.length - 1; const sequence = new Array(values.length); if (last >= 0) markParserRef(ctx.base, id); for (let i = 0; i <= last; i++) sequence[i] = createStreamEventNode(i < last ? 32 : events.success ? 34 : 33, id, parseSOS(ctx, depth, values[i])); return sequence; } function parseStream(ctx, depth, id, current) { const reference = parseSpecialReference(ctx.base, 4); if (ctx.type === 2) { const result = createStreamConstructorNode(id, reference, []); ctx.state.stream(ctx, depth, id, current); return result; } return createStreamConstructorNode(id, reference, parseEndedStream(ctx, depth, id, current)); } function parseLiveStream(ctx, depth, id, current) { if (ctx.type !== 2) throw new require_shared.SerovalUnsupportedTypeError(current); const result = createStreamConstructorNode(id, parseSpecialReference(ctx.base, 4), [], 1); ctx.state.live(ctx, depth, id, current); return result; } function parsePromise(ctx, depth, id, current) { if (ctx.type !== 2) throw new require_shared.SerovalUnsupportedTypeError(current); const resolver = createIndexForValue(ctx.base, {}); ctx.state.promise(ctx, resolver, depth, current); return createPromiseConstructorNode(ctx.base, id, resolver); } function parsePluginSync(ctx, depth, id, current, currentPlugins) { for (let i = 0, len = currentPlugins.length; i < len; i++) { const plugin = currentPlugins[i]; if (plugin.parse.sync && plugin.test(current)) return createPluginNode(id, plugin.tag, plugin.parse.sync(current, { parse: (value) => parseSOS(ctx, depth, value) }, { id })); } } function parsePlugin(ctx, depth, id, current, currentPlugins) { if (currentPlugins) return ctx.type === 1 ? parsePluginSync(ctx, depth, id, current, currentPlugins) : ctx.state.plugin(ctx, depth, id, current, currentPlugins); } function parseSequence(ctx, depth, id, current) { const len = current.v.length; const nodes = new Array(len); for (let i = 0; i < len; i++) nodes[i] = parseSOS(ctx, depth, current.v[i]); return createSequenceNode(id, nodes, current.t, current.d); } function parseObjectPhase2(ctx, depth, id, current, currentClass) { if (currentClass === Object) return parsePlainObject(ctx, depth, id, current, false); switch (getObjectKind(current, currentClass, ctx.base.features)) { case 2: return parsePlainObject(ctx, depth, id, current, true); case 3: return createDateNode(id, current); case 4: return parseError(ctx, depth, 13, id, current); case 5: return parseError(ctx, depth, 14, id, current); case 6: return parseBoxed(ctx, depth, id, current); case 7: return createArrayBufferNode(ctx.base, id, current); case 8: return parseView(ctx, depth, 15, id, current); case 9: return parseView(ctx, depth, 16, id, current); case 10: return parseView(ctx, depth, 20, id, current); case 11: return parseMap(ctx, depth, id, current); case 12: return parseSet(ctx, depth, id, current); case 13: return parsePromise(ctx, depth, id, current); case 14: return createRegExpNode(id, current); case 15: return createTemporalNode(id, getTemporalType(currentClass), currentClass, current); case 16: return parsePlainObject(ctx, depth, id, current, !!currentClass); default: throw new require_shared.SerovalUnsupportedTypeError(current); } } function parseObject(ctx, depth, id, current) { if (Array.isArray(current)) return parseArray(ctx, depth, id, current); if (require_shared.isLiveStream(current)) return parseLiveStream(ctx, depth, id, current); if (current instanceof require_shared.Stream) return parseStream(ctx, depth, id, current); if (require_shared.isSequence(current)) return parseSequence(ctx, depth, id, current); const currentClass = getObjectClass(current); if (currentClass === require_shared.OpaqueReference) return parseSOS(ctx, depth, current.replacement); const parsed = parsePlugin(ctx, depth, id, current, getObjectPlugins(ctx.base, current, currentClass)); if (parsed) return parsed; return parseObjectPhase2(ctx, depth, id, current, currentClass); } function parseFunction(ctx, depth, current) { const ref = getReferenceNode(ctx.base, current); if (typeof ref !== "number") return ref; const plugin = parsePlugin(ctx, depth, ref, current, ctx.base.plugins); if (plugin) return plugin; throw new require_shared.SerovalUnsupportedTypeError(current); } function parseSOS(ctx, depth, current) { if (depth >= ctx.base.depthLimit) throw new require_shared.SerovalDepthLimitError(ctx.base.depthLimit); switch (typeof current) { case "boolean": return current ? TRUE_NODE : FALSE_NODE; case "undefined": return UNDEFINED_NODE; case "string": return createStringNode(current); case "number": return createNumberNode(current); case "bigint": return createBigIntNode(current); case "object": if (current) { const ref = getReferenceNode(ctx.base, current); return typeof ref === "number" ? parseObject(ctx, depth + 1, ref, current) : ref; } return NULL_NODE; case "symbol": return parseWellKnownSymbol(ctx.base, current); case "function": return parseFunction(ctx, depth, current); default: throw new require_shared.SerovalUnsupportedTypeError(current); } } function parseTop(ctx, current) { const refs = ctx.base.refs; const size = refs.size; try { return parseSOS(ctx, 0, current); } catch (error) { rollbackRefs(refs, size); throw error instanceof require_shared.SerovalParserError ? error : new require_shared.SerovalParserError(error); } } //#endregion //#region src/core/context/stream-parser.ts /** * Streaming parse mode. Everything here is reached through the function * fields of the stream parser state, which only `createStreamParserContext` * sets, so synchronous consumers (`serialize`, `toJSON`) never bundle it. */ function createStreamParsePluginContext(ctx, depth) { const state = ctx.state; function parse(current) { state.parsing++; try { return parseSOS(ctx, depth, current); } finally { state.parsing--; if (!state.alive) releaseParserValues(ctx); } } return { parse, parseStreamSource(current) { state.parsing++; try { if (depth >= ctx.base.depthLimit) throw new require_shared.SerovalDepthLimitError(ctx.base.depthLimit); const id = createIndexForValue(ctx.base, {}); const node = createStreamConstructorNode(id, parseSpecialReference(ctx.base, 4), [], 1); iterateAsync(ctx, depth + 1, id, current, true); return node; } finally { state.parsing--; if (!state.alive) releaseParserValues(ctx); } }, parseWithError(current) { try { return parse(current); } catch (error) { stopStreamParse(ctx, 1, error); return; } }, isAlive: () => state.alive, pushPendingState: () => { pushPendingState(ctx); }, popPendingState: () => { popPendingState(ctx); }, onParse(node) { if (state.alive) { state.queue.push({ node, initial: false, accept: void 0, refs: ctx.base.refs.size }); drainOutput(ctx); } }, onError(error) { stopStreamParse(ctx, 1, error); }, addCleanup(callback) { addCleanup(ctx, callback); } }; } function getStreamParsePluginContext(ctx, depth) { const contexts = ctx.state.pluginContexts; return contexts[depth] ?? (contexts[depth] = createStreamParsePluginContext(ctx, depth)); } function addCleanup(ctx, callback) { if (ctx.state.alive) ctx.state.cleanups.push(callback); else callback(); } function parsePluginStream(ctx, depth, id, current, currentPlugins) { for (let i = 0, len = currentPlugins.length; i < len; i++) { const plugin = currentPlugins[i]; if (plugin.parse.stream && plugin.test(current)) return createPluginNode(id, plugin.tag, plugin.parse.stream(current, getStreamParsePluginContext(ctx, depth), { id })); } } /** * One listener shape serves both `Stream.on` (no accept) and * `LiveStream.pump` (accept tied to record acceptance). Handlers return the * parse error so the pump can stop the source. */ function streamListener(ctx, depth, id, subscription) { const handle = (type, terminal) => (value, accept) => { let failure = void 0; if (ctx.state.alive) try { failure = parseEvent(ctx, depth, value, createStreamEventNode.bind(null, type, id), accept); } catch (error) { if (!subscription?.active) throw error; subscription.failure ?? (subscription.failure = { value: error }); failure = error; } if (terminal && !accept) popPendingState(ctx); return failure; }; return { next: handle(32, false), throw: handle(33, true), return: handle(34, true), done() { popPendingState(ctx); }, error(reason) { if (ctx.state.alive) stopStreamParse(ctx, 1, reason); } }; } function subscribeStream(ctx, depth, id, current) { pushPendingState(ctx); const subscription = { active: true, failure: void 0 }; let cleanup; try { cleanup = current.on(streamListener(ctx, depth, id, subscription)); } finally { subscription.active = false; } try { addCleanup(ctx, cleanup); } catch (error) { subscription.failure ?? (subscription.failure = { value: error }); } const failure = subscription.failure; subscription.failure = void 0; if (failure) throw failure.value; } function consumeLiveStream(ctx, depth, id, current) { const cancel = current.pump(streamListener(ctx, depth, id)); pushPendingState(ctx); addCleanup(ctx, () => { cancel(ctx.state.reason); }); } function wrapPromiseResult(ctx, type, id, node) { return createSerovalNode(type, id, void 0, void 0, void 0, void 0, void 0, [parseSpecialReference(ctx.base, type === 23 ? 2 : 3), node]); } function handlePromise(type, id, depth, data) { if (this.state.alive) parseEvent(this, depth, data, wrapPromiseResult.bind(null, this, type, id), void 0); popPendingState(this); } function watchPromise(ctx, resolver, depth, current) { pushPendingState(ctx); let settled = false; current.then((data) => { if (!settled) { settled = true; handlePromise.call(ctx, 23, resolver, depth, data); } }, (data) => { if (!settled) { settled = true; handlePromise.call(ctx, 24, resolver, depth, data); } }); } function returnIterator(iterator) { Promise.resolve().then(() => iterator.return?.()).catch(() => {}); } /** * Drives an async iterator directly. The next value is pulled only after the * record for the previous one has been accepted, and cancellation returns * the iterator once. */ function iterateAsync(ctx, depth, id, current, forwardReason) { const iterator = current[require_shared.SYM_ASYNC_ITERATOR](); const listener = streamListener(ctx, depth, id); let active = true; function stop() { if (active) { active = false; if (forwardReason) try { Promise.resolve(iterator.return?.(ctx.state.reason)).catch(() => {}); } catch {} else returnIterator(iterator); } } function pull() { if (active) iterator.next().then((result) => { if (active) { if (result.done) { active = false; listener.return(result.value, void 0); } else if (listener.next(result.value, pull) !== void 0) { stop(); listener.done(); } } }, (error) => { if (active) { active = false; listener.throw(error, void 0); } }); } pushPendingState(ctx); addCleanup(ctx, stop); pull(); } function createStreamParserState(options) { return { alive: true, pending: 0, parsing: 0, queue: [], head: 0, writing: false, inFlight: void 0, reason: void 0, starting: false, onParse: options.onParse, onError: options.onError, onDone: options.onDone, cleanups: [], pluginContexts: [], stream: subscribeStream, live: consumeLiveStream, promise: watchPromise, iterable: iterateAsync, plugin: parsePluginStream }; } function createStreamParserContext(options) { return { type: 2, base: createBaseParserContext(options), state: createStreamParserState(options) }; } function pushPendingState(ctx) { if (ctx.state.alive) ctx.state.pending++; } function popPendingState(ctx) { if (ctx.state.alive) { ctx.state.pending--; checkStreamParse(ctx); } } /** * Parses a value that arrived after the root. Its record is queued before * parsing starts so that records discovered inside it follow it, and it is * dropped again if parsing fails. Returns the parse error after reporting * it, or `undefined`. */ function parseEvent(ctx, depth, value, wrap, accept) { const state = ctx.state; const record = { node: void 0, initial: false, accept, refs: ctx.base.refs.size }; let failure; state.queue.push(record); state.parsing++; try { record.node = wrap(parseSOS(ctx, depth, value)); } catch (error) { failure = { value: error }; } finally { state.parsing--; if (!state.alive) releaseParserValues(ctx); } if (failure) stopStreamParse(ctx, 1, failure.value); else drainOutput(ctx); return failure?.value; } function takeRecord(state) { const record = state.queue[state.head]; state.queue[state.head++] = void 0; if (state.head === state.queue.length) { state.queue.length = 0; state.head = 0; } else if (state.head > 1024 && state.head * 2 > state.queue.length) { state.queue.splice(0, state.head); state.head = 0; } return record; } /** * Emits queued records one at a time. A callback that returns a promise * pauses emission until it settles; the source event behind the record is * accepted only after that. */ function drainOutput(ctx) { const state = ctx.state; if (state.writing || state.parsing > 0) return; while (state.alive && state.head < state.queue.length) { const record = takeRecord(state); if (!record.node) continue; let pending; state.writing = true; state.inFlight = record; state.parsing++; try { if (!state.onParse) throw new Error("Stream output callback is unavailable"); const result = state.onParse(record.node, record.initial); if (result !== null && (typeof result === "object" || typeof result === "function")) { const then = Reflect.get(result, "then"); if (typeof then === "function") pending = new Promise((resolve, reject) => { Reflect.apply(then, result, [resolve, reject]); }); } } catch (error) { releaseRecord(record); stopStreamParse(ctx, 1, error); return; } finally { state.parsing--; if (!state.alive) releaseParserValues(ctx); } record.node = void 0; if (pending) { if (!state.alive) releaseRecord(record); pending.then(() => { state.writing = false; state.inFlight = void 0; if (state.alive) { const accept = record.accept; releaseRecord(record); accept?.(); drainOutput(ctx); } }, (error) => { state.writing = false; state.inFlight = void 0; releaseRecord(record); stopStreamParse(ctx, 1, error); }); return; } if (!state.alive) { releaseRecord(record); return; } state.writing = false; state.inFlight = void 0; const accept = record.accept; releaseRecord(record); accept?.(); } checkStreamParse(ctx); } function checkStreamParse(ctx) { const state = ctx.state; if (state.alive && state.parsing === 0 && state.pending <= 0 && state.head === state.queue.length && !state.writing) stopStreamParse(ctx, 0); } function startStreamParse(ctx, current) { const state = ctx.state; let parsed; let failure; const refs = ctx.base.refs; const size = refs.size; state.starting = true; try { state.parsing++; try { parsed = parseSOS(ctx, 0, current); } catch (error) { failure = { value: error }; } finally { state.parsing--; if (!state.alive) releaseParserValues(ctx); } if (failure) { rollbackRefs(refs, size); if (state.alive) stopStreamParse(ctx, 1, failure.value); else throw failure.value; } else if (parsed && state.alive) { state.queue.unshift({ node: parsed, initial: true, accept: void 0, refs: size }); drainOutput(ctx); } } finally { state.starting = false; } } function runCleanups(state) { const cleanups = state.cleanups; let failure; state.cleanups = []; for (const record of state.queue) if (record) releaseRecord(record); state.queue.length = 0; state.head = 0; if (state.inFlight) releaseRecord(state.inFlight); state.inFlight = void 0; for (let i = 0, len = cleanups.length; i < len; i++) try { cleanups[i](); } catch (error) { failure ?? (failure = { value: error }); } if (failure) throw failure.value; } function releaseRecord(record) { record.node = void 0; record.accept = void 0; } function releaseParserValues(ctx) { ctx.base.refs = /* @__PURE__ */ new Map(); ctx.base.marked.clear(); ctx.base.plugins = void 0; ctx.base.plainObjectPlugins = void 0; ctx.state.pluginContexts = []; if (ctx.state.parsing === 0) ctx.state.reason = void 0; } /** * Ends the parse once: `onDone` on success, `onError` on failure, and every * cleanup either way. */ function stopStreamParse(ctx, mode, reason) { const state = ctx.state; if (state.alive) { state.alive = false; const unsent = state.queue[state.head]; if (mode !== 0 && unsent) rollbackRefs(ctx.base.refs, unsent.refs); const onError = state.onError; const onDone = state.onDone; if (mode === 1 && !onError && !(reason instanceof require_shared.SerovalParserError)) reason = new require_shared.SerovalParserError(reason); state.reason = reason; state.onParse = void 0; state.onError = void 0; state.onDone = void 0; state.writing = false; state.parsing++; let failure; try { if (mode === 1) { if (onError) onError(reason); else if (state.starting) throw reason; } else if (mode === 0) onDone?.(); } catch (error) { failure = { value: error }; } try { runCleanups(state); } catch (error) { failure ?? (failure = { value: error }); } finally { state.parsing--; releaseParserValues(ctx); state.pending = 0; } if (failure) throw failure.value; } } function destroyStreamParse(ctx, reason) { stopStreamParse(ctx, 2, reason); } //#endregion //#region src/core/cross/write.ts function crossSerialize(source, options = {}) { const plugins = require_shared.resolvePlugins(options.plugins); const ctx = createSyncParserContext({ compactArrayBufferViews: options.compactArrayBufferViews, depthLimit: options.depthLimit, plugins, disabledFeatures: options.disabledFeatures, refs: options.refs }); const tree = parseTop(ctx, source); return serializeTopCross(createCrossSerializerContext({ plugins, features: ctx.base.features, scopeId: options.scopeId, markedRefs: ctx.base.marked, assignSharedRefsOnly: options.assignSharedRefsOnly }), tree); } async function crossSerializeAsync(source, options = {}) { const plugins = require_shared.resolvePlugins(options.plugins); const ctx = createAsyncParserContext({ compactArrayBufferViews: options.compactArrayBufferViews, depthLimit: options.depthLimit, plugins, disabledFeatures: options.disabledFeatures, refs: options.refs }); const tree = await parseTopAsync(ctx, source); return serializeTopCross(createCrossSerializerContext({ plugins, features: ctx.base.features, scopeId: options.scopeId, markedRefs: ctx.base.marked, assignSharedRefsOnly: options.assignSharedRefsOnly }), tree); } function toCrossJSON(source, options = {}) { const plugins = require_shared.resolvePlugins(options.plugins); return parseTop(createSyncParserContext({ compactArrayBufferViews: options.compactArrayBufferViews, depthLimit: options.depthLimit, plugins, disabledFeatures: options.disabledFeatures, refs: options.refs }), source); } async function toCrossJSONAsync(source, options = {}) { const plugins = require_shared.resolvePlugins(options.plugins); return await parseTopAsync(createAsyncParserContext({ compactArrayBufferViews: options.compactArrayBufferViews, depthLimit: options.depthLimit, plugins, disabledFeatures: options.disabledFeatures, refs: options.refs }), source); } function crossSerializeStream(source, options) { const plugins = require_shared.resolvePlugins(options.plugins); const onSerialize = options.onSerialize; const scopeId = options.scopeId; const ctx = createStreamParserContext({ compactArrayBufferViews: options.compactArrayBufferViews, depthLimit: options.depthLimit, plugins, refs: options.refs, disabledFeatures: options.disabledFeatures, onParse(node, initial) { const serial = createCrossSerializerContext({ plugins, features: ctx.base.features, scopeId, markedRefs: ctx.base.marked }); return onSerialize(serializeTopCross(serial, node), initial); }, onError: options.onError, onDone: options.onDone }); startStreamParse(ctx, source); return destroyStreamParse.bind(null, ctx); } function toCrossJSONStream(source, options) { const plugins = require_shared.resolvePlugins(options.plugins); const ctx = createStreamParserContext({ compactArrayBufferViews: options.compactArrayBufferViews, plugins, refs: options.refs, disabledFeatures: options.disabledFeatures, depthLimit: options.depthLimit, onParse: options.onParse, onError: options.onError, onDone: options.onDone }); startStreamParse(ctx, source); return destroyStreamParse.bind(null, ctx); } //#endregion //#region src/core/Serializer.ts var Serializer = class { constructor(options) { this.alive = true; this.flushed = false; this.done = false; this.pending = 0; this.cleanups = []; this.refs = /* @__PURE__ */ new Map(); this.keys = /* @__PURE__ */ new Set(); this.ids = 0; this.options = options; this.plugins = require_shared.resolvePlugins(options.plugins); } write(key, value) { const options = this.options; if (this.alive && !this.flushed && options) { this.pending++; this.keys.add(key); let starting = true; const cleanup = crossSerializeStream(value, { plugins: this.plugins, scopeId: options.scopeId, refs: this.refs, disabledFeatures: options.disabledFeatures, compactArrayBufferViews: options.compactArrayBufferViews, depthLimit: options.depthLimit, onError: (error) => { let failure; try { if (options.onError) options.onError(error); else if (starting) throw error instanceof require_shared.SerovalParserError ? error : new require_shared.SerovalParserError(error); } catch (handlerError) { failure = { value: handlerError }; } try { this.finishWrite(); } catch (finishError) { failure ?? (failure = { value: finishError }); } if (failure) throw failure.value; }, onSerialize: (data, initial) => { const current = this.options; if (this.alive && current) current.onData(initial ? current.globalIdentifier + "[\"" + require_shared.serializeString(key) + "\"]=" + data : data); }, onDone: () => { this.finishWrite(); } }); starting = false; if (this.alive) this.cleanups.push(cleanup); else cleanup(); } } finishWrite() { if (this.alive) { this.pending--; if (this.pending <= 0 && this.flushed && !this.done) this.close(); } } getNextID() { while (this.keys.has("" + this.ids)) this.ids++; return "" + this.ids; } push(value) { const newID = this.getNextID(); this.write(newID, value); return newID; } flush() { if (this.alive) { this.flushed = true; if (this.pending <= 0 && !this.done) this.close(); } } close() { this.finish(); } finish() { if (this.alive) { this.alive = false; const options = this.options; this.options = void 0; this.plugins = void 0; const cleanups = this.cleanups; this.cleanups = []; let failure; for (let index = 0, length = cleanups.length; index < length; index++) try { cleanups[index](); } catch (error) { failure ?? (failure = { value: error }); } this.refs.clear(); if (!this.done) { this.done = true; try { options?.onDone?.(); } catch (error) { failure ?? (failure = { value: error }); } } if (failure) throw failure.value; } } }; //#endregion //#region src/core/tree/write.ts function serialize(source, options = {}) { const plugins = require_shared.resolvePlugins(options.plugins); const ctx = createSyncParserContext({ compactArrayBufferViews: options.compactArrayBufferViews, depthLimit: options.depthLimit, plugins, disabledFeatures: options.disabledFeatures }); const tree = parseTop(ctx, source); return serializeTopVanilla(createVanillaSerializerContext({ plugins, features: ctx.base.features, markedRefs: ctx.base.marked }), tree); } async function serializeAsync(source, options = {}) { const plugins = require_shared.resolvePlugins(options.plugins); const ctx = createAsyncParserContext({ compactArrayBufferViews: options.compactArrayBufferViews, depthLimit: options.depthLimit, plugins, disabledFeatures: options.disabledFeatures }); const tree = await parseTopAsync(ctx, source); return serializeTopVanilla(createVanillaSerializerContext({ plugins, features: ctx.base.features, markedRefs: ctx.base.marked }), tree); } function toJSON(source, options = {}) { const plugins = require_shared.resolvePlugins(options.plugins); const ctx = createSyncParserContext({ compactArrayBufferViews: options.compactArrayBufferViews, depthLimit: options.depthLimit, plugins, disabledFeatures: options.disabledFeatures }); return { t: parseTop(ctx, source), f: ctx.base.features, m: Array.from(ctx.base.marked) }; } async function toJSONAsync(source, options = {}) { const plugins = require_shared.resolvePlugins(options.plugins); const ctx = createAsyncParserContext({ compactArrayBufferViews: options.compactArrayBufferViews, depthLimit: options.depthLimit, plugins, disabledFeatures: options.disabledFeatures }); return { t: await parseTopAsync(ctx, source), f: ctx.base.features, m: Array.from(ctx.base.marked) }; } function compileJSON(source, options = {}) { return serializeTopVanilla(createVanillaSerializerContext({ plugins: require_shared.resolvePlugins(options.plugins), features: source.f, markedRefs: source.m }), source.t); } //#endregion Object.defineProperty(exports, "Serializer", { enumerable: true, get: function() { return Serializer; } }); Object.defineProperty(exports, "compileJSON", { enumerable: true, get: function() { return compileJSON; } }); Object.defineProperty(exports, "crossSerialize", { enumerable: true, get: function() { return crossSerialize; } }); Object.defineProperty(exports, "crossSerializeAsync", { enumerable: true, get: function() { return crossSerializeAsync; } }); Object.defineProperty(exports, "crossSerializeStream", { enumerable: true, get: function() { return crossSerializeStream; } }); Object.defineProperty(exports, "serialize", { enumerable: true, get: function() { return serialize; } }); Object.defineProperty(exports, "serializeAsync", { enumerable: true, get: function() { return serializeAsync; } }); Object.defineProperty(exports, "toCrossJSON", { enumerable: true, get: function() { return toCrossJSON; } }); Object.defineProperty(exports, "toCrossJSONAsync", { enumerable: true, get: function() { return toCrossJSONAsync; } }); Object.defineProperty(exports, "toCrossJSONStream", { enumerable: true, get: function() { return toCrossJSONStream; } }); Object.defineProperty(exports, "toJSON", { enumerable: true, get: function() { return toJSON; } }); Object.defineProperty(exports, "toJSONAsync", { enumerable: true, get: function() { return toJSONAsync; } });