89 lines
No EOL
2.3 KiB
TypeScript
89 lines
No EOL
2.3 KiB
TypeScript
import type { CacheProvider } from './types';
|
|
|
|
/**
|
|
* A cache wrapper that automatically prefixes all keys with a namespace
|
|
* Used to provide isolated cache spaces for different services
|
|
*/
|
|
export class NamespacedCache implements CacheProvider {
|
|
private readonly prefix: string;
|
|
|
|
constructor(
|
|
private readonly cache: CacheProvider,
|
|
private readonly namespace: string
|
|
) {
|
|
this.prefix = `cache:${namespace}:`;
|
|
}
|
|
|
|
async get<T = any>(key: string): Promise<T | null> {
|
|
return this.cache.get(`${this.prefix}${key}`);
|
|
}
|
|
|
|
async set<T>(
|
|
key: string,
|
|
value: T,
|
|
options?:
|
|
| number
|
|
| {
|
|
ttl?: number;
|
|
preserveTTL?: boolean;
|
|
onlyIfExists?: boolean;
|
|
onlyIfNotExists?: boolean;
|
|
getOldValue?: boolean;
|
|
}
|
|
): Promise<T | null> {
|
|
return this.cache.set(`${this.prefix}${key}`, value, options);
|
|
}
|
|
|
|
async del(key: string): Promise<void> {
|
|
return this.cache.del(`${this.prefix}${key}`);
|
|
}
|
|
|
|
async exists(key: string): Promise<boolean> {
|
|
return this.cache.exists(`${this.prefix}${key}`);
|
|
}
|
|
|
|
async keys(pattern: string = '*'): Promise<string[]> {
|
|
const fullPattern = `${this.prefix}${pattern}`;
|
|
const keys = await this.cache.keys(fullPattern);
|
|
// Remove the prefix from returned keys for cleaner API
|
|
return keys.map(k => k.substring(this.prefix.length));
|
|
}
|
|
|
|
async clear(): Promise<void> {
|
|
// Clear only keys with this namespace prefix
|
|
const keys = await this.cache.keys(`${this.prefix}*`);
|
|
if (keys.length > 0) {
|
|
await Promise.all(keys.map(key => this.cache.del(key)));
|
|
}
|
|
}
|
|
|
|
|
|
getStats() {
|
|
return this.cache.getStats();
|
|
}
|
|
|
|
async health(): Promise<boolean> {
|
|
return this.cache.health();
|
|
}
|
|
|
|
isReady(): boolean {
|
|
return this.cache.isReady();
|
|
}
|
|
|
|
async waitForReady(timeout?: number): Promise<void> {
|
|
return this.cache.waitForReady(timeout);
|
|
}
|
|
|
|
async close(): Promise<void> {
|
|
// Namespaced cache doesn't own the connection, so we don't close it
|
|
// The underlying cache instance should be closed by its owner
|
|
}
|
|
|
|
getNamespace(): string {
|
|
return this.namespace;
|
|
}
|
|
|
|
getFullPrefix(): string {
|
|
return this.prefix;
|
|
}
|
|
} |