456 lines
18 KiB
JavaScript
456 lines
18 KiB
JavaScript
|
|
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-Cf-Bmoy-.js";
|
||
|
|
import { i as decodeArrayBuffer, t as getTypedArrayConstructor } from "./typed-array-C3haUQv_.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 };
|