UNPKG

bentocache

Version:

Multi-tier cache module for Node.js. Redis, Upstash, CloudfareKV, File, in-memory and others drivers

150 lines (148 loc) 3.71 kB
import { resolveTtl } from "./chunk-YAGCWAYQ.js"; import { BaseDriver } from "./chunk-BO75WXSS.js"; // src/drivers/database/database.ts var DatabaseDriver = class extends BaseDriver { type = "l2"; /** * The underlying adapter */ #adapter; /** * A promise that resolves when the table is created */ #initialized; /** * Pruning interval */ #pruneInterval; constructor(adapter, config, isNamespace = false) { super(config); this.#adapter = adapter; if (isNamespace) { this.#initialized = Promise.resolve(); return; } this.#adapter.setTableName(config.tableName || "bentocache"); if (config.autoCreateTable !== false) { this.#initialized = this.#adapter.createTableIfNotExists(); } else { this.#initialized = Promise.resolve(); } if (config.pruneInterval === false) return; this.#startPruneInterval(resolveTtl(config.pruneInterval)); } /** * Start the interval that will prune expired entries * Maybe rework this using a node Worker ? */ #startPruneInterval(interval) { this.#pruneInterval = setInterval(async () => { await this.#initialized; await this.#adapter.pruneExpiredEntries().catch((err) => console.error("[bentocache] failed to prune expired entries", err)); }, interval); } /** * Check if the given timestamp is expired */ #isExpired(expiration) { return expiration !== null && expiration < Date.now(); } /** * Returns a new instance of the driver namespaced */ namespace(namespace) { const store = new this.constructor( this.#adapter, { ...this.config, prefix: this.createNamespacePrefix(namespace) }, true ); return store; } /** * Get a value from the cache */ async get(key) { await this.#initialized; const result = await this.#adapter.get(this.getItemKey(key)); if (!result) return; if (this.#isExpired(result.expiresAt)) { await this.#adapter.delete(key); return; } return result.value; } /** * Get the value of a key and delete it * * Returns the value if the key exists, undefined otherwise */ async pull(key) { const value = await this.get(key); if (value) await this.delete(key); return value; } /** * Set a value in the cache * Returns true if the value was set, false otherwise */ async set(key, value, ttl) { await this.#initialized; await this.#adapter.set({ key: this.getItemKey(key), value, expiresAt: ttl ? new Date(Date.now() + ttl) : null }); return true; } /** * Check if a key exists in the cache */ async has(key) { await this.#initialized; const result = await this.get(key); if (!result) return false; return true; } /** * Remove all items from the cache */ async clear() { await this.#initialized; await this.#adapter.clear(this.prefix); } /** * Delete a key from the cache * Returns true if the key was deleted, false otherwise */ async delete(key) { await this.#initialized; return this.#adapter.delete(this.getItemKey(key)); } /** * Delete multiple keys from the cache */ async deleteMany(keys) { if (keys.length === 0) return true; await this.#initialized; keys = keys.map((key) => this.getItemKey(key)); const result = await this.#adapter.deleteMany(keys); return result > 0; } /** * Disconnect from the database */ async disconnect() { if (this.#pruneInterval) { clearInterval(this.#pruneInterval); } await this.#adapter.disconnect(); } }; export { DatabaseDriver }; //# sourceMappingURL=chunk-NUZ5HZGD.js.map