UNPKG

cache-kit

Version:

A simple caching layer for fetch requests — supports memory, browser (localStorage), and Node.js (filesystem) adapters with smart strategies.

111 lines (108 loc) 3.11 kB
import { getExpiryTimeCacheKey } from "./chunk-IDUKVVV3.mjs"; import { __async } from "./chunk-VM2JCVBB.mjs"; // src/utils/node.util.ts import fs from "fs"; import path from "path"; var FileMemory = class { constructor(folderName = "cache") { this.baseDir = path.resolve(folderName); if (!fs.existsSync(this.baseDir)) { fs.mkdirSync(this.baseDir, { recursive: true }); } } getFilePath(key) { return path.resolve(this.baseDir, `${key}.json`); } set(key, data) { fs.writeFileSync(this.getFilePath(key), JSON.stringify(data)); } get(key) { try { const data = fs.readFileSync(this.getFilePath(key), "utf8"); return JSON.parse(data); } catch (e) { return null; } } has(key) { return fs.existsSync(this.getFilePath(key)); } delete(key) { const filePath = this.getFilePath(key); if (fs.existsSync(filePath)) { fs.unlinkSync(filePath); } } clear() { const files = fs.readdirSync(this.baseDir); for (const file of files) { if (file.endsWith(".json")) { fs.unlinkSync(path.join(this.baseDir, file)); } } } }; // src/adapters/node.ts var fileCache = null; var nodeCachedFetch = (normalizedUrl, options, cacheOptions) => __async(null, null, function* () { const cacheKey = btoa(normalizedUrl); if (!fileCache) { const folderName = (cacheOptions == null ? void 0 : cacheOptions.folderName) || "cache-kit-data"; fileCache = new FileMemory(folderName); } let response; if (cacheOptions.strategy === "cache-first") { if (fileCache.has(cacheKey)) { const cached = fileCache.get(cacheKey); if (cached.expiredAt > Date.now()) { return cached.response.clone(); } } const res = yield fetch(normalizedUrl, options); fileCache.set(cacheKey, { response: res.clone(), expiredAt: getExpiryTimeCacheKey(cacheOptions.revalidate) }); return res; } else if (cacheOptions.strategy === "network-first") { try { const res = yield fetch(normalizedUrl, options); fileCache.set(cacheKey, { response: res.clone(), expiredAt: getExpiryTimeCacheKey(cacheOptions.revalidate) }); return res; } catch (e) { if (fileCache.has(cacheKey)) { const cached = fileCache.get(cacheKey); if (cached.expiredAt > Date.now()) { return cached.response.clone(); } } throw new Error("Network failed and no valid cache found"); } } else if (cacheOptions.strategy === "stale-while-revalidate") { if (fileCache.has(cacheKey)) { const cached = fileCache.get(cacheKey); response = cached.response.clone(); } fetch(normalizedUrl, options).then((res) => { fileCache.set(cacheKey, { response: res, expiredAt: getExpiryTimeCacheKey(cacheOptions.revalidate) }); }).catch((err) => { console.warn("Revalidation failed:", err); }); return response; } throw new Error("No valid response available."); }); var node_default = nodeCachedFetch; export { node_default as default };