/** * Redis Cache Adapter * Decoupled Redis implementation */ import type { CacheAdapter, CacheConfig } from './interfaces'; export class RedisCacheAdapter implements CacheAdapter { private client: any = null; private prefix: string; private defaultTTL: number; private redisUrl: string; constructor(config: CacheConfig & { redisUrl?: string } = {}) { this.prefix = config.prefix || 'mintel:'; this.defaultTTL = config.defaultTTL || 3600; this.redisUrl = config.redisUrl || process.env.REDIS_URL || 'redis://localhost:6379'; } private async init(): Promise { if (this.client !== null) return true; try { const Redis = await import('ioredis'); this.client = new Redis.default(this.redisUrl); this.client.on('error', (err: Error) => { console.warn('Redis connection error:', err.message); this.client = null; }); this.client.on('connect', () => { console.log('✅ Redis connected'); }); // Test connection await this.client.set(this.prefix + '__test__', 'ok', 'EX', 1); return true; } catch (error) { console.warn('Redis unavailable:', error); this.client = null; return false; } } async get(key: string): Promise { const available = await this.init(); if (!available || !this.client) return null; try { const data = await this.client.get(this.prefix + key); return data ? JSON.parse(data) : null; } catch (error) { console.warn('Redis get error:', error); return null; } } async set(key: string, value: T, ttl?: number): Promise { const available = await this.init(); if (!available || !this.client) return; try { const finalTTL = ttl || this.defaultTTL; await this.client.setex(this.prefix + key, finalTTL, JSON.stringify(value)); } catch (error) { console.warn('Redis set error:', error); } } async del(key: string): Promise { const available = await this.init(); if (!available || !this.client) return; try { await this.client.del(this.prefix + key); } catch (error) { console.warn('Redis del error:', error); } } async clear(): Promise { const available = await this.init(); if (!available || !this.client) return; try { const keys = await this.client.keys(this.prefix + '*'); if (keys.length > 0) { await this.client.del(...keys); } } catch (error) { console.warn('Redis clear error:', error); } } }