import { type CacheOrGetOptions, shouldGetFromCache, } from "../cacheOrGetOptions" import { cacheLogger } from "../logger" import { generateCacheKey } from "./generateCacheKey" import { get } from "./get" import { set } from "./set" import type { CacheTime, DataCache } from "../Cache" export const cacheOrGet: DataCache["cacheOrGet"] = async ( key: string | string[], callback: (overrideTTL: (cacheTime: CacheTime) => void) => Promise, ttl: CacheTime, opts?: CacheOrGetOptions ) => { const cacheKey = generateCacheKey(key, { includeGitHashInKey: opts?.includeGitHashInKey ?? true, }) let cachedValue: Awaited | undefined = undefined if (shouldGetFromCache(opts)) { cachedValue = await get(cacheKey) } let realTTL = ttl const overrideTTL = function (cacheTime: CacheTime) { realTTL = cacheTime } if (!cachedValue) { const perf = performance.now() const data = await callback(overrideTTL) const size = JSON.stringify(data).length / (1024 * 1024) if (size >= 5) { cacheLogger.warn(`'${key}' is larger than 5MB!`) } cacheLogger.debug( `Fetching data took ${(performance.now() - perf).toFixed(2)}ms ${size.toFixed(4)}MB for '${key}'` ) await set(cacheKey, data, realTTL) return data } return cachedValue }