UNPKG

@trieb.work/nextjs-turbo-redis-cache

Version:

The ultimate Redis caching solution for Next.js. Built for production-ready, large-scale projects, it delivers unparalleled performance and efficiency with features tailored for high-traffic applications.

62 lines (56 loc) 1.95 kB
import { SyncedMap } from './SyncedMap'; export class DeduplicatedRequestHandler< T extends (...args: [never, never]) => Promise<K>, K, > { private inMemoryDeduplicationCache: SyncedMap<Promise<K>>; private cachingTimeMs: number; private fn: T; constructor( fn: T, cachingTimeMs: number, inMemoryDeduplicationCache: SyncedMap<Promise<K>>, ) { this.fn = fn; this.cachingTimeMs = cachingTimeMs; this.inMemoryDeduplicationCache = inMemoryDeduplicationCache; } // Method to manually seed a result into the cache seedRequestReturn(key: string, value: K): void { const resultPromise = new Promise<K>((res) => res(value)); this.inMemoryDeduplicationCache.set(key, resultPromise); setTimeout(() => { this.inMemoryDeduplicationCache.delete(key); }, this.cachingTimeMs); } // Method to handle deduplicated requests deduplicatedFunction = (key: string): T => { //eslint-disable-next-line @typescript-eslint/no-this-alias const self = this; const dedupedFn = async (...args: [never, never]): Promise<K> => { // If there's already a pending request with the same key, return it if ( self.inMemoryDeduplicationCache && self.inMemoryDeduplicationCache.has(key) ) { const res = await self.inMemoryDeduplicationCache .get(key)! .then((v) => structuredClone(v)); return res; } // If no pending request, call the original function and store the promise const promise = self.fn(...args); self.inMemoryDeduplicationCache.set(key, promise); try { const result = await promise; return structuredClone(result); } finally { // Once the promise is resolved/rejected, remove it from the map setTimeout(() => { self.inMemoryDeduplicationCache.delete(key); }, self.cachingTimeMs); } }; return dedupedFn as T; }; }