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.

71 lines (70 loc) 2.95 kB
/*! idmp v4.1.0 | (c) github/haozi | MIT */ //#region src/index.ts var e = /* @__PURE__ */ function(e) { return e[e.UNSENT = 0] = "UNSENT", e[e.OPENING = 1] = "OPENING", e[e.ABORTED = 2] = "ABORTED", e[e.REJECTED = 3] = "REJECTED", e[e.RESOLVED = 4] = "RESOLVED", e; }(e || {}), t = /* @__PURE__ */ function(e) { return e[e.retryCount = 0] = "retryCount", e[e.status = 1] = "status", e[e.pendingList = 2] = "pendingList", e[e.resolvedData = 3] = "resolvedData", e[e.rejectionError = 4] = "rejectionError", e[e.cachedPromiseFunc = 5] = "cachedPromiseFunc", e[e.timerId = 6] = "timerId", e[e._originalErrorStack = 7] = "_originalErrorStack", e; }(t || {}), n = 3e3, r = 6048e5, i = () => {}, a = void 0, o = setTimeout, s = clearTimeout, c = (e, t) => e > t ? e : t, l = (e, t) => e < t ? e : t, u = (e) => e < 0 ? 0 : e > r ? r : e, d = {}, f = (e) => { let { maxRetry: t = 30, maxAge: r = n, minRetryDelay: a = 50, maxRetryDelay: o = 5e3, onBeforeRetry: s = i, signal: c } = e || {}; return { maxRetry: t, maxAge: u(r), minRetryDelay: a, maxRetryDelay: o, onBeforeRetry: s, f: r === Infinity, signal: c }; }, p = (e) => { if (!e) return; let n = d[e]; n && (n[t.timerId] && s(n[t.timerId]), d[e] = a); }, m = () => { for (let e of Object.keys(d)) p(e); d = {}; }, h = (n, r, i) => { if (!n) return r(); let { maxRetry: s, minRetryDelay: u, maxRetryDelay: m, maxAge: h, onBeforeRetry: g, f: _, signal: v } = f(i); d[n] = d[n] || [ 0, e.UNSENT, [] ]; let y = d[n], b = () => { y[t.status] = e.UNSENT, y[t.resolvedData] = y[t.rejectionError] = a; }, x = () => { let e = y[t.pendingList].length; for (let n = 0; n < e; ++n) y[t.pendingList][n][0](y[t.resolvedData]); y[t.pendingList] = [], _ || (y[t.timerId] = o(() => { p(n); }, h)); }, S = () => { let e = y[t.pendingList].length, r; r = e - s, (r < 0 || !isFinite(e)) && (r = c(1, y[t.pendingList].length - 3)); for (let e = 0; e < r; ++e) y[t.pendingList][e][1](y[t.rejectionError]); p(n); }, C = () => new Promise((i, a) => { if (!y[t.cachedPromiseFunc] && (y[t.cachedPromiseFunc] = r), y[t.status] === e.RESOLVED) { i(y[t.resolvedData]); return; } if (v) { if (v.aborted) return; v.addEventListener("abort", () => { b(), y[t.rejectionError] = new DOMException(v.reason, "AbortError"), S(); }); } y[t.status] === e.UNSENT ? (y[t.status] = e.OPENING, y[t.pendingList].push([i, a]), y[t.cachedPromiseFunc]().then((n) => { y[t.resolvedData] = n, x(), y[t.status] = e.RESOLVED; }).catch((r) => { y[t.status] = e.REJECTED, y[t.rejectionError] = r, ++y[t.retryCount], y[t.retryCount] > s ? S() : (g(r, { globalKey: n, retryCount: y[t.retryCount] }), b(), o(C, l(m, u * Math.pow(2, y[t.retryCount] - 1)))); })) : y[t.status] === e.OPENING && y[t.pendingList].push([i, a]); }); return C(); }; h.flush = p, h.flushAll = m, h._s = a; //#endregion export { h as default, h as idmp, f as getOptions };