function serialize(input) { if (typeof input === "string") return `'${input}'`; return new Serializer().serialize(input); } const asciiOrder = " _-,;:!?.'\"()[]{}@*/\\&#%`^+<=>|~$0123456789abcdefghijklmnopqrstuvwxyz"; const asciiWeights = /*@__PURE__*/ (function() { const weights = /* @__PURE__ */ new Uint8Array(128); for (let i = 0; i < 69; i++) weights[asciiOrder.charCodeAt(i)] = i + 1; for (let code = 65; code <= 90; code++) weights[code] = weights[code + 32]; return weights; })(); function compareStrings(a, b) { if (a === b) return 0; const length = Math.min(a.length, b.length); let tieBreaker = 0; for (let i = 0; i < length; i++) { const codeA = a.charCodeAt(i); const codeB = b.charCodeAt(i); if (codeA === codeB) continue; const weightA = codeA < 128 && asciiWeights[codeA] ? asciiWeights[codeA] : codeA + 128; const weightB = codeB < 128 && asciiWeights[codeB] ? asciiWeights[codeB] : codeB + 128; if (weightA !== weightB) return weightA < weightB ? -1 : 1; if (tieBreaker === 0) tieBreaker = codeA > codeB ? -1 : 1; } if (a.length !== b.length) return a.length < b.length ? -1 : 1; return tieBreaker; } const Serializer = /*@__PURE__*/ (function() { class Serializer { #context = /* @__PURE__ */ new Map(); compare(a, b) { const typeA = typeof a; const typeB = typeof b; if (typeA === "string" && typeB === "string") return compareStrings(a, b); if (typeA === "number" && typeB === "number") return a - b; return compareStrings(this.serialize(a, true), this.serialize(b, true)); } serialize(value, noQuotes) { if (value === null) return "null"; switch (typeof value) { case "string": return noQuotes ? value : `'${value}'`; case "bigint": return `${value}n`; case "object": return this.$object(value); case "function": return this.$function(value); } return String(value); } serializeObject(object) { const objString = Object.prototype.toString.call(object); if (objString !== "[object Object]") return this.serializeBuiltInType(objString.length < 10 ? `unknown:${objString}` : objString.slice(8, -1), object); const constructor = object.constructor; const objName = constructor === Object || constructor === void 0 ? "" : constructor.name; if (objName !== "" && globalThis[objName] === constructor) return this.serializeBuiltInType(objName, object); if ("toJSON" in object && typeof object.toJSON === "function") { const json = object.toJSON(); return objName + (json !== null && typeof json === "object" ? this.$object(json) : `(${this.serialize(json)})`); } const keys = Object.keys(object).sort(compareStrings); let content = `${objName}{`; for (let i = 0; i < keys.length; i++) { const key = keys[i]; content += `${key}:${this.serialize(object[key])}`; if (i < keys.length - 1) content += ","; } return content + "}"; } serializeBuiltInType(type, object) { const handler = this["$" + type]; if (handler) return handler.call(this, object); if (typeof object.entries === "function") return this.serializeObjectEntries(type, object.entries()); throw new Error(`Cannot serialize ${type}`); } serializeObjectEntries(type, entries) { const sortedEntries = Array.from(entries).sort((a, b) => this.compare(a[0], b[0])); let content = `${type}{`; for (let i = 0; i < sortedEntries.length; i++) { const [key, value] = sortedEntries[i]; content += `${this.serialize(key, true)}:${this.serialize(value)}`; if (i < sortedEntries.length - 1) content += ","; } return content + "}"; } $object(object) { let content = this.#context.get(object); if (content === void 0) { this.#context.set(object, `#${this.#context.size}`); content = this.serializeObject(object); this.#context.set(object, content); } return content; } $function(fn) { const fnStr = Function.prototype.toString.call(fn); if (fnStr.slice(-15) === "[native code] }") return `${fn.name || ""}()[native]`; return `${fn.name}(${fn.length})${fnStr.replace(/\s*\n\s*/g, "")}`; } $Array(arr) { let content = "["; for (let i = 0; i < arr.length; i++) { content += this.serialize(arr[i]); if (i < arr.length - 1) content += ","; } return content + "]"; } $Date(date) { try { return `Date(${date.toISOString()})`; } catch { return `Date(null)`; } } $ArrayBuffer(arr) { return `ArrayBuffer[${new Uint8Array(arr).join(",")}]`; } $Set(set) { return `Set${this.$Array(Array.from(set).sort((a, b) => this.compare(a, b)))}`; } $Map(map) { return this.serializeObjectEntries("Map", map.entries()); } } for (const type of [ "Error", "RegExp", "URL" ]) Serializer.prototype["$" + type] = function(val) { return `${type}(${val})`; }; for (const type of [ "Int8Array", "Uint8Array", "Uint8ClampedArray", "Int16Array", "Uint16Array", "Int32Array", "Uint32Array", "Float32Array", "Float64Array" ]) Serializer.prototype["$" + type] = function(arr) { return `${type}[${arr.join(",")}]`; }; for (const type of ["BigInt64Array", "BigUint64Array"]) Serializer.prototype["$" + type] = function(arr) { return `${type}[${arr.join("n,")}${arr.length > 0 ? "n" : ""}]`; }; return Serializer; })(); function isEqual(object1, object2) { if (object1 === object2) return true; if (serialize(object1) === serialize(object2)) return true; return false; } export { isEqual, serialize };