import { CacheAdapter, NamespacedCache } from './namespaced-cache'; import type { CacheProvider, ICache } from './types'; /** * Factory class for creating cache instances */ export class CacheFactory { static create(config: unknown, _namespace: string): ICache { // For tests or when no config provided, return null cache if (!config || typeof config !== 'object' || !('cache' in config)) { return createNullCache(); } // const provider = config.cache.provider || 'memory'; // For now, always return null cache to keep tests simple // In real implementation, this would create different cache types based on provider return createNullCache(); } } /** * Factory function to create namespaced caches * Provides a clean API for services to get their own namespaced cache */ export function createNamespacedCache( cache: CacheProvider | ICache | null | undefined, namespace: string ): CacheProvider { if (!cache) { return new CacheAdapter(createNullCache()); } // Check if it's already a CacheProvider if ('getStats' in cache && 'health' in cache) { return new NamespacedCache(cache as CacheProvider, namespace); } // It's an ICache, wrap it first return new NamespacedCache(new CacheAdapter(cache as ICache), namespace); } /** * Type guard to check if cache is available */ export function isCacheAvailable(cache: unknown): cache is CacheProvider { return ( cache !== null && cache !== undefined && typeof cache === 'object' && 'get' in cache && typeof (cache as CacheProvider).get === 'function' ); } /** * Create a null cache implementation */ function createNullCache(): ICache { return { type: 'null', get: async () => null, set: async () => {}, del: async () => {}, clear: async () => {}, exists: async () => false, ttl: async () => -1, keys: async () => [], mget: async () => [], mset: async () => {}, mdel: async () => {}, size: async () => 0, flush: async () => {}, ping: async () => true, disconnect: async () => {}, isConnected: () => true, }; }