export type Cache = Map; export type AsyncCache = Map>; export function withCache T>( callback: U, key: string, cache: Cache, ): (...args: Parameters) => T { return (...args) => { if (cache.has(key)) { return cache.get(key) as T; } const value = callback(...args); cache.set(key, value); return value; }; } export function withAsyncCache Promise>( callback: U, key: string, cache: AsyncCache, ): (...args: Parameters) => Promise { return async (...args) => { if (cache.has(key)) { return (await cache.get(key)) as T; } const value = callback(...args); cache.set(key, value); return await value; }; } export function useWithCache( callback: (...args: unknown[]) => T, ): [(uri: string) => T, Cache] { const cache: Cache = new Map(); return [(uri: string) => withCache(callback, uri, cache)(uri), cache]; } export function useWithAsyncCache( callback: (...args: unknown[]) => Promise, ): [(uri: string) => Promise, AsyncCache] { const cache: AsyncCache = new Map(); return [(uri: string) => withAsyncCache(callback, uri, cache)(uri), cache]; }