mastercache
Version:
Multi-tier cache module for Node.js. Redis, Upstash, CloudfareKV, File, in-memory and others drivers
118 lines (101 loc) • 3.23 kB
text/typescript
import { CacheEntry } from '../cache-entry/cache-entry';
import type { Logger, L1CacheDriver } from '../../types/main';
import type { CacheEntryOptions } from '../cache-entry/cache-entry-options';
/**
* LocalCache is a wrapper around a CacheDriver that provides a
* some handy methods for interacting with a local cache ( in-memory )
*/
export class LocalCache {
#driver: L1CacheDriver;
#logger: Logger;
constructor(driver: L1CacheDriver, logger: Logger) {
this.#driver = driver;
this.#logger = logger.child({ context: 'mastercache.localCache' });
}
/**
* Get an item from the local cache
*/
get(key: string, options: CacheEntryOptions) {
/**
* Try to get the item from the local cache
*/
this.#logger.trace({ key, opId: options.id }, 'try getting local cache item');
const value = this.#driver.get(key);
/**
* If the item is not found, return undefined
*/
if (value === undefined) {
this.#logger.trace({ key, opId: options.id }, 'local cache item not found');
return;
}
return CacheEntry.fromDriver(key, value);
}
/**
* Set a new item in the local cache
*/
set(key: string, value: string, options: CacheEntryOptions) {
/**
* If grace period is disabled and Physical TTL is 0 or less, we can just delete the item.
*/
if (!options.isGracePeriodEnabled && options.physicalTtl && options.physicalTtl <= 0) {
return this.delete(key, options);
}
/**
* Save the item to the local cache
*/
this.#logger.trace({ key, value, opId: options.id }, 'saving local cache item');
this.#driver.set(key, value, options.physicalTtl);
}
/**
* Delete an item from the local cache
*/
delete(key: string, options?: CacheEntryOptions) {
this.#logger.trace({ key, opId: options?.id }, 'deleting local cache item');
return this.#driver.delete(key);
}
/**
* Make an item logically expire in the local cache
*
* That means that the item will be expired but kept in the cache
* in order to be able to return it to the user if the remote cache
* is down and the grace period is enabled
*/
logicallyExpire(key: string) {
this.#logger.trace({ key }, 'logically expiring local cache item');
const value = this.#driver.get(key);
if (value === undefined) return;
const newEntry = CacheEntry.fromDriver(key, value).expire().serialize();
return this.#driver.set(key, newEntry, this.#driver.getRemainingTtl(key));
}
/**
* Delete many item from the local cache
*/
deleteMany(keys: string[], options: CacheEntryOptions) {
this.#logger.trace({ keys, options, opId: options.id }, 'deleting local cache items');
this.#driver.deleteMany(keys);
}
/**
* Create a new namespace for the local cache
*/
namespace(namespace: string) {
return this.#driver.namespace(namespace) as L1CacheDriver;
}
/**
* Check if an item exists in the local cache
*/
has(key: string) {
return this.#driver.has(key);
}
/**
* Clear the local cache
*/
clear() {
return this.#driver.clear();
}
/**
* Disconnect from the local cache
*/
disconnect() {
return this.#driver.disconnect();
}
}