Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | 66x 847x 847x 847x 847x 847x 847x 847x 77x 770x 770x 675x 95x 95x 85x 85x 85x 76x 76x 76x 76x 76x 85x 66x 847x 847x 847x 847x 77x 77x 77x 77x 66x 171x 171x 171x 66x 923x 66x 941x 941x | import { GetRequestBundleWaitingSeconds, GetRequestCacheExpirySeconds, PendingRequestsCacheKey } from '@config/base'; // eslint-disable-next-line @typescript-eslint/no-explicit-any export const cachedFetch = async (url: string, options: any): Promise<any> => { let expiry = GetRequestCacheExpirySeconds; const cacheKey = url; Iif (typeof options === 'number') { expiry = options; options = undefined; } else Eif (typeof options === 'object') { expiry = options.seconds || expiry; } const resp = getCachedResponse(cacheKey, expiry); if (resp != null) { return await resp; } const pendingRequests: Set<string> = getPendingRequests(); if (pendingRequests.has(url)) { //If currently there is a same request on going, just wait for a while await new Promise(resolve => setTimeout(resolve, GetRequestBundleWaitingSeconds * 1000)); const resp = getCachedResponse(cacheKey, expiry); if (resp != null) { return await resp; } } else { updatePendingRequestList(url, "add"); } return fetch(url, options).then(response => { // let's only store in cache if the content-type is JSON or something // non-binary Eif (response.status === 200) { const ct = response.headers.get('Content-Type'); if (ct && (ct.match(/application\/json/i) || ct.match(/text\//i))) { // There is a .json() instead of .text() but we're going to store it in // sessionStorage as string anyway. If we don't clone the response, it // will be consumed by the time it's returned. This way we're being // un-intrusive. response.clone().text().then(content => { localStorage.setItem(cacheKey, content); localStorage.setItem(getTsCacheKey(cacheKey), `${Date.now()}`); updatePendingRequestList(url, "delete"); // Auto delete the cache after GetRequestCacheExpirySeconds + 1 seconds setTimeout(() => { localStorage.removeItem(cacheKey); localStorage.removeItem(getTsCacheKey(cacheKey)); }, (GetRequestCacheExpirySeconds + 3) * 1000); }); } } return response; }); }; // eslint-disable-next-line @typescript-eslint/no-explicit-any const getCachedResponse = (cacheKey: string, expiry: number): Promise<any> | undefined => { const cached = localStorage.getItem(cacheKey); const tsCacheKey = getTsCacheKey(cacheKey); const whenCached = parseInt(localStorage.getItem(tsCacheKey) ?? "0"); if (cached !== null && whenCached !== null) { // it was in sessionStorage! Yay! // Even though 'whenCached' is a string, this operation // works because the minus sign tries to convert the // string to an integer and it will work. const age = (Date.now() - whenCached) / 1000; if (age < expiry) { const response = new Response(new Blob([cached])); return Promise.resolve(response); } else E{ // We need to clean up this old key localStorage.removeItem(cacheKey); localStorage.removeItem(tsCacheKey); } } }; const updatePendingRequestList = (url: string, operation: "delete" | "add"): void => { const newPendingRequests = getPendingRequests(); (operation === "delete") ? newPendingRequests.delete(url) : newPendingRequests.add(url); localStorage.setItem(PendingRequestsCacheKey, JSON.stringify(Array.from(newPendingRequests))); }; const getTsCacheKey = (cacheKey: string): string => { return cacheKey + ":ts"; }; const getPendingRequests = (): Set<string> => { const pendingRequests: Set<string> = new Set( JSON.parse(localStorage.getItem(PendingRequestsCacheKey) ?? '[]')); return pendingRequests; }; |