UNPKG

idmp

Version:

A lightweight TypeScript library for deduplicating and caching async function calls with automatic retries, designed for idempotent network requests in React and Node.js.

161 lines (160 loc) 3.96 kB
/*! idmp v0.0.0 | (c) github/haozi | MIT */ "use strict"; var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } }); /*! idmp v3.4.4 | (c) github/haozi | MIT */ const DEFAULT_MAX_AGE = 3e3; const _7days = 6048e5; const noop = () => { }; const getRange = (maxAge) => { if (maxAge < 0) return 0; if (maxAge > _7days) return _7days; return maxAge; }; const getOptions = (options) => { const { maxRetry = 30, maxAge: paramMaxAge = DEFAULT_MAX_AGE, minRetryDelay = 50, maxRetryDelay = 5e3, onBeforeRetry = noop, signal } = options || {}; const maxAge = getRange(paramMaxAge); return { maxRetry, maxAge, minRetryDelay, maxRetryDelay, onBeforeRetry, f: paramMaxAge === 1 / 0, // Infinity signal }; }; const UNDEFINED = void 0; const PREFIX = "@idmp/v1/"; const getCacheKey = (globalKey) => `${PREFIX}${globalKey}`; const initStorage = (storageType) => { let storage; try { storage = window[storageType]; } catch (e) { } const remove = (key) => { if (!key) return; try { const cacheKey = getCacheKey(key); storage.removeItem(cacheKey); } catch (e) { } }; const get = (key) => { if (!key) return; const cacheKey = getCacheKey(key); let localData; try { localData = JSON.parse(storage.getItem(cacheKey) || ""); if (localData === UNDEFINED) return; const { t, a: maxAge, d: data } = localData; if (Date.now() - t > maxAge) { remove(cacheKey); return; } return data; } catch (e) { } }; const set = (key, data, maxAge) => { if (!key) return; const cacheKey = getCacheKey(key); try { storage.setItem( cacheKey, JSON.stringify({ t: Date.now(), // timestamp a: maxAge, // age (ttl) d: data // data }) ); } catch (e) { } }; const clear = () => { try { for (let i = storage.length - 1; i >= 0; i--) { const key = storage.key(i); if (key && key.startsWith(PREFIX)) { remove(key); } } } catch (e) { } }; return { get, set, remove, clear }; }; const storageIdmpWrap = (_idmp, storageType = "sessionStorage") => { const storage = initStorage(storageType); const newIdmp = (globalKey, promiseFunc, options) => { const finalOptions = getOptions(options); return _idmp( globalKey, () => __async(null, null, function* () { const localData = storage.get(globalKey); if (localData !== UNDEFINED) { if (process.env.NODE_ENV !== "production") { console.log( `[idmp-plugin browser-storage debug] ${globalKey} from ${storageType}["${getCacheKey(globalKey)}"]` ); } return localData; } const memoryData = yield promiseFunc(); if (memoryData !== UNDEFINED) { storage.set(globalKey, memoryData, finalOptions.maxAge); } return memoryData; }), options ); }; newIdmp.flush = (globalKey) => { _idmp.flush(globalKey); storage.remove(globalKey); }; newIdmp.flushAll = () => { _idmp.flushAll(); storage.clear(); }; return newIdmp; }; exports.default = storageIdmpWrap; exports.getCacheKey = getCacheKey;