UNPKG

@akomalabs/kemono

Version:

A production-grade TypeScript API wrapper for the Kemono/Coomer platforms

133 lines 3.81 kB
import Redis from 'ioredis'; /** * In-memory cache implementation */ class MemoryCache { cache; constructor() { this.cache = new Map(); } async get(key) { const item = this.cache.get(key); if (!item) return null; if (Date.now() > item.expiry) { this.cache.delete(key); return null; } return item.value; } async set(key, value, ttl = 300) { this.cache.set(key, { value, expiry: Date.now() + ttl * 1000, }); } async del(key) { this.cache.delete(key); } } /** * Redis cache implementation */ class RedisCache { client; logger; isConnected = false; constructor(config, logger) { if (!config || !config.host || !config.port) { throw new Error('Invalid Redis configuration: host and port are required'); } this.client = new Redis({ host: config.host, port: config.port, password: config.password, retryStrategy: (times) => { const delay = Math.min(times * 50, 2000); return delay; }, }); this.logger = logger; this.client.on('connect', () => { this.isConnected = true; this.logger.info('Redis cache connected'); }); this.client.on('error', (err) => { this.isConnected = false; this.logger.error('Redis cache error:', err); }); this.client.on('close', () => { this.isConnected = false; this.logger.warn('Redis cache connection closed'); }); } async get(key) { if (!this.isConnected) { this.logger.warn('Redis cache not connected, falling back to null'); return null; } try { return await this.client.get(key); } catch (error) { this.logger.error('Redis get error:', error); return null; } } async set(key, value, ttl = 300) { if (!this.isConnected) { this.logger.warn('Redis cache not connected, skipping set operation'); return; } try { await this.client.set(key, value, 'EX', ttl); } catch (error) { this.logger.error('Redis set error:', error); } } async del(key) { if (!this.isConnected) { this.logger.warn('Redis cache not connected, skipping delete operation'); return; } try { await this.client.del(key); } catch (error) { this.logger.error('Redis del error:', error); } } } /** * Creates a cache instance based on the configuration * @param config Cache configuration from KemonoConfig * @param logger Logger instance * @returns Cache instance */ export function createCache(config, logger) { // Return no-op cache if caching is disabled or config is undefined if (!config?.enabled) { logger.info('Cache disabled, using no-op cache'); return { get: async () => null, set: async () => { }, del: async () => { }, }; } // Try to create Redis cache if Redis config is provided if (config.redis) { try { logger.info('Initializing Redis cache'); return new RedisCache(config.redis, logger); } catch (error) { logger.error('Failed to initialize Redis cache, falling back to memory cache:', error); return new MemoryCache(); } } // Default to memory cache logger.info('Initializing memory cache'); return new MemoryCache(); } //# sourceMappingURL=cache.js.map