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) • 4.68 kB
JavaScript
/*! idmp v4.1.0 | (c) github/haozi | MIT */
//#region ../../dist/index.js
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
//#region \0@oxc-project+runtime@0.121.0/helpers/asyncToGenerator.js
function g(e, t, n, r, i, a, o) {
try {
var s = e[a](o), c = s.value;
} catch (e) {
n(e);
return;
}
s.done ? t(c) : Promise.resolve(c).then(r, i);
}
function _(e) {
return function() {
var t = this, n = arguments;
return new Promise(function(r, i) {
var a = e.apply(t, n);
function o(e) {
g(a, r, i, o, s, "next", e);
}
function s(e) {
g(a, r, i, o, s, "throw", e);
}
o(void 0);
});
};
}
//#endregion
//#region src/index.ts
var v = void 0, y = "@idmp/v4/", b = (e) => `${y}${e}`, x = (e) => {
let t;
try {
t = window[e];
} catch (e) {}
let n = (e) => {
if (e) try {
let n = b(e);
t.removeItem(n);
} catch (e) {}
};
return {
get: (e) => {
if (!e) return;
let r = b(e), i;
try {
if (i = JSON.parse(t.getItem(r) || ""), i === v) return;
let { t: e, a, d: o } = i;
if (Date.now() - e > a) {
n(r);
return;
}
return o;
} catch (e) {}
},
set: (e, n, r) => {
if (!e) return;
let i = b(e);
try {
t.setItem(i, JSON.stringify({
t: Date.now(),
a: r,
d: n
}));
} catch (e) {}
},
remove: n,
clear: () => {
try {
for (let e = t.length - 1; e >= 0; e--) {
let r = t.key(e);
r && r.startsWith(y) && n(r);
}
} catch (e) {}
}
};
}, S = (e, t = "sessionStorage") => {
let n = x(t), r = (t, r, i) => {
let a = f(i);
return e(t, _(function* () {
let e = n.get(t);
if (e !== v) return e;
let i = yield r();
return i !== v && n.set(t, i, a.maxAge), i;
}), i);
};
return r.flush = (t) => {
e.flush(t), n.remove(t);
}, r.flushAll = () => {
e.flushAll(), n.clear();
}, r;
};
//#endregion
export { S as default, b as getCacheKey };