tessl install tessl/npm-cache-manager@7.2.0Cache Manager for Node.js with support for multi-store caching, background refresh, and Keyv-compatible storage adapters
Complete TypeScript type definitions for cache-manager.
Main cache interface returned by createCache().
type Cache = {
// Read operations
get<T>(key: string): Promise<T | undefined>;
mget<T>(keys: string[]): Promise<Array<T | undefined>>;
ttl(key: string): Promise<number | undefined>;
// Write operations
set<T>(key: string, value: T, ttl?: number): Promise<T>;
mset<T>(list: Array<{ key: string; value: T; ttl?: number }>): Promise<Array<{ key: string; value: T; ttl?: number }>>;
// Delete operations
del(key: string): Promise<boolean>;
mdel(keys: string[]): Promise<boolean>;
clear(): Promise<boolean>;
// Function wrapping
wrap<T>(key: string, fnc: () => T | Promise<T>, ttl?: number, refreshThreshold?: number): Promise<T>;
wrap<T>(key: string, fnc: () => T | Promise<T>, options: WrapOptions<T>): Promise<T>;
wrap<T>(key: string, fnc: () => T | Promise<T>, options: WrapOptionsRaw<T>): Promise<StoredDataRaw<T>>;
// Event system
on<E extends keyof Events>(event: E, listener: Events[E]): EventEmitter;
off<E extends keyof Events>(event: E, listener: Events[E]): EventEmitter;
// Metadata
cacheId(): string;
stores: Keyv[];
disconnect(): Promise<undefined>;
};Configuration options for createCache().
type CreateCacheOptions = {
stores?: Keyv[];
ttl?: number;
refreshThreshold?: number;
refreshAllStores?: boolean;
nonBlocking?: boolean;
cacheId?: string;
};Event type signatures for cache operations.
type Events = {
get<T>(data: { key: string; value?: T; store?: string; error?: unknown }): void;
mget<T>(data: { keys: string[]; values?: T[]; error?: unknown }): void;
set<T>(data: { key: string; value: T; store?: string; error?: unknown }): void;
mset<T>(data: { list: Array<{ key: string; value: T; ttl?: number }>; error?: unknown }): void;
del(data: { key: string; error?: unknown }): void;
mdel(data: { keys: string[]; error?: unknown }): void;
clear(error?: unknown): void;
ttl(data: { key: string; value?: any; error?: unknown }): void;
refresh<T>(data: { key: string; value: T; error?: unknown }): void;
};Options for wrap() method.
type WrapOptions<T> = {
ttl?: number | ((value: T) => number);
refreshThreshold?: number | ((value: T) => number);
};
type WrapOptionsRaw<T> = WrapOptions<T> & {
raw: true;
};Raw cached data with expiration timestamp.
type StoredDataRaw<T> = {
value: T;
expires: number; // Unix timestamp in milliseconds
};Union type for stored data.
type StoredData<T> = T | StoredDataRaw<T> | undefined;Main Keyv class for storage abstraction.
declare class Keyv {
constructor(options?: KeyvOptions);
// Core methods
get<T>(key: string, options?: { raw?: boolean }): Promise<T | undefined>;
set(key: string, value: any, ttl?: number): Promise<boolean>;
delete(key: string): Promise<boolean>;
clear(): Promise<void>;
// Batch methods
getMany<T>(keys: string[]): Promise<Array<T | undefined>>;
setMany(data: Array<{ key: string; value: any; ttl?: number }>): Promise<boolean>;
// Connection
disconnect(): Promise<void>;
// Iteration (if supported by store)
iterator?(): AsyncIterableIterator<[string, any]>;
}Configuration options for Keyv instances.
interface KeyvOptions {
store?: any;
namespace?: string;
ttl?: number;
serialize?: (data: any) => string;
deserialize?: (data: string) => any;
compression?: any;
}Interface that storage adapters must implement.
interface KeyvStoreAdapter {
opts: any;
namespace?: string | undefined;
get<T>(key: string): Promise<StoredData<T> | undefined>;
set(key: string, value: any, ttl?: number): Promise<boolean>;
delete(key: string): Promise<boolean>;
clear?(): Promise<void>;
has?(key: string): Promise<boolean>;
getMany?<T>(keys: string[]): Promise<Array<StoredData<T | undefined>>>;
deleteMany?(keys: string[]): Promise<boolean>;
on?(event: string, listener: (...arguments_: any[]) => void): any;
disconnect?(): Promise<void>;
}Node.js EventEmitter class.
declare class EventEmitter {
addListener(event: string | symbol, listener: (...args: any[]) => void): this;
on(event: string | symbol, listener: (...args: any[]) => void): this;
once(event: string | symbol, listener: (...args: any[]) => void): this;
removeListener(event: string | symbol, listener: (...args: any[]) => void): this;
off(event: string | symbol, listener: (...args: any[]) => void): this;
removeAllListeners(event?: string | symbol): this;
setMaxListeners(n: number): this;
getMaxListeners(): number;
listeners(event: string | symbol): Function[];
rawListeners(event: string | symbol): Function[];
emit(event: string | symbol, ...args: any[]): boolean;
listenerCount(event: string | symbol): number;
prependListener(event: string | symbol, listener: (...args: any[]) => void): this;
prependOnceListener(event: string | symbol, listener: (...args: any[]) => void): this;
eventNames(): Array<string | symbol>;
}Interface for cache-manager v5 storage adapters.
type CacheManagerStore = {
name: string;
isCacheable?: (value: unknown) => boolean;
get(key: string): Promise<any>;
mget(...keys: string[]): Promise<unknown[]>;
set(key: string, value: any, ttl?: number): Promise<any>;
mset(data: Record<string, any>, ttl?: number): Promise<void>;
del(key: string): Promise<void>;
mdel(...keys: string[]): Promise<void>;
ttl(key: string, ttl?: number): Promise<number>;
keys(): Promise<string[]>;
reset?(): Promise<void>;
on?(event: string, listener: (...arguments_: any[]) => void): void;
disconnect?(): Promise<void>;
};Adapter class for legacy stores.
declare class KeyvAdapter implements KeyvStoreAdapter {
constructor(store: CacheManagerStore);
opts: any;
namespace?: string | undefined;
get<T>(key: string): Promise<StoredData<T> | undefined>;
set(key: string, value: any, ttl?: number): Promise<boolean>;
delete(key: string): Promise<boolean>;
clear(): Promise<void>;
has?(key: string): Promise<boolean>;
getMany?<T>(keys: string[]): Promise<Array<StoredData<T | undefined>>>;
deleteMany?(key: string[]): Promise<boolean>;
on(event: string, listener: (...arguments_: any[]) => void): this;
disconnect?(): Promise<void>;
}// Typed get
const user = await cache.get<User>('user:123');
// user: User | undefined
// Typed mget
const users = await cache.mget<User>(['user:1', 'user:2']);
// users: Array<User | undefined>
// Typed set
await cache.set<Product>('product:456', { id: 456, name: 'Widget' });
// Typed wrap
const config = await cache.wrap<Config>(
'config',
async () => ({ theme: 'dark' }),
60000
);
// config: Config// Type inferred from value
await cache.set('count', 42);
const count = await cache.get('count'); // Type: number | undefined
// Explicit type when needed
interface UserSession {
userId: number;
email: string;
}
const session = await cache.get<UserSession>('session:abc');
if (session) {
console.log(session.email); // TypeScript knows session.email exists
}// Cache with multiple value types
type CacheValue = string | number | { id: number; name: string };
await cache.set<CacheValue>('str', 'text');
await cache.set<CacheValue>('num', 42);
await cache.set<CacheValue>('obj', { id: 1, name: 'Alice' });
// Retrieve with type narrowing
const value = await cache.get<CacheValue>('str');
if (typeof value === 'string') {
console.log(value.toUpperCase());
} else if (typeof value === 'number') {
console.log(value * 2);
} else if (value && typeof value === 'object') {
console.log(value.name);
}function createCache(options?: CreateCacheOptions): Cache;import type { Cache, CreateCacheOptions } from 'cache-manager';
function createCustomCache(config: CreateCacheOptions): Cache {
return createCache({
...config,
cacheId: 'custom-cache',
});
}type MSetItem<T> = {
key: string;
value: T;
ttl?: number;
};
// Usage
const items: MSetItem<User>[] = [
{ key: 'user:1', value: { id: 1, name: 'Alice' }, ttl: 60000 },
{ key: 'user:2', value: { id: 2, name: 'Bob' } },
];
await cache.mset(items);type GetEventListener<T> = (data: {
key: string;
value?: T;
store?: string;
error?: unknown;
}) => void;
const listener: GetEventListener<User> = ({ key, value, error }) => {
if (error) {
console.error(`Get error for ${key}:`, error);
} else if (value) {
console.log(`Got user: ${value.name}`);
}
};
cache.on('get', listener);function isRawData<T>(data: T | StoredDataRaw<T>): data is StoredDataRaw<T> {
return typeof data === 'object' &&
data !== null &&
'value' in data &&
'expires' in data;
}
// Usage
const data = await cache.wrap('key', fetchData, { ttl: 60000, raw: true });
if (isRawData(data)) {
console.log('Value:', data.value);
console.log('Expires:', new Date(data.expires));
}function isCacheMiss<T>(value: T | undefined): value is undefined {
return value === undefined;
}
// Usage
const user = await cache.get<User>('user:123');
if (isCacheMiss(user)) {
// Fetch from source
const freshUser = await db.users.findById(123);
await cache.set('user:123', freshUser, 60000);
}// custom-cache.d.ts
import 'cache-manager';
declare module 'cache-manager' {
interface Cache {
// Add custom methods
getOrSet<T>(key: string, fetchFn: () => Promise<T>, ttl?: number): Promise<T>;
}
}
// Implementation
Cache.prototype.getOrSet = async function<T>(
key: string,
fetchFn: () => Promise<T>,
ttl?: number
): Promise<T> {
const cached = await this.get<T>(key);
if (cached !== undefined) return cached;
const fresh = await fetchFn();
await this.set(key, fresh, ttl);
return fresh;
};