@@ -155,6 +155,30 @@ function request<T>(url: string, type: 'json' | 'text', opts?: RequestOpts, feed
155155 } )
156156}
157157
158+ type ExpiringCacheEntry = { expires : ReturnType < DateConstructor [ 'now' ] > , data : any }
159+ const responseCache = new Map < string , ExpiringCacheEntry > ( )
160+
161+ async function getFromCacheOr < T > ( cacheKey : string , cacheSeconds : number , getData : ( ) => Promise < T > ) : Promise < T > {
162+ const cacheEntry = responseCache . get ( cacheKey )
163+ if ( cacheEntry && cacheEntry . expires >= Date . now ( ) ) {
164+ return cacheEntry . data as T
165+ } else {
166+ responseCache . delete ( cacheKey )
167+ }
168+
169+ const newExpirationTime = Date . now ( ) + ( cacheSeconds * 1000 )
170+ return getData ( ) . then ( ( data : T ) => {
171+ responseCache . set ( cacheKey , { expires : newExpirationTime , data : data } )
172+ return data
173+ } )
174+ }
175+
176+ export function fetchCachedJSON < T > ( cacheSeconds : number , url : string , opts ?: RequestOpts , feedback = false ) : Promise < T > {
177+ return getFromCacheOr ( url , cacheSeconds , ( ) => {
178+ return request < T > ( url , 'json' , opts , feedback )
179+ } )
180+ }
181+
158182export function fetchJSON < T > ( url : string , opts ?: RequestOpts , feedback = false ) : Promise < T > {
159183 return request < T > ( url , 'json' , opts , feedback )
160184}
0 commit comments