UNPKG

@aurios/jason

Version:

A simple, lightweight, and embeddable JSON document database built on Bun.

115 lines (114 loc) 3.43 kB
export default class Cache { #data = new Map(); #queue = []; #timeout = 60000; #maxSize; #cleanupTimer; constructor(cacheTimout = 60_000, maxSize = 1000) { this.#timeout = cacheTimout; this.#maxSize = maxSize; this.#cleanupTimer = setInterval(() => this.#cleanup(), Math.min(30_000, this.#timeout)); } /** * Gets the current cache timeout duration. * Defaults to 60 seconds (1 minute). * @returns The duration in milliseconds after which cached items are automatically removed. */ get timeout() { return this.#timeout; } /** * Sets the cache timeout duration. * * @param timeout - The duration in milliseconds after which the cached item should be removed. */ set timeout(timeout) { this.#timeout = timeout; } /** * Updates the cache with the given id and value. * * If the cache has reached its maximum size, it will remove 10% of the items * in the cache before adding the new item. * * @param id - The id of the item to be updated. * @param value - The value of the item to be updated. */ update(id, value) { if (this.#data.has(id)) { const entry = this.#data.get(id); if (!entry) return; entry.value = value; entry.timestamp = this.#getNow(); this.#refresh(id); } else { if (this.#data.size >= this.#maxSize) { this.#evict(Math.floor(this.#maxSize * 0.1)); } this.#data.set(id, { value, timestamp: this.#getNow() }); this.#queue.push(id); } } /** * Retrieves an item from the cache by its id. * * If the item is not found or has exceeded the cache timeout, it returns null. * Otherwise, it returns the cached value. * * @param id - The id of the item to retrieve from the cache. * @returns The cached value, or null if not found or expired. */ get(id) { const entry = this.#data.get(id); if (!entry) return null; const now = this.#getNow(); if (now - entry.timestamp > this.#timeout) { this.#data.delete(id); return null; } this.#refresh(id); return entry.value; } /** * Removes the item with the specified id from the cache. * * @param id - The id of the item to be removed from the cache. */ delete(id) { this.#data.delete(id); } /** * Destroys the cache by stopping the automatic cleanup interval. * * Use this method when you are finished with the cache. */ destroy() { clearInterval(this.#cleanupTimer); } #refresh(id) { const idx = this.#queue.indexOf(id); if (idx > -1) { this.#queue.splice(idx, 1); } this.#queue.push(id); } #evict(count) { const victims = this.#queue.splice(0, count); for (const id of victims) { this.#data.delete(id); } } #cleanup() { const now = this.#getNow(); const threshold = now - this.#timeout; for (const [id, entry] of this.#data) { if (entry.timestamp < threshold) { this.#data.delete(id); } } } #getNow = Date.now.bind(Date); }