@intlayer/config
Version:
Retrieve Intlayer configurations and manage environment variables for both server-side and client-side environments.
186 lines (184 loc) • 7.06 kB
JavaScript
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
const require_utils_cacheMemory = require('./cacheMemory.cjs');
let node_path = require("node:path");
let node_fs_promises = require("node:fs/promises");
let node_v8 = require("node:v8");
let node_zlib = require("node:zlib");
let _intlayer_types_package_json = require("@intlayer/types/package.json");
_intlayer_types_package_json = require_runtime.__toESM(_intlayer_types_package_json);
//#region src/utils/cacheDisk.ts
const DEFAULTS = { compress: true };
const ensureDir = async (dir) => {
await (0, node_fs_promises.mkdir)(dir, { recursive: true });
};
const atomicWriteFile = async (file, data, tempDir) => {
if (tempDir) try {
await ensureDir(tempDir);
} catch {}
const tempFileName = `${(0, node_path.basename)(file)}.tmp-${process.pid}-${Math.random().toString(36).slice(2)}`;
const tmp = tempDir ? (0, node_path.join)(tempDir, tempFileName) : `${file}.tmp-${process.pid}-${Math.random().toString(36).slice(2)}`;
try {
await (0, node_fs_promises.writeFile)(tmp, data);
await (0, node_fs_promises.rename)(tmp, file);
} catch (error) {
try {
await (0, node_fs_promises.rm)(tmp, { force: true });
} catch {}
throw error;
}
};
const shouldUseCompression = (buf, force) => force === true || force !== false && buf.byteLength > 1024;
/** Derive on-disk path from config dir + namespace + key id. */
const cachePath = (cacheDir, id, ns) => (0, node_path.join)(cacheDir, ns ? (0, node_path.join)(ns, id) : id);
/** ------------------------- Local cache facade ------------------------- **/
const cacheMap = /* @__PURE__ */ new Map();
/** Clears the in-memory portion of the disk cache without touching disk files. */
const clearDiskCacheMemory = () => {
cacheMap.clear();
};
const cacheDisk = (intlayerConfig, keys, options) => {
const { cacheDir, tempDir } = intlayerConfig.system;
const buildCacheEnabled = intlayerConfig.build.cache ?? true;
const persistent = options?.persistent === true || typeof options?.persistent === "undefined" && buildCacheEnabled;
const { compress, ttlMs, maxTimeMs, namespace } = {
...DEFAULTS,
...options
};
const id = require_utils_cacheMemory.computeKeyId(keys);
const filePath = cachePath(cacheDir, id, namespace);
const readFromDisk = async () => {
try {
const statValue = await (0, node_fs_promises.stat)(filePath).catch(() => void 0);
if (!statValue) return void 0;
if (typeof ttlMs === "number" && ttlMs > 0) {
if (Date.now() - statValue.mtimeMs > ttlMs) return void 0;
}
let raw = await (0, node_fs_promises.readFile)(filePath);
const flag = raw[0];
raw = raw.subarray(1);
const deserialized = (0, node_v8.deserialize)(flag === 1 ? (0, node_zlib.gunzipSync)(raw) : raw);
let value;
const maybeObj = deserialized;
if (!!maybeObj && typeof maybeObj === "object" && typeof maybeObj.version === "string" && typeof maybeObj.timestamp === "number" && Object.hasOwn(maybeObj, "data")) {
const entry = maybeObj;
if (entry.version !== _intlayer_types_package_json.default.version) {
try {
await (0, node_fs_promises.unlink)(filePath);
} catch {}
return;
}
if (typeof maxTimeMs === "number" && maxTimeMs > 0) {
if (Date.now() - entry.timestamp > maxTimeMs) {
try {
await (0, node_fs_promises.unlink)(filePath);
} catch {}
return;
}
}
value = entry.data;
} else {
if (typeof maxTimeMs === "number" && maxTimeMs > 0) {
if (Date.now() - statValue.mtimeMs > maxTimeMs) {
try {
await (0, node_fs_promises.unlink)(filePath);
} catch {}
return;
}
}
value = deserialized;
}
cacheMap.set(id, value);
return value;
} catch {
return;
}
};
const writeToDisk = async (value) => {
try {
await ensureDir((0, node_path.dirname)(filePath));
const envelope = {
version: _intlayer_types_package_json.default.version,
timestamp: Date.now(),
data: value
};
const payload = Buffer.from((0, node_v8.serialize)(envelope));
const gz = shouldUseCompression(payload, compress) ? (0, node_zlib.gzipSync)(payload) : payload;
await atomicWriteFile(filePath, Buffer.concat([Buffer.from([gz === payload ? 0 : 1]), gz]), tempDir);
} catch {}
};
return {
/** In-memory first, then disk (if enabled), otherwise undefined. */
get: async () => {
const mem = cacheMap.get(id);
if (mem !== void 0) return mem;
if (persistent && buildCacheEnabled) return await readFromDisk();
},
/** Sets in-memory (always) and persists to disk if enabled. */
set: async (value) => {
cacheMap.set(id, value);
if (persistent && buildCacheEnabled) await writeToDisk(value);
},
/** Clears only this entry from memory and disk. */
clear: async () => {
cacheMap.delete(id);
try {
await (0, node_fs_promises.unlink)(filePath);
} catch {}
},
/** Clears ALL cached entries (memory Map and entire cacheDir namespace if persistent). */
clearAll: async () => {
require_utils_cacheMemory.clearAllCache();
if (persistent && buildCacheEnabled) {
const base = namespace ? (0, node_path.join)(cacheDir, namespace) : cacheDir;
try {
await (0, node_fs_promises.rm)(base, {
recursive: true,
force: true
});
} catch {}
try {
await (0, node_fs_promises.mkdir)(base, { recursive: true });
} catch {}
}
},
/** Expose the computed id (useful if you want to key other structures). */
isValid: async () => {
if (cacheMap.get(id) !== void 0) return true;
if (!persistent || !buildCacheEnabled) return false;
try {
const statValue = await (0, node_fs_promises.stat)(filePath).catch(() => void 0);
if (!statValue) return false;
if (typeof ttlMs === "number" && ttlMs > 0) {
if (Date.now() - statValue.mtimeMs > ttlMs) return false;
}
let raw = await (0, node_fs_promises.readFile)(filePath);
const flag = raw[0];
raw = raw.subarray(1);
const maybeObj = (0, node_v8.deserialize)(flag === 1 ? (0, node_zlib.gunzipSync)(raw) : raw);
if (!!maybeObj && typeof maybeObj === "object" && typeof maybeObj.version === "string" && typeof maybeObj.timestamp === "number" && Object.hasOwn(maybeObj, "data")) {
const entry = maybeObj;
if (entry.version !== _intlayer_types_package_json.default.version) return false;
if (typeof maxTimeMs === "number" && maxTimeMs > 0) {
if (Date.now() - entry.timestamp > maxTimeMs) return false;
}
return true;
}
if (typeof maxTimeMs === "number" && maxTimeMs > 0) {
if (Date.now() - statValue.mtimeMs > maxTimeMs) return false;
}
return true;
} catch {
return false;
}
},
/** Expose the computed id (useful if you want to key other structures). */
id,
/** Expose the absolute file path for debugging. */
filePath
};
};
//#endregion
exports.cacheDisk = cacheDisk;
exports.clearDiskCacheMemory = clearDiskCacheMemory;
//# sourceMappingURL=cacheDisk.cjs.map