1- import { LRUCache } from ' lru-cache'
1+ import { LRUCache } from " lru-cache" ;
22
33declare global {
44 // @ts -expect-error - globalThis.docCache is set in the server entrypoint
5- var docCache : LRUCache < string , unknown >
5+ var docCache : LRUCache < string , unknown > ;
66}
77
88const docCache =
@@ -11,23 +11,40 @@ const docCache =
1111 ( globalThis . docCache = new LRUCache < string , unknown > ( {
1212 max : 300 ,
1313 // ttl: 1,
14- ttl : process . env . NODE_ENV === 'production' ? 1 : 1000000 ,
15- } ) )
14+ ttl : process . env . NODE_ENV === "production" ? 1 : 1000000 ,
15+ } ) ) ;
16+
17+ const pendingDocCache = new Map < string , Promise < unknown > > ( ) ;
1618
1719export async function fetchCached < T > ( opts : {
18- fn : ( ) => Promise < T >
19- key : string
20- ttl : number
20+ fn : ( ) => Promise < T > ;
21+ key : string ;
22+ ttl : number ;
2123} ) : Promise < T > {
2224 if ( docCache . has ( opts . key ) ) {
23- return docCache . get ( opts . key ) as T
25+ return docCache . get ( opts . key ) as T ;
2426 }
2527
26- const result = await opts . fn ( )
28+ const pending = pendingDocCache . get ( opts . key ) ;
29+
30+ if ( pending ) {
31+ return pending as Promise < T > ;
32+ }
33+
34+ const resultPromise = opts
35+ . fn ( )
36+ . then ( ( result ) => {
37+ docCache . set ( opts . key , result , {
38+ ttl : opts . ttl ,
39+ } ) ;
40+
41+ return result ;
42+ } )
43+ . finally ( ( ) => {
44+ pendingDocCache . delete ( opts . key ) ;
45+ } ) ;
2746
28- docCache . set ( opts . key , result , {
29- ttl : opts . ttl ,
30- } )
47+ pendingDocCache . set ( opts . key , resultPromise ) ;
3148
32- return result
49+ return resultPromise ;
3350}
0 commit comments