import { createClient, type RedisClientType } from 'redis'; import type { CacheService, CacheSetOptions } from './cache-service'; export type RedisCacheServiceOptions = { url: string; keyPrefix?: string; }; // Thin wrapper around shared Redis (platform provides host `redis`). // Values are JSON-serialized. export class RedisCacheService implements CacheService { private readonly client: RedisClientType; private readonly keyPrefix: string; constructor(options: RedisCacheServiceOptions) { this.client = createClient({ url: options.url }); this.keyPrefix = options.keyPrefix ?? ''; // Fire-and-forget connect. this.client.connect().catch(() => undefined); } private k(key: string) { return `${this.keyPrefix}${key}`; } async get(key: string): Promise { const raw = await this.client.get(this.k(key)); if (raw == null) return undefined; return JSON.parse(raw) as T; } async set(key: string, value: T, options?: CacheSetOptions): Promise { const ttl = options?.ttlSeconds; const raw = JSON.stringify(value); if (ttl && ttl > 0) { await this.client.set(this.k(key), raw, { EX: ttl }); return; } await this.client.set(this.k(key), raw); } async del(key: string): Promise { await this.client.del(this.k(key)); } }