removed old tests, created new ones and format

This commit is contained in:
Boki 2025-06-25 07:46:59 -04:00
parent 7579afa3c3
commit b03231b849
57 changed files with 4092 additions and 5901 deletions

View file

@ -1,37 +1,27 @@
import type { CacheProvider } from './types';
import type { CacheProvider, ICache } 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 {
export class NamespacedCache implements ICache {
private readonly prefix: string;
public readonly type: string;
constructor(
private readonly cache: CacheProvider,
private readonly cache: ICache,
private readonly namespace: string
) {
this.prefix = `cache:${namespace}:`;
this.prefix = `${namespace}:`;
this.type = cache.type;
}
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 set<T>(key: string, value: T, ttl?: number): Promise<void> {
return this.cache.set(`${this.prefix}${key}`, value, ttl);
}
async del(key: string): Promise<void> {
@ -42,11 +32,15 @@ export class NamespacedCache implements CacheProvider {
return this.cache.exists(`${this.prefix}${key}`);
}
async ttl(key: string): Promise<number> {
return this.cache.ttl(`${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));
return keys.filter(k => k.startsWith(this.prefix)).map(k => k.substring(this.prefix.length));
}
async clear(): Promise<void> {
@ -57,25 +51,44 @@ export class NamespacedCache implements CacheProvider {
}
}
getStats() {
return this.cache.getStats();
async mget<T>(keys: string[]): Promise<(T | null)[]> {
const prefixedKeys = keys.map(k => `${this.prefix}${k}`);
return this.cache.mget(prefixedKeys);
}
async health(): Promise<boolean> {
return this.cache.health();
async mset<T>(items: Record<string, T>, ttl?: number): Promise<void> {
const prefixedItems: Record<string, T> = {};
for (const [key, value] of Object.entries(items)) {
prefixedItems[`${this.prefix}${key}`] = value;
}
return this.cache.mset(prefixedItems, ttl);
}
isReady(): boolean {
return this.cache.isReady();
async mdel(keys: string[]): Promise<void> {
const prefixedKeys = keys.map(k => `${this.prefix}${k}`);
return this.cache.mdel(prefixedKeys);
}
async waitForReady(timeout?: number): Promise<void> {
return this.cache.waitForReady(timeout);
async size(): Promise<number> {
const keys = await this.keys('*');
return keys.length;
}
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
async flush(): Promise<void> {
return this.clear();
}
async ping(): Promise<boolean> {
return this.cache.ping();
}
async disconnect(): Promise<void> {
// Namespaced cache doesn't own the connection, so we don't disconnect
// The underlying cache instance should be disconnected by its owner
}
isConnected(): boolean {
return this.cache.isConnected();
}
getNamespace(): string {
@ -85,16 +98,4 @@ export class NamespacedCache implements CacheProvider {
getFullPrefix(): string {
return this.prefix;
}
/**
* Get a value using a raw Redis key (bypassing the namespace prefix)
* Delegates to the underlying cache's getRaw method if available
*/
async getRaw<T = unknown>(key: string): Promise<T | null> {
if (this.cache.getRaw) {
return this.cache.getRaw<T>(key);
}
// Fallback for caches that don't implement getRaw
return null;
}
}