Client & Core
The Client class is the primary entry point for Cachemate. It manages connection pooling, table versioning, caching strategies, and key derivation.
import { Client, type ClientOptions } from 'cachemate';
Constructor
new Client(options: ClientOptions)
Creates a new Cachemate client instance.
ClientOptions
| Property | Type | Default | Description |
|---|---|---|---|
memoryMaxMb | number | Required in TS | Maximum size (in MB) for in-memory LRU failover store. (Default in JS if invalid: 64). |
redisUrls | RedisUrlSpec[] | [] | List of Redis URLs or descriptor objects (string | number | { url, maxMemoryMb }). |
registry | TableRegistry | undefined | Table registry mapping table names to tags and version keys. |
appName | string | undefined | App name prefix for diagnostic logging (e.g. [api][cachemate]). |
log | (msg: string) => void | undefined | Custom logging callback. Non-throwing. |
defaultTtl | number | 60 | Default TTL in seconds for join queries (client.cache). |
flatTtl | number | 20 | Default TTL in seconds for flat queries (client.flat). |
keyPrefix | string | 'cm' | Global key prefix prepended to all generated cache keys. |
Instance Methods
.ready(): Promise<void>
Waits for all configured Redis nodes in the pool to initialize their initial connection handshake.
const client = new Client({ memoryMaxMb: 64, redisUrls: ['redis://127.0.0.1:6379'] });
await client.ready();
.cache<T>(params): Promise<T>
Caches a multi-table join query with automatic table versioning.
const userWithOrders = await client.cache<UserOrdersResult>({
tables: ['users', 'orders'],
filters: { userId: '123' },
ttlSeconds: 300, // optional, defaults to defaultTtl (60s)
loader: async () => {
return await db.fetchUserOrders('123');
},
});
- Parameters:
tables: string[]: Array of table names participating in the query.filters: unknown: Filter object or parameters used to compute the deterministic query hash.ttlSeconds?: number: TTL in seconds for the cached JSON payload.loader: () => Promise<T>: Async callback to fetch fresh data on cache miss.
.flat<T>(params): Promise<T>
Caches an entity or query in an isolated namespace without table version tracking.
const settings = await client.flat<AppSettings>({
ns: 'global-settings',
filters: { env: 'production' },
ttlSeconds: 3600,
loader: async () => await db.fetchSettings('production'),
});
- Parameters:
ns: string: Namespace string.filters: unknown: Filter object.ttlSeconds?: number: TTL in seconds (defaults toflatTtl, 20s).loader: () => Promise<T>: Async callback on cache miss.
.rows<T, M = unknown>(params): Promise<{ rows: T[]; meta?: M }>
Performs two-tier collection caching, separating query index lists from entity row payloads.
const { rows, meta } = await client.rows<Product, PageInfo>({
namespace: 'catalog',
tables: ['products'],
filters: { category: 'audio', sort: 'price_asc' },
ttlSeconds: 300,
rowId: (p) => p.id,
getByAll: async () => {
const res = await db.fetchProducts({ category: 'audio' });
return { rows: res.items, meta: res.pageInfo };
},
getAllById: async (ids) => {
return await db.fetchProductsByIds(ids);
},
});
.invalidate(table: string): Promise<void>
Increments the version counter for the specified table in the registry, instantly invalidating all cached queries that depend on it.
await client.invalidate('users');
.bumpAll(): Promise<void>
Increments all version keys registered in the TableRegistry simultaneously. Useful during major migrations or deployments.
await client.bumpAll();
.get(key: string): Promise<string | null>
Reads a raw string key from the active pool node or in-memory store.
const val = await client.get('my-key');
.set(key: string, val: string, ttlSeconds?: number): Promise<void>
Writes a raw string key to the active node with an optional TTL in seconds.
await client.set('my-key', 'hello', 60);
.del(key: string): Promise<void>
Deletes a raw key from the active cache store.
await client.del('my-key');
.mget(keys: string[]): Promise<(string | null)[]>
Fetches multiple string keys in a single round trip.
const [v1, v2] = await client.mget(['cm:ver:users', 'cm:ver:orders']);
.incr(key: string): Promise<number>
Increments an integer key in Redis (or in-memory store) atomically and returns the new value.
const nextVer = await client.incr('cm:ver:users');
.close(): Promise<void>
Decrements the shared Core reference count and closes all underlying Redis socket connections when the ref count reaches zero.
await client.close();
Core Deduplication & Multi-Instance Sharing
Cachemate automatically pools and deduplicates identical client configurations using Core.
If multiple new Client(options) instances are created with identical options, they share the underlying Core instance and NodePool, minimizing Redis connection counts.