UNPKG

@net-vert/core

Version:

Dependency Inversion Network Library with Type-Safe Injection.

328 lines (327 loc) 7.51 kB
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 };