UNPKG

@intlayer/config

Version:

Retrieve Intlayer configurations and manage environment variables for both server-side and client-side environments.

270 lines (268 loc) 7.78 kB
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); const require_runtime = require('../_virtual/_rolldown/runtime.cjs'); let node_crypto = require("node:crypto"); //#region src/utils/cacheMemory.ts /** ------------------------- Utilities ------------------------- **/ /** Prefer a fast non-crypto hash if available, then fast crypto, then sha256. */ const pickHashAlgorithm = () => { try { (0, node_crypto.createHash)("xxhash64").update("test").digest(); return "xxhash64"; } catch {} try { (0, node_crypto.createHash)("sha1").update("test").digest(); return "sha1"; } catch {} return "sha256"; }; const HASH_ALGORITHM = pickHashAlgorithm(); /** Base64url without padding for compact, file-system-safe ids. */ const toBase64Url = (buffer) => buffer.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, ""); /** Token helpers to minimize collisions while streaming to the hasher. */ const token = { start: (hasher, tag) => hasher.update(`<${tag}>`), sep: (hasher) => hasher.update("|"), end: (hasher, tag) => hasher.update(`</${tag}>`), str: (hasher, stringValue) => { hasher.update(`${stringValue.length}#`); hasher.update(stringValue); }, num: (hasher, numberValue) => hasher.update(Number.isNaN(numberValue) ? "NaN" : numberValue === Infinity ? "Inf" : numberValue === -Infinity ? "-Inf" : String(numberValue)), big: (hasher, bigintValue) => hasher.update(bigintValue.toString(10)), bool: (hasher, booleanValue) => hasher.update(booleanValue ? "1" : "0") }; /** * Streams a canonical representation of `value` into `hasher` without * constructing large intermediate strings. Objects/Maps/Sets are normalized. */ const stableHashValue = (hasher, value, seen) => { const valueType = typeof value; if (value === null) { token.start(hasher, "null"); token.end(hasher, "null"); return; } if (valueType === "undefined") { token.start(hasher, "undef"); token.end(hasher, "undef"); return; } if (valueType === "number") { token.start(hasher, "num"); token.num(hasher, value); token.end(hasher, "num"); return; } if (valueType === "bigint") { token.start(hasher, "big"); token.big(hasher, value); token.end(hasher, "big"); return; } if (valueType === "boolean") { token.start(hasher, "bool"); token.bool(hasher, value); token.end(hasher, "bool"); return; } if (valueType === "string") { token.start(hasher, "str"); token.str(hasher, value); token.end(hasher, "str"); return; } if (valueType === "symbol") { token.start(hasher, "sym"); token.str(hasher, String(value)); token.end(hasher, "sym"); return; } if (valueType === "function") { const functionValue = value; token.start(hasher, "fn"); token.str(hasher, functionValue.name ?? ""); token.sep(hasher); token.num(hasher, functionValue.length); token.end(hasher, "fn"); return; } if (Array.isArray(value)) { if (seen.has(value)) { token.start(hasher, "arr"); token.str(hasher, "Circular"); token.end(hasher, "arr"); return; } seen.add(value); token.start(hasher, "arr"); for (let i = 0; i < value.length; i++) { token.sep(hasher); stableHashValue(hasher, value[i], seen); } token.end(hasher, "arr"); seen.delete(value); return; } if (value instanceof Date) { token.start(hasher, "date"); token.str(hasher, value.toISOString()); token.end(hasher, "date"); return; } if (value instanceof RegExp) { const regex = value; token.start(hasher, "re"); token.str(hasher, regex.source); token.sep(hasher); token.str(hasher, regex.flags); token.end(hasher, "re"); return; } if (value instanceof Set) { const setValue = value; if (seen.has(setValue)) { token.start(hasher, "set"); token.str(hasher, "Circular"); token.end(hasher, "set"); return; } seen.add(setValue); const items = []; for (const v of setValue) items.push(stableStringify(v)); items.sort(); token.start(hasher, "set"); for (const item of items) { token.sep(hasher); token.str(hasher, item); } token.end(hasher, "set"); seen.delete(setValue); return; } if (value instanceof Map) { const mapObject = value; if (seen.has(mapObject)) { token.start(hasher, "map"); token.str(hasher, "Circular"); token.end(hasher, "map"); return; } seen.add(mapObject); const entries = []; for (const [k, v] of mapObject.entries()) entries.push([stableStringify(k), v]); entries.sort((a, b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0); token.start(hasher, "map"); for (const [keyFingerprint, entryValue] of entries) { token.sep(hasher); token.str(hasher, keyFingerprint); token.sep(hasher); stableHashValue(hasher, entryValue, seen); } token.end(hasher, "map"); seen.delete(mapObject); return; } if (ArrayBuffer.isView(value)) { const view = value; token.start(hasher, "typed"); token.str(hasher, Object.getPrototypeOf(view).constructor.name); token.sep(hasher); hasher.update(Buffer.from(view.buffer, view.byteOffset, view.byteLength)); token.end(hasher, "typed"); return; } if (value instanceof ArrayBuffer) { const buffer = Buffer.from(value); token.start(hasher, "ab"); hasher.update(buffer); token.end(hasher, "ab"); return; } if (typeof URL !== "undefined" && value instanceof URL) { token.start(hasher, "url"); token.str(hasher, value.toString()); token.end(hasher, "url"); return; } if (value instanceof Error) { const errorValue = value; token.start(hasher, "err"); token.str(hasher, errorValue.name || ""); token.sep(hasher); token.str(hasher, errorValue.message || ""); token.sep(hasher); token.str(hasher, errorValue.stack || ""); token.end(hasher, "err"); return; } if (valueType === "object") { const objectValue = value; if (seen.has(objectValue)) { token.start(hasher, "obj"); token.str(hasher, "Circular"); token.end(hasher, "obj"); return; } seen.add(objectValue); const keys = Object.keys(objectValue).sort(); token.start(hasher, "obj"); for (const key of keys) { token.sep(hasher); token.str(hasher, key); token.sep(hasher); stableHashValue(hasher, objectValue[key], seen); } token.end(hasher, "obj"); seen.delete(objectValue); return; } token.start(hasher, "other"); token.str(hasher, String(value)); token.end(hasher, "other"); }; /** Public stringify kept for convenience / debugging (now faster & broader). */ const stableStringify = (value, _stack = /* @__PURE__ */ new WeakSet()) => { const hasher = (0, node_crypto.createHash)(HASH_ALGORITHM); stableHashValue(hasher, value, _stack); return toBase64Url(hasher.digest()); }; /** Compute a compact, stable id for arbitrary key tuples. */ const computeKeyId = (keyParts) => { const h = (0, node_crypto.createHash)(HASH_ALGORITHM); token.start(h, "keys"); for (let i = 0; i < keyParts.length; i++) { token.sep(h); stableHashValue(h, keyParts[i], /* @__PURE__ */ new WeakSet()); } token.end(h, "keys"); return toBase64Url(h.digest()); }; const cacheMap = /* @__PURE__ */ new Map(); const getCache = (...key) => { return cacheMap.get(computeKeyId(key)); }; const setCache = (...args) => { const value = args[args.length - 1]; const key = args.slice(0, -1); cacheMap.set(computeKeyId(key), value); }; const clearCache = (idOrKey) => { cacheMap.delete(idOrKey); }; const clearAllCache = () => { cacheMap.clear(); }; const cacheMemory = { get: getCache, set: setCache, clear: clearCache }; //#endregion exports.cacheMemory = cacheMemory; exports.clearAllCache = clearAllCache; exports.clearCache = clearCache; exports.computeKeyId = computeKeyId; exports.getCache = getCache; exports.setCache = setCache; exports.stableStringify = stableStringify; //# sourceMappingURL=cacheMemory.cjs.map