CacheManager
CacheManager is the central coordinator for all caching operations. It owns a map of named ICacheProvider instances and exposes a unified API for reading, writing, and invalidating cached values. A single global instance is available via getGlobalCacheManager().
Key Concepts
- Providers map. Multiple backends (memory, Redis, CDN) can be registered under their strategy name. A request for strategy
'auto'or an unknown name falls back to the'memory'provider. - Tag index. When an entry is stored with tags, the manager records the
tag → keymapping internally so thatinvalidate({ tags })can remove all associated keys without querying every provider. - Event invalidation.
setupEventInvalidation()registers a handler so thathandleEvent(name, payload)can evict keys, patterns, or tags in response to domain events. - Auto TTL. When
ttl: 'auto'is passed togetOrSet, the TTL is derived from the factory's compute duration:max(60, min(computeMs * 10, 3600))seconds. This means expensive operations receive longer cache lifetimes automatically.
API Reference
Constructor
new CacheManager(options?: CacheManagerOptions)
CacheManagerOptions:
| Field | Type | Default | Description |
|---|---|---|---|
defaultProvider |
CacheStrategy |
'memory' |
Backend used when no strategy is specified |
providers |
Map<string, ICacheProvider> |
— | Pre-registered provider instances |
aiEnabled |
boolean |
false |
Reserved for future AI-driven strategy selection |
defaultTTL |
number |
300 |
Fallback TTL in seconds |
Primary Methods
getOrSet<T>(key, factory, options?): Promise<T>
The main caching primitive. Checks the cache first; on a miss, calls factory(), stores the result, then returns it.
options: AICacheOptions & { strategy?: CacheStrategy }
| Option | Type | Description |
|---|---|---|
strategy |
CacheStrategy |
Override the default provider |
ttl |
'auto' | number |
TTL in seconds, or 'auto' |
tags |
string[] |
Tags for grouped invalidation |
get<T>(key, strategy?): Promise<T | null>
Returns the cached value or null.
set<T>(key, value, options?): Promise<void>
Stores a value. Options include ttl, tags, priority, compress, and strategy.
delete(key): Promise<boolean>
Removes the key from all registered providers. Returns true if at least one provider deleted it.
invalidate(options: InvalidateOptions): Promise<void>
Evicts by key, glob pattern, or tags.
interface InvalidateOptions {
key?: string; // exact key
pattern?: string; // wildcard pattern: 'user:*'
tags?: string[]; // tag names
}
clear(pattern?): Promise<void>
Clears all providers (optionally filtered by pattern). Also resets the internal tag index when no pattern is given.
getStats(): Promise<CacheStats & { byProvider: Map<string, CacheStats> }>
Returns aggregated statistics plus a per-provider breakdown.
CacheStats:
| Field | Type | Description |
|---|---|---|
hits |
number |
Total cache hits |
misses |
number |
Total cache misses |
hitRate |
number |
hits / (hits + misses) (0–1) |
size |
number |
Approximate byte size |
keys |
number |
Number of live entries |
prewarm(predictions: CachePrediction[]): Promise<void>
Calls getOrSet for each prediction with confidence > 0.7.
setupEventInvalidation(config: EventInvalidationConfig): void
Registers a mapping from a domain event name to keys, tags, or a pattern to invalidate.
handleEvent(eventName, payload): Promise<void>
Triggers all invalidations registered for eventName.
registerProvider(name, provider): void
Adds or replaces a named provider at runtime.
Global Manager Helpers
getGlobalCacheManager(): CacheManager // lazy-creates a default manager
setGlobalCacheManager(manager): void // replace the global instance
resetGlobalCacheManager(): void // set to null (useful in tests)
Basic Usage
import {
CacheManager,
setGlobalCacheManager,
} from '@tagna/udiot';
// Configure once at startup
const cache = new CacheManager({ defaultTTL: 600 });
setGlobalCacheManager(cache);
// Use in a service
const user = await cache.getOrSet(
`user:${id}`,
() => db.users.findById(id),
{ ttl: 300, tags: ['user', `user:${id}`] }
);
Common Patterns
Wrapping a database query
import { getGlobalCacheManager } from '@tagna/udiot';
async function getProduct(id: string) {
const cache = getGlobalCacheManager();
return cache.getOrSet(
`product:${id}`,
() => db.products.findById(id),
{ ttl: 120, tags: ['products', `product:${id}`] }
);
}
Manual invalidation after an update
async function updateProduct(id: string, data: Partial<Product>) {
const updated = await db.products.update(id, data);
const cache = getGlobalCacheManager();
await cache.invalidate({ tags: [`product:${id}`, 'products'] });
return updated;
}
Printing stats
const stats = await cache.getStats();
console.log(`Hit rate: ${(stats.hitRate * 100).toFixed(1)}%`);
console.log(`Keys: ${stats.keys}, Size: ${stats.size} bytes`);
for (const [name, s] of stats.byProvider) {
console.log(` [${name}] hits=${s.hits} misses=${s.misses}`);
}
Integration Notes
getOrSetemits OpenTelemetry spans (cache.getOrSet) and incrementscache.hit/cache.missmetrics automatically.- The
'auto'strategy resolves to the default provider at runtime; it does not yet invokeAICacheAnalyzerfor routing decisions. deleteiterates all providers, so a key can be evicted from every tier in one call.
Pitfalls
- Do not call
resetGlobalCacheManager()in production code; it is intended only for test isolation. - Tag indexes live in memory within the manager instance. If you create multiple
CacheManagerinstances each pointing at the same Redis backend, tag-based invalidation from one instance will not be visible to the other. clear()without a pattern resets the tag index. After a full clear, previously tagged keys can no longer be invalidated by tag until they are re-written.