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
JavaScript
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
};