@net-vert/core 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,318 @@
1
+
2
+ ---
3
+
4
+ # @net-vert/core
5
+
6
+ **轻量级依赖倒置网络请求库,专为扩展和易用而设计。**
7
+
8
+ GitHub 开源仓库 👉 [https://github.com/yvygyyth/net-vert](https://github.com/yvygyyth/net-vert)
9
+
10
+ ---
11
+
12
+ ## ✨ 核心特性
13
+
14
+ ✅ 解耦网络层,按需注入 axios、fetch 或自定义请求器
15
+ ✅ 支持缓存、幂等、重试等扩展
16
+ ✅ TypeScript 全类型提示,开发更丝滑
17
+ ✅ 内置幂等、缓存、重试等扩展
18
+ ✅ 零配置上手,API 极简
19
+
20
+ ---
21
+
22
+ ## 📦 安装
23
+
24
+ ```bash
25
+ npm install @net-vert/core
26
+ ```
27
+
28
+ ---
29
+
30
+ ## 🚀 快速上手
31
+
32
+ ### 1️⃣ 注入请求器(以 axios 为例)
33
+
34
+ ```typescript
35
+ import axios from 'axios';
36
+ import { inject, useRequestor } from '@net-vert/core';
37
+
38
+ const instance = axios.create({ baseURL: '/api', timeout: 60000 });
39
+ const axiosAdapter = (config) => instance.request(config);
40
+
41
+ inject(axiosAdapter); // 注入 axios 实例
42
+ ```
43
+
44
+ ---
45
+
46
+ ### 2️⃣ 发起请求
47
+
48
+ ```typescript
49
+ const api = useRequestor();
50
+
51
+ api.get('/user/info', { params: { id: 1 } }).then(console.log);
52
+ api.post('/user/create', { name: 'Alice' }).then(console.log);
53
+ ```
54
+
55
+ ---
56
+
57
+ ## 🛠 扩展能力(requestExtender)
58
+
59
+ ```typescript
60
+ import { requestExtender } from '@net-vert/core';
61
+ ```
62
+
63
+ ✅ **缓存请求**
64
+ ```typescript
65
+ const cachedApi = requestExtender.cacheRequestor();
66
+ cachedApi.get('/user/info', { params: { id: 1 } });
67
+ ```
68
+
69
+ ✅ **幂等请求**
70
+ ```typescript
71
+ const idempotentApi = requestExtender.idempotencyRequestor();
72
+ idempotentApi.post('/user/create', { name: 'Alice' });
73
+ ```
74
+
75
+ ✅ **自动重试**
76
+ ```typescript
77
+ const retryApi = requestExtender.retryRequestor({ retries: 3, delay: 1000 });
78
+ retryApi.get('/unstable-api');
79
+ ```
80
+
81
+ ---
82
+
83
+ ## 🔎 缓存设计说明
84
+
85
+ - 本库默认内置缓存支持
86
+ - **后续将完全依赖官方独立包:`@net-vert/cache`**
87
+ - 用户无需关注存储机制,专注请求本身
88
+
89
+ ---
90
+
91
+ ## 🧩 核心 API
92
+
93
+ | 方法 | 描述 |
94
+ |-----|------|
95
+ | `inject(adapter, instanceKey?)` | 注入请求适配器,不填默认为'default' |
96
+ | `useRequestor(instanceKey?)` | 获取请求实例 |
97
+ | `requestExtender.cacheRequestor(options)` | 创建带缓存能力的请求器 |
98
+ | `requestExtender.idempotencyRequestor(options)` | 创建幂等请求器 |
99
+ | `requestExtender.retryRequestor(options)` | 创建重试请求器 |
100
+
101
+ 非常专业!以下是针对你这份缓存扩展的专属文档(带源码思路和示例):
102
+
103
+ ---
104
+
105
+ ## 🗂 缓存扩展 `requestExtender.cacheRequestor(options)`
106
+
107
+ `cacheRequestor` 是 `@net-vert/core` 内置的缓存增强器,为请求增加缓存命中机制,避免重复请求,提升性能。
108
+
109
+ ### ✅ 核心特性
110
+
111
+ - 支持本地缓存或内存缓存(未来由 `@net-vert/cache` 提供存储支持)
112
+ - 同一请求中的并发合并(Promise 复用)
113
+ - 支持缓存过期时间配置
114
+ - 支持缓存 key 自定义生成逻辑
115
+ - 自动处理 Promise 缓存清理
116
+
117
+ ---
118
+
119
+ ### ⚙️ 配置参数(可选)
120
+
121
+ | 参数 | 类型 | 说明 | 默认值 |
122
+ | ------------ | ----------------------------------------------- | ---------------------------------------------- | -------------- |
123
+ | `key` | `(config: UnifiedConfig) => string` | 自定义缓存 key 生成规则 | `config.url` |
124
+ | `persist` | `boolean` | 是否持久化缓存(默认走内存) | `false` |
125
+ | `cacheTime` | `number` 或 `({config, response}) => number` | 缓存有效期(毫秒)或动态计算缓存时间 | `Infinity` |
126
+
127
+ ---
128
+
129
+ ### 📥 使用示例
130
+
131
+ ```typescript
132
+ import { requestExtender } from '@net-vert/core';
133
+
134
+ const cachedApi = requestExtender.cacheRequestor({
135
+ cacheTime: 5000, // 缓存 5 秒
136
+ key: (config) => `${config.method}-${config.url}` // 自定义缓存 key
137
+ });
138
+
139
+ // 第一次请求发出
140
+ cachedApi.get('/user/info', { params: { id: 1 } }).then(console.log);
141
+
142
+ // 5 秒内相同请求直接走缓存
143
+ cachedApi.get('/user/info', { params: { id: 1 } }).then(console.log);
144
+ ```
145
+
146
+ ---
147
+
148
+ ### 🔥 示例动态缓存时间计算
149
+
150
+ ```typescript
151
+ const dynamicCachedApi = requestExtender.cacheRequestor({
152
+ cacheTime: ({ config, response }) => {
153
+ // 根据接口返回决定缓存时间
154
+ return response.isHot ? 10000 : 3000;
155
+ }
156
+ });
157
+ ```
158
+
159
+ ## ♻️ 幂等扩展 `requestExtender.idempotencyRequestor(options)`
160
+
161
+ `idempotencyRequestor` 是基于 `cacheRequestor` 封装的幂等增强器,确保同一参数的请求,在请求未完成前只发送一次,自动合并并发请求,避免重复提交和资源浪费。
162
+
163
+ ---
164
+
165
+ ### ✅ 核心特性
166
+
167
+ - 采用 **哈希生成请求唯一标识**,自动识别重复请求
168
+ - 请求未完成时直接复用 Promise,避免短时间内重复请求接口
169
+ - 请求完成自动清理,确保后续请求正常发起
170
+ - 内存缓存(`persist: false`),适合表单提交、按钮防抖等场景
171
+
172
+ ---
173
+
174
+ ### ⚙️ 内部默认的哈希算法(hashRequest)
175
+
176
+ ```typescript
177
+ const hashRequest = (config: UnifiedConfig) => {
178
+ const { method, url, params, data } = config
179
+ return [method, url, JSON.stringify(params), JSON.stringify(data)].join('|')
180
+ }
181
+ ```
182
+ 支持用户传入自定义生成规则:
183
+
184
+ ```typescript
185
+ const idempotentApi = requestExtender.idempotencyRequestor((config) => {
186
+ return `custom-key-${config.url}`;
187
+ });
188
+ ```
189
+
190
+ ---
191
+
192
+ ## 🔁 重试扩展 `requestExtender.retryRequestor(options)`
193
+
194
+ `retryRequestor` 是基于 `Requestor` 增强的请求重试器,提供自动重试机制,确保请求失败时自动重试,提升请求稳定性。
195
+
196
+ ---
197
+
198
+ ### ✅ 核心特性
199
+
200
+ - 支持 **最大重试次数**,可避免无限重试
201
+ - 支持 **延迟重试**,延迟时间可自定义,默认 1000ms
202
+ - 支持 **重试条件**,根据特定错误判断是否重试
203
+ - 自动处理请求失败,符合幂等性原则,保证稳定性
204
+
205
+ ---
206
+
207
+ ### ⚙️ 配置选项
208
+
209
+ | 参数 | 类型 | 说明 | 默认值 |
210
+ | ----------------- | ------------------------------------------ | ------------------------------------------------ | ------------ |
211
+ | `retries` | `number` | 最大重试次数 | `3` |
212
+ | `delay` | `number` 或 `({attempt: number}) => number` | 延迟重试时间(默认延迟 1000ms) | `1000ms` |
213
+ | `retryCondition` | `(error: any) => boolean` | 重试条件,返回 `true` 时触发重试(默认对所有错误重试) | `() => true` |
214
+
215
+ ---
216
+
217
+ ### 📥 使用示例
218
+
219
+ ```typescript
220
+ import { requestExtender } from '@net-vert/core';
221
+
222
+ // 配置最大重试次数为 5 次,延迟 2 秒
223
+ const retryApi = requestExtender.retryRequestor({
224
+ retries: 5,
225
+ delay: 2000
226
+ });
227
+
228
+ // 请求失败时自动重试
229
+ retryApi.get('/unstable-api').then(console.log).catch(console.error);
230
+ ```
231
+
232
+ ---
233
+
234
+ ### 🔎 重试逻辑解析
235
+
236
+ 1. **最大重试次数 (`retries`)**:当请求失败时,最多重试 `retries` 次。
237
+ 2. **延迟策略 (`delay`)**:每次重试之间等待一段时间,支持固定时间或动态计算。
238
+ - 默认:1000ms(1秒)
239
+ - 可以根据重试次数动态调整延迟时间:
240
+ ```typescript
241
+ delay: (attempt) => attempt * 1000 // 每次重试延迟递增
242
+ ```
243
+ 3. **重试条件 (`retryCondition`)**:只有当错误符合重试条件时才会进行重试,默认为所有错误都重试。
244
+
245
+ ---
246
+
247
+ ### ⚠️ 使用建议
248
+
249
+ - **避免无限重试**:设置合适的最大重试次数(`retries`)和延迟时间(`delay`),防止请求卡死。
250
+ - **根据错误类型重试**:可以根据特定的错误类型或者状态码设定 `retryCondition`,例如:
251
+ ```typescript
252
+ retryCondition: (error) => error.response.status === 500
253
+ ```
254
+ 这样仅在服务器错误时才会进行重试。
255
+
256
+ ---
257
+
258
+ ### 🔥 典型应用场景
259
+
260
+ - **API 请求失败重试**:对那些偶尔会失败的网络请求,提供自动重试能力,提升成功率。
261
+ - **避免因瞬时网络问题而导致的请求失败**。
262
+ - **服务宕机恢复后自动重新发起请求**。
263
+
264
+ ---
265
+
266
+ ### 📥 使用示例
267
+
268
+ ```typescript
269
+ import { requestExtender } from '@net-vert/core';
270
+
271
+ const idempotentApi = requestExtender.idempotencyRequestor();
272
+
273
+ // 短时间内连续点击两次,只会发出一次请求
274
+ idempotentApi.post('/user/create', { name: 'Alice' }).then(console.log);
275
+ idempotentApi.post('/user/create', { name: 'Alice' }).then(console.log);
276
+ ```
277
+
278
+ 控制台:
279
+ ```
280
+ ===> 已存在该请求: POST|/user/create|{}|{"name":"Alice"}
281
+ ```
282
+
283
+ ---
284
+
285
+ ### 🔎 典型应用场景
286
+
287
+ ✅ 表单防重复提交
288
+ ✅ 提交按钮多次点击防抖
289
+ ✅ 防止接口雪崩(接口短时间被高频调用)
290
+
291
+ ---
292
+
293
+ ### ⚠️ 使用注意
294
+
295
+ - 本功能专为短时防重复设计,**缓存不持久化**
296
+ - 推荐用于 POST、PUT 等存在副作用的接口
297
+ - 自动清理缓存,确保下一次请求正常发出
298
+
299
+ ---
300
+
301
+ ## 📤 开源信息
302
+
303
+ - 仓库地址:[https://github.com/yvygyyth/net-vert](https://github.com/yvygyyth/net-vert)
304
+ - 许可证:MIT
305
+ - 支持 Tree-Shaking
306
+ - 无副作用 (`sideEffects: false`)
307
+
308
+ ---
309
+
310
+ ## 🔥 设计理念
311
+
312
+ - 网络层完全解耦,未来自由扩展
313
+ - 内置强大的请求能力,零上手成本
314
+ - 存储与缓存拆分,保持核心轻量纯粹
315
+
316
+ ---
317
+
318
+ 如果你确定了包名是 `@net-vert/cache`,我可以直接帮你生成一段未来文档里的“缓存插件使用示例”,随时告诉我!
package/dist/index.d.ts CHANGED
@@ -3,23 +3,6 @@ declare interface BasicCredentials {
3
3
  password: string;
4
4
  }
5
5
 
6
- export declare const extendRequestor: {
7
- createCacheRequestor: (config?: {
8
- key?: (config: UnifiedConfig) => string;
9
- persist?: boolean;
10
- cacheTime?: number | (({ config, response }: {
11
- config: UnifiedConfig;
12
- response: any;
13
- }) => number);
14
- }) => Requestor;
15
- createIdempotencyRequestor: (genKey?: (config: UnifiedConfig) => string) => Requestor;
16
- createRetryRequestor: (config?: {
17
- retries?: number;
18
- delay?: number | ((attempt: number) => number);
19
- retryCondition?: (error: any) => boolean;
20
- }) => Requestor;
21
- };
22
-
23
6
  export declare const inject: (requestor: UnifiedRequestor, instanceKey?: string) => void;
24
7
 
25
8
  declare interface RequestConfig<D = any> {
@@ -38,6 +21,23 @@ declare interface RequestConfig<D = any> {
38
21
  signal?: AbortSignal;
39
22
  }
40
23
 
24
+ export declare const requestExtender: {
25
+ cacheRequestor: (config?: {
26
+ key?: (config: UnifiedConfig) => string;
27
+ persist?: boolean;
28
+ cacheTime?: number | (({ config, response }: {
29
+ config: UnifiedConfig;
30
+ response: any;
31
+ }) => number);
32
+ }) => Requestor;
33
+ idempotencyRequestor: (genKey?: (config: UnifiedConfig) => string) => Requestor;
34
+ retryRequestor: (config?: {
35
+ retries?: number;
36
+ delay?: number | ((attempt: number) => number);
37
+ retryCondition?: (error: any) => boolean;
38
+ }) => Requestor;
39
+ };
40
+
41
41
  export declare interface Requestor {
42
42
  get<R = any, D = any>(url: string, config?: RequestConfig<D>): Promise<R>;
43
43
  post<R = any, D = any>(url: string, data?: D, config?: RequestConfig<D>): Promise<R>;
package/dist/index.js CHANGED
@@ -26,7 +26,7 @@ const y = {
26
26
  }),
27
27
  request: (t) => t
28
28
  };
29
- function R(t) {
29
+ function x(t) {
30
30
  const e = {};
31
31
  return Object.keys(y).forEach(
32
32
  (r) => {
@@ -40,14 +40,14 @@ function R(t) {
40
40
  request: t
41
41
  };
42
42
  }
43
- const q = /* @__PURE__ */ new Map(), z = (t, e = "default") => {
44
- q.set(e, R(t));
45
- }, f = (t = "default") => {
46
- const e = q.get(t);
43
+ const P = "default", f = /* @__PURE__ */ new Map(), N = (t, e = P) => {
44
+ f.set(e, x(t));
45
+ }, w = (t = P) => {
46
+ const e = f.get(t);
47
47
  if (!e) throw new Error(`Requestor实例 ${t} 未注册`);
48
48
  return e;
49
49
  };
50
- class x {
50
+ class E {
51
51
  // 是否存在
52
52
  has(e) {
53
53
  return !!localStorage.getItem(e);
@@ -82,7 +82,7 @@ class x {
82
82
  localStorage.clear();
83
83
  }
84
84
  }
85
- const M = new x(), T = /* @__PURE__ */ new Map(), v = (t) => t ? M : T, j = () => {
85
+ const T = new E(), M = /* @__PURE__ */ new Map(), v = (t) => t ? T : M, j = () => {
86
86
  const t = /* @__PURE__ */ new Map();
87
87
  return {
88
88
  getPromise: (o) => t.get(o),
@@ -96,51 +96,51 @@ const M = new x(), T = /* @__PURE__ */ new Map(), v = (t) => t ? M : T, j = () =
96
96
  t.clear();
97
97
  }
98
98
  };
99
- }, E = {
99
+ }, I = {
100
100
  key: (t) => t.url,
101
101
  persist: !1,
102
102
  cacheTime: 1 / 0
103
- }, P = (t, e) => ({
103
+ }, C = (t, e) => ({
104
104
  value: t,
105
105
  expiresAt: Date.now() + e
106
- }), I = (t) => Date.now() > t.expiresAt, w = (t = {}) => {
107
- const e = { ...E, ...t }, r = v(e.persist), { getPromise: s, setPromise: a, delPromise: o } = j(), i = {
106
+ }), O = (t) => Date.now() > t.expiresAt, R = (t = {}) => {
107
+ const e = { ...I, ...t }, r = v(e.persist), { getPromise: s, setPromise: a, delPromise: o } = j(), i = {
108
108
  get(d, c) {
109
109
  return (...l) => {
110
- const h = y[c](...l), n = e.key(h), g = s(n);
111
- if (g)
112
- return console.log(`===> 已存在该请求: ${n}`), g;
110
+ const h = y[c](...l), n = e.key(h), q = s(n);
111
+ if (q)
112
+ return console.log(`===> 已存在该请求: ${n}`), q;
113
113
  const p = r.get(n);
114
- if (p && !I(p))
114
+ if (p && !O(p))
115
115
  return p.value;
116
116
  {
117
- const C = Reflect.apply(d[c], d, l).then((u) => (typeof e.cacheTime == "number" ? r.set(n, P(u, e.cacheTime)) : r.set(
117
+ const g = Reflect.apply(d[c], d, l).then((u) => (typeof e.cacheTime == "number" ? r.set(n, C(u, e.cacheTime)) : r.set(
118
118
  n,
119
- P(
119
+ C(
120
120
  u,
121
121
  e.cacheTime({ config: h, response: u })
122
122
  )
123
123
  ), console.log("===>cache", "成功", n, u), u)).finally(() => {
124
124
  o(n);
125
125
  });
126
- return a(n, C), C;
126
+ return a(n, g), g;
127
127
  }
128
128
  };
129
129
  }
130
130
  };
131
- return new Proxy(f(), i);
132
- }, O = (t) => {
131
+ return new Proxy(w(), i);
132
+ }, k = (t) => {
133
133
  const { method: e, url: r, params: s, data: a } = t;
134
134
  return [e, r, JSON.stringify(s), JSON.stringify(a)].join("|");
135
- }, k = (t) => w({
136
- key: (e) => t ? t(e) : O(e),
135
+ }, A = (t) => R({
136
+ key: (e) => t ? t(e) : k(e),
137
137
  persist: !1
138
- }), J = {
138
+ }), D = {
139
139
  retries: 3,
140
140
  delay: 1e3,
141
141
  retryCondition: () => !0
142
- }, N = (t = {}) => {
143
- const { retries: e, delay: r, retryCondition: s } = { ...J, ...t }, a = {
142
+ }, J = (t = {}) => {
143
+ const { retries: e, delay: r, retryCondition: s } = { ...D, ...t }, a = {
144
144
  get(o, i) {
145
145
  return (...d) => {
146
146
  let c = 0;
@@ -158,14 +158,14 @@ const M = new x(), T = /* @__PURE__ */ new Map(), v = (t) => t ? M : T, j = () =
158
158
  };
159
159
  }
160
160
  };
161
- return new Proxy(f(), a);
162
- }, A = {
163
- createCacheRequestor: w,
164
- createIdempotencyRequestor: k,
165
- createRetryRequestor: N
161
+ return new Proxy(w(), a);
162
+ }, z = {
163
+ cacheRequestor: R,
164
+ idempotencyRequestor: A,
165
+ retryRequestor: J
166
166
  };
167
167
  export {
168
- A as extendRequestor,
169
- z as inject,
170
- f as useRequestor
168
+ N as inject,
169
+ z as requestExtender,
170
+ w as useRequestor
171
171
  };
@@ -1 +1 @@
1
- (function(a,i){typeof exports=="object"&&typeof module<"u"?i(exports):typeof define=="function"&&define.amd?define(["exports"],i):(a=typeof globalThis<"u"?globalThis:a||self,i(a["net-vert/core"]={}))})(this,function(a){"use strict";const i={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 w(t){const e={};return Object.keys(i).forEach(r=>{e[r]=(...o)=>{const c=i[r](...o);return t(c)}}),{...e,request:t}}const q=new Map,T=(t,e="default")=>{q.set(e,w(t))},y=(t="default")=>{const e=q.get(t);if(!e)throw new Error(`Requestor实例 ${t} 未注册`);return e};class j{has(e){return!!localStorage.getItem(e)}get(e){const r=localStorage.getItem(e);if(r)try{return JSON.parse(r)}catch(o){console.error("Error parsing cached data",o);return}}set(e,r){try{const o=JSON.stringify(r);localStorage.setItem(e,o)}catch(o){console.error("Error saving data to localStorage",o)}return r}delete(e){localStorage.removeItem(e)}clear(){localStorage.clear()}}const v=new j,x=new Map,M=t=>t?v:x,O=()=>{const t=new Map;return{getPromise:s=>t.get(s),setPromise:(s,l)=>{t.set(s,l)},delPromise:s=>{t.delete(s)},clearCache:()=>{t.clear()}}},E={key:t=>t.url,persist:!1,cacheTime:1/0},P=(t,e)=>({value:t,expiresAt:Date.now()+e}),I=t=>Date.now()>t.expiresAt,C=(t={})=>{const e={...E,...t},r=M(e.persist),{getPromise:o,setPromise:c,delPromise:s}=O(),l={get(m,u){return(...d)=>{const p=i[u](...d),n=e.key(p),S=o(n);if(S)return console.log(`===> 已存在该请求: ${n}`),S;const g=r.get(n);if(g&&!I(g))return g.value;{const R=Reflect.apply(m[u],m,d).then(h=>(typeof e.cacheTime=="number"?r.set(n,P(h,e.cacheTime)):r.set(n,P(h,e.cacheTime({config:p,response:h}))),console.log("===>cache","成功",n,h),h)).finally(()=>{s(n)});return c(n,R),R}}}};return new Proxy(y(),l)},b=t=>{const{method:e,url:r,params:o,data:c}=t;return[e,r,JSON.stringify(o),JSON.stringify(c)].join("|")},k=t=>C({key:e=>t?t(e):b(e),persist:!1}),J={retries:3,delay:1e3,retryCondition:()=>!0},N={createCacheRequestor:C,createIdempotencyRequestor:k,createRetryRequestor:(t={})=>{const{retries:e,delay:r,retryCondition:o}={...J,...t},c={get(s,l){return(...m)=>{let u=0;const f=()=>Reflect.apply(s[l],s,m).catch(d=>{if(u<e&&o(d)){u++;const p=typeof r=="function"?r(u):r;return new Promise(n=>{setTimeout(()=>n(f()),p)})}return Promise.reject(d)});return f()}}};return new Proxy(y(),c)}};a.extendRequestor=N,a.inject=T,a.useRequestor=y,Object.defineProperty(a,Symbol.toStringTag,{value:"Module"})});
1
+ (function(c,i){typeof exports=="object"&&typeof module<"u"?i(exports):typeof define=="function"&&define.amd?define(["exports"],i):(c=typeof globalThis<"u"?globalThis:c||self,i(c["net-vert/core"]={}))})(this,function(c){"use strict";const i={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 T(t){const e={};return Object.keys(i).forEach(r=>{e[r]=(...o)=>{const a=i[r](...o);return t(a)}}),{...e,request:t}}const g="default",P=new Map,j=(t,e=g)=>{P.set(e,T(t))},y=(t=g)=>{const e=P.get(t);if(!e)throw new Error(`Requestor实例 ${t} 未注册`);return e};class v{has(e){return!!localStorage.getItem(e)}get(e){const r=localStorage.getItem(e);if(r)try{return JSON.parse(r)}catch(o){console.error("Error parsing cached data",o);return}}set(e,r){try{const o=JSON.stringify(r);localStorage.setItem(e,o)}catch(o){console.error("Error saving data to localStorage",o)}return r}delete(e){localStorage.removeItem(e)}clear(){localStorage.clear()}}const x=new v,E=new Map,M=t=>t?x:E,O=()=>{const t=new Map;return{getPromise:s=>t.get(s),setPromise:(s,l)=>{t.set(s,l)},delPromise:s=>{t.delete(s)},clearCache:()=>{t.clear()}}},I={key:t=>t.url,persist:!1,cacheTime:1/0},C=(t,e)=>({value:t,expiresAt:Date.now()+e}),b=t=>Date.now()>t.expiresAt,R=(t={})=>{const e={...I,...t},r=M(e.persist),{getPromise:o,setPromise:a,delPromise:s}=O(),l={get(m,u){return(...d)=>{const p=i[u](...d),n=e.key(p),S=o(n);if(S)return console.log(`===> 已存在该请求: ${n}`),S;const q=r.get(n);if(q&&!b(q))return q.value;{const w=Reflect.apply(m[u],m,d).then(h=>(typeof e.cacheTime=="number"?r.set(n,C(h,e.cacheTime)):r.set(n,C(h,e.cacheTime({config:p,response:h}))),console.log("===>cache","成功",n,h),h)).finally(()=>{s(n)});return a(n,w),w}}}};return new Proxy(y(),l)},k=t=>{const{method:e,url:r,params:o,data:a}=t;return[e,r,JSON.stringify(o),JSON.stringify(a)].join("|")},A=t=>R({key:e=>t?t(e):k(e),persist:!1}),D={retries:3,delay:1e3,retryCondition:()=>!0},J={cacheRequestor:R,idempotencyRequestor:A,retryRequestor:(t={})=>{const{retries:e,delay:r,retryCondition:o}={...D,...t},a={get(s,l){return(...m)=>{let u=0;const f=()=>Reflect.apply(s[l],s,m).catch(d=>{if(u<e&&o(d)){u++;const p=typeof r=="function"?r(u):r;return new Promise(n=>{setTimeout(()=>n(f()),p)})}return Promise.reject(d)});return f()}}};return new Proxy(y(),a)}};c.inject=j,c.requestExtender=J,c.useRequestor=y,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@net-vert/core",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "description": "Dependency Inversion Network Library with Type-Safe Injection.",
5
5
  "main": "dist/index",
6
6
  "type": "module",