Skip to content

Instantly share code, notes, and snippets.

@RodrigoNovais
Created February 20, 2025 04:28
Show Gist options
  • Save RodrigoNovais/fb65b741ff1de4599ad152c3b5e2f4f6 to your computer and use it in GitHub Desktop.
Save RodrigoNovais/fb65b741ff1de4599ad152c3b5e2f4f6 to your computer and use it in GitHub Desktop.
Cache fetch requests
type CacheEntry<R> = {
value: R;
timestamp: number;
};
const promises = new Map<string, Promise<unknown>>;
export const cacheTTL = <Args extends unknown[], R>(
fn: (...args: Args) => Promise<R>,
ttl: number,
keyResolver?: (...args: Args) => string
): ((...args: Args) => Promise<R>) => {
const identifier = fn.name || fn.toString();
return (...args: Args): Promise<R> => {
const argsKey = keyResolver
? keyResolver(...args)
: JSON.stringify(args);
const key = `cacheTTL:${identifier}:${argsKey}`;
const now = Date.now();
const cached = localStorage.getItem(key);
if (cached) {
const entry = JSON.parse(cached) as CacheEntry<R>;
if (now - entry.timestamp < ttl)
return Promise.resolve(entry.value);
}
if (promises.has(key))
return promises.get(key)! as Promise<R>;
const promise = fn(...args)
.then(result => {
localStorage.setItem(
key,
JSON.stringify({ value: result, timestamp: now })
);
promises.delete(key);
return result;
})
.catch((error: unknown) => {
promises.delete(key);
throw error;
});
promises.set(key, promise);
return promise;
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment