UNPKG

@dephub/cache

Version:

Simple file-based cache with persistent storage for Node.js applications

144 lines (143 loc) 4.2 kB
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 };