import { dirname, join } from "node:path";
import { createHash } from "node:crypto";
import "node:fs/promises";
import "node:v8";
import "node:zlib";

//#region ../react-intlayer/dist/esm/@intlayer/config/dist/esm/utils/cache.mjs
/** ------------------------- Utilities ------------------------- **/
/** Prefer a fast non-crypto hash if available, then fast crypto, then sha256. */
const pickHashAlgorithm = () => {
	try {
		createHash("xxhash64").update("test").digest();
		return "xxhash64";
	} catch {}
	try {
		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 = 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 = 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 cache = {
	get: getCache,
	set: setCache,
	clear: clearCache
};

//#endregion
export { cache };
//# sourceMappingURL=cache.mjs.map