Lumi/plugins/lumi_ai_web_search/backend/cache.js
2026-06-14 05:01:13 +02:00

77 lines
2.2 KiB
JavaScript

const crypto = require("crypto");
const fs = require("fs");
const path = require("path");
class ToolCache {
constructor(options = {}) {
this.directory = options.directory;
this.now = options.now || Date.now;
}
get(key, ttlSeconds) {
if (!ttlSeconds) return null;
const file = this.fileFor(key);
try {
const value = JSON.parse(fs.readFileSync(file, "utf8"));
if (!Number.isFinite(value.created_at) || value.created_at + ttlSeconds * 1000 <= this.now()) {
fs.rmSync(file, { force: true });
return null;
}
return value.data;
} catch {
return null;
}
}
set(key, data) {
fs.mkdirSync(this.directory, { recursive: true });
const file = this.fileFor(key);
const temporary = `${file}.${process.pid}.tmp`;
fs.writeFileSync(temporary, `${JSON.stringify({ created_at: this.now(), data })}\n`);
try { fs.renameSync(temporary, file); }
catch (error) {
if (!["EEXIST", "EPERM"].includes(error.code)) throw error;
fs.rmSync(file, { force: true });
fs.renameSync(temporary, file);
}
this.prune(200);
return data;
}
clear() {
fs.rmSync(this.directory, { recursive: true, force: true });
fs.mkdirSync(this.directory, { recursive: true });
}
stats() {
try {
const files = fs.readdirSync(this.directory).filter((name) => name.endsWith(".json"));
return {
entries: files.length,
bytes: files.reduce((total, name) => total + fs.statSync(path.join(this.directory, name)).size, 0)
};
} catch {
return { entries: 0, bytes: 0 };
}
}
prune(maximum) {
let files;
try {
files = fs.readdirSync(this.directory)
.filter((name) => name.endsWith(".json"))
.map((name) => ({ name, mtime: fs.statSync(path.join(this.directory, name)).mtimeMs }))
.sort((left, right) => right.mtime - left.mtime);
} catch {
return;
}
for (const file of files.slice(maximum)) fs.rmSync(path.join(this.directory, file.name), { force: true });
}
fileFor(key) {
return path.join(this.directory, `${crypto.createHash("sha256").update(String(key)).digest("hex")}.json`);
}
}
module.exports = { ToolCache };