interface CahcedValue { value: T; time: number; } export type CvgCache = { get: (...u: U) => Promise; clear: () => void; }; export const useCache = ( valueGetter: (...u: U) => Promise, stalenessSeconds = 300 ): CvgCache => { const stalenessMs = stalenessSeconds * 1_000; let cache: CahcedValue | null = null; let operation: Promise | undefined; return { get: async (...u: U) => { if (cache !== null) { if (Date.now() - cache.time <= stalenessMs) { // return cached value return cache.value; } // clear cached value once expired cache = null; operation = undefined; } // return existing getter promise or start a new one let value: T; if (operation) { value = await operation; } else { operation = valueGetter(...u); value = await operation; } cache = { value, time: Date.now(), }; return cache.value; }, clear: () => { cache = null; operation = undefined; }, }; };