Cache
An in-memory cache with a size limit (the least recently used entries go first), expiry per entry, and stats. getOrSet() loads a missing value only once, even when many callers ask for it at the same moment.
const { Cache } = require("@ix-xs/node-comfort");
import Cache from "@ix-xs/node-comfort/cache";const users = new nc.Cache({ max: 1000, ttl: "5m" });
const user = await users.getOrSet(id, () => db.users.find(id));
users.stats; // { hits: 12, misses: 3, hitRate: 0.8, ... }Cache.Constructor and methods
new Cache()
new Cache<K, V>(options?: CacheOptions<K, V>): Cache<K, V>Parameters
| Name | Type |
|---|---|
optionsoptional | CacheOptions<K, V> |
Example
const cache = new nc.Cache({ max: 500, ttl: "1h", updateAgeOnGet: true });cache.get()method
get(key: K): V | undefinedReads a value and marks it as recently used.
Parameters
| Name | Type |
|---|---|
key | K |
Returns V | undefined: undefined if missing or expired.
cache.peek()method
peek(key: K): V | undefinedReads a value without counting it as a use or touching the stats.
Parameters
| Name | Type |
|---|---|
key | K |
Returns V | undefined
cache.set()method
set(key: K, value: V, options?: CacheSetOptions): Cache<K, V>Stores a value. When the cache is full, the least recently used entry goes.
Parameters
| Name | Type |
|---|---|
key | K |
value | V |
optionsoptional | CacheSetOptions |
Returns this
Example
cache.set("token", token, { ttl: "15m" });cache.getOrSet()method
getOrSet(key: K, loader: () => V | PromiseLike<V>, options?: CacheSetOptions): Promise<V>Returns the cached value, or calls loader, stores the result and returns it. Simultaneous calls for the same key share one loader call, and a failed load caches nothing.
Parameters
| Name | Type |
|---|---|
key | K |
loader | () => V | PromiseLike<V> |
optionsoptional | CacheSetOptions |
Returns Promise<V>
Example
const profile = await cache.getOrSet(`profile:${id}`, () => api.fetchProfile(id), { ttl: "10m" });cache.has()method
has(key: K): booleanIs there a fresh entry for this key? Doesn't count as a use.
Parameters
| Name | Type |
|---|---|
key | K |
Returns boolean
cache.delete()method
delete(key: K): booleanRemoves an entry.
Parameters
| Name | Type |
|---|---|
key | K |
Returns boolean: true if there was one.
cache.clear()method
clear(): voidRemoves every entry. Stats are kept.
cache.prune()method
prune(): numberRemoves expired entries now instead of waiting for them to be read.
Returns number: How many were removed.
cache.ttl()method
ttl(key: K): number | undefinedTime left before an entry expires.
Parameters
| Name | Type |
|---|---|
key | K |
Returns number | undefined: Milliseconds, Infinity if it never expires, undefined if missing.
cache.wrap()method
wrap<A extends any[]>(fn: (...args: A) => V | PromiseLike<V>, options?: { key?: ((...args: A) => K) | undefined; ttl?: string | number; } | undefined): (...args: A) => Promise<V>Wraps a function so its results are cached here.
Parameters
| Name | Type | Description |
|---|---|---|
fn | (...args: A) => V | PromiseLike<V> | |
optionsoptional | { key?: (...args: A) => K, ttl?: number | string } | key builds the cache key from the arguments; by default they're turned into JSON. |
Returns (...args: A) => Promise<V>
Example
const getWeather = cache.wrap((city) => api.weather(city), { key: (city) => city.toLowerCase(), ttl: "30m" });
await getWeather("Paris");cache.sizeproperty
size: numberNumber of entries, including expired ones not yet removed.
cache.statsproperty
stats: CacheStatsHit and miss counts.
cache.keys()method
keys(): K[]Fresh keys, least recently used first.
Returns K[]
cache.values()method
values(): V[]Fresh values, least recently used first.
Returns V[]
cache.entries()method
entries(): [K, V][]Fresh [key, value] pairs, least recently used first.
Returns Array<[K, V]>
Types
Import any of them in TypeScript with import type { CacheOptions } from "@ix-xs/node-comfort", or in JavaScript with import("@ix-xs/node-comfort").CacheOptions.
CacheOptions
Options for new Cache().
| Property | Type | Description |
|---|---|---|
maxoptional | number | Maximum number of entries. When full, the least recently used goes. No limit by default. |
ttloptional | string | number | How long entries live, in ms or like "10m". 0 means forever, the default. |
updateAgeOnGetoptional | boolean | Reading an entry restarts its time to live. |
onRemoveoptional | ((key: K, value: V, reason: CacheRemovalReason) => void) | Called whenever an entry leaves the cache. |
CacheRemovalReason
Why an entry left the cache.
type CacheRemovalReason = "evict" | "expire" | "delete" | "set" | "clear"CacheSetOptions
Options for set() and getOrSet().
| Property | Type | Description |
|---|---|---|
ttloptional | string | number | Time to live of this entry. 0 means forever. |
CacheStats
Cache stats.
| Property | Type | Description |
|---|---|---|
hits | number | Reads that found a fresh entry. |
misses | number | Reads that found nothing or an expired entry. |
sets | number | |
evictions | number | Entries dropped because the cache was full. |
expirations | number | Entries dropped because they expired. |
hitRate | number | From 0 to 1. |