feat: harden analytics dashboard
This commit is contained in:
39
lib/query-cache.ts
Normal file
39
lib/query-cache.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
export interface QueryCacheOptions {
|
||||
ttlMs: number;
|
||||
maxEntries: number;
|
||||
now?: () => number;
|
||||
}
|
||||
|
||||
export function createQueryCache(options: QueryCacheOptions) {
|
||||
const now = options.now ?? Date.now;
|
||||
const entries = new Map<string, { data: unknown; ts: number }>();
|
||||
|
||||
async function cached<T>(key: string, fn: () => Promise<T>): Promise<T> {
|
||||
const hit = entries.get(key);
|
||||
if (hit && now() - hit.ts < options.ttlMs) {
|
||||
return hit.data as T;
|
||||
}
|
||||
|
||||
const data = await fn();
|
||||
entries.set(key, { data, ts: now() });
|
||||
|
||||
while (entries.size > options.maxEntries) {
|
||||
const oldestKey = entries.keys().next().value;
|
||||
if (oldestKey === undefined) break;
|
||||
entries.delete(oldestKey);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
function clear() {
|
||||
entries.clear();
|
||||
}
|
||||
|
||||
return { cached, clear };
|
||||
}
|
||||
|
||||
export const queryCache = createQueryCache({
|
||||
ttlMs: 120_000,
|
||||
maxEntries: 500,
|
||||
});
|
||||
Reference in New Issue
Block a user