UNPKG

bentocache

Version:

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

149 lines (147 loc) 3.75 kB
import { resolveTtl } from "./chunk-YAGCWAYQ.js"; import { BaseDriver } from "./chunk-BO75WXSS.js"; // src/drivers/database/database.ts import { asyncNoop, once } from "@julr/utils/functions"; var DatabaseDriver = class extends BaseDriver { type = "l2"; /** * The underlying adapter */ #adapter; /** * Initialize by creating the table */ #initializer; /** * Pruning interval */ #pruneInterval; constructor(adapter, config, isNamespace = false) { super(config); this.#adapter = adapter; if (isNamespace) { this.#initializer = asyncNoop; return; } this.#adapter.setTableName(config.tableName || "bentocache"); if (config.autoCreateTable !== false) { this.#initializer = once(async () => await this.#adapter.createTableIfNotExists()); } else { this.#initializer = asyncNoop; } 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.#initializer(); 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.#initializer(); const result = await this.#adapter.get(this.getItemKey(key)); if (!result) return; if (this.#isExpired(result.expiresAt)) { await this.#adapter.delete(this.getItemKey(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.#initializer(); await this.#adapter.set({ key: this.getItemKey(key), value, expiresAt: ttl ? new Date(Date.now() + ttl) : null }); return true; } /** * Remove all items from the cache */ async clear() { await this.#initializer(); 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.#initializer(); return this.#adapter.delete(this.getItemKey(key)); } /** * Delete multiple keys from the cache */ async deleteMany(keys) { if (keys.length === 0) return true; await this.#initializer(); 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(); } /** * Manually prune expired cache entries. */ async prune() { await this.#initializer(); await this.#adapter.pruneExpiredEntries(); } }; export { DatabaseDriver }; //# sourceMappingURL=chunk-CVIVKJ25.js.map