/home/techb158/balavpn.abdallabala.com/src/lib
NameSizeModeActions
api-client.js10120644editdlrm
crypto.js16760644editdlrm
email.js21750644editdlrm
http.js5630644editdlrm
idempotency.js5700644editdlrm
metrics.js10610644editdlrm
oidc.js17300644editdlrm
prisma.js2800644editdlrm
rate-limit.js26620644editdlrm
redis.js35170644editdlrm
request-context.js37250644editdlrm
tenant-guard.js14270644editdlrm
Edit: /home/techb158/balavpn.abdallabala.com/src/lib/redis.js (3517B)
const Redis = require('ioredis'); const REDIS_URL = process.env.REDIS_URL || 'redis://localhost:6379'; const ENABLED = process.env.COSMIC_REDIS_ENABLED !== 'false'; let redis = null; const fallbackStore = new Map(); const fallbackTimers = new Map(); function createClient() { if (!ENABLED) return null; try { const client = new Redis(REDIS_URL, { maxRetriesPerRequest: 1, retryStrategy(times) { if (times > 3) return null; return Math.min(times * 200, 2000); }, lazyConnect: true, enableOfflineQueue: false, }); client.on('error', () => {}); client.on('close', () => {}); return client; } catch { try { redis.disconnect(); } catch {} redis = false; return null; } } async function ensureConnected() { if (redis === null) redis = createClient(); if (!redis || redis.status === 'ready') return redis; try { await redis.connect(); return redis; } catch { try { redis.disconnect(); } catch {} redis = false; return null; } } function fallbackGet(key) { const entry = fallbackStore.get(key); if (!entry) return null; if (entry.expiry && Date.now() > entry.expiry) { fallbackStore.delete(key); return null; } return entry.value; } function fallbackSet(key, value, ttlMs) { fallbackStore.set(key, { value, expiry: ttlMs ? Date.now() + ttlMs : null }); if (fallbackTimers.has(key)) clearTimeout(fallbackTimers.get(key)); if (ttlMs) { const timer = setTimeout(() => { fallbackStore.delete(key); fallbackTimers.delete(key); }, ttlMs); timer.unref(); fallbackTimers.set(key, timer); } } function fallbackDel(key) { fallbackStore.delete(key); if (fallbackTimers.has(key)) { clearTimeout(fallbackTimers.get(key)); fallbackTimers.delete(key); } } async function redisGet(key) { const client = await ensureConnected(); if (client) { try { return await client.get(key); } catch { return null; } } return fallbackGet(key); } async function redisSet(key, value, ttlMs) { const client = await ensureConnected(); if (client) { try { if (ttlMs) await client.set(key, value, 'PX', ttlMs); else await client.set(key, value); return; } catch {} } fallbackSet(key, value, ttlMs); } async function redisDel(key) { const client = await ensureConnected(); if (client) { try { await client.del(key); return; } catch {} } fallbackDel(key); } async function redisIncr(key, ttlMs) { const client = await ensureConnected(); if (client) { try { const val = await client.incr(key); if (ttlMs && val === 1) await client.pexpire(key, ttlMs); return val; } catch {} } const val = (parseInt(fallbackGet(key), 10) || 0) + 1; fallbackSet(key, String(val), ttlMs); return val; } async function redisTtl(key) { const client = await ensureConnected(); if (client) { try { return await client.ttl(key); } catch { return -2; } } const entry = fallbackStore.get(key); if (!entry || !entry.expiry) return -1; const remaining = Math.max(0, Math.floor((entry.expiry - Date.now()) / 1000)); return remaining > 0 ? remaining : -2; } async function redisFlush() { const client = await ensureConnected(); if (client) { try { await client.flushdb(); return; } catch {} } fallbackStore.clear(); for (const timer of fallbackTimers.values()) clearTimeout(timer); fallbackTimers.clear(); } module.exports = { redisGet, redisSet, redisDel, redisIncr, redisTtl, redisFlush };