@net-vert/core
Version:
Dependency Inversion Network Library with Type-Safe Injection.
328 lines (327 loc) • 7.51 kB
JavaScript
import D from "localforage";
import { TaskQueue as E } from "id-queue";
const k = {
get: (t, e) => ({
url: t,
method: "get",
...e,
params: e == null ? void 0 : e.params
}),
post: (t, e, r) => ({
url: t,
method: "post",
data: e,
headers: { "Content-Type": "application/json", ...r == null ? void 0 : r.headers },
...r
}),
delete: (t, e) => ({
url: t,
method: "delete",
...e
}),
put: (t, e, r) => ({
url: t,
method: "put",
data: e,
headers: { "Content-Type": "application/json", ...r == null ? void 0 : r.headers },
...r
}),
request: (t) => t
};
function j(t) {
const e = {};
return Object.keys(k).forEach(
(r) => {
e[r] = (...n) => {
const o = k[r](...n);
return t(o);
};
}
), {
...e,
request: t
};
}
const M = "default", z = () => `${Date.now()}_${Math.random().toString().slice(2, 8)}`, I = /* @__PURE__ */ new Map(), V = (t, e = M) => {
I.set(e, j(t));
}, v = (t = M) => {
const e = I.get(t);
if (!e) throw new Error(`Requestor实例 ${t} 未注册`);
return e;
};
class O {
has(e) {
return !!this.get(e);
}
// 获取缓存
get(e) {
const r = localStorage.getItem(e);
if (r)
try {
return JSON.parse(r);
} catch (n) {
console.error("Error parsing cached data", n);
return;
}
}
// 设置缓存
set(e, r) {
try {
const n = JSON.stringify(r);
localStorage.setItem(e, n);
} catch (n) {
console.error("Error saving data to localStorage", n);
}
return r;
}
// 删除缓存
remove(e) {
localStorage.removeItem(e);
}
// 清空所有缓存
clear() {
localStorage.clear();
}
}
const T = new O(), H = ({ persist: t, name: e, sync: r }) => {
if (t && r)
return T;
if (t) {
const n = D.createInstance({
name: e
// driver: sync
// ?undefined
// :localforage.LOCALSTORAGE,
});
return {
has: (o) => n.keys().then((s) => s.includes(o)),
get: (o) => n.getItem(o),
set: (o, s) => n.setItem(o, s),
remove: (o) => n.removeItem(o),
clear: () => n.clear()
};
} else {
const n = /* @__PURE__ */ new Map();
return {
has: (o) => n.has(o),
get: (o) => n.get(o),
set: (o, s) => n.set(o, s),
remove: (o) => n.delete(o),
clear: () => n.clear()
};
}
}, U = () => {
const t = /* @__PURE__ */ new Map();
return {
getPromise: (s) => t.get(s),
setPromise: (s, i) => {
t.set(s, i);
},
delPromise: (s) => {
t.delete(s);
},
clearCache: () => {
t.clear();
}
};
}, _ = (t, e) => ({
value: t,
expiresAt: Date.now() + e
}), x = (t) => t.expiresAt > Date.now(), A = {
key: (t) => t.url,
persist: !1,
duration: 1 / 0,
sync: !1
}, S = (t) => {
const e = { ...A, ...t }, { name: r, persist: n, sync: o } = e, s = H({ persist: n, name: r, sync: o }), { getPromise: i, setPromise: P, delPromise: f } = U();
function c(a, d) {
const { isValid: l } = e, h = s.get(a);
let g = !1;
if (h && x(h)) {
try {
g = (l == null ? void 0 : l({
key: a,
config: d,
cachedData: h
})) ?? !0;
} catch (u) {
console.error(`校验异常 ${a}`, u);
}
!g && s.remove(a);
}
return { shouldUseCache: g, cachedData: h };
}
async function w(a, d) {
const { isValid: l } = e, h = await s.get(a);
let g = !1;
if (h && x(h)) {
try {
g = await (l == null ? void 0 : l({
key: a,
config: d,
cachedData: h
})) ?? !0;
} catch (u) {
console.error(`校验异常 ${a}`, u);
}
!g && s.remove(a);
}
return { shouldUseCache: g, cachedData: h };
}
const p = {
get(a, d) {
function l(u, m, ...y) {
const C = Reflect.apply(a[d], a, y).then(async (q) => {
const R = typeof e.duration == "number" ? e.duration : e.duration({
key: u,
config: m,
response: q
});
return s.set(u, _(q, R)), q;
}).finally(() => {
f(u);
});
return P(u, C), C;
}
return o ? (...u) => {
const m = k[d](...u), y = e.key(m), C = i(y);
if (C)
return C;
const { shouldUseCache: q, cachedData: R } = c(y, m);
return q ? R.value : l(y, m, ...u);
} : async (...u) => {
const m = k[d](...u), y = e.key(m), C = i(y);
if (C)
return C;
const { shouldUseCache: q, cachedData: R } = await w(y, m);
return q ? R.value : l(y, m, ...u);
};
}
};
return {
requestor: new Proxy(v(), p),
store: s
};
}, J = (t) => {
const { method: e, url: r, params: n, data: o } = t;
return [e, r, JSON.stringify(n), JSON.stringify(o)].join("|");
}, N = (t) => {
const {
requestor: e
} = S({
key: (r) => t ? t(r) : J(r),
persist: !1
});
return {
requestor: e
};
}, b = {
retries: 3,
delay: 0,
retryCondition: () => !0
}, $ = (t) => {
const { retries: e, delay: r, retryCondition: n } = { ...b, ...t }, o = {
get(s, i) {
return (...f) => {
let c = 0;
const w = () => Reflect.apply(s[i], s, f).catch((p) => {
if (c < e && n(p)) {
c++;
const a = typeof r == "function" ? r(c) : r;
return new Promise((d) => {
setTimeout(() => d(w()), a);
});
}
return Promise.reject(p);
});
return w();
};
}
};
return {
requestor: new Proxy(v(), o)
};
};
class F {
constructor(e = 4) {
this.parallelCount = e, this.tasks = new E(), this.runningCount = 0;
}
// 加入
add(e, r) {
return new Promise((n, o) => {
this.tasks.enqueue(e, {
task: r,
resolve: n,
reject: o
}), this._run();
});
}
// 删除
remove(e) {
this.tasks.remove(e);
}
execute(e) {
const { task: r, resolve: n, reject: o } = e;
return r().then(n).catch(o).finally(() => {
this.runningCount--, this._run();
});
}
_run() {
for (; this.runningCount < this.parallelCount && this.tasks.size > 0; ) {
const e = this.tasks.dequeue();
this.runningCount++, this.execute(e);
}
}
}
const L = {
parallelCount: 4,
retries: 0,
createId: () => z()
}, Q = (t) => {
const e = { ...L, ...t }, { parallelCount: r, createId: n, ...o } = e, s = new F(r), { requestor: i = null } = o.retries > 0 ? $(o) : {}, P = {
get(f, c) {
return (...p) => {
const a = k[c](...p), d = n(a), l = () => i ? Reflect.apply(i[c], i, p) : Reflect.apply(f[c], f, p);
return s.add(d, l);
};
}
};
return {
requestor: new Proxy(v(), P),
concurrentPool: s
};
}, W = {
persist: !1,
sync: !0
}, Y = (t) => {
const e = { ...W, ...t }, { ...r } = e, {
requestor: n
} = S(r), o = {
get(s, i) {
return (...f) => {
try {
const c = Reflect.apply(s[i], s, f);
if (c instanceof Promise)
throw c;
return c;
} catch (c) {
throw c;
}
};
}
};
return {
requestor: new Proxy(n, o)
};
}, X = {
cacheRequestor: S,
idempotencyRequestor: N,
retryRequestor: $,
concurrentPoolRequestor: Q,
syncRequestor: Y
};
export {
V as inject,
X as requestExtender,
v as useRequestor
};