UNPKG

rsshub

Version:
143 lines (139 loc) 4.58 kB
import { t as config } from "./config-C37vj7VH.mjs"; import { t as logger_default } from "./logger-Czu8UMNd.mjs"; import { LRUCache } from "lru-cache"; import Redis from "ioredis"; //#region lib/utils/cache/memory.ts const status$1 = { available: false }; const clients$1 = {}; var memory_default = { init: () => { clients$1.memoryCache = new LRUCache({ ttl: config.cache.routeExpire * 1e3, max: config.memory.max }); status$1.available = true; }, get: (key, refresh = true) => { if (key && status$1.available && clients$1.memoryCache) { let value = clients$1.memoryCache.get(key, { updateAgeOnGet: refresh }); if (value) value = value + ""; return value; } else return null; }, set: (key, value, maxAge = config.cache.contentExpire) => { if (!value || value === "undefined") value = ""; if (typeof value === "object") value = JSON.stringify(value); if (key && status$1.available && clients$1.memoryCache) return clients$1.memoryCache.set(key, value, { ttl: maxAge * 1e3 }); }, clients: clients$1, status: status$1 }; //#endregion //#region lib/utils/cache/redis.ts const status = { available: false }; const clients = {}; const getCacheTtlKey = (key) => { if (key.startsWith("rsshub:cacheTtl:")) throw new Error("\"rsshub:cacheTtl:\" prefix is reserved for the internal usage, please change your cache key"); return `rsshub:cacheTtl:${key}`; }; var redis_default = { init: () => { clients.redisClient = new Redis(config.redis.url); clients.redisClient.on("error", (error) => { status.available = false; logger_default.error("Redis error: ", error); }); clients.redisClient.on("end", () => { status.available = false; }); clients.redisClient.on("connect", () => { status.available = true; logger_default.info("Redis connected."); }); }, get: async (key, refresh = true) => { if (key && status.available && clients.redisClient) { const cacheTtlKey = getCacheTtlKey(key); let [value, cacheTtl] = await clients.redisClient.mget(key, cacheTtlKey); if (value && refresh) { if (cacheTtl) clients.redisClient.expire(cacheTtlKey, cacheTtl); else cacheTtl = config.cache.contentExpire + ""; clients.redisClient.expire(key, cacheTtl); value = value + ""; } return value || ""; } else return null; }, set: (key, value, maxAge = config.cache.contentExpire) => { if (!status.available || !clients.redisClient) return; if (!value || value === "undefined") value = ""; if (typeof value === "object") value = JSON.stringify(value); if (key) { if (maxAge !== config.cache.contentExpire) clients.redisClient.set(getCacheTtlKey(key), maxAge, "EX", maxAge); return clients.redisClient.set(key, value, "EX", maxAge); } }, clients, status }; //#endregion //#region lib/utils/cache/index.ts const globalCache = { get: () => null, set: () => null }; let cacheModule; if (config.cache.type === "redis") { cacheModule = redis_default; cacheModule.init(); const { redisClient } = cacheModule.clients; globalCache.get = async (key) => { if (key && cacheModule.status.available && redisClient) return await redisClient.get(key); }; globalCache.set = cacheModule.set; } else if (config.cache.type === "memory") { cacheModule = memory_default; cacheModule.init(); const { memoryCache } = cacheModule.clients; globalCache.get = (key) => { if (key && cacheModule.status.available && memoryCache) return memoryCache.get(key, { updateAgeOnGet: false }); }; globalCache.set = (key, value, maxAge = config.cache.routeExpire) => { if (!value || value === "undefined") value = ""; if (typeof value === "object") value = JSON.stringify(value); if (key && memoryCache) return memoryCache.set(key, value, { ttl: maxAge * 1e3 }); }; } else { cacheModule = { init: () => null, get: () => null, set: () => null, status: { available: false }, clients: {} }; logger_default.error("Cache not available, concurrent requests are not limited. This could lead to bad behavior."); } var cache_default = { ...cacheModule, tryGet: async (key, getValueFunc, maxAge = config.cache.contentExpire, refresh = true) => { if (typeof key !== "string") throw new TypeError("Cache key must be a string"); let v = await cacheModule.get(key, refresh); if (v) { let parsed; try { parsed = JSON.parse(v); } catch { parsed = null; } if (parsed) v = parsed; return v; } else { const value = await getValueFunc(); cacheModule.set(key, value, maxAge); return value; } }, globalCache }; //#endregion export { cache_default as t };