import { type CacheTime, type DataCache, getCacheTimeInSeconds, } from "../../Cache" import { type CacheOrGetOptions, shouldGetFromCache, } from "../../cacheOrGetOptions" import { cacheLogger } from "../../logger" import { get } from "./get" import { set } from "./set" export const cacheOrGet: DataCache["cacheOrGet"] = async ( key: string | string[], callback: (overrideTTL?: (cacheTime: CacheTime) => void) => Promise, ttl: CacheTime, opts?: CacheOrGetOptions ): Promise => { if (Array.isArray(key)) { key = key.join("-") } let realTTL = ttl const overrideTTL = function (cacheTime: CacheTime) { realTTL = cacheTime } if (getCacheTimeInSeconds(ttl) <= 0) { cacheLogger.debug(`'Fetching ${key}' with ttl=0. Skipping cache!`) return await callback(overrideTTL) } let cached: Awaited | undefined = undefined if (shouldGetFromCache(opts)) { cached = await get(key) if (cached) { return cached } cacheLogger.debug(`Miss for key '${key}'`) } try { const data = await callback(overrideTTL) await set(key, data, realTTL) return data } catch (e) { cacheLogger.error( `Error while fetching data for key '${key}', avoid caching`, e ) throw e } }