import { loadLocalStorageData, saveLocalStorageData, } from '../../../lib/local-storage-helpers' import fetchWithTimeout from '../../../../app/scripts/lib/fetch-with-timeout' const fetchWithCache = async (url, fetchOptions = {}, { cacheRefreshTime = 360000, timeout = 30000 } = {}) => { if (fetchOptions.body || (fetchOptions.method && fetchOptions.method !== 'GET')) { throw new Error('fetchWithCache only supports GET requests') } if (!(fetchOptions.headers instanceof window.Headers)) { fetchOptions.headers = new window.Headers(fetchOptions.headers) } if ( fetchOptions.headers && fetchOptions.headers.has('Content-Type') && fetchOptions.headers.get('Content-Type') !== 'application/json' ) { throw new Error('fetchWithCache only supports JSON responses') } const currentTime = Date.now() const cachedFetch = loadLocalStorageData('cachedFetch') || {} const { cachedResponse, cachedTime } = cachedFetch[url] || {} if (cachedResponse && currentTime - cachedTime < cacheRefreshTime) { return cachedResponse } else { fetchOptions.headers.set('Content-Type', 'application/json') const _fetch = timeout ? fetchWithTimeout({ timeout }) : window.fetch const response = await _fetch(url, { referrerPolicy: 'no-referrer-when-downgrade', body: null, method: 'GET', mode: 'cors', ...fetchOptions, }) if (!response.ok) { throw new Error(`Fetch failed with status '${response.status}': '${response.statusText}'`) } const responseJson = await response.json() const cacheEntry = { cachedResponse: responseJson, cachedTime: currentTime, } cachedFetch[url] = cacheEntry saveLocalStorageData(cachedFetch, 'cachedFetch') return responseJson } } export default fetchWithCache