49 lines
952 B
TypeScript
49 lines
952 B
TypeScript
export type Cache<T> = Map<unknown, T>;
|
|
|
|
export function withCache<T, U extends (...args: Parameters<U>) => T>(
|
|
fn: U,
|
|
cache: Cache<T>,
|
|
): (key: unknown, ...args: Parameters<U>) => T {
|
|
return (key, ...args) => {
|
|
if (cache.has(key)) {
|
|
return cache.get(key) as T;
|
|
}
|
|
|
|
const value = fn(...args);
|
|
cache.set(key, value);
|
|
|
|
return value;
|
|
};
|
|
}
|
|
|
|
export function withCacheAsync<
|
|
T,
|
|
U extends (...args: Parameters<U>) => Promise<T>,
|
|
>(
|
|
fn: U,
|
|
cache: Cache<Promise<T>>,
|
|
): (key: unknown, ...args: Parameters<U>) => Promise<T> {
|
|
return async (key, ...args) => {
|
|
if (cache.has(key)) {
|
|
return (await cache.get(key)) as T;
|
|
}
|
|
|
|
const value = fn(...args);
|
|
cache.set(key, value);
|
|
|
|
return await value;
|
|
};
|
|
}
|
|
|
|
export function memoize<T, U>(fn: (arg: U) => T): [(arg: U) => T, Cache<T>] {
|
|
const cache = new Map<unknown, T>();
|
|
const callback = withCache(fn, cache);
|
|
|
|
return [
|
|
(arg) => {
|
|
return callback(arg, arg);
|
|
},
|
|
cache,
|
|
];
|
|
}
|