UNPKG

@typed/http

Version:

HTTP requests for node and browsers

69 lines 2.54 kB
import { Disposable } from '@typed/disposable'; import { curry, pipe } from '@typed/lambda'; import { whenIdle } from '@typed/timer'; import { isValidStatus } from './isValidStatus'; // milliseconds const SECOND = 1000; const MINUTE = 60 * SECOND; const DEFAULT_EXPIRATION = 5 * MINUTE; const DEFAULT_METHODS_TO_CACHE = ['GET', 'HEAD', 'OPTIONS']; export const withHttpManagement = curry(__withHttpManagement); function __withHttpManagement(options, env) { const { timer, expiration = DEFAULT_EXPIRATION, methodsToCache = DEFAULT_METHODS_TO_CACHE, getCacheKey = defaultCacheKey, } = options; const cache = new Map(); let cacheClearDisposable = Disposable.None; function clearAllOldResponses(deadline, time) { const expired = time - expiration; const iterator = cache.entries()[Symbol.iterator](); let current = iterator.next(); while (deadline.timeRemaining() > 0 && !current.done) { const [key, { timestamp }] = current.value; if (timestamp <= expired) { cache.delete(key); } current = iterator.next(); } } function scheduleNextClear() { cacheClearDisposable.dispose(); cacheClearDisposable = whenIdle(clearAllOldResponses, timer); } function clearOldResponse(key) { const now = timer.currentTime(); const expired = now - expiration; const response = cache.get(key); if (response.timestamp <= expired) { cache.delete(key); } } function cacheResponseByKey(key) { return (response) => { if (isValidStatus(response)) { cache.set(key, { timestamp: timer.currentTime(), response }); } scheduleNextClear(); return response; }; } function http(url, options, callbacks) { const { success } = callbacks; const key = getCacheKey(url, options); const isCacheable = methodsToCache.includes(options.method || 'GET'); const lastResponse = cache.get(key); if (isCacheable && lastResponse) { clearOldResponse(key); return timer.delay(() => success(lastResponse.response), 0); } return env.http(url, options, { ...callbacks, success: isCacheable ? pipe(cacheResponseByKey(key), success) : success, }); } return { http, }; } function defaultCacheKey(url, _) { return url; } //# sourceMappingURL=withHttpManagement.js.map