@dephub/cache
Version:
Simple file-based cache with persistent storage for Node.js applications
144 lines (143 loc) • 4.2 kB
JavaScript
import { rm as h } from "node:fs/promises";
import { cwd as e } from "@dephub/path";
import { readFile as c } from "@dephub/read";
import { writeFile as o } from "@dephub/write";
import { MemoryCache as r } from "./memory.js";
class d {
#t = new r();
#e;
#s = "";
/**
* Creates a new file-based cache instance.
*
* @param options - Configuration options for the cache file
*/
constructor(t = {}) {
const { name: i = "cache.json", directory: s = e("cache") } = t;
this.#s = e(s, i), this.#e = this.#r();
}
/**
* Sets a value in the cache and persists to file.
*
* @param key - Cache key (must be a string)
* @param value - Value to store (string, number, or boolean)
* @returns Promise that resolves with the cache instance for chaining
* @throws {Error} If cache initialization fails
* @throws {Error} If file write operation fails
* @throws {Error} If key is not a string or value is invalid type
*/
async set(t, i) {
return await this.#i(), this.#t.set(t, i), await this.#a(), this;
}
/**
* Deletes a key from the cache and persists the change to file.
*
* @param key - The key to delete
* @returns Promise that resolves with true if the key was found and deleted, false otherwise
* @throws {Error} If cache initialization fails
* @throws {Error} If file write operation fails
*/
async delete(t) {
await this.#i();
const i = this.#t.delete(t);
return await this.#a(), i;
}
/**
* Clears all entries from the cache and persists the change to file.
*
* @returns Promise that resolves when the cache is cleared
* @throws {Error} If file write operation fails
*/
async clear() {
this.#t.clear(), await this.#a(), await h(this.#s);
}
/**
* Gets a value from the cache.
*
* @param key - The key to look up
* @returns Promise that resolves with the value if found, undefined otherwise
* @throws {Error} If cache initialization fails
*/
async get(t) {
return await this.#i(), this.#t.get(t);
}
/**
* Checks if a key exists in the cache.
*
* @param key - The key to check
* @returns Promise that resolves with true if the key exists, false otherwise
* @throws {Error} If cache initialization fails
*/
async has(t) {
return await this.#i(), this.#t.has(t);
}
/**
* Returns the number of entries in the cache.
*
* @returns Promise that resolves with the number of entries
* @throws {Error} If cache initialization fails
*/
async size() {
return await this.#i(), this.#t.size;
}
/**
* Returns an array of all keys in the cache.
*
* @returns Promise that resolves with an array of keys
* @throws {Error} If cache initialization fails
*/
async keys() {
return await this.#i(), Array.from(this.#t.keys());
}
/**
* Returns an array of all values in the cache.
*
* @returns Promise that resolves with an array of values
* @throws {Error} If cache initialization fails
*/
async values() {
return await this.#i(), Array.from(this.#t.values());
}
/**
* Returns an array of [key, value] pairs in the cache.
*
* @returns Promise that resolves with an array of entries
* @throws {Error} If cache initialization fails
*/
async entries() {
return await this.#i(), Array.from(this.#t.entries());
}
/**
* Executes a callback for each entry in the cache.
*
* @param callback - The function to call for each entry, receiving value and key
* @returns Promise that resolves when the iteration is complete
* @throws {Error} If cache initialization fails
*/
async forEach(t) {
await this.#i(), this.#t.forEach(t);
}
async #a() {
const t = Object.fromEntries(this.#t);
await o(this.#s, JSON.stringify(t, null, 2));
}
async #i() {
await this.#e;
}
async #r() {
try {
const t = await c(this.#s), i = JSON.parse(t), s = new r();
for (const [n, a] of Object.entries(i))
this.#n(a) && s.set(n, a);
this.#t = s;
} catch {
this.#t.clear();
}
}
#n(t) {
return ["string", "number", "boolean"].includes(typeof t);
}
}
export {
d as FileCache
};