UNPKG

seroval

Version:
2,075 lines (2,046 loc) 107 kB
// src/core/compat.ts var Feature = /* @__PURE__ */ ((Feature2) => { Feature2[Feature2["AggregateError"] = 1] = "AggregateError"; Feature2[Feature2["ArrowFunction"] = 2] = "ArrowFunction"; Feature2[Feature2["ErrorPrototypeStack"] = 4] = "ErrorPrototypeStack"; Feature2[Feature2["ObjectAssign"] = 8] = "ObjectAssign"; Feature2[Feature2["BigIntTypedArray"] = 16] = "BigIntTypedArray"; Feature2[Feature2["AbortSignal"] = 32] = "AbortSignal"; return Feature2; })(Feature || {}); var ALL_ENABLED = 47; // src/core/string.ts function serializeChar(str) { switch (str) { case '"': return '\\"'; case "\\": return "\\\\"; case "\n": return "\\n"; case "\r": return "\\r"; case "\b": return "\\b"; case " ": return "\\t"; case "\f": return "\\f"; case "<": return "\\x3C"; case "\u2028": return "\\u2028"; case "\u2029": return "\\u2029"; default: return void 0; } } function serializeString(str) { let result = ""; let lastPos = 0; let replacement; for (let i = 0, len = str.length; i < len; i++) { replacement = serializeChar(str[i]); if (replacement) { result += str.slice(lastPos, i) + replacement; lastPos = i + 1; } } if (lastPos === 0) { result = str; } else { result += str.slice(lastPos); } return result; } function deserializeReplacer(str) { switch (str) { case "\\\\": return "\\"; case '\\"': return '"'; case "\\n": return "\n"; case "\\r": return "\r"; case "\\b": return "\b"; case "\\t": return " "; case "\\f": return "\f"; case "\\x3C": return "<"; case "\\u2028": return "\u2028"; case "\\u2029": return "\u2029"; default: return str; } } function deserializeString(str) { return str.replace( /(\\\\|\\"|\\n|\\r|\\b|\\t|\\f|\\u2028|\\u2029|\\x3C)/g, deserializeReplacer ); } // src/core/keys.ts var REFERENCES_KEY = "__SEROVAL_REFS__"; var GLOBAL_CONTEXT_REFERENCES = "$R"; var GLOBAL_CONTEXT_R = `self.${GLOBAL_CONTEXT_REFERENCES}`; function getCrossReferenceHeader(id) { if (id == null) { return `${GLOBAL_CONTEXT_R}=${GLOBAL_CONTEXT_R}||[]`; } return `(${GLOBAL_CONTEXT_R}=${GLOBAL_CONTEXT_R}||{})["${serializeString( id )}"]=[]`; } // src/core/utils/assert.ts function assert(cond, error) { if (!cond) { throw error; } } // src/core/reference.ts var REFERENCE = /* @__PURE__ */ new Map(); var INV_REFERENCE = /* @__PURE__ */ new Map(); function createReference(id, value) { REFERENCE.set(value, id); INV_REFERENCE.set(id, value); return value; } function hasReferenceID(value) { return REFERENCE.has(value); } function hasReference(id) { return INV_REFERENCE.has(id); } function getReferenceID(value) { assert(hasReferenceID(value), new SerovalMissingReferenceError(value)); return REFERENCE.get(value); } function getReference(id) { assert(hasReference(id), new SerovalMissingReferenceForIdError(id)); return INV_REFERENCE.get(id); } if (typeof globalThis !== "undefined") { Object.defineProperty(globalThis, REFERENCES_KEY, { value: INV_REFERENCE, configurable: true, writable: false, enumerable: false }); } else if (typeof window !== "undefined") { Object.defineProperty(window, REFERENCES_KEY, { value: INV_REFERENCE, configurable: true, writable: false, enumerable: false }); } else if (typeof self !== "undefined") { Object.defineProperty(self, REFERENCES_KEY, { value: INV_REFERENCE, configurable: true, writable: false, enumerable: false }); } else if (typeof global !== "undefined") { Object.defineProperty(global, REFERENCES_KEY, { value: INV_REFERENCE, configurable: true, writable: false, enumerable: false }); } // src/core/plugin.ts function createPlugin(plugin) { return plugin; } function dedupePlugins(deduped, plugins) { for (let i = 0, len = plugins.length; i < len; i++) { const current = plugins[i]; if (!deduped.has(current)) { deduped.add(current); if (current.extends) { dedupePlugins(deduped, current.extends); } } } } function resolvePlugins(plugins) { if (plugins) { const deduped = /* @__PURE__ */ new Set(); dedupePlugins(deduped, plugins); return [...deduped]; } return void 0; } // src/core/abort-signal.ts function resolveAbortSignalResult(resolve) { resolve(this.reason); } function resolveAbortSignal(resolve) { this.addEventListener("abort", resolveAbortSignalResult.bind(this, resolve), { once: true }); } function abortSignalToPromise(signal) { return new Promise(resolveAbortSignal.bind(signal)); } // src/core/constants.ts var SYMBOL_STRING = { [0 /* AsyncIterator */]: "Symbol.asyncIterator", [1 /* HasInstance */]: "Symbol.hasInstance", [2 /* IsConcatSpreadable */]: "Symbol.isConcatSpreadable", [3 /* Iterator */]: "Symbol.iterator", [4 /* Match */]: "Symbol.match", [5 /* MatchAll */]: "Symbol.matchAll", [6 /* Replace */]: "Symbol.replace", [7 /* Search */]: "Symbol.search", [8 /* Species */]: "Symbol.species", [9 /* Split */]: "Symbol.split", [10 /* ToPrimitive */]: "Symbol.toPrimitive", [11 /* ToStringTag */]: "Symbol.toStringTag", [12 /* Unscopables */]: "Symbol.unscopables" }; var INV_SYMBOL_REF = { [Symbol.asyncIterator]: 0 /* AsyncIterator */, [Symbol.hasInstance]: 1 /* HasInstance */, [Symbol.isConcatSpreadable]: 2 /* IsConcatSpreadable */, [Symbol.iterator]: 3 /* Iterator */, [Symbol.match]: 4 /* Match */, [Symbol.matchAll]: 5 /* MatchAll */, [Symbol.replace]: 6 /* Replace */, [Symbol.search]: 7 /* Search */, [Symbol.species]: 8 /* Species */, [Symbol.split]: 9 /* Split */, [Symbol.toPrimitive]: 10 /* ToPrimitive */, [Symbol.toStringTag]: 11 /* ToStringTag */, [Symbol.unscopables]: 12 /* Unscopables */ }; var SYMBOL_REF = { [0 /* AsyncIterator */]: Symbol.asyncIterator, [1 /* HasInstance */]: Symbol.hasInstance, [2 /* IsConcatSpreadable */]: Symbol.isConcatSpreadable, [3 /* Iterator */]: Symbol.iterator, [4 /* Match */]: Symbol.match, [5 /* MatchAll */]: Symbol.matchAll, [6 /* Replace */]: Symbol.replace, [7 /* Search */]: Symbol.search, [8 /* Species */]: Symbol.species, [9 /* Split */]: Symbol.split, [10 /* ToPrimitive */]: Symbol.toPrimitive, [11 /* ToStringTag */]: Symbol.toStringTag, [12 /* Unscopables */]: Symbol.unscopables }; var CONSTANT_STRING = { [2 /* True */]: "!0", [3 /* False */]: "!1", [1 /* Undefined */]: "void 0", [0 /* Null */]: "null", [4 /* NegZero */]: "-0", [5 /* Inf */]: "1/0", [6 /* NegInf */]: "-1/0", [7 /* Nan */]: "0/0" }; var CONSTANT_VAL = { [2 /* True */]: true, [3 /* False */]: false, [1 /* Undefined */]: void 0, [0 /* Null */]: null, [4 /* NegZero */]: -0, [5 /* Inf */]: Number.POSITIVE_INFINITY, [6 /* NegInf */]: Number.NEGATIVE_INFINITY, [7 /* Nan */]: Number.NaN }; var ERROR_CONSTRUCTOR_STRING = { [0 /* Error */]: "Error", [1 /* EvalError */]: "EvalError", [2 /* RangeError */]: "RangeError", [3 /* ReferenceError */]: "ReferenceError", [4 /* SyntaxError */]: "SyntaxError", [5 /* TypeError */]: "TypeError", [6 /* URIError */]: "URIError" }; var ERROR_CONSTRUCTOR = { [0 /* Error */]: Error, [1 /* EvalError */]: EvalError, [2 /* RangeError */]: RangeError, [3 /* ReferenceError */]: ReferenceError, [4 /* SyntaxError */]: SyntaxError, [5 /* TypeError */]: TypeError, [6 /* URIError */]: URIError }; var NIL = void 0; // src/core/node.ts function createSerovalNode(t, i, s, l, c, m, p, e, a, f, b, o) { return { t, i, s, l, c, m, p, e, a, f, b, o }; } // src/core/literals.ts function createConstantNode(value) { return createSerovalNode( 2 /* Constant */, NIL, value, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL ); } var TRUE_NODE = /* @__PURE__ */ createConstantNode( 2 /* True */ ); var FALSE_NODE = /* @__PURE__ */ createConstantNode( 3 /* False */ ); var UNDEFINED_NODE = /* @__PURE__ */ createConstantNode( 1 /* Undefined */ ); var NULL_NODE = /* @__PURE__ */ createConstantNode( 0 /* Null */ ); var NEG_ZERO_NODE = /* @__PURE__ */ createConstantNode( 4 /* NegZero */ ); var INFINITY_NODE = /* @__PURE__ */ createConstantNode( 5 /* Inf */ ); var NEG_INFINITY_NODE = /* @__PURE__ */ createConstantNode( 6 /* NegInf */ ); var NAN_NODE = /* @__PURE__ */ createConstantNode(7 /* Nan */); // src/core/utils/error.ts function getErrorConstructor(error) { if (error instanceof EvalError) { return 1 /* EvalError */; } if (error instanceof RangeError) { return 2 /* RangeError */; } if (error instanceof ReferenceError) { return 3 /* ReferenceError */; } if (error instanceof SyntaxError) { return 4 /* SyntaxError */; } if (error instanceof TypeError) { return 5 /* TypeError */; } if (error instanceof URIError) { return 6 /* URIError */; } return 0 /* Error */; } function getInitialErrorOptions(error) { const construct = ERROR_CONSTRUCTOR_STRING[getErrorConstructor(error)]; if (error.name !== construct) { return { name: error.name }; } if (error.constructor.name !== construct) { return { name: error.constructor.name }; } return {}; } function getErrorOptions(error, features) { let options = getInitialErrorOptions(error); const names = Object.getOwnPropertyNames(error); for (let i = 0, len = names.length, name; i < len; i++) { name = names[i]; if (name !== "name" && name !== "message") { if (name === "stack") { if (features & 4 /* ErrorPrototypeStack */) { options = options || {}; options[name] = error[name]; } } else { options = options || {}; options[name] = error[name]; } } } return options; } // src/core/utils/get-object-flag.ts function getObjectFlag(obj) { if (Object.isFrozen(obj)) { return 3 /* Frozen */; } if (Object.isSealed(obj)) { return 2 /* Sealed */; } if (Object.isExtensible(obj)) { return 0 /* None */; } return 1 /* NonExtensible */; } // 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 /* Number */, NIL, value, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL ); } function createStringNode(value) { return createSerovalNode( 1 /* String */, NIL, serializeString(value), NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL ); } function createBigIntNode(current) { return createSerovalNode( 3 /* BigInt */, NIL, "" + current, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL ); } function createIndexedValueNode(id) { return createSerovalNode( 4 /* IndexedValue */, id, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL ); } function createDateNode(id, current) { return createSerovalNode( 5 /* Date */, id, current.toISOString(), NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL ); } function createRegExpNode(id, current) { return createSerovalNode( 6 /* RegExp */, id, NIL, NIL, serializeString(current.source), current.flags, NIL, NIL, NIL, NIL, NIL, NIL ); } function createArrayBufferNode(id, current) { const bytes = new Uint8Array(current); const len = bytes.length; const values = new Array(len); for (let i = 0; i < len; i++) { values[i] = bytes[i]; } return createSerovalNode( 19 /* ArrayBuffer */, id, values, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL ); } function createWKSymbolNode(id, current) { return createSerovalNode( 17 /* WKSymbol */, id, INV_SYMBOL_REF[current], NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL ); } function createReferenceNode(id, ref) { return createSerovalNode( 18 /* Reference */, id, serializeString(getReferenceID(ref)), NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL ); } function createPluginNode(id, tag, value) { return createSerovalNode( 25 /* Plugin */, id, value, NIL, serializeString(tag), NIL, NIL, NIL, NIL, NIL, NIL, NIL ); } function createArrayNode(id, current, parsedItems) { return createSerovalNode( 9 /* Array */, id, NIL, current.length, NIL, NIL, NIL, NIL, parsedItems, NIL, NIL, getObjectFlag(current) ); } function createBoxedNode(id, boxed) { return createSerovalNode( 21 /* Boxed */, id, NIL, NIL, NIL, NIL, NIL, NIL, NIL, boxed, NIL, NIL ); } function createTypedArrayNode(id, current, buffer) { return createSerovalNode( 15 /* TypedArray */, id, NIL, current.length, current.constructor.name, NIL, NIL, NIL, NIL, buffer, current.byteOffset, NIL ); } function createBigIntTypedArrayNode(id, current, buffer) { return createSerovalNode( 16 /* BigIntTypedArray */, id, NIL, current.length, current.constructor.name, NIL, NIL, NIL, NIL, buffer, current.byteOffset, NIL ); } function createDataViewNode(id, current, buffer) { return createSerovalNode( 20 /* DataView */, id, NIL, current.byteLength, NIL, NIL, NIL, NIL, NIL, buffer, current.byteOffset, NIL ); } function createErrorNode(id, current, options) { return createSerovalNode( 13 /* Error */, id, getErrorConstructor(current), NIL, NIL, serializeString(current.message), options, NIL, NIL, NIL, NIL, NIL ); } function createAggregateErrorNode(id, current, options) { return createSerovalNode( 14 /* AggregateError */, id, getErrorConstructor(current), NIL, NIL, serializeString(current.message), options, NIL, NIL, NIL, NIL, NIL ); } function createSetNode(id, size, items) { return createSerovalNode( 7 /* Set */, id, NIL, size, NIL, NIL, NIL, NIL, items, NIL, NIL, NIL ); } function createIteratorFactoryInstanceNode(factory, items) { return createSerovalNode( 28 /* IteratorFactoryInstance */, NIL, NIL, NIL, NIL, NIL, NIL, NIL, [factory, items], NIL, NIL, NIL ); } function createAsyncIteratorFactoryInstanceNode(factory, items) { return createSerovalNode( 30 /* AsyncIteratorFactoryInstance */, NIL, NIL, NIL, NIL, NIL, NIL, NIL, [factory, items], NIL, NIL, NIL ); } function createStreamConstructorNode(id, factory, sequence) { return createSerovalNode( 31 /* StreamConstructor */, id, NIL, NIL, NIL, NIL, NIL, NIL, sequence, factory, NIL, NIL ); } function createStreamNextNode(id, parsed) { return createSerovalNode( 32 /* StreamNext */, id, NIL, NIL, NIL, NIL, NIL, NIL, NIL, parsed, NIL, NIL ); } function createStreamThrowNode(id, parsed) { return createSerovalNode( 33 /* StreamThrow */, id, NIL, NIL, NIL, NIL, NIL, NIL, NIL, parsed, NIL, NIL ); } function createStreamReturnNode(id, parsed) { return createSerovalNode( 34 /* StreamReturn */, id, NIL, NIL, NIL, NIL, NIL, NIL, NIL, parsed, NIL, NIL ); } // src/core/errors.ts var { toString: objectToString } = Object.prototype; function getErrorMessage(type, cause) { if (cause instanceof Error) { return `Seroval caught an error during the ${type} process. ${cause.name} ${cause.message} - For more information, please check the "cause" property of this error. - If you believe this is an error in Seroval, please submit an issue at https://github.com/lxsmnsyc/seroval/issues/new`; } return `Seroval caught an error during the ${type} process. "${objectToString.call(cause)}" For more information, please check the "cause" property of this error.`; } var SerovalError = class extends Error { constructor(type, cause) { super(getErrorMessage(type, cause)); this.cause = cause; } }; var SerovalParserError = class extends SerovalError { constructor(cause) { super("parsing", cause); } }; var SerovalSerializationError = class extends SerovalError { constructor(cause) { super("serialization", cause); } }; var SerovalDeserializationError = class extends SerovalError { constructor(cause) { super("deserialization", cause); } }; var SerovalUnsupportedTypeError = class extends Error { constructor(value) { super( `The value ${objectToString.call(value)} of type "${typeof value}" cannot be parsed/serialized. There are few workarounds for this problem: - Transform the value in a way that it can be serialized. - If the reference is present on multiple runtimes (isomorphic), you can use the Reference API to map the references.` ); this.value = value; } }; var SerovalUnsupportedNodeError = class extends Error { constructor(node) { super('Unsupported node type "' + node.t + '".'); } }; var SerovalMissingPluginError = class extends Error { constructor(tag) { super('Missing plugin for tag "' + tag + '".'); } }; var SerovalMissingInstanceError = class extends Error { constructor(tag) { super('Missing "' + tag + '" instance.'); } }; var SerovalMissingReferenceError = class extends Error { constructor(value) { super( 'Missing reference for the value "' + objectToString.call(value) + '" of type "' + typeof value + '"' ); this.value = value; } }; var SerovalMissingReferenceForIdError = class extends Error { constructor(id) { super('Missing reference for id "' + serializeString(id) + '"'); } }; var SerovalUnknownTypedArrayError = class extends Error { constructor(name) { super('Unknown TypedArray "' + name + '"'); } }; // src/core/opaque-reference.ts var OpaqueReference = class { constructor(value, replacement) { this.value = value; this.replacement = replacement; } }; // src/core/special-reference.ts var ITERATOR = {}; var ASYNC_ITERATOR = {}; var SPECIAL_REFS = { [0 /* MapSentinel */]: {}, [1 /* PromiseConstructor */]: {}, [2 /* PromiseResolve */]: {}, [3 /* PromiseReject */]: {}, [4 /* StreamConstructor */]: {}, [5 /* AbortSignalConstructor */]: {}, [6 /* AbortSignalAbort */]: {} }; // src/core/utils/deferred.ts function createDeferred() { let resolve; let reject; return { promise: new Promise((res, rej) => { resolve = res; reject = rej; }), resolve(value) { resolve(value); }, reject(value) { reject(value); } }; } // src/core/stream.ts function isStream(value) { return "__SEROVAL_STREAM__" in value; } function createStream() { const listeners = /* @__PURE__ */ new Set(); const buffer = []; let alive = true; let success = true; function flushNext(value) { for (const listener of listeners.keys()) { listener.next(value); } } function flushThrow(value) { for (const listener of listeners.keys()) { listener.throw(value); } } function flushReturn(value) { for (const listener of listeners.keys()) { listener.return(value); } } return { __SEROVAL_STREAM__: true, on(listener) { if (alive) { listeners.add(listener); } for (let i = 0, len = buffer.length; i < len; i++) { const value = buffer[i]; if (i === len - 1 && !alive) { if (success) { listener.return(value); } else { listener.throw(value); } } else { listener.next(value); } } return () => { if (alive) { listeners.delete(listener); } }; }, next(value) { if (alive) { buffer.push(value); flushNext(value); } }, throw(value) { if (alive) { buffer.push(value); flushThrow(value); alive = false; success = false; listeners.clear(); } }, return(value) { if (alive) { buffer.push(value); flushReturn(value); alive = false; success = true; listeners.clear(); } } }; } function createStreamFromAsyncIterable(iterable) { const stream = createStream(); const iterator = iterable[Symbol.asyncIterator](); async function push() { try { const value = await iterator.next(); if (value.done) { stream.return(value.value); } else { stream.next(value.value); await push(); } } catch (error) { stream.throw(error); } } push().catch(() => { }); return stream; } function streamToAsyncIterable(stream) { return () => { const buffer = []; const pending = []; let count = 0; let doneAt = -1; let isThrow = false; function resolveAll() { for (let i = 0, len = pending.length; i < len; i++) { pending[i].resolve({ done: true, value: void 0 }); } } stream.on({ next(value) { const current = pending.shift(); if (current) { current.resolve({ done: false, value }); } buffer.push(value); }, throw(value) { const current = pending.shift(); if (current) { current.reject(value); } resolveAll(); doneAt = buffer.length; buffer.push(value); isThrow = true; }, return(value) { const current = pending.shift(); if (current) { current.resolve({ done: true, value }); } resolveAll(); doneAt = buffer.length; buffer.push(value); } }); function finalize() { const current = count++; const value = buffer[current]; if (current !== doneAt) { return { done: false, value }; } if (isThrow) { throw value; } return { done: true, value }; } return { [Symbol.asyncIterator]() { return this; }, async next() { if (doneAt === -1) { const current = count++; if (current >= buffer.length) { const deferred = createDeferred(); pending.push(deferred); return await deferred.promise; } return { done: false, value: buffer[current] }; } if (count > doneAt) { return { done: true, value: void 0 }; } return finalize(); } }; }; } // src/core/utils/iterator-to-sequence.ts function iteratorToSequence(source) { const values = []; let throwsAt = -1; let doneAt = -1; const iterator = source[Symbol.iterator](); while (true) { try { const value = iterator.next(); values.push(value.value); if (value.done) { doneAt = values.length - 1; break; } } catch (error) { throwsAt = values.length; values.push(error); } } return { v: values, t: throwsAt, d: doneAt }; } function sequenceToIterator(sequence) { return () => { let index = 0; return { [Symbol.iterator]() { return this; }, next() { if (index > sequence.d) { return { done: true, value: NIL }; } const currentIndex = index++; const currentItem = sequence.v[currentIndex]; if (currentIndex === sequence.t) { throw currentItem; } return { done: currentIndex === sequence.d, value: currentItem }; } }; }; } // src/core/utils/promise-to-result.ts async function promiseToResult(current) { try { return [1, await current]; } catch (e) { return [0, e]; } } // src/core/context/parser.ts var BaseParserContext = class { constructor(options) { this.marked = /* @__PURE__ */ new Set(); this.plugins = options.plugins; this.features = ALL_ENABLED ^ (options.disabledFeatures || 0); this.refs = options.refs || /* @__PURE__ */ new Map(); } markRef(id) { this.marked.add(id); } isMarked(id) { return this.marked.has(id); } getIndexedValue(current) { const registeredId = this.refs.get(current); if (registeredId != null) { this.markRef(registeredId); return { type: 1 /* Indexed */, value: createIndexedValueNode(registeredId) }; } const id = this.refs.size; this.refs.set(current, id); return { type: 0 /* Fresh */, value: id }; } getReference(current) { const indexed = this.getIndexedValue(current); if (indexed.type === 1 /* Indexed */) { return indexed; } if (hasReferenceID(current)) { return { type: 2 /* Referenced */, value: createReferenceNode(indexed.value, current) }; } return indexed; } parseWellKnownSymbol(current) { const ref = this.getReference(current); if (ref.type !== 0 /* Fresh */) { return ref.value; } assert(current in INV_SYMBOL_REF, new SerovalUnsupportedTypeError(current)); return createWKSymbolNode(ref.value, current); } parseSpecialReference(ref) { const result = this.getIndexedValue(SPECIAL_REFS[ref]); if (result.type === 1 /* Indexed */) { return result.value; } return createSerovalNode( 26 /* SpecialReference */, result.value, ref, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL ); } parseIteratorFactory() { const result = this.getIndexedValue(ITERATOR); if (result.type === 1 /* Indexed */) { return result.value; } return createSerovalNode( 27 /* IteratorFactory */, result.value, NIL, NIL, NIL, NIL, NIL, NIL, NIL, this.parseWellKnownSymbol(Symbol.iterator), NIL, NIL ); } parseAsyncIteratorFactory() { const result = this.getIndexedValue(ASYNC_ITERATOR); if (result.type === 1 /* Indexed */) { return result.value; } return createSerovalNode( 29 /* AsyncIteratorFactory */, result.value, NIL, NIL, NIL, NIL, NIL, NIL, [ this.parseSpecialReference(1 /* PromiseConstructor */), this.parseWellKnownSymbol(Symbol.asyncIterator) ], NIL, NIL, NIL ); } createObjectNode(id, current, empty, record) { return createSerovalNode( empty ? 11 /* NullConstructor */ : 10 /* Object */, id, NIL, NIL, NIL, NIL, record, NIL, NIL, NIL, NIL, getObjectFlag(current) ); } createMapNode(id, k, v, s) { return createSerovalNode( 8 /* Map */, id, NIL, NIL, NIL, NIL, NIL, { k, v, s }, NIL, this.parseSpecialReference(0 /* MapSentinel */), NIL, NIL ); } createPromiseConstructorNode(id) { return createSerovalNode( 22 /* PromiseConstructor */, id, NIL, NIL, NIL, NIL, NIL, NIL, NIL, this.parseSpecialReference(1 /* PromiseConstructor */), NIL, NIL ); } createAbortSignalConstructorNode(id) { return createSerovalNode( 35 /* AbortSignalConstructor */, id, NIL, NIL, NIL, NIL, NIL, NIL, NIL, this.parseSpecialReference(5 /* AbortSignalConstructor */), NIL, NIL ); } }; // src/core/context/parser/async.ts var BaseAsyncParserContext = class extends BaseParserContext { async parseItems(current) { const nodes = []; for (let i = 0, len = current.length; i < len; i++) { if (i in current) { nodes[i] = await this.parse(current[i]); } } return nodes; } async parseArray(id, current) { return createArrayNode(id, current, await this.parseItems(current)); } async parseProperties(properties) { const entries = Object.entries(properties); const keyNodes = []; const valueNodes = []; for (let i = 0, len = entries.length; i < len; i++) { keyNodes.push(serializeString(entries[i][0])); valueNodes.push(await this.parse(entries[i][1])); } let symbol = Symbol.iterator; if (symbol in properties) { keyNodes.push(this.parseWellKnownSymbol(symbol)); valueNodes.push( createIteratorFactoryInstanceNode( this.parseIteratorFactory(), await this.parse( iteratorToSequence(properties) ) ) ); } symbol = Symbol.asyncIterator; if (symbol in properties) { keyNodes.push(this.parseWellKnownSymbol(symbol)); valueNodes.push( createAsyncIteratorFactoryInstanceNode( this.parseAsyncIteratorFactory(), await this.parse( createStreamFromAsyncIterable( properties ) ) ) ); } symbol = Symbol.toStringTag; if (symbol in properties) { keyNodes.push(this.parseWellKnownSymbol(symbol)); valueNodes.push(createStringNode(properties[symbol])); } symbol = Symbol.isConcatSpreadable; if (symbol in properties) { keyNodes.push(this.parseWellKnownSymbol(symbol)); valueNodes.push(properties[symbol] ? TRUE_NODE : FALSE_NODE); } return { k: keyNodes, v: valueNodes, s: keyNodes.length }; } async parsePlainObject(id, current, empty) { return this.createObjectNode( id, current, empty, await this.parseProperties(current) ); } async parseBoxed(id, current) { return createBoxedNode(id, await this.parse(current.valueOf())); } async parseTypedArray(id, current) { return createTypedArrayNode(id, current, await this.parse(current.buffer)); } async parseBigIntTypedArray(id, current) { return createBigIntTypedArrayNode( id, current, await this.parse(current.buffer) ); } async parseDataView(id, current) { return createDataViewNode(id, current, await this.parse(current.buffer)); } async parseError(id, current) { const options = getErrorOptions(current, this.features); return createErrorNode( id, current, options ? await this.parseProperties(options) : NIL ); } async parseAggregateError(id, current) { const options = getErrorOptions(current, this.features); return createAggregateErrorNode( id, current, options ? await this.parseProperties(options) : NIL ); } async parseMap(id, current) { const keyNodes = []; const valueNodes = []; for (const [key, value] of current.entries()) { keyNodes.push(await this.parse(key)); valueNodes.push(await this.parse(value)); } return this.createMapNode(id, keyNodes, valueNodes, current.size); } async parseSet(id, current) { const items = []; for (const item of current.keys()) { items.push(await this.parse(item)); } return createSetNode(id, current.size, items); } async parsePromise(id, current) { const [status, result] = await promiseToResult(current); return createSerovalNode( 12 /* Promise */, id, status, NIL, NIL, NIL, NIL, NIL, NIL, await this.parse(result), NIL, NIL ); } async parsePlugin(id, current) { const currentPlugins = this.plugins; 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, this, { id }) ); } } } return NIL; } async parseStream(id, current) { return createStreamConstructorNode( id, this.parseSpecialReference(4 /* StreamConstructor */), await new Promise((resolve, reject) => { const sequence = []; const cleanup = current.on({ next: (value) => { this.markRef(id); this.parse(value).then( (data) => { sequence.push(createStreamNextNode(id, data)); }, (data) => { reject(data); cleanup(); } ); }, throw: (value) => { this.markRef(id); this.parse(value).then( (data) => { sequence.push(createStreamThrowNode(id, data)); resolve(sequence); cleanup(); }, (data) => { reject(data); cleanup(); } ); }, return: (value) => { this.markRef(id); this.parse(value).then( (data) => { sequence.push(createStreamReturnNode(id, data)); resolve(sequence); cleanup(); }, (data) => { reject(data); cleanup(); } ); } }); }) ); } async parseAbortSignalSync(id, current) { return createSerovalNode( 37 /* AbortSignalSync */, id, NIL, NIL, NIL, NIL, NIL, NIL, NIL, await this.parse(current.reason), NIL, NIL ); } async parseAbortSignal(id, current) { if (!current.aborted) { await abortSignalToPromise(current); } return this.parseAbortSignalSync(id, current); } // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: ehh async parseObject(id, current) { if (Array.isArray(current)) { return this.parseArray(id, current); } if (isStream(current)) { return this.parseStream(id, current); } const currentClass = current.constructor; if (currentClass === OpaqueReference) { return this.parse( current.replacement ); } const parsed = await this.parsePlugin(id, current); if (parsed) { return parsed; } switch (currentClass) { case Object: return this.parsePlainObject( id, current, false ); case NIL: return this.parsePlainObject( id, current, true ); case Date: return createDateNode(id, current); case RegExp: return createRegExpNode(id, current); case Error: case EvalError: case RangeError: case ReferenceError: case SyntaxError: case TypeError: case URIError: return this.parseError(id, current); case Number: case Boolean: case String: case BigInt: return this.parseBoxed(id, current); case ArrayBuffer: return createArrayBufferNode(id, current); case Int8Array: case Int16Array: case Int32Array: case Uint8Array: case Uint16Array: case Uint32Array: case Uint8ClampedArray: case Float32Array: case Float64Array: return this.parseTypedArray(id, current); case DataView: return this.parseDataView(id, current); case Map: return this.parseMap(id, current); case Set: return this.parseSet(id, current); default: break; } if (currentClass === Promise || current instanceof Promise) { return this.parsePromise(id, current); } const currentFeatures = this.features; if (currentFeatures & 32 /* AbortSignal */ && typeof AbortSignal !== "undefined" && currentClass === AbortSignal) { return this.parseAbortSignal(id, current); } if (currentFeatures & 16 /* BigIntTypedArray */) { switch (currentClass) { case BigInt64Array: case BigUint64Array: return this.parseBigIntTypedArray( id, current ); default: break; } } if (currentFeatures & 1 /* AggregateError */ && typeof AggregateError !== "undefined" && (currentClass === AggregateError || current instanceof AggregateError)) { return this.parseAggregateError(id, current); } if (current instanceof Error) { return this.parseError(id, current); } if (Symbol.iterator in current || Symbol.asyncIterator in current) { return this.parsePlainObject(id, current, !!currentClass); } throw new SerovalUnsupportedTypeError(current); } async parseFunction(current) { const ref = this.getReference(current); if (ref.type !== 0 /* Fresh */) { return ref.value; } const plugin = await this.parsePlugin(ref.value, current); if (plugin) { return plugin; } throw new SerovalUnsupportedTypeError(current); } async parse(current) { try { 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 = this.getReference(current); return ref.type === 0 ? await this.parseObject(ref.value, current) : ref.value; } return NULL_NODE; } case "symbol": return this.parseWellKnownSymbol(current); case "function": return this.parseFunction(current); default: throw new SerovalUnsupportedTypeError(current); } } catch (error) { throw new SerovalParserError(error); } } }; // src/core/cross/async.ts var CrossAsyncParserContext = class extends BaseAsyncParserContext { constructor() { super(...arguments); this.mode = "cross"; } }; // src/core/utils/typed-array.ts function getTypedArrayConstructor(name) { switch (name) { case "Int8Array": return Int8Array; case "Int16Array": return Int16Array; case "Int32Array": return Int32Array; case "Uint8Array": return Uint8Array; case "Uint16Array": return Uint16Array; case "Uint32Array": return Uint32Array; case "Uint8ClampedArray": return Uint8ClampedArray; case "Float32Array": return Float32Array; case "Float64Array": return Float64Array; case "BigInt64Array": return BigInt64Array; case "BigUint64Array": return BigUint64Array; default: throw new SerovalUnknownTypedArrayError(name); } } // src/core/context/deserializer.ts function applyObjectFlag(obj, flag) { switch (flag) { case 3 /* Frozen */: return Object.freeze(obj); case 1 /* NonExtensible */: return Object.preventExtensions(obj); case 2 /* Sealed */: return Object.seal(obj); default: return obj; } } var BaseDeserializerContext = class { constructor(options) { this.plugins = options.plugins; this.refs = options.refs || /* @__PURE__ */ new Map(); } deserializeReference(node) { return this.assignIndexedValue( node.i, getReference(deserializeString(node.s)) ); } deserializeArray(node) { const len = node.l; const result = this.assignIndexedValue( node.i, new Array(len) ); let item; for (let i = 0; i < len; i++) { item = node.a[i]; if (item) { result[i] = this.deserialize(item); } } applyObjectFlag(result, node.o); return result; } deserializeProperties(node, result) { const len = node.s; if (len) { const keys = node.k; const vals = node.v; for (let i = 0, key; i < len; i++) { key = keys[i]; if (typeof key === "string") { result[deserializeString(key)] = this.deserialize(vals[i]); } else { result[this.deserialize(key)] = this.deserialize(vals[i]); } } } return result; } deserializeObject(node) { const result = this.assignIndexedValue( node.i, node.t === 10 /* Object */ ? {} : /* @__PURE__ */ Object.create(null) ); this.deserializeProperties(node.p, result); applyObjectFlag(result, node.o); return result; } deserializeDate(node) { return this.assignIndexedValue(node.i, new Date(node.s)); } deserializeRegExp(node) { return this.assignIndexedValue( node.i, new RegExp(deserializeString(node.c), node.m) ); } deserializeSet(node) { const result = this.assignIndexedValue(node.i, /* @__PURE__ */ new Set()); const items = node.a; for (let i = 0, len = node.l; i < len; i++) { result.add(this.deserialize(items[i])); } return result; } deserializeMap(node) { const result = this.assignIndexedValue(node.i, /* @__PURE__ */ new Map()); const keys = node.e.k; const vals = node.e.v; for (let i = 0, len = node.e.s; i < len; i++) { result.set(this.deserialize(keys[i]), this.deserialize(vals[i])); } return result; } deserializeArrayBuffer(node) { const bytes = new Uint8Array(node.s); const result = this.assignIndexedValue(node.i, bytes.buffer); return result; } deserializeTypedArray(node) { const construct = getTypedArrayConstructor(node.c); const source = this.deserialize(node.f); const result = this.assignIndexedValue( node.i, new construct(source, node.b, node.l) ); return result; } deserializeDataView(node) { const source = this.deserialize(node.f); const result = this.assignIndexedValue( node.i, new DataView(source, node.b, node.l) ); return result; } deserializeDictionary(node, result) { if (node.p) { const fields = this.deserializeProperties(node.p, {}); Object.assign(result, fields); } return result; } deserializeAggregateError(node) { const result = this.assignIndexedValue( node.i, new AggregateError([], deserializeString(node.m)) ); return this.deserializeDictionary(node, result); } deserializeError(node) { const construct = ERROR_CONSTRUCTOR[node.s]; const result = this.assignIndexedValue( node.i, new construct(deserializeString(node.m)) ); return this.deserializeDictionary(node, result); } deserializePromise(node) { const deferred = createDeferred(); const result = this.assignIndexedValue(node.i, deferred); const deserialized = this.deserialize(node.f); if (node.s) { deferred.resolve(deserialized); } else { deferred.reject(deserialized); } return result.promise; } deserializeBoxed(node) { return this.assignIndexedValue(node.i, Object(this.deserialize(node.f))); } deserializePlugin(node) { const currentPlugins = this.plugins; if (currentPlugins) { const tag = deserializeString(node.c); for (let i = 0, len = currentPlugins.length; i < len; i++) { const plugin = currentPlugins[i]; if (plugin.tag === tag) { return this.assignIndexedValue( node.i, plugin.deserialize(node.s, this, { id: node.i }) ); } } } throw new SerovalMissingPluginError(node.c); } deserializePromiseConstructor(node) { return this.assignIndexedValue(node.i, createDeferred()).promise; } deserializePromiseResolve(node) { const deferred = this.refs.get(node.i); assert(deferred, new SerovalMissingInstanceError("Promise")); deferred.resolve(this.deserialize(node.a[1])); return void 0; } deserializePromiseReject(node) { const deferred = this.refs.get(node.i); assert(deferred, new SerovalMissingInstanceError("Promise")); deferred.reject(this.deserialize(node.a[1])); return void 0; } deserializeIteratorFactoryInstance(node) { this.deserialize(node.a[0]); const source = this.deserialize(node.a[1]); return sequenceToIterator(source); } deserializeAsyncIteratorFactoryInstance(node) { this.deserialize(node.a[0]); const source = this.deserialize(node.a[1]); return streamToAsyncIterable(source); } deserializeStreamConstructor(node) { const result = this.assignIndexedValue(node.i, createStream()); const len = node.a.length; if (len) { for (let i = 0; i < len; i++) { this.deserialize(node.a[i]); } } return result; } deserializeStreamNext(node) { const deferred = this.refs.get(node.i); assert(deferred, new SerovalMissingInstanceError("Stream")); deferred.next(this.deserialize(node.f)); return void 0; } deserializeStreamThrow(node) { const deferred = this.refs.get(node.i); assert(deferred, new SerovalMissingInstanceError("Stream")); deferred.throw(this.deserialize(node.f)); return void 0; } deserializeStreamReturn(node) { const deferred = this.refs.get(node.i); assert(deferred, new SerovalMissingInstanceError("Stream")); deferred.return(this.deserialize(node.f)); return void 0; } deserializeIteratorFactory(node) { this.deserialize(node.f); return void 0; } deserializeAsyncIteratorFactory(node) { this.deserialize(node.a[1]); return void 0; } deserializeAbortSignalConstructor(node) { return this.assignIndexedValue(node.i, new AbortController()).signal; } deserializeAbortSignalAbort(node) { const controller = this.refs.get(node.i); assert(controller, new SerovalMissingInstanceError("AbortSignal")); controller.abort(this.deserialize(node.a[1])); return void 0; } deserializeAbortSignalSync(node) { return this.assignIndexedValue( node.i, AbortSignal.abort(this.deserialize(node.f)) ); } deserialize(node) { try { switch (node.t) { case 2 /* Constant */: return CONSTANT_VAL[node.s]; case 0 /* Number */: return node.s; case 1 /* String */: return deserializeString(node.s); case 3 /* BigInt */: return BigInt(node.s); case 4 /* IndexedValue */: return this.refs.get(node.i); case 18 /* Reference */: return this.deserializeReference(node); case 9 /* Array */: return this.deserializeArray(node); case 10 /* Object */: case 11 /* NullConstructor */: return this.deserializeObject(node); case 5 /* Date */: return this.deserializeDate(node); case 6 /* RegExp */: return this.deserializeRegExp(node); case 7 /* Set */: return this.deserializeSet(node); case 8 /* Map */: return this.deserializeMap(node); case 19 /* ArrayBuffer */: return this.deserializeArrayBuffer(node); case 16 /* BigIntTypedArray */: case 15 /* TypedArray */: return this.deserializeTypedArray(node); case 20 /* DataView */: return this.deserializeDataView(node); case 14 /* AggregateError */: return this.deserializeAggregateError(node); case 13 /* Error */: return this.deserializeError(node); case 12 /* Promise */: return this.deserializePromise(node); case 17 /* WKSymbol */: return SYMBOL_REF[node.s]; case 21 /* Boxed */: return this.deserializeBoxed(node); case 25 /* Plugin */: return this.deserializePlugin(node); case 22 /* PromiseConstructor */: return this.deserializePromiseConstructor(node); case 23 /* PromiseResolve */: return this.deserializePromiseResolve(node); case 24 /* PromiseReject */: return this.deserializePromiseReject(node); case 28 /* IteratorFactoryInstance */: return this.deserializeIteratorFactoryInstance(node); case 30 /* AsyncIteratorFactoryInstance */: return this.deserializeAsyncIteratorFactoryInstance(node); case 31 /* StreamConstructor */: return this.deserializeStreamConstructor(node); case 32 /* StreamNext */: return this.deserializeStreamNext(node); case 33 /* StreamThrow */: return this.deserializeStreamThrow(node); case 34 /* StreamReturn */: return this.deserializeStreamReturn(node); case 27 /* IteratorFactory */: return this.deserializeIteratorFactory(node); case 29 /* AsyncIteratorFactory */: return this.deserializeAsyncIteratorFactory(node); case 36 /* AbortSignalAbort */: return this.deserializeAbortSignalAbort(node); case 35 /* AbortSignalConstructor */: return this.deserializeAbortSignalConstructor(node); case 37 /* AbortSignalSync */: return this.deserializeAbortSignalSync(node); /