import { $ as SYM_ITERATOR, A as SerovalMalformedNodeError, D as SerovalDeserializationError, E as SerovalDepthLimitError, G as ERROR_CONSTRUCTOR, I as SerovalPluginValidationError, J as SYMBOL_REF, M as SerovalMissingPluginError, Q as SYM_IS_CONCAT_SPREADABLE, T as SerovalConflictedNodeIdError, V as deserializeString, W as CONSTANT_VAL, X as TEMPORAL_TYPE_NAME, Z as SYM_ASYNC_ITERATOR, _ as isSequence, b as getReference, et as SYM_TO_STRING_TAG, h as createSequence, j as SerovalMissingInstanceError, l as isStream, o as resolvePlugins, rt as PROMISE_CONSTRUCTOR, s as Stream, u as streamToAsyncIterable, v as sequenceToIterator, w as SerovalAbortedError, z as SerovalUnsupportedNodeError } from "./shared-DJIVyqa9.js"; import { i as decodeArrayBuffer, t as getTypedArrayConstructor } from "./typed-array-BWH0IKxT.js"; //#region src/core/utils/valid-properties.ts function isValidKey(key) { switch (key) { case "constructor": case "__proto__": case "prototype": case "__defineGetter__": case "__defineSetter__": case "__lookupGetter__": case "__lookupSetter__": return false; default: return true; } } function isValidSymbol(symbol) { switch (symbol) { case SYM_ASYNC_ITERATOR: case SYM_IS_CONCAT_SPREADABLE: case SYM_TO_STRING_TAG: case SYM_ITERATOR: return true; default: return false; } } //#endregion //#region src/core/context/deserializer.ts const DEFAULT_MAX_BASE64_LENGTH = 1e6; const MAX_BIGINT_LENGTH = 1e4; const MAX_REGEXP_SOURCE_LENGTH = 2e4; function applyObjectFlag(obj, flag) { switch (flag) { case 3: return Object.freeze(obj); case 1: return Object.preventExtensions(obj); case 2: return Object.seal(obj); default: return obj; } } const DEFAULT_DEPTH_LIMIT = 1e3; const MAX_REGEXP_PROPERTY_ESCAPES = 32; const REGEXP_PROPERTY_ESCAPE = /\\[pP]\{/g; function createBaseDeserializerContext(options) { const maxBase64Length = options.maxBase64Length ?? DEFAULT_MAX_BASE64_LENGTH; if (!Number.isSafeInteger(maxBase64Length) || maxBase64Length < 0) throw new RangeError("maxBase64Length must be a non-negative safe integer"); const refs = options.refs ?? /* @__PURE__ */ new Map(); if (!("types" in refs)) Object.assign(refs, { types: /* @__PURE__ */ new Map() }); return { plugins: options.plugins, refs, features: options.features ?? 127 ^ (options.disabledFeatures ?? 0), depthLimit: options.depthLimit || DEFAULT_DEPTH_LIMIT, maxBase64Length, regexpPropertyEscapes: MAX_REGEXP_PROPERTY_ESCAPES }; } function createVanillaDeserializerContext(options) { return { base: createBaseDeserializerContext(options), marked: new Set(options.markedRefs) }; } function createCrossDeserializerContext(options) { return { base: createBaseDeserializerContext(options), marked: void 0 }; } function guardIndexedValue(ctx, id) { const node = { t: 4, i: id }; if (id < 0 || !Number.isInteger(id)) throw new SerovalMalformedNodeError(node); if (ctx.refs.has(id)) throw new SerovalConflictedNodeIdError(node); } function isThennable(value) { return !!value && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function"; } const ignoreRejection = () => {}; function assignIndexedValue(ctx, id, value) { guardIndexedValue(ctx.base, id); if (value instanceof Promise) value.catch(ignoreRejection); const marked = ctx.marked; if (!marked || marked.has(id)) ctx.base.refs.set(id, value); return value; } function deserializeKnownValue(node, record, key) { if (Object.hasOwn(record, key)) return record[key]; throw new SerovalMalformedNodeError(node); } function deserializeReference(ctx, node) { return assignIndexedValue(ctx, node.i, getReference(deserializeString(node.s))); } function validateNodeList(node, list) { if (!Array.isArray(list)) throw new SerovalMalformedNodeError(node); } function deserializeArray(ctx, depth, node) { const items = node.a; validateNodeList(node, items); const len = items.length; const result = assignIndexedValue(ctx, node.i, new Array(len)); for (let i = 0, item; i < len; i++) { item = items[i]; if (item) result[i] = deserialize$1(ctx, depth, item); } applyObjectFlag(result, node.o); return result; } function assignStringProperty(object, key, value) { if (isValidKey(key)) object[key] = value; else Object.defineProperty(object, key, { value, configurable: true, enumerable: true, writable: true }); } function assignProperty(ctx, depth, object, key, value) { if (typeof key === "string") assignStringProperty(object, deserializeString(key), deserialize$1(ctx, depth, value)); else { const actual = deserialize$1(ctx, depth, key); switch (typeof actual) { case "string": assignStringProperty(object, actual, deserialize$1(ctx, depth, value)); break; case "symbol": if (isValidSymbol(actual)) object[actual] = deserialize$1(ctx, depth, value); break; default: throw new SerovalMalformedNodeError(key); } } } function assignNodeType(ctx, id, type) { ctx.base.refs.types.set(id, type); } function validateNodeType(ctx, node, id, type) { if (ctx.base.refs.types.get(id) !== type) throw new SerovalMalformedNodeError(node); } function deserializeProperties(ctx, depth, node, result) { const keys = node.k; validateNodeList(node, keys); validateNodeList(node, node.v); const len = keys.length; if (len > 0) for (let i = 0, vals = node.v; i < len; i++) assignProperty(ctx, depth, result, keys[i], vals[i]); return result; } function deserializeObject(ctx, depth, node) { const result = assignIndexedValue(ctx, node.i, node.t === 10 ? {} : Object.create(null)); deserializeProperties(ctx, depth, node.p, result); applyObjectFlag(result, node.o); return result; } function deserializeDate(ctx, node) { return assignIndexedValue(ctx, node.i, new Date(node.s)); } function deserializeTemporal(ctx, node) { if (!(ctx.base.features & 64)) throw new SerovalUnsupportedNodeError(node); const construct = Temporal[deserializeKnownValue(node, TEMPORAL_TYPE_NAME, node.c)]; return assignIndexedValue(ctx, node.i, construct.from(node.s)); } function deserializeRegExp(ctx, node) { if (ctx.base.features & 32) { const source = deserializeString(node.c); if (source.length > MAX_REGEXP_SOURCE_LENGTH) throw new SerovalMalformedNodeError(node); if (/[uv]/.test(String(node.m))) { const escapes = source.match(REGEXP_PROPERTY_ESCAPE); if (escapes) { ctx.base.regexpPropertyEscapes -= escapes.length; if (ctx.base.regexpPropertyEscapes < 0) throw new SerovalMalformedNodeError(node); } } return assignIndexedValue(ctx, node.i, new RegExp(source, node.m)); } throw new SerovalUnsupportedNodeError(node); } function deserializeSet(ctx, depth, node) { const result = assignIndexedValue(ctx, node.i, /* @__PURE__ */ new Set()); validateNodeList(node, node.a); for (let i = 0, items = node.a, len = items.length; i < len; i++) result.add(deserialize$1(ctx, depth, items[i])); return result; } function deserializeMap(ctx, depth, node) { const result = assignIndexedValue(ctx, node.i, /* @__PURE__ */ new Map()); validateNodeList(node, node.e.k); validateNodeList(node, node.e.v); for (let i = 0, keys = node.e.k, vals = node.e.v, len = keys.length; i < len; i++) result.set(deserialize$1(ctx, depth, keys[i]), deserialize$1(ctx, depth, vals[i])); return result; } function deserializeArrayBuffer(ctx, node) { if (typeof node.s !== "string") throw new SerovalMalformedNodeError(node); if (node.s.length > ctx.base.maxBase64Length) throw new RangeError("ArrayBuffer exceeds maxBase64Length (" + ctx.base.maxBase64Length + ")"); const source = deserializeString(node.s); const buffer = decodeArrayBuffer(source); return assignIndexedValue(ctx, node.i, buffer); } function deserializeView(ctx, depth, node, construct) { const source = deserialize$1(ctx, depth, node.f); if (!(source instanceof ArrayBuffer)) throw new SerovalMalformedNodeError(node); const offset = node.b ?? 0; if (offset < 0 || offset > source.byteLength) throw new SerovalMalformedNodeError(node); return assignIndexedValue(ctx, node.i, construct ? new construct(source, offset, node.l) : new DataView(source, offset, node.l)); } function deserializeDictionary(ctx, depth, node, result) { if (node.p) { const fields = deserializeProperties(ctx, depth, node.p, {}); Object.defineProperties(result, Object.getOwnPropertyDescriptors(fields)); } return result; } function deserializeAggregateError(ctx, depth, node) { return deserializeDictionary(ctx, depth, node, assignIndexedValue(ctx, node.i, new AggregateError([], deserializeString(node.m)))); } function deserializeError(ctx, depth, node) { const construct = deserializeKnownValue(node, ERROR_CONSTRUCTOR, node.s); return deserializeDictionary(ctx, depth, node, assignIndexedValue(ctx, node.i, new construct(deserializeString(node.m)))); } function deserializePromise(ctx, depth, node) { const deferred = PROMISE_CONSTRUCTOR(); const result = assignIndexedValue(ctx, node.i, deferred.p); const deserialized = deserialize$1(ctx, depth, node.f); if (isThennable(deserialized)) throw new SerovalMalformedNodeError(node.f); if (node.s) deferred.s(deserialized); else deferred.f(deserialized); return result; } function deserializeBoxed(ctx, depth, node) { return assignIndexedValue(ctx, node.i, Object(deserialize$1(ctx, depth, node.f))); } function getPluginFieldChecks(node, validate) { const info = node.s; if (info == null || typeof info !== "object") throw new SerovalMalformedNodeError(node); const checks = []; for (const field of Object.keys(validate)) { const check = validate[field]; if (check) checks.push([ Reflect.get(info, field), field, check ]); } return checks; } function deserializePlugin(ctx, depth, node) { const currentPlugins = ctx.base.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) { const checks = plugin.validate ? getPluginFieldChecks(node, plugin.validate) : void 0; return assignIndexedValue(ctx, node.i, plugin.deserialize(node.s, { deserialize: (current) => { const value = deserialize$1(ctx, depth, current); if (checks) { for (const [fieldNode, field, check] of checks) if (fieldNode === current && !check(value)) throw new SerovalPluginValidationError(tag, field); } return value; } }, { id: node.i })); } } } throw new SerovalMissingPluginError(node.c); } function deserializePromiseConstructor(ctx, node) { const value = assignIndexedValue(ctx, node.i, assignIndexedValue(ctx, node.s, PROMISE_CONSTRUCTOR()).p); assignNodeType(ctx, node.s, 22); ctx.base.pending?.add(node.s); return value; } function deserializePromiseFulfill(ctx, depth, node) { const deferred = ctx.base.refs.get(node.i); if (deferred) { validateNodeType(ctx, node, node.i, 22); const deserialized = deserialize$1(ctx, depth, node.a[1]); if (isThennable(deserialized)) throw new SerovalMalformedNodeError(node.a[1]); if (node.t === 23) deferred.s(deserialized); else deferred.f(deserialized); ctx.base.pending?.delete(node.i); return; } throw new SerovalMissingInstanceError("Promise"); } function deserializeIteratorFactoryInstance(ctx, depth, node) { deserialize$1(ctx, depth, node.a[0]); const source = deserialize$1(ctx, depth, node.a[1]); if (!isSequence(source)) throw new SerovalMalformedNodeError(node.a[1]); return sequenceToIterator(source); } function deserializeAsyncIteratorFactoryInstance(ctx, depth, node) { deserialize$1(ctx, depth, node.a[0]); const source = deserialize$1(ctx, depth, node.a[1]); if (!isStream(source)) throw new SerovalMalformedNodeError(node.a[1]); return streamToAsyncIterable(source); } function deserializeStreamConstructor(ctx, depth, node) { const result = assignIndexedValue(ctx, node.i, new Stream(node.l === 1 ? 1 : void 0)); assignNodeType(ctx, node.i, 31); ctx.base.pending?.add(node.i); const items = node.a; validateNodeList(node, items); const len = items.length; if (len) for (let i = 0; i < len; i++) deserialize$1(ctx, depth, items[i]); return result; } function deserializeStreamCall(ctx, depth, node, method) { const deferred = ctx.base.refs.get(node.i); if (deferred) { validateNodeType(ctx, node, node.i, 31); deferred[method](deserialize$1(ctx, depth, node.f)); if (method !== "next") ctx.base.pending?.delete(node.i); return; } throw new SerovalMissingInstanceError("Stream"); } function deserializeIteratorFactory(ctx, depth, node) { deserialize$1(ctx, depth, node.f); } function deserializeAsyncIteratorFactory(ctx, depth, node) { deserialize$1(ctx, depth, node.a[1]); } function isSequenceIndex(value, size) { return Number.isInteger(value) && value >= -1 && value < size; } function deserializeSequence(ctx, depth, node) { validateNodeList(node, node.a); const size = node.a.length; if (!(isSequenceIndex(node.s, size) && isSequenceIndex(node.l, size))) throw new SerovalMalformedNodeError(node); const result = assignIndexedValue(ctx, node.i, createSequence([], node.s, node.l)); assignNodeType(ctx, node.i, 35); for (let i = 0; i < size; i++) result.v[i] = deserialize$1(ctx, depth, node.a[i]); return result; } function deserialize$1(ctx, depth, node) { if (depth > ctx.base.depthLimit) throw new SerovalDepthLimitError(ctx.base.depthLimit); depth += 1; switch (node.t) { case 2: return deserializeKnownValue(node, CONSTANT_VAL, node.s); case 0: return Number(node.s); case 1: return deserializeString(String(node.s)); case 3: if (String(node.s).length > MAX_BIGINT_LENGTH) throw new SerovalMalformedNodeError(node); return BigInt(node.s); case 4: return ctx.base.refs.get(node.i); case 18: return deserializeReference(ctx, node); case 9: return deserializeArray(ctx, depth, node); case 10: case 11: return deserializeObject(ctx, depth, node); case 5: return deserializeDate(ctx, node); case 6: return deserializeRegExp(ctx, node); case 7: return deserializeSet(ctx, depth, node); case 8: return deserializeMap(ctx, depth, node); case 19: return deserializeArrayBuffer(ctx, node); case 16: case 15: return deserializeView(ctx, depth, node, getTypedArrayConstructor(node.c)); case 20: return deserializeView(ctx, depth, node); case 14: return deserializeAggregateError(ctx, depth, node); case 13: return deserializeError(ctx, depth, node); case 12: return deserializePromise(ctx, depth, node); case 17: return assignIndexedValue(ctx, node.i, deserializeKnownValue(node, SYMBOL_REF, node.s)); case 21: return deserializeBoxed(ctx, depth, node); case 25: return deserializePlugin(ctx, depth, node); case 22: return deserializePromiseConstructor(ctx, node); case 23: case 24: return deserializePromiseFulfill(ctx, depth, node); case 28: return deserializeIteratorFactoryInstance(ctx, depth, node); case 30: return deserializeAsyncIteratorFactoryInstance(ctx, depth, node); case 31: return deserializeStreamConstructor(ctx, depth, node); case 32: return deserializeStreamCall(ctx, depth, node, "next"); case 33: return deserializeStreamCall(ctx, depth, node, "throw"); case 34: return deserializeStreamCall(ctx, depth, node, "return"); case 27: return deserializeIteratorFactory(ctx, depth, node); case 29: return deserializeAsyncIteratorFactory(ctx, depth, node); case 35: return deserializeSequence(ctx, depth, node); case 36: return deserializeTemporal(ctx, node); default: throw new SerovalUnsupportedNodeError(node); } } function deserializeTop(ctx, node) { ctx.base.regexpPropertyEscapes = MAX_REGEXP_PROPERTY_ESCAPES; try { return deserialize$1(ctx, 0, node); } catch (error) { throw new SerovalDeserializationError(error); } } /** * Rejects every pending promise and throws into every open stream tracked * by `ctx.base.pending`, then drops the bookkeeping so the context no longer * accepts deferred values. Does nothing once the bookkeeping is gone. */ function abortDeferred(ctx, reason) { const pending = ctx.base.pending; if (pending) { ctx.base.pending = void 0; const refs = ctx.base.refs; const errors = []; for (const id of pending) try { const value = refs.get(id); if (refs.types.get(id) === 22) value.f(reason); else value.throw(reason); } catch (error) { errors.push(error); } if (errors.length) throw errors[0]; } } //#endregion //#region src/core/cross/read.ts function createFromCrossJSONContext(options) { return createCrossDeserializerContext({ maxBase64Length: options.maxBase64Length, plugins: resolvePlugins(options.plugins), refs: options.refs, features: options.features, disabledFeatures: options.disabledFeatures, depthLimit: options.depthLimit }); } function fromCrossJSON(source, options) { return deserializeTop(createFromCrossJSONContext(options), source); } function createCrossDeserializer(options) { const ctx = createFromCrossJSONContext(options); ctx.base.pending = /* @__PURE__ */ new Set(); return { deserialize(node) { if (!ctx.base.pending) throw new SerovalAbortedError(); return deserializeTop(ctx, node); }, get pending() { return ctx.base.pending?.size ?? 0; }, abort(reason) { abortDeferred(ctx, reason); } }; } //#endregion //#region src/core/tree/read.ts function deserialize(source) { return (0, eval)(source); } function fromJSON(source, options = {}) { const plugins = resolvePlugins(options.plugins); const disabledFeatures = options.disabledFeatures ?? 0; const sourceFeatures = source.f ?? 127; return deserializeTop(createVanillaDeserializerContext({ depthLimit: options.depthLimit, maxBase64Length: options.maxBase64Length, plugins, markedRefs: source.m, features: sourceFeatures & ~disabledFeatures, disabledFeatures }), source.t); } //#endregion export { fromCrossJSON as i, fromJSON as n, createCrossDeserializer as r, deserialize as t };