"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var src_exports = {}; __export(src_exports, { Feature: () => Feature, compileJSON: () => compileJSON, default: () => src_default, deserialize: () => deserialize, fromJSON: () => fromJSON, serialize: () => serialize, serializeAsync: () => serializeAsync, toJSON: () => toJSON, toJSONAsync: () => toJSONAsync }); module.exports = __toCommonJS(src_exports); // src/compat.ts var Feature = /* @__PURE__ */ ((Feature2) => { Feature2[Feature2["AggregateError"] = 1] = "AggregateError"; Feature2[Feature2["ArrayPrototypeValues"] = 2] = "ArrayPrototypeValues"; Feature2[Feature2["ArrowFunction"] = 4] = "ArrowFunction"; Feature2[Feature2["BigInt"] = 8] = "BigInt"; Feature2[Feature2["ErrorPrototypeStack"] = 16] = "ErrorPrototypeStack"; Feature2[Feature2["Map"] = 32] = "Map"; Feature2[Feature2["MethodShorthand"] = 64] = "MethodShorthand"; Feature2[Feature2["ObjectAssign"] = 128] = "ObjectAssign"; Feature2[Feature2["Promise"] = 256] = "Promise"; Feature2[Feature2["Set"] = 512] = "Set"; Feature2[Feature2["Symbol"] = 1024] = "Symbol"; Feature2[Feature2["TypedArray"] = 2048] = "TypedArray"; Feature2[Feature2["BigIntTypedArray"] = 4096] = "BigIntTypedArray"; return Feature2; })(Feature || {}); var ALL_ENABLED = 8191; // src/get-identifier.ts var REF_START_CHARS = "hjkmoquxzABCDEFGHIJKLNPQRTUVWXYZ$_"; var REF_START_CHARS_LEN = REF_START_CHARS.length; var REF_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$_"; var REF_CHARS_LEN = REF_CHARS.length; 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; } // src/context.ts var DEFAULT_OPTIONS = { disabledFeatures: 0 }; function createParserContext(options = {}) { const result = Object.assign({}, DEFAULT_OPTIONS, options || {}); return { markedRefs: /* @__PURE__ */ new Set(), refs: /* @__PURE__ */ new Map(), features: ALL_ENABLED ^ result.disabledFeatures }; } function createSerializationContext(options) { return { stack: [], vars: [], assignments: [], validRefs: [], refSize: 0, features: options.features, markedRefs: new Set(options.markedRefs), valueMap: /* @__PURE__ */ new Map() }; } function markRef(ctx, current) { ctx.markedRefs.add(current); } function getRefParam(ctx, index) { let actualIndex = ctx.validRefs[index]; if (actualIndex == null) { actualIndex = ctx.refSize++; ctx.validRefs[index] = actualIndex; } let identifier = ctx.vars[actualIndex]; if (identifier == null) { identifier = getIdentifier(actualIndex); ctx.vars[actualIndex] = identifier; } return identifier; } function getRootID(ctx, current) { const ref = ctx.refs.get(current); if (ref == null) { return ctx.refs.size; } return ref; } function createRef(ctx, current) { const ref = ctx.refs.get(current); if (ref == null) { const id = ctx.refs.size; ctx.refs.set(current, id); return id; } markRef(ctx, ref); return ref; } // src/assert.ts function assert(cond, error) { if (!cond) { throw new Error(error); } } // src/quote.ts function quote(str) { let result = ""; let lastPos = 0; for (let i = 0, len = str.length; i < len; i++) { let replacement; switch (str[i]) { case '"': replacement = '\\"'; break; case "\\": replacement = "\\\\"; break; case "<": replacement = "\\x3C"; break; case "\n": replacement = "\\n"; break; case "\r": replacement = "\\r"; break; case "\u2028": replacement = "\\u2028"; break; case "\u2029": replacement = "\\u2029"; break; default: continue; } result += str.slice(lastPos, i) + replacement; lastPos = i + 1; } if (lastPos === 0) { result = str; } else { result += str.slice(lastPos); } return result; } function invQuote(str) { return str.replace(/\\"/g, '"').replace(/\\\\/g, "\\").replace(/\\x3C/g, "<").replace(/\\n/g, "\n").replace(/\\r/g, "\r").replace(/\\u2028/g, "\u2028").replace(/\\u2029/g, "\u2029"); } // src/tree/symbols.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 }; // src/tree/primitives.ts var TRUE_NODE = { t: 2 /* Boolean */, i: void 0, s: true, l: void 0, c: void 0, m: void 0, d: void 0, a: void 0, f: void 0 }; var FALSE_NODE = { t: 2 /* Boolean */, i: void 0, s: false, l: void 0, c: void 0, m: void 0, d: void 0, a: void 0, f: void 0 }; var UNDEFINED_NODE = { t: 4 /* Undefined */, i: void 0, s: void 0, l: void 0, c: void 0, m: void 0, d: void 0, a: void 0, f: void 0 }; var NULL_NODE = { t: 3 /* Null */, i: void 0, s: void 0, l: void 0, c: void 0, m: void 0, d: void 0, a: void 0, f: void 0 }; var NEG_ZERO_NODE = { t: 5 /* NegativeZero */, i: void 0, s: void 0, l: void 0, c: void 0, m: void 0, d: void 0, a: void 0, f: void 0 }; var INFINITY_NODE = { t: 6 /* Infinity */, i: void 0, s: void 0, l: void 0, c: void 0, m: void 0, d: void 0, a: void 0, f: void 0 }; var NEG_INFINITY_NODE = { t: 7 /* NegativeInfinity */, i: void 0, s: void 0, l: void 0, c: void 0, m: void 0, d: void 0, a: void 0, f: void 0 }; var NAN_NODE = { t: 8 /* NaN */, i: void 0, s: void 0, l: void 0, c: void 0, m: void 0, d: void 0, a: void 0, f: void 0 }; function createNumberNode(value) { return { t: 0 /* Number */, i: void 0, s: value, l: void 0, c: void 0, m: void 0, d: void 0, a: void 0, f: void 0 }; } function createStringNode(value) { return { t: 1 /* String */, i: void 0, s: quote(value), l: void 0, c: void 0, m: void 0, d: void 0, a: void 0, f: void 0 }; } function createBigIntNode(ctx, current) { assert(ctx.features & 8 /* BigInt */, 'Unsupported type "BigInt"'); return { t: 9 /* BigInt */, i: void 0, s: "" + current, l: void 0, c: void 0, m: void 0, d: void 0, a: void 0, f: void 0 }; } function createReferenceNode(id) { return { t: 10 /* Reference */, i: id, s: void 0, l: void 0, c: void 0, m: void 0, d: void 0, a: void 0, f: void 0 }; } function createDateNode(id, current) { return { t: 11 /* Date */, i: id, s: current.toISOString(), l: void 0, c: void 0, m: void 0, d: void 0, f: void 0, a: void 0 }; } function createRegExpNode(id, current) { return { t: 12 /* RegExp */, i: id, s: void 0, l: void 0, c: current.source, m: current.flags, d: void 0, a: void 0, f: void 0 }; } function createTypedArrayNode(ctx, id, current) { const constructor = current.constructor.name; assert(ctx.features & 2048 /* TypedArray */, `Unsupported value type "${constructor}"`); const len = current.length; const values = new Array(len); for (let i = 0; i < len; i++) { values[i] = "" + current[i]; } return { t: 22 /* TypedArray */, i: id, s: values, l: current.byteOffset, c: constructor, m: void 0, d: void 0, a: void 0, f: void 0 }; } var BIGINT_FLAG = 4096 /* BigIntTypedArray */ | 8 /* BigInt */; function createBigIntTypedArrayNode(ctx, id, current) { const constructor = current.constructor.name; assert( (ctx.features & BIGINT_FLAG) === BIGINT_FLAG, `Unsupported value type "${constructor}"` ); const len = current.length; const values = new Array(len); for (let i = 0; i < len; i++) { values[i] = "" + current[i]; } return { t: 23 /* BigIntTypedArray */, i: id, s: values, l: current.byteOffset, c: constructor, m: void 0, d: void 0, a: void 0, f: void 0 }; } function createWKSymbolNode(current) { return { t: 24 /* WKSymbol */, i: void 0, s: INV_SYMBOL_REF[current], l: void 0, c: void 0, m: void 0, d: void 0, a: void 0, f: void 0 }; } // src/tree/shared.ts function getErrorConstructorName(error) { if (error instanceof EvalError) { return "EvalError"; } if (error instanceof RangeError) { return "RangeError"; } if (error instanceof ReferenceError) { return "ReferenceError"; } if (error instanceof SyntaxError) { return "SyntaxError"; } if (error instanceof TypeError) { return "TypeError"; } if (error instanceof URIError) { return "URIError"; } return "Error"; } function getErrorConstructor(errorName) { switch (errorName) { case "Error": return Error; case "EvalError": return EvalError; case "RangeError": return RangeError; case "ReferenceError": return ReferenceError; case "SyntaxError": return SyntaxError; case "TypeError": return TypeError; case "URIError": return URIError; default: throw new Error(`Unknown Error constructor "${errorName}"`); } } function getErrorOptions(ctx, error) { let options; const constructor = getErrorConstructorName(error); if (error.name !== constructor) { options = { name: error.name }; } else if (error.constructor.name !== constructor) { options = { name: error.constructor.name }; } const names = Object.getOwnPropertyNames(error); for (const name of names) { if (name !== "name" && name !== "message") { if (name === "stack") { if (ctx.features & 16 /* ErrorPrototypeStack */) { options = options || {}; options[name] = error[name]; } } else { options = options || {}; options[name] = error[name]; } } } return options; } function getIterableOptions(obj) { const names = Object.getOwnPropertyNames(obj); if (names.length) { const options = {}; for (const name of names) { options[name] = obj[name]; } return options; } return void 0; } function isIterable(value) { if (!value || typeof value !== "object") { return false; } if (Array.isArray(value)) { return false; } switch (value.constructor) { case Map: case Set: case Int8Array: case Int16Array: case Int32Array: case Uint8Array: case Uint16Array: case Uint32Array: case Uint8ClampedArray: case Float32Array: case Float64Array: case BigInt64Array: case BigUint64Array: return false; default: break; } return Symbol.iterator in value; } 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 Error(`Unknown TypedArray "${name}"`); } } var IDENTIFIER_CHECK = /^[$A-Z_][0-9A-Z_$]*$/i; function isValidIdentifier(name) { const char = name[0]; return (char === "$" || char === "_" || char >= "A" && char <= "Z" || char >= "a" && char <= "z") && IDENTIFIER_CHECK.test(name); } // src/tree/async.ts async function generateNodeList(ctx, current) { const size = current.length; const nodes = new Array(size); const deferred = new Array(size); let item; for (let i = 0; i < size; i++) { if (i in current) { item = current[i]; if (isIterable(item)) { deferred[i] = item; } else { nodes[i] = await parse(ctx, item); } } } for (let i = 0; i < size; i++) { if (i in deferred) { nodes[i] = await parse(ctx, deferred[i]); } } return nodes; } async function generateArrayNode(ctx, id, current) { return { t: 15 /* Array */, i: id, s: void 0, l: current.length, c: void 0, m: void 0, d: void 0, a: await generateNodeList(ctx, current), f: void 0 }; } async function generateMapNode(ctx, id, current) { assert(ctx.features & 32 /* Map */, 'Unsupported type "Map"'); const len = current.size; const keyNodes = new Array(len); const valueNodes = new Array(len); const deferredKey = new Array(len); const deferredValue = new Array(len); let deferredSize = 0; let nodeSize = 0; for (const [key, value] of current.entries()) { if (isIterable(key) || isIterable(value)) { deferredKey[deferredSize] = key; deferredValue[deferredSize] = value; deferredSize++; } else { keyNodes[nodeSize] = await parse(ctx, key); valueNodes[nodeSize] = await parse(ctx, value); nodeSize++; } } for (let i = 0; i < deferredSize; i++) { keyNodes[nodeSize + i] = await parse(ctx, deferredKey[i]); valueNodes[nodeSize + i] = await parse(ctx, deferredValue[i]); } return { t: 14 /* Map */, i: id, s: void 0, l: void 0, c: void 0, m: void 0, d: { k: keyNodes, v: valueNodes, s: len }, a: void 0, f: void 0 }; } async function generateSetNode(ctx, id, current) { assert(ctx.features & 512 /* Set */, 'Unsupported type "Set"'); const len = current.size; const nodes = new Array(len); const deferred = new Array(len); let deferredSize = 0; let nodeSize = 0; for (const item of current.keys()) { if (isIterable(item)) { deferred[deferredSize++] = item; } else { nodes[nodeSize++] = await parse(ctx, item); } } for (let i = 0; i < deferredSize; i++) { nodes[nodeSize + i] = await parse(ctx, deferred[i]); } return { t: 13 /* Set */, i: id, s: void 0, l: len, c: void 0, m: void 0, d: void 0, a: nodes, f: void 0 }; } async function generateProperties(ctx, properties) { const keys = Object.keys(properties); const size = keys.length; const keyNodes = new Array(size); const valueNodes = new Array(size); const deferredKeys = new Array(size); const deferredValues = new Array(size); let deferredSize = 0; let nodesSize = 0; let item; for (const key of keys) { item = properties[key]; if (isIterable(item)) { deferredKeys[deferredSize] = key; deferredValues[deferredSize] = item; deferredSize++; } else { keyNodes[nodesSize] = key; valueNodes[nodesSize] = await parse(ctx, item); nodesSize++; } } for (let i = 0; i < deferredSize; i++) { keyNodes[nodesSize + i] = deferredKeys[i]; valueNodes[nodesSize + i] = await parse(ctx, deferredValues[i]); } return { k: keyNodes, v: valueNodes, s: size }; } async function generateIterableNode(ctx, id, current) { assert(ctx.features & 1024 /* Symbol */, 'Unsupported type "Iterable"'); const options = getIterableOptions(current); const array = Array.from(current); return { t: 21 /* Iterable */, i: id, s: void 0, l: array.length, c: void 0, m: void 0, // Parse options first before the items d: options ? await generateProperties(ctx, options) : void 0, a: await generateNodeList(ctx, array), f: void 0 }; } async function generatePromiseNode(ctx, id, current) { assert(ctx.features & 256 /* Promise */, 'Unsupported type "Promise"'); return current.then(async (value) => ({ t: 18 /* Promise */, i: id, s: void 0, l: void 0, c: void 0, m: void 0, // Parse options first before the items d: void 0, a: void 0, f: await parse(ctx, value) })); } async function generateObjectNode(ctx, id, current, empty) { if (Symbol.iterator in current) { return generateIterableNode(ctx, id, current); } if ("then" in current && typeof current.then === "function") { return generatePromiseNode(ctx, id, current); } return { t: empty ? 17 /* NullConstructor */ : 16 /* Object */, i: id, s: void 0, l: void 0, c: void 0, m: void 0, d: await generateProperties(ctx, current), a: void 0, f: void 0 }; } async function generateAggregateErrorNode(ctx, id, current) { const options = getErrorOptions(ctx, current); const optionsNode = options ? await generateProperties(ctx, options) : void 0; return { t: 20 /* AggregateError */, i: id, s: void 0, l: current.errors.length, c: void 0, m: current.message, d: optionsNode, a: await generateNodeList(ctx, current.errors), f: void 0 }; } async function generateErrorNode(ctx, id, current) { const options = getErrorOptions(ctx, current); const optionsNode = options ? await generateProperties(ctx, options) : void 0; return { t: 19 /* Error */, i: id, s: void 0, l: void 0, c: getErrorConstructorName(current), m: current.message, d: optionsNode, a: void 0, f: void 0 }; } async function parse(ctx, current) { switch (typeof current) { case "boolean": return current ? TRUE_NODE : FALSE_NODE; case "undefined": return UNDEFINED_NODE; case "string": return createStringNode(current); case "number": switch (current) { case Infinity: return INFINITY_NODE; case -Infinity: return NEG_INFINITY_NODE; default: break; } if (current !== current) { return NAN_NODE; } if (Object.is(current, -0)) { return NEG_ZERO_NODE; } return createNumberNode(current); case "bigint": return createBigIntNode(ctx, current); case "object": { if (!current) { return NULL_NODE; } const id = createRef(ctx, current); if (ctx.markedRefs.has(id)) { return createReferenceNode(id); } if (Array.isArray(current)) { return generateArrayNode(ctx, id, current); } switch (current.constructor) { case Date: return createDateNode(id, current); case RegExp: return createRegExpNode(id, current); case Promise: return generatePromiseNode(ctx, id, current); case Int8Array: case Int16Array: case Int32Array: case Uint8Array: case Uint16Array: case Uint32Array: case Uint8ClampedArray: case Float32Array: case Float64Array: return createTypedArrayNode(ctx, id, current); case BigInt64Array: case BigUint64Array: return createBigIntTypedArrayNode(ctx, id, current); case Map: return generateMapNode( ctx, id, current ); case Set: return generateSetNode( ctx, id, current ); case Object: return generateObjectNode( ctx, id, current, false ); case void 0: return generateObjectNode( ctx, id, current, true ); case AggregateError: if (ctx.features & 1 /* AggregateError */) { return generateAggregateErrorNode(ctx, id, current); } return generateErrorNode(ctx, id, current); case Error: case EvalError: case RangeError: case ReferenceError: case SyntaxError: case TypeError: case URIError: return generateErrorNode(ctx, id, current); default: break; } if (current instanceof AggregateError) { if (ctx.features & 1 /* AggregateError */) { return generateAggregateErrorNode(ctx, id, current); } return generateErrorNode(ctx, id, current); } if (current instanceof Error) { return generateErrorNode(ctx, id, current); } if (current instanceof Promise) { return generatePromiseNode(ctx, id, current); } if (Symbol.iterator in current) { return generateIterableNode(ctx, id, current); } if ("then" in current && typeof current.then === "function") { return generatePromiseNode(ctx, id, current); } throw new Error("Unsupported type"); } case "symbol": assert(ctx.features & 1024 /* Symbol */, 'Unsupported type "symbol"'); assert(current in INV_SYMBOL_REF, "seroval only supports well-known symbols"); return createWKSymbolNode(current); default: throw new Error("Unsupported type"); } } async function parseAsync(ctx, current) { const result = await parse(ctx, current); const isObject = result.t === 16 /* Object */ || result.t === 21 /* Iterable */; return [result, getRootID(ctx, current), isObject]; } // src/tree/deserialize.ts function assignRef(ctx, index, value) { ctx.valueMap.set(index, value); return value; } function deserializeNodeList(ctx, node, result) { let item; for (let i = 0, len = node.a.length; i < len; i++) { item = node.a[i]; if (item) { result[i] = deserializeTree(ctx, item); } } return result; } function deserializeArray(ctx, node) { const result = assignRef( ctx, node.i, new Array(node.l) ); ctx.stack.push(node.i); deserializeNodeList(ctx, node, result); ctx.stack.pop(); return result; } function deserializeProperties(ctx, node, result) { if (node.s === 0) { return {}; } for (let i = 0; i < node.s; i++) { result[node.k[i]] = deserializeTree(ctx, node.v[i]); } return result; } function deserializeNullConstructor(ctx, node) { const result = assignRef(ctx, node.i, /* @__PURE__ */ Object.create(null)); ctx.stack.push(node.i); deserializeProperties(ctx, node.d, result); ctx.stack.pop(); return result; } function deserializeObject(ctx, node) { const result = assignRef(ctx, node.i, {}); ctx.stack.push(node.i); deserializeProperties(ctx, node.d, result); ctx.stack.pop(); return result; } function deserializeSet(ctx, node) { const result = assignRef(ctx, node.i, /* @__PURE__ */ new Set()); ctx.stack.push(node.i); for (let i = 0, len = node.a.length; i < len; i++) { result.add(deserializeTree(ctx, node.a[i])); } ctx.stack.pop(); return result; } function deserializeMap(ctx, node) { const result = assignRef( ctx, node.i, /* @__PURE__ */ new Map() ); ctx.stack.push(node.i); for (let i = 0; i < node.d.s; i++) { result.set( deserializeTree(ctx, node.d.k[i]), deserializeTree(ctx, node.d.v[i]) ); } ctx.stack.pop(); return result; } function deserializeDictionary(ctx, node, result) { if (node.d) { ctx.stack.push(node.i); const fields = deserializeProperties(ctx, node.d, {}); ctx.stack.pop(); Object.assign(result, fields); } return result; } function deserializeAggregateError(ctx, node) { const result = assignRef(ctx, node.i, new AggregateError([], node.m)); ctx.stack.push(node.i); result.errors = deserializeNodeList(ctx, node, new Array(node.l)); ctx.stack.pop(); return deserializeDictionary(ctx, node, result); } function deserializeError(ctx, node) { const ErrorConstructor = getErrorConstructor(node.c); const result = assignRef(ctx, node.i, new ErrorConstructor(node.m)); return deserializeDictionary(ctx, node, result); } function createDeferred() { let resolver; return { resolve(v) { resolver(v); }, promise: new Promise((res) => { resolver = res; }) }; } function deserializePromise(ctx, node) { const deferred = createDeferred(); const result = assignRef(ctx, node.i, deferred.promise); deferred.resolve(deserializeTree(ctx, node.f)); return result; } function deserializeTypedArray(ctx, node) { const TypedArray = getTypedArrayConstructor(node.c); const dummy = new TypedArray(); const result = assignRef(ctx, node.i, new TypedArray( dummy.buffer, node.l )); for (let i = 0, len = node.s.length; i < len; i++) { result[i] = node.t === 23 /* BigIntTypedArray */ ? BigInt(node.s[i]) : Number(node.s[i]); } return result; } function deserializeIterable(ctx, node) { const values = []; deserializeNodeList(ctx, node, values); const result = assignRef(ctx, node.i, { [Symbol.iterator]: () => values.values() }); return deserializeDictionary(ctx, node, result); } function deserializeTree(ctx, node) { switch (node.t) { case 0 /* Number */: case 2 /* Boolean */: return node.s; case 1 /* String */: return invQuote(node.s); case 4 /* Undefined */: return void 0; case 3 /* Null */: return null; case 5 /* NegativeZero */: return -0; case 6 /* Infinity */: return Infinity; case 7 /* NegativeInfinity */: return -Infinity; case 8 /* NaN */: return NaN; case 9 /* BigInt */: return BigInt(node.s); case 10 /* Reference */: return ctx.valueMap.get(node.i); case 15 /* Array */: return deserializeArray(ctx, node); case 16 /* Object */: return deserializeObject(ctx, node); case 17 /* NullConstructor */: return deserializeNullConstructor(ctx, node); case 11 /* Date */: return assignRef(ctx, node.i, new Date(node.s)); case 12 /* RegExp */: return assignRef(ctx, node.i, new RegExp(node.c, node.m)); case 13 /* Set */: return deserializeSet(ctx, node); case 14 /* Map */: return deserializeMap(ctx, node); case 23 /* BigIntTypedArray */: case 22 /* TypedArray */: return deserializeTypedArray(ctx, node); case 20 /* AggregateError */: return deserializeAggregateError(ctx, node); case 19 /* Error */: return deserializeError(ctx, node); case 21 /* Iterable */: return deserializeIterable(ctx, node); case 18 /* Promise */: return deserializePromise(ctx, node); case 24 /* WKSymbol */: return SYMBOL_REF[node.s]; default: throw new Error("Unsupported type"); } } // src/tree/serialize.ts function getAssignmentExpression(assignment) { switch (assignment.t) { case "index": return assignment.s + "=" + assignment.v; case "map": return assignment.s + ".set(" + assignment.k + "," + assignment.v + ")"; case "set": return assignment.s + ".add(" + assignment.v + ")"; default: return ""; } } function mergeAssignments(assignments) { const newAssignments = []; let current = assignments[0]; let prev = current; let item; for (let i = 1, len = assignments.length; i < len; i++) { item = assignments[i]; if (item.t === prev.t) { switch (item.t) { case "index": if (item.v === prev.v) { current = { t: "index", s: item.s, k: void 0, v: getAssignmentExpression(current) }; } else { newAssignments.push(current); current = item; } break; case "map": if (item.s === prev.s) { current = { t: "map", s: getAssignmentExpression(current), k: item.k, v: item.v }; } else { newAssignments.push(current); current = item; } break; case "set": if (item.s === prev.s) { current = { t: "set", s: getAssignmentExpression(current), k: void 0, v: item.v }; } else { newAssignments.push(current); current = item; } break; default: break; } } else { newAssignments.push(current); current = item; } prev = item; } newAssignments.push(current); return newAssignments; } function resolveAssignments(assignments) { if (assignments.length) { let result = ""; const merged = mergeAssignments(assignments); for (let i = 0, len = merged.length; i < len; i++) { result += getAssignmentExpression(merged[i]) + ","; } return result; } return void 0; } function resolvePatches(ctx) { return resolveAssignments(ctx.assignments); } function createAssignment(ctx, source, value) { ctx.assignments.push({ t: "index", s: source, k: void 0, v: value }); } function createSetAdd(ctx, ref, value) { markRef(ctx, ref); ctx.assignments.push({ t: "set", s: getRefParam(ctx, ref), k: void 0, v: value }); } function createMapSet(ctx, ref, key, value) { markRef(ctx, ref); ctx.assignments.push({ t: "map", s: getRefParam(ctx, ref), k: key, v: value }); } function createArrayAssign(ctx, ref, index, value) { markRef(ctx, ref); createAssignment(ctx, getRefParam(ctx, ref) + "[" + index + "]", value); } function createObjectAssign(ctx, ref, key, value) { markRef(ctx, ref); createAssignment(ctx, getRefParam(ctx, ref) + "." + key, value); } function assignRef2(ctx, index, value) { if (ctx.markedRefs.has(index)) { return getRefParam(ctx, index) + "=" + value; } return value; } function isReferenceInStack(ctx, node) { return node.t === 10 /* Reference */ && ctx.stack.includes(node.i); } function serializeNodeList(ctx, node) { const size = node.l; let values = ""; let item; let isHoley = false; for (let i = 0; i < size; i++) { if (i !== 0) { values += ","; } item = node.a[i]; if (item) { if (isReferenceInStack(ctx, item)) { createArrayAssign(ctx, node.i, i, getRefParam(ctx, item.i)); isHoley = true; } else { values += serializeTree(ctx, item); isHoley = false; } } else { isHoley = true; } } return "[" + values + (isHoley ? ",]" : "]"); } function serializeArray(ctx, node) { ctx.stack.push(node.i); const result = serializeNodeList(ctx, node); ctx.stack.pop(); return assignRef2(ctx, node.i, result); } function serializeProperties(ctx, sourceID, node) { if (node.s === 0) { return "{}"; } let result = ""; ctx.stack.push(sourceID); let key; let val; let check; let isIdentifier; let refParam; let hasPrev = false; for (let i = 0; i < node.s; i++) { key = node.k[i]; val = node.v[i]; check = Number(key); isIdentifier = check >= 0 || isValidIdentifier(key); if (isReferenceInStack(ctx, val)) { refParam = getRefParam(ctx, val.i); if (isIdentifier && Number.isNaN(check)) { createObjectAssign(ctx, sourceID, key, refParam); } else { createArrayAssign(ctx, sourceID, isIdentifier ? key : '"' + quote(key) + '"', refParam); } } else { result += (hasPrev ? "," : "") + (isIdentifier ? key : '"' + quote(key) + '"') + ":" + serializeTree(ctx, val); hasPrev = true; } } ctx.stack.pop(); return "{" + result + "}"; } function serializeWithObjectAssign(ctx, value, id, serialized) { const fields = serializeProperties(ctx, id, value); if (fields !== "{}") { return "Object.assign(" + serialized + "," + fields + ")"; } return serialized; } function serializeAssignments(ctx, sourceID, node) { ctx.stack.push(sourceID); const mainAssignments = []; let parentStack; let refParam; let key; let check; let parentAssignment; let isIdentifier; for (let i = 0; i < node.s; i++) { parentStack = ctx.stack; ctx.stack = []; refParam = serializeTree(ctx, node.v[i]); ctx.stack = parentStack; key = node.k[i]; check = Number(key); parentAssignment = ctx.assignments; ctx.assignments = mainAssignments; isIdentifier = check >= 0 || isValidIdentifier(key); if (isIdentifier && Number.isNaN(check)) { createObjectAssign(ctx, sourceID, key, refParam); } else { createArrayAssign(ctx, sourceID, isIdentifier ? key : '"' + quote(key) + '"', refParam); } ctx.assignments = parentAssignment; } ctx.stack.pop(); return resolveAssignments(mainAssignments); } function serializeDictionary(ctx, i, d, init) { if (d) { if (ctx.features & 128 /* ObjectAssign */) { init = serializeWithObjectAssign(ctx, d, i, init); } else { markRef(ctx, i); const assignments = serializeAssignments(ctx, i, d); if (assignments) { return "(" + assignRef2(ctx, i, init) + "," + assignments + getRefParam(ctx, i) + ")"; } } } return assignRef2(ctx, i, init); } function serializeNullConstructor(ctx, node) { return serializeDictionary(ctx, node.i, node.d, "Object.create(null)"); } function serializeObject(ctx, node) { return assignRef2(ctx, node.i, serializeProperties(ctx, node.i, node.d)); } function serializeSet(ctx, node) { let serialized = "new Set"; const size = node.l; if (size) { let result = ""; ctx.stack.push(node.i); let item; let hasPrev = false; for (let i = 0; i < size; i++) { item = node.a[i]; if (isReferenceInStack(ctx, item)) { createSetAdd(ctx, node.i, getRefParam(ctx, item.i)); } else { result += (hasPrev ? "," : "") + serializeTree(ctx, item); hasPrev = true; } } ctx.stack.pop(); if (result) { serialized += "([" + result + "])"; } } return assignRef2(ctx, node.i, serialized); } function serializeMap(ctx, node) { let serialized = "new Map"; if (node.d.s) { let result = ""; ctx.stack.push(node.i); let key; let val; let keyRef; let valueRef; let parent; let hasPrev = false; for (let i = 0; i < node.d.s; i++) { key = node.d.k[i]; val = node.d.v[i]; if (isReferenceInStack(ctx, key)) { keyRef = getRefParam(ctx, key.i); if (isReferenceInStack(ctx, val)) { valueRef = getRefParam(ctx, val.i); createMapSet(ctx, node.i, keyRef, valueRef); } else { parent = ctx.stack; ctx.stack = []; createMapSet(ctx, node.i, keyRef, serializeTree(ctx, val)); ctx.stack = parent; } } else if (isReferenceInStack(ctx, val)) { valueRef = getRefParam(ctx, val.i); parent = ctx.stack; ctx.stack = []; createMapSet(ctx, node.i, serializeTree(ctx, key), valueRef); ctx.stack = parent; } else { result += (hasPrev ? ",[" : "[") + serializeTree(ctx, key) + "," + serializeTree(ctx, val) + "]"; hasPrev = true; } } ctx.stack.pop(); if (result) { serialized += "([" + result + "])"; } } return assignRef2(ctx, node.i, serialized); } function serializeAggregateError(ctx, node) { ctx.stack.push(node.i); const serialized = "new AggregateError(" + serializeNodeList(ctx, node) + ',"' + quote(node.m) + '")'; ctx.stack.pop(); return serializeDictionary(ctx, node.i, node.d, serialized); } function serializeError(ctx, node) { const serialized = "new " + node.c + '("' + quote(node.m) + '")'; return serializeDictionary(ctx, node.i, node.d, serialized); } function serializePromise(ctx, node) { let serialized; if (isReferenceInStack(ctx, node.f)) { const ref = getRefParam(ctx, node.f.i); if (ctx.features & 4 /* ArrowFunction */) { serialized = "Promise.resolve().then(()=>" + ref + ")"; } else { serialized = "Promise.resolve().then(function(){return " + ref + "})"; } } else { ctx.stack.push(node.i); const result = serializeTree(ctx, node.f); ctx.stack.pop(); serialized = "Promise.resolve(" + result + ")"; } return assignRef2(ctx, node.i, serialized); } function serializeTypedArray(ctx, node) { let result = ""; const isBigInt = node.t === 23 /* BigIntTypedArray */; for (let i = 0, len = node.s.length; i < len; i++) { result += (i !== 0 ? "," : "") + node.s[i] + (isBigInt ? "n" : ""); } const args = "[" + result + "]" + (node.l !== 0 ? "," + node.l : ""); return assignRef2(ctx, node.i, "new " + node.c + "(" + args + ")"); } function serializeIterable(ctx, node) { const parent = ctx.stack; ctx.stack = []; const values = serializeNodeList(ctx, node); ctx.stack = parent; let serialized = values; if (ctx.features & 2 /* ArrayPrototypeValues */) { serialized += ".values()"; } else { serialized += "[Symbol.iterator]()"; } if (ctx.features & 4 /* ArrowFunction */) { serialized = "{[Symbol.iterator]:()=>" + serialized + "}"; } else if (ctx.features & 64 /* MethodShorthand */) { serialized = "{[Symbol.iterator](){return " + serialized + "}}"; } else { serialized = "{[Symbol.iterator]:function(){return " + serialized + "}}"; } return serializeDictionary(ctx, node.i, node.d, serialized); } function serializeTree(ctx, node) { switch (node.t) { case 0 /* Number */: return "" + node.s; case 1 /* String */: return '"' + node.s + '"'; case 2 /* Boolean */: return node.s ? "!0" : "!1"; case 4 /* Undefined */: return "void 0"; case 3 /* Null */: return "null"; case 5 /* NegativeZero */: return "-0"; case 6 /* Infinity */: return "1/0"; case 7 /* NegativeInfinity */: return "-1/0"; case 8 /* NaN */: return "NaN"; case 9 /* BigInt */: return node.s + "n"; case 10 /* Reference */: return getRefParam(ctx, node.i); case 15 /* Array */: return serializeArray(ctx, node); case 16 /* Object */: return serializeObject(ctx, node); case 17 /* NullConstructor */: return serializeNullConstructor(ctx, node); case 11 /* Date */: return assignRef2(ctx, node.i, 'new Date("' + node.s + '")'); case 12 /* RegExp */: return assignRef2(ctx, node.i, "/" + node.c + "/" + node.m); case 13 /* Set */: return serializeSet(ctx, node); case 14 /* Map */: return serializeMap(ctx, node); case 23 /* BigIntTypedArray */: case 22 /* TypedArray */: return serializeTypedArray(ctx, node); case 20 /* AggregateError */: return serializeAggregateError(ctx, node); case 19 /* Error */: return serializeError(ctx, node); case 21 /* Iterable */: return serializeIterable(ctx, node); case 18 /* Promise */: return serializePromise(ctx, node); case 24 /* WKSymbol */: return SYMBOL_STRING[node.s]; default: throw new Error("Unsupported type"); } } // src/tree/sync.ts function generateNodeList2(ctx, current) { const size = current.length; const nodes = new Array(size); const deferred = new Array(size); let item; for (let i = 0; i < size; i++) { if (i in current) { item = current[i]; if (isIterable(item)) { deferred[i] = item; } else { nodes[i] = parse2(ctx, item); } } } for (let i = 0; i < size; i++) { if (i in deferred) { nodes[i] = parse2(ctx, deferred[i]); } } return nodes; } function generateArrayNode2(ctx, id, current) { return { t: 15 /* Array */, i: id, s: void 0, l: current.length, c: void 0, m: void 0, d: void 0, a: generateNodeList2(ctx, current), f: void 0 }; } function generateMapNode2(ctx, id, current) { assert(ctx.features & 32 /* Map */, 'Unsupported type "Map"'); const len = current.size; const keyNodes = new Array(len); const valueNodes = new Array(len); const deferredKey = new Array(len); const deferredValue = new Array(len); let deferredSize = 0; let nodeSize = 0; for (const [key, value] of current.entries()) { if (isIterable(key) || isIterable(value)) { deferredKey[deferredSize] = key; deferredValue[deferredSize] = value; deferredSize++; } else { keyNodes[nodeSize] = parse2(ctx, key); valueNodes[nodeSize] = parse2(ctx, value); nodeSize++; } } for (let i = 0; i < deferredSize; i++) { keyNodes[nodeSize + i] = parse2(ctx, deferredKey[i]); valueNodes[nodeSize + i] = parse2(ctx, deferredValue[i]); } return { t: 14 /* Map */, i: id, s: void 0, l: void 0, c: void 0, m: void 0, d: { k: keyNodes, v: valueNodes, s: len }, a: void 0, f: void 0 }; } function generateSetNode2(ctx, id, current) { assert(ctx.features & 512 /* Set */, 'Unsupported type "Set"'); const len = current.size; const nodes = new Array(len); const deferred = new Array(len); let deferredSize = 0; let nodeSize = 0; for (const item of current.keys()) { if (isIterable(item)) { deferred[deferredSize++] = item; } else { nodes[nodeSize++] = parse2(ctx, item); } } for (let i = 0; i < deferredSize; i++) { nodes[nodeSize + i] = parse2(ctx, deferred[i]); } return { t: 13 /* Set */, i: id, s: void 0, l: len, c: void 0, m: void 0, d: void 0, a: nodes, f: void 0 }; } function generateProperties2(ctx, properties) { const keys = Object.keys(properties); const size = keys.length; const keyNodes = new Array(size); const valueNodes = new Array(size); const deferredKeys = new Array(size); const deferredValues = new Array(size); let deferredSize = 0; let nodesSize = 0; let item; for (const key of keys) { item = properties[key]; if (isIterable(item)) { deferredKeys[deferredSize] = key; deferredValues[deferredSize] = item; deferredSize++; } else { keyNodes[nodesSize] = key; valueNodes[nodesSize] = parse2(ctx, item); nodesSize++; } } for (let i = 0; i < deferredSize; i++) { keyNodes[nodesSize + i] = deferredKeys[i]; valueNodes[nodesSize + i] = parse2(ctx, deferredValues[i]); } return { k: keyNodes, v: valueNodes, s: size }; } function generateIterableNode2(ctx, id, current) { assert(ctx.features & 1024 /* Symbol */, 'Unsupported type "Iterable"'); const options = getIterableOptions(current); const array = Array.from(current); return { t: 21 /* Iterable */, i: id, s: void 0, l: array.length, c: void 0, m: void 0, // Parse options first before the items d: options ? generateProperties2(ctx, options) : void 0, a: generateNodeList2(ctx, array), f: void 0 }; } function generateObjectNode2(ctx, id, current, empty) { if (Symbol.iterator in current) { return generateIterableNode2(ctx, id, current); } return { t: empty ? 17 /* NullConstructor */ : 16 /* Object */, i: id, s: void 0, l: void 0, c: void 0, m: void 0, d: generateProperties2(ctx, current), a: void 0, f: void 0 }; } function generateAggregateErrorNode2(ctx, id, current) { const options = getErrorOptions(ctx, current); const optionsNode = options ? generateProperties2(ctx, options) : void 0; return { t: 20 /* AggregateError */, i: id, s: void 0, l: current.errors.length, c: void 0, m: current.message, d: optionsNode, a: generateNodeList2(ctx, current.errors), f: void 0 }; } function generateErrorNode2(ctx, id, current) { const options = getErrorOptions(ctx, current); const optionsNode = options ? generateProperties2(ctx, options) : void 0; return { t: 19 /* Error */, i: id, s: void 0, l: void 0, c: getErrorConstructorName(current), m: current.message, d: optionsNode, a: void 0, f: void 0 }; } function parse2(ctx, current) { switch (typeof current) { case "boolean": return current ? TRUE_NODE : FALSE_NODE; case "undefined": return UNDEFINED_NODE; case "string": return createStringNode(current); case "number": switch (current) { case Infinity: return INFINITY_NODE; case -Infinity: return NEG_INFINITY_NODE; default: break; } if (current !== current) { return NAN_NODE; } if (Object.is(current, -0)) { return NEG_ZERO_NODE; } return createNumberNode(current); case "bigint": return createBigIntNode(ctx, current); case "object": { if (!current) { return NULL_NODE; } const id = createRef(ctx, current); if (ctx.markedRefs.has(id)) { return createReferenceNode(id); } if (Array.isArray(current)) { return generateArrayNode2(ctx, id, current); } switch (current.constructor) { case Date: return createDateNode(id, current); case RegExp: return createRegExpNode(id, current); case Int8Array: case Int16Array: case Int32Array: case Uint8Array: case Uint16Array: case Uint32Array: case Uint8ClampedArray: case Float32Array: case Float64Array: return createTypedArrayNode(ctx, id, current); case BigInt64Array: case BigUint64Array: return createBigIntTypedArrayNode(ctx, id, current); case Map: return generateMapNode2(ctx, id, current); case Set: return generateSetNode2(ctx, id, current); case Object: return generateObjectNode2(ctx, id, current, false); case void 0: return generateObjectNode2(ctx, id, current, true); case AggregateError: if (ctx.features & 1 /* AggregateError */) { return generateAggregateErrorNode2(ctx, id, current); } return generateErrorNode2(ctx, id, current); case Error: case EvalError: case RangeError: case ReferenceError: case SyntaxError: case TypeError: case URIError: return generateErrorNode2(ctx, id, current); default: break; } if (current instanceof AggregateError) { if (ctx.features & 1 /* AggregateError */) { return generateAggregateErrorNode2(ctx, id, current); } return generateErrorNode2(ctx, id, current); } if (current instanceof Error) { return generateErrorNode2(ctx, id, current); } if (Symbol.iterator in current) { return generateIterableNode2(ctx, id, current); } throw new Error("Unsupported type"); } case "symbol": assert(ctx.features & 1024 /* Symbol */, 'Unsupported type "symbol"'); assert(current in INV_SYMBOL_REF, "seroval only supports well-known symbols"); return createWKSymbolNode(current); default: throw new Error("Unsupported type"); } } function parseSync(ctx, current) { const result = parse2(ctx, current); const isObject = result.t === 16 /* Object */ || result.t === 21 /* Iterable */; return [result, getRootID(ctx, current), isObject]; } // src/index.ts function finalize(ctx, rootID, isObject, result) { if (ctx.vars.length) { const patches = resolvePatches(ctx); let body = result; if (patches) { const index = getRefParam(ctx, rootID); body = result + "," + patches + index; if (!result.startsWith(index + "=")) { body = index + "=" + body; } } let params = ctx.vars.length > 1 ? ctx.vars.join(",") : ctx.vars[0]; if (ctx.features & 4 /* ArrowFunction */) { params = ctx.vars.length > 1 || ctx.vars.length === 0 ? "(" + params + ")" : params; return "(" + params + "=>(" + body + "))()"; } return "(function(" + params + "){return " + body + "})()"; } if (isObject) { return "(" + result + ")"; } return result; } function serialize(source, options) { const ctx = createParserContext(options); const [tree, rootID, isObject] = parseSync(ctx, source); const serial = createSerializationContext(ctx); const result = serializeTree(serial, tree); return finalize(serial, rootID, isObject, result); } async function serializeAsync(source, options) { const ctx = createParserContext(options); const [tree, rootID, isObject] = await parseAsync(ctx, source); const serial = createSerializationContext(ctx); const result = serializeTree(serial, tree); return finalize(serial, rootID, isObject, result); } function deserialize(source) { return (0, eval)(source); } function toJSON(source, options) { const ctx = createParserContext(options); const [tree, root, isObject] = parseSync(ctx, source); return { t: tree, r: root, i: isObject, f: ctx.features, m: Array.from(ctx.markedRefs) }; } async function toJSONAsync(source, options) { const ctx = createParserContext(options); const [tree, root, isObject] = await parseAsync(ctx, source); return { t: tree, r: root, i: isObject, f: ctx.features, m: Array.from(ctx.markedRefs) }; } function compileJSON(source) { const serial = createSerializationContext({ features: source.f, markedRefs: source.m }); const result = serializeTree(serial, source.t); return finalize(serial, source.r, source.i, result); } function fromJSON(source) { const serial = createSerializationContext({ features: source.f, markedRefs: source.m }); return deserializeTree(serial, source.t); } var src_default = serialize; //# sourceMappingURL=index.cjs.map