@net-vert/core 1.0.0 → 1.2.1

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/dist/index.d.ts CHANGED
@@ -1,67 +1,11 @@
1
+ import { AnyRecord } from 'store-vert';
2
+ import { EnhancedStore } from 'store-vert';
3
+ import { Key as Key_2 } from 'store-vert';
4
+ import { Store } from 'store-vert';
5
+ import { StoreFactory } from 'store-vert';
6
+ import { StoreKey } from 'store-vert';
1
7
  import { TaskQueue } from 'id-queue';
2
8
 
3
- declare type AnyRecord = Record<string | number | symbol, any>;
4
-
5
- declare type AnyRecord_2 = Record<string, any>;
6
-
7
- /**
8
- * 缓存存储基类
9
- * 提供针对缓存场景的快捷方法,自动处理 ExpirableValue 的封装和解封
10
- */
11
- declare abstract class BaseCacheStorage<K extends string | number | symbol, R> {
12
- abstract getItem(key: K): ExpirableValue<R> | undefined;
13
- abstract setItem(key: K, value: ExpirableValue<R>): ExpirableValue<R>;
14
- abstract removeItem(key: K): void;
15
- abstract clear(): void;
16
- abstract length(): number;
17
- abstract keys(): K[];
18
- abstract iterate(iteratee: (value: ExpirableValue<R>, key: K, iterationNumber: number) => void): void;
19
- /**
20
- * 获取缓存值(自动处理过期检查和解包)
21
- * @param key 缓存键
22
- * @returns 缓存的原始值,如果不存在或已过期返回 undefined
23
- */
24
- get(key: K): R | undefined;
25
- /**
26
- * 设置缓存值(自动包装为 ExpirableValue)
27
- * @param key 缓存键
28
- * @param value 要缓存的值
29
- * @param duration 有效期(毫秒),默认 24 小时
30
- */
31
- set(key: K, value: R, duration?: number): void;
32
- /**
33
- * 删除指定缓存(别名方法,等同于 removeItem)
34
- * @param key 缓存键
35
- */
36
- delete(key: K): void;
37
- /**
38
- * 检查缓存是否存在且未过期
39
- * @param key 缓存键
40
- */
41
- has(key: K): boolean;
42
- /**
43
- * 获取缓存数量(别名方法,等同于 length)
44
- */
45
- size(): number;
46
- /**
47
- * 遍历所有有效的缓存(自动跳过已过期的,并解包值)
48
- * @param callback 回调函数,接收解包后的值、键和索引
49
- */
50
- forEach(callback: (value: R, key: K, index: number) => void): void;
51
- /**
52
- * 清理所有过期的缓存
53
- * @returns 清理的缓存数量
54
- */
55
- clearExpired(): number;
56
- /**
57
- * 更新缓存的过期时间(不改变值)
58
- * @param key 缓存键
59
- * @param duration 新的有效期(毫秒)
60
- * @returns 是否更新成功
61
- */
62
- touch(key: K, duration: number): boolean;
63
- }
64
-
65
9
  export declare type BaseRequestor = (config: RequestConfig<any>) => any;
66
10
 
67
11
  /**
@@ -70,7 +14,7 @@ export declare type BaseRequestor = (config: RequestConfig<any>) => any;
70
14
  * - 自定义缓存 key 生成
71
15
  * - 自定义缓存有效期(固定时长或动态计算)
72
16
  * - 自定义缓存有效性校验
73
- * - 持久化存储(LocalStorage)或内存存储
17
+ * - 自定义存储介质
74
18
  */
75
19
  export declare const cache: <D = any, R = any>(options?: Partial<CacheOptions<D, R>>) => CacheMiddleware<D, R>;
76
20
 
@@ -78,7 +22,7 @@ export declare const cache: <D = any, R = any>(options?: Partial<CacheOptions<D,
78
22
  declare interface CacheCheckContext<D = any, R = any> {
79
23
  key: CacheKey;
80
24
  config: RequestConfig<D>;
81
- cachedData?: ExpirableValue<R>;
25
+ cachedData?: R;
82
26
  }
83
27
 
84
28
  /**
@@ -90,46 +34,16 @@ IdempotencyOptions<D>
90
34
  ]>;
91
35
 
92
36
  /** 缓存 key 类型 */
93
- declare type CacheKey = string | number | symbol;
37
+ export declare type CacheKey = string | number | symbol;
94
38
 
95
39
  /** 请求前上下文:生成缓存 key */
96
40
  declare interface CacheKeyContext<D = any> {
97
41
  config: RequestConfig<D>;
98
42
  }
99
43
 
100
- /**
101
- * 基于 LocalStorage 的缓存存储
102
- * 继承 LocalStorage 并扩展缓存快捷方法
103
- */
104
- declare class CacheLocalStorage<K extends string | number | symbol = string, R = any> extends LocalStorage<Record<K, ExpirableValue<R>>> implements BaseCacheStorage<K, R> {
105
- get: (key: any) => any;
106
- set: (key: any, value: any, duration?: number) => void;
107
- delete: (key: any) => void;
108
- has: (key: any) => boolean;
109
- size: () => number;
110
- forEach: (callback: (value: any, key: any, index: number) => void) => void;
111
- clearExpired: () => number;
112
- touch: (key: any, duration: number) => boolean;
113
- }
114
-
115
- /**
116
- * 基于内存的缓存存储
117
- * 继承 MemoryStorage 并扩展缓存快捷方法
118
- */
119
- declare class CacheMemoryStorage<K extends string | number | symbol = string, R = any> extends MemoryStorage<Record<K, ExpirableValue<R>>> implements BaseCacheStorage<K, R> {
120
- get: (key: any) => any;
121
- set: (key: any, value: any, duration?: number) => void;
122
- delete: (key: any) => void;
123
- has: (key: any) => boolean;
124
- size: () => number;
125
- forEach: (callback: (value: any, key: any, index: number) => void) => void;
126
- clearExpired: () => number;
127
- touch: (key: any, duration: number) => boolean;
128
- }
129
-
130
44
  /** 缓存中间件类型(带 storage 实例)*/
131
45
  declare type CacheMiddleware<D = any, R = any> = TypedMiddleware<MIDDLEWARE_TYPE.CACHE, false, D, R> & {
132
- storage: CacheStorage_2<CacheKey, R>;
46
+ storage: CacheStorageInstance<R>;
133
47
  };
134
48
 
135
49
  /** 缓存模块配置 */
@@ -151,21 +65,19 @@ declare interface CacheOptions<D = any, R = any> {
151
65
  * - 返回 boolean 或 Promise<boolean>
152
66
  */
153
67
  isValid: (ctx: CacheCheckContext<D, R>) => boolean | Promise<boolean>;
154
- /** 缓存介质, 待开发, 目前只支持内存和持久化 */
155
- persist: boolean;
68
+ /** 缓存介质 */
69
+ store: StoreDescriptor;
156
70
  }
157
71
 
158
- /**
159
- * CacheStorage 类型别名
160
- * 可以是 CacheMemoryStorage CacheLocalStorage
161
- */
162
- declare type CacheStorage_2<K extends string | number | symbol = string, R = any> = CacheMemoryStorage<K, R> | CacheLocalStorage<K, R>;
72
+ declare type CacheSchema<R> = Record<CacheKey, R>;
73
+
74
+ declare type CacheStorageInstance<R = any> = ExpirableCacheStorage<R> & EnhancedStore<ExpirableSchema<CacheSchema<R>>>;
163
75
 
164
76
  /** 请求后上下文:更新缓存 */
165
77
  declare interface CacheUpdateContext<D = any, R = any> {
166
78
  key: CacheKey;
167
79
  config: RequestConfig<D>;
168
- cachedData?: ExpirableValue<R>;
80
+ cachedData?: R;
169
81
  response: R;
170
82
  }
171
83
 
@@ -235,6 +147,38 @@ export declare interface CreateRequestorConfig<Extensions extends readonly Middl
235
147
  instanceKey?: Key;
236
148
  }
237
149
 
150
+ declare class ExpirableCacheStorage<R = any> {
151
+ store: EnhancedStore<ExpirableSchema<CacheSchema<R>>>;
152
+ constructor(store: StoreDescriptor);
153
+ /**
154
+ * 设置缓存(自动包装成 ExpirableValue)
155
+ * @param key 缓存 key
156
+ * @param value 要缓存的值
157
+ * @param duration 过期时长(毫秒),默认 24 小时
158
+ */
159
+ setCache(key: CacheKey, value: R, duration?: number): void;
160
+ /**
161
+ * 获取缓存值(检查过期,如果过期返回 undefined)
162
+ * @param key 缓存 key
163
+ * @returns 未过期返回值,已过期返回 undefined
164
+ */
165
+ getCache(key: CacheKey): Promise<R | undefined>;
166
+ /**
167
+ * 检查是否有有效的缓存(未过期)
168
+ * @param key 缓存 key
169
+ * @returns true 表示有有效缓存,false 表示无缓存或已过期
170
+ */
171
+ hasValidCache(key: CacheKey): Promise<boolean>;
172
+ }
173
+
174
+ /**
175
+ * 将 Schema 的所有值类型映射为 ExpirableValue 包装的版本
176
+ * 用于缓存存储的类型转换
177
+ */
178
+ export declare type ExpirableSchema<Schema extends AnyRecord> = {
179
+ [K in keyof Schema]: ExpirableValue<Schema[K]>;
180
+ };
181
+
238
182
  /**
239
183
  * 带过期时间的值类型(通用型)
240
184
  * 可用于缓存、幂等、同步等需要时间控制的场景
@@ -288,71 +232,10 @@ declare type IdempotentMiddleware<D = any, R = any> = TypedMiddleware<MIDDLEWARE
288
232
 
289
233
  export declare const inject: (requestor: BaseRequestor, instanceKey?: string) => void;
290
234
 
291
- /**
292
- * Storage 接口
293
- * 定义存储器的基本操作
294
- */
295
- export declare interface IStorage<Schema extends Record<string, any> = Record<string, any>> {
296
- /**
297
- * 获取存储项
298
- */
299
- getItem<K extends keyof Schema>(key: K): Schema[K] | undefined;
300
- /**
301
- * 设置存储项
302
- */
303
- setItem<K extends keyof Schema>(key: K, value: Schema[K]): Schema[K];
304
- /**
305
- * 删除存储项
306
- */
307
- removeItem<K extends keyof Schema>(key: K): void;
308
- /**
309
- * 清空所有存储项
310
- */
311
- clear(): void;
312
- /**
313
- * 获取存储项数量
314
- */
315
- length(): number;
316
- /**
317
- * 获取所有 key
318
- */
319
- keys(): (keyof Schema)[];
320
- /**
321
- * 遍历所有存储项
322
- */
323
- iterate(iteratee: <K extends keyof Schema>(value: Schema[K], key: K, iterationNumber: number) => void): void;
324
- }
325
-
326
235
  export declare type Key = string | symbol | number;
327
236
 
328
- /**
329
- * LocalStorage 存储类
330
- * 基于浏览器的 localStorage 实现
331
- */
332
- declare class LocalStorage<Schema extends AnyRecord_2 = AnyRecord_2> implements IStorage<Schema> {
333
- constructor();
334
- getItem<K extends keyof Schema>(key: K): Schema[K] | undefined;
335
- setItem<K extends keyof Schema>(key: K, value: Schema[K]): Schema[K];
336
- removeItem<K extends keyof Schema>(key: K): void;
337
- clear(): void;
338
- length(): number;
339
- keys(): (keyof Schema)[];
340
- iterate(iteratee: <K extends keyof Schema>(value: Schema[K], key: K, iterationNumber: number) => void): void;
341
- }
342
-
343
237
  export declare type MaybePromise<IsSync, R> = IsSync extends true ? R : IsSync extends false ? Promise<R> : R | Promise<R>;
344
238
 
345
- declare class MemoryStorage<Schema extends AnyRecord = AnyRecord> implements IStorage<Schema> {
346
- private store;
347
- getItem<K extends keyof Schema>(key: K): Schema[K] | undefined;
348
- setItem<K extends keyof Schema>(key: K, value: Schema[K]): Schema[K];
349
- removeItem<K extends keyof Schema>(key: K): void;
350
- clear(): void;
351
- length(): number;
352
- keys(): (keyof Schema)[];
353
- iterate(iteratee: <K extends keyof Schema>(value: Schema[K], key: K, iterationNumber: number) => void): void;
354
- }
355
-
356
239
  export declare type Middleware<IsSync extends boolean = false, D = any, R = any> = (context: {
357
240
  config: RequestConfig<D>;
358
241
  next: () => MaybePromise<IsSync, R>;
@@ -413,6 +296,11 @@ declare type RetryOptions<D = any> = {
413
296
 
414
297
  declare type SafeKey = string | number | symbol;
415
298
 
299
+ export declare type StoreDescriptor = StoreKey | {
300
+ key: Key_2;
301
+ factory: StoreFactory<Store<AnyRecord>, any[]>;
302
+ };
303
+
416
304
  /**
417
305
  * 缓存中有数据则直接返回。
418
306
  * suspense 为 true 时,会抛出一个 Promise(而不是普通错误),Promise resolve 后得到数据。
package/dist/index.js CHANGED
@@ -1,72 +1,69 @@
1
- var T = Object.defineProperty;
2
- var q = (r, e, t) => e in r ? T(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t;
3
- var c = (r, e, t) => q(r, typeof e != "symbol" ? e + "" : e, t);
4
- import { TaskQueue as O } from "id-queue";
5
- var y = /* @__PURE__ */ ((r) => (r.GET = "get", r.POST = "post", r.PUT = "put", r.DELETE = "delete", r))(y || {}), f = /* @__PURE__ */ ((r) => (r.CACHE = "cache", r.RETRY = "retry", r.IDEMPOTENT = "idempotent", r.CONCURRENT = "concurrent", r.SYNC = "sync", r))(f || {});
6
- const I = "default", N = {
1
+ import { TaskQueue as j } from "id-queue";
2
+ var f = /* @__PURE__ */ ((r) => (r.GET = "get", r.POST = "post", r.PUT = "put", r.DELETE = "delete", r))(f || {}), m = /* @__PURE__ */ ((r) => (r.CACHE = "cache", r.RETRY = "retry", r.IDEMPOTENT = "idempotent", r.CONCURRENT = "concurrent", r.SYNC = "sync", r))(m || {});
3
+ const S = "default", D = {
7
4
  retries: 3,
8
5
  delay: 0,
9
6
  retryCondition: () => !0
10
- }, V = (r) => {
11
- const e = { ...N, ...r };
12
- return Object.assign(async ({ config: s, next: n }) => {
7
+ }, F = (r) => {
8
+ const e = { ...D, ...r };
9
+ return Object.assign(async ({ config: n, next: s }) => {
13
10
  let o = 0, i;
14
11
  for (; o <= e.retries; )
15
12
  try {
16
- return await n();
13
+ return await s();
17
14
  } catch (a) {
18
15
  if (i = a, o === e.retries)
19
16
  throw a;
20
- const u = {
21
- config: s,
17
+ const c = {
18
+ config: n,
22
19
  lastResponse: a,
23
20
  attempt: o
24
21
  };
25
- if (!e.retryCondition(u))
22
+ if (!e.retryCondition(c))
26
23
  throw a;
27
24
  o++;
28
- const d = typeof e.delay == "function" ? e.delay(u) : e.delay;
29
- d > 0 && await new Promise((h) => setTimeout(h, d));
25
+ const u = typeof e.delay == "function" ? e.delay(c) : e.delay;
26
+ u > 0 && await new Promise((l) => setTimeout(l, u));
30
27
  }
31
28
  throw i;
32
- }, { __middlewareType: f.RETRY });
33
- }, j = () => {
29
+ }, { __middlewareType: m.RETRY });
30
+ }, $ = () => {
34
31
  const r = /* @__PURE__ */ new Map();
35
32
  return { getPromise: (o) => r.get(o), setPromise: (o, i) => {
36
33
  r.set(o, i), i.finally(() => r.delete(o));
37
34
  }, delPromise: (o) => r.delete(o), clearCache: () => r.clear() };
38
- }, K = (r) => {
39
- const { config: e } = r, { method: t, url: s, data: n } = e;
40
- return [t, s, JSON.stringify(n)].join("|");
41
- }, R = {
42
- key: K
43
- }, b = (r) => {
44
- const e = { ...R, ...r }, t = j();
45
- return Object.assign(({ config: n, next: o }) => {
46
- const i = e.key({ config: n }), a = t.getPromise(i);
35
+ }, E = (r) => {
36
+ const { config: e } = r, { method: t, url: n, data: s } = e;
37
+ return [t, n, JSON.stringify(s)].join("|");
38
+ }, T = {
39
+ key: E
40
+ }, q = (r) => {
41
+ const e = { ...T, ...r }, t = $();
42
+ return Object.assign(({ config: s, next: o }) => {
43
+ const i = e.key({ config: s }), a = t.getPromise(i);
47
44
  if (a)
48
45
  return a;
49
- const u = o();
50
- return t.setPromise(i, u), u;
46
+ const c = o();
47
+ return t.setPromise(i, c), c;
51
48
  }, {
52
- __middlewareType: f.IDEMPOTENT,
49
+ __middlewareType: m.IDEMPOTENT,
53
50
  promiseCache: t
54
51
  });
55
52
  };
56
- class z {
53
+ class R {
54
+ parallelCount;
55
+ tasks;
56
+ runningCount;
57
57
  constructor(e = 4) {
58
- c(this, "parallelCount");
59
- c(this, "tasks");
60
- c(this, "runningCount");
61
- this.parallelCount = e, this.tasks = new O(), this.runningCount = 0;
58
+ this.parallelCount = e, this.tasks = new j(), this.runningCount = 0;
62
59
  }
63
60
  // 加入
64
61
  add(e, t) {
65
- return new Promise((s, n) => {
62
+ return new Promise((n, s) => {
66
63
  this.tasks.enqueue(e, {
67
64
  task: t,
68
- resolve: s,
69
- reject: n
65
+ resolve: n,
66
+ reject: s
70
67
  }), this._run();
71
68
  });
72
69
  }
@@ -75,8 +72,8 @@ class z {
75
72
  this.tasks.remove(e);
76
73
  }
77
74
  execute(e) {
78
- const { task: t, resolve: s, reject: n } = e;
79
- return t().then(s).catch(n).finally(() => {
75
+ const { task: t, resolve: n, reject: s } = e;
76
+ return t().then(n).catch(s).finally(() => {
80
77
  this.runningCount--, this._run();
81
78
  });
82
79
  }
@@ -87,21 +84,27 @@ class z {
87
84
  }
88
85
  }
89
86
  }
90
- let _ = 0;
91
- const $ = {
87
+ let B = 0;
88
+ const _ = {
92
89
  parallelCount: 4,
93
- createId: () => _++
94
- }, J = (r) => {
95
- const { parallelCount: e, createId: t } = { ...$, ...r }, s = new z(e);
90
+ createId: () => B++
91
+ }, K = (r) => {
92
+ const { parallelCount: e, createId: t } = { ..._, ...r }, n = new R(e);
96
93
  return Object.assign(({ config: o, next: i }) => {
97
94
  const a = t({ config: o });
98
- return s.add(a, () => i());
99
- }, { __middlewareType: f.CONCURRENT, pool: s });
95
+ return n.add(a, () => i());
96
+ }, { __middlewareType: m.CONCURRENT, pool: n });
97
+ }, v = /* @__PURE__ */ new Map(), y = (r, e) => {
98
+ v.set(e, r);
100
99
  };
101
- class v {
102
- constructor() {
103
- c(this, "store", /* @__PURE__ */ new Map());
104
- }
100
+ function A(r) {
101
+ const e = v.get(r);
102
+ if (!e)
103
+ throw new Error(`Store实例 ${String(r)} 未注册`);
104
+ return e;
105
+ }
106
+ class J {
107
+ store = /* @__PURE__ */ new Map();
105
108
  getItem(e) {
106
109
  return this.store.get(e);
107
110
  }
@@ -117,353 +120,574 @@ class v {
117
120
  length() {
118
121
  return this.store.size;
119
122
  }
123
+ key(e) {
124
+ return Array.from(this.store.keys())[e];
125
+ }
120
126
  keys() {
121
127
  return Array.from(this.store.keys());
122
128
  }
123
129
  iterate(e) {
124
130
  let t = 0;
125
- for (const [s, n] of this.store.entries())
126
- e(n, s, t), t++;
131
+ for (const [n, s] of this.store.entries())
132
+ e(s, n, t), t++;
127
133
  }
128
134
  }
129
- const p = typeof window < "u" ? window.localStorage : {};
130
- class k {
135
+ const z = (r) => !!r && (typeof r == "object" || typeof r == "function") && typeof r.then == "function", b = (r) => typeof window < "u" ? r() : {
136
+ getItem() {
137
+ return null;
138
+ },
139
+ setItem() {
140
+ },
141
+ removeItem() {
142
+ },
143
+ clear() {
144
+ },
145
+ key() {
146
+ return null;
147
+ },
148
+ get length() {
149
+ return 0;
150
+ }
151
+ }, h = b(() => window.localStorage);
152
+ class G {
131
153
  constructor() {
132
154
  }
133
155
  getItem(e) {
134
- const t = String(e), s = p.getItem(t);
135
- if (s !== null)
156
+ const t = String(e), n = h.getItem(t);
157
+ if (n !== null)
136
158
  try {
137
- return JSON.parse(s);
138
- } catch (n) {
139
- console.error(`Failed to parse value for key: ${t}`, n);
159
+ return JSON.parse(n);
160
+ } catch (s) {
161
+ console.error(`Failed to parse value for key: ${t}`, s);
140
162
  return;
141
163
  }
142
164
  }
143
165
  setItem(e, t) {
144
- const s = String(e);
166
+ const n = String(e);
145
167
  try {
146
- p.setItem(s, JSON.stringify(t));
147
- } catch (n) {
148
- throw console.error(`Failed to set value for key: ${s}`, n), n;
168
+ h.setItem(n, JSON.stringify(t));
169
+ } catch (s) {
170
+ throw console.error(`Failed to set value for key: ${n}`, s), s;
149
171
  }
150
172
  return t;
151
173
  }
152
174
  removeItem(e) {
153
175
  const t = String(e);
154
- p.removeItem(t);
176
+ h.removeItem(t);
155
177
  }
156
178
  clear() {
157
- p.clear();
179
+ h.clear();
158
180
  }
159
181
  length() {
160
- return p.length;
182
+ return h.length;
183
+ }
184
+ key(e) {
185
+ return h.key(e);
161
186
  }
162
187
  keys() {
163
188
  const e = [];
164
- for (let t = 0; t < p.length; t++) {
165
- const s = p.key(t);
166
- s && e.push(s);
189
+ for (let t = 0; t < h.length; t++) {
190
+ const n = h.key(t);
191
+ n && e.push(n);
167
192
  }
168
193
  return e;
169
194
  }
170
195
  iterate(e) {
171
- this.keys().forEach((s, n) => {
172
- const o = this.getItem(s);
173
- o !== void 0 && e(o, s, n);
196
+ this.keys().forEach((t, n) => {
197
+ const s = this.getItem(t);
198
+ s !== void 0 && e(s, t, n);
174
199
  });
175
200
  }
176
201
  }
177
- function w(r, e) {
202
+ const d = b(() => window.sessionStorage);
203
+ class U {
204
+ constructor() {
205
+ }
206
+ getItem(e) {
207
+ const t = String(e), n = d.getItem(t);
208
+ if (n !== null)
209
+ try {
210
+ return JSON.parse(n);
211
+ } catch (s) {
212
+ console.error(`Failed to parse value for key: ${t}`, s);
213
+ return;
214
+ }
215
+ }
216
+ setItem(e, t) {
217
+ const n = String(e);
218
+ try {
219
+ d.setItem(n, JSON.stringify(t));
220
+ } catch (s) {
221
+ throw console.error(`Failed to set value for key: ${n}`, s), s;
222
+ }
223
+ return t;
224
+ }
225
+ removeItem(e) {
226
+ const t = String(e);
227
+ d.removeItem(t);
228
+ }
229
+ clear() {
230
+ d.clear();
231
+ }
232
+ length() {
233
+ return d.length;
234
+ }
235
+ key(e) {
236
+ return d.key(e);
237
+ }
238
+ keys() {
239
+ const e = [];
240
+ for (let t = 0; t < d.length; t++) {
241
+ const n = d.key(t);
242
+ n && e.push(n);
243
+ }
244
+ return e;
245
+ }
246
+ iterate(e) {
247
+ this.keys().forEach((t, n) => {
248
+ const s = this.getItem(t);
249
+ s !== void 0 && e(s, t, n);
250
+ });
251
+ }
252
+ }
253
+ class Y {
254
+ dbName;
255
+ storeName;
256
+ dbPromise = null;
257
+ DB_VERSION = 1;
258
+ constructor(e, t) {
259
+ this.dbName = e, this.storeName = t, this.initDB();
260
+ }
261
+ /**
262
+ * 初始化数据库连接
263
+ */
264
+ initDB() {
265
+ if (typeof window > "u" || !window.indexedDB) {
266
+ console.warn("IndexedDB is not available");
267
+ return;
268
+ }
269
+ this.dbPromise = new Promise((e, t) => {
270
+ const n = indexedDB.open(this.dbName, this.DB_VERSION);
271
+ n.onerror = () => {
272
+ t(new Error(`Failed to open database: ${this.dbName}`));
273
+ }, n.onsuccess = () => {
274
+ e(n.result);
275
+ }, n.onupgradeneeded = (s) => {
276
+ const o = s.target.result;
277
+ o.objectStoreNames.contains(this.storeName) || o.createObjectStore(this.storeName);
278
+ };
279
+ });
280
+ }
281
+ /**
282
+ * 获取数据库实例
283
+ */
284
+ async getDB() {
285
+ if (!this.dbPromise)
286
+ throw new Error("IndexedDB is not initialized");
287
+ return this.dbPromise;
288
+ }
289
+ /**
290
+ * 执行事务
291
+ */
292
+ async withStore(e, t) {
293
+ const n = await this.getDB();
294
+ return new Promise((s, o) => {
295
+ const i = n.transaction([this.storeName], e).objectStore(this.storeName), a = t(i);
296
+ a.onsuccess = () => {
297
+ s(a.result);
298
+ }, a.onerror = () => {
299
+ o(a.error);
300
+ };
301
+ });
302
+ }
303
+ async getItem(e) {
304
+ try {
305
+ const t = await this.withStore("readonly", (n) => n.get(String(e)));
306
+ return t === void 0 ? void 0 : t;
307
+ } catch (t) {
308
+ console.error(`Failed to get value for key: ${String(e)}`, t);
309
+ return;
310
+ }
311
+ }
312
+ async setItem(e, t) {
313
+ try {
314
+ return await this.withStore("readwrite", (n) => n.put(t, String(e))), t;
315
+ } catch (n) {
316
+ throw console.error(`Failed to set value for key: ${String(e)}`, n), n;
317
+ }
318
+ }
319
+ async removeItem(e) {
320
+ try {
321
+ await this.withStore("readwrite", (t) => t.delete(String(e)));
322
+ } catch (t) {
323
+ throw console.error(`Failed to remove value for key: ${String(e)}`, t), t;
324
+ }
325
+ }
326
+ async clear() {
327
+ try {
328
+ await this.withStore("readwrite", (e) => e.clear());
329
+ } catch (e) {
330
+ throw console.error("Failed to clear storage", e), e;
331
+ }
332
+ }
333
+ async length() {
334
+ try {
335
+ return await this.withStore("readonly", (e) => e.count());
336
+ } catch (e) {
337
+ return console.error("Failed to get storage length", e), 0;
338
+ }
339
+ }
340
+ async key(e) {
341
+ try {
342
+ return (await this.withStore("readonly", (t) => t.getAllKeys()))[e];
343
+ } catch (t) {
344
+ console.error("Failed to get key", t);
345
+ return;
346
+ }
347
+ }
348
+ async keys() {
349
+ try {
350
+ return await this.withStore("readonly", (e) => e.getAllKeys());
351
+ } catch (e) {
352
+ return console.error("Failed to get all keys", e), [];
353
+ }
354
+ }
355
+ async iterate(e) {
356
+ try {
357
+ const t = (await this.getDB()).transaction([this.storeName], "readonly").objectStore(this.storeName).openCursor();
358
+ return new Promise((n, s) => {
359
+ let o = 0;
360
+ t.onsuccess = (i) => {
361
+ const a = i.target.result;
362
+ if (a) {
363
+ const c = a.key, u = a.value;
364
+ e(u, c, o), o++, a.continue();
365
+ } else
366
+ n();
367
+ }, t.onerror = () => {
368
+ s(t.error);
369
+ };
370
+ });
371
+ } catch (t) {
372
+ console.error("Failed to iterate storage", t);
373
+ }
374
+ }
375
+ }
376
+ const g = {
377
+ memory: "memory",
378
+ local: "local",
379
+ session: "session",
380
+ indexeddb: "indexeddb"
381
+ };
382
+ function N(r, e) {
383
+ Object.assign(r, e);
384
+ }
385
+ function M(r) {
386
+ return N(r, {
387
+ async getItemOrDefault(e, t) {
388
+ const n = await this.getItem(e);
389
+ return n !== null ? n : t;
390
+ },
391
+ async hasItem(e) {
392
+ return await this.getItem(e) !== null;
393
+ },
394
+ async removeItems(e) {
395
+ await Promise.all(e.map((t) => this.removeItem(t)));
396
+ },
397
+ async getItems(e) {
398
+ return await Promise.all(e.map((t) => this.getItem(t)));
399
+ }
400
+ }), r;
401
+ }
402
+ function X(r) {
403
+ return N(r, {
404
+ getItemOrDefault(e, t) {
405
+ const n = this.getItem(e);
406
+ return n !== null ? n : t;
407
+ },
408
+ hasItem(e) {
409
+ return this.getItem(e) !== null;
410
+ },
411
+ removeItems(e) {
412
+ e.forEach((t) => this.removeItem(t));
413
+ },
414
+ getItems(e) {
415
+ return e.map((t) => this.getItem(t));
416
+ }
417
+ }), r;
418
+ }
419
+ function Z(r) {
420
+ const e = r.getItem("");
421
+ return z(e) ? M(r) : X(r);
422
+ }
423
+ function w(r, ...e) {
424
+ const t = A(r);
425
+ let n;
426
+ try {
427
+ n = new t(...e);
428
+ } catch {
429
+ n = t(...e);
430
+ }
431
+ return Z(n);
432
+ }
433
+ y(J, g.memory);
434
+ y(G, g.local);
435
+ y(U, g.session);
436
+ y(Y, g.indexeddb);
437
+ function C(r, e) {
178
438
  return {
179
439
  value: r,
180
440
  expireAt: Date.now() + e
181
441
  };
182
442
  }
183
- function m(r, e = Date.now()) {
443
+ function I(r, e = Date.now()) {
184
444
  return r.expireAt <= e;
185
445
  }
186
- function g(r) {
187
- return r.value;
446
+ function x(r, e = Date.now()) {
447
+ return I(r, e) ? void 0 : r.value;
188
448
  }
189
- const A = (r) => {
190
- const { config: e } = r, { method: t, url: s, data: n } = e;
191
- return [t, s, JSON.stringify(n)].join("|");
192
- }, F = () => !0, x = 24 * 60 * 60 * 1e3, G = {
193
- key: A,
194
- duration: x,
195
- isValid: F,
196
- persist: !1
449
+ const H = (r) => {
450
+ const { config: e } = r, { method: t, url: n, data: s } = e;
451
+ return [t, n, JSON.stringify(s)].join("|");
452
+ }, L = () => !0, k = 24 * 60 * 60 * 1e3, Q = {
453
+ key: H,
454
+ duration: k,
455
+ isValid: L,
456
+ store: g.memory
197
457
  // 默认不持久化,使用内存存储
198
458
  };
199
- class l {
200
- // ============ 扩展方法(自动处理过期和封装)============
201
- /**
202
- * 获取缓存值(自动处理过期检查和解包)
203
- * @param key 缓存键
204
- * @returns 缓存的原始值,如果不存在或已过期返回 undefined
205
- */
206
- get(e) {
207
- const t = this.getItem(e);
208
- if (t) {
209
- if (m(t)) {
210
- this.removeItem(e);
211
- return;
459
+ let W = class {
460
+ store;
461
+ constructor(e) {
462
+ return typeof e == "string" ? this.store = w(e) : (y(e.factory, e.key), this.store = w(e.key)), new Proxy(this, {
463
+ get(t, n) {
464
+ if (n in t)
465
+ return t[n];
466
+ const s = t.store[n];
467
+ return typeof s == "function" ? s.bind(t.store) : s;
212
468
  }
213
- return g(t);
214
- }
469
+ });
215
470
  }
216
471
  /**
217
- * 设置缓存值(自动包装为 ExpirableValue)
218
- * @param key 缓存键
472
+ * 设置缓存(自动包装成 ExpirableValue)
473
+ * @param key 缓存 key
219
474
  * @param value 要缓存的值
220
- * @param duration 有效期(毫秒),默认 24 小时
475
+ * @param duration 过期时长(毫秒),默认 24 小时
221
476
  */
222
- set(e, t, s = x) {
223
- const n = w(t, s);
224
- this.setItem(e, n);
477
+ setCache(e, t, n = k) {
478
+ const s = C(t, n);
479
+ this.store.setItem(e, s);
225
480
  }
226
481
  /**
227
- * 删除指定缓存(别名方法,等同于 removeItem
228
- * @param key 缓存键
482
+ * 获取缓存值(检查过期,如果过期返回 undefined
483
+ * @param key 缓存 key
484
+ * @returns 未过期返回值,已过期返回 undefined
229
485
  */
230
- delete(e) {
231
- this.removeItem(e);
486
+ async getCache(e) {
487
+ const t = await this.store.getItem(e);
488
+ if (t)
489
+ return x(t);
232
490
  }
233
491
  /**
234
- * 检查缓存是否存在且未过期
235
- * @param key 缓存键
492
+ * 检查是否有有效的缓存(未过期)
493
+ * @param key 缓存 key
494
+ * @returns true 表示有有效缓存,false 表示无缓存或已过期
236
495
  */
237
- has(e) {
238
- const t = this.getItem(e);
239
- return t ? m(t) ? (this.removeItem(e), !1) : !0 : !1;
496
+ async hasValidCache(e) {
497
+ const t = await this.store.getItem(e);
498
+ return t ? !I(t) : !1;
240
499
  }
241
- /**
242
- * 获取缓存数量(别名方法,等同于 length)
243
- */
244
- size() {
245
- return this.length();
246
- }
247
- /**
248
- * 遍历所有有效的缓存(自动跳过已过期的,并解包值)
249
- * @param callback 回调函数,接收解包后的值、键和索引
250
- */
251
- forEach(e) {
252
- let t = 0;
253
- this.iterate((s, n, o) => {
254
- if (m(s))
255
- this.removeItem(n);
256
- else {
257
- const i = g(s);
258
- e(i, n, t), t++;
500
+ };
501
+ const ee = W, te = (r) => {
502
+ const e = { ...Q, ...r }, t = new ee(e.store), n = (o) => typeof e.duration == "function" ? e.duration(o) : e.duration;
503
+ return Object.assign(async ({ config: o, next: i }) => {
504
+ const a = e.key({ config: o }), c = await t.getCache(a);
505
+ if (c) {
506
+ if (await e.isValid({
507
+ key: a,
508
+ config: o,
509
+ cachedData: c
510
+ })) return c;
511
+ t.removeItem(a);
512
+ }
513
+ const u = await i(), l = n({ key: a, config: o, cachedData: c, response: u }), p = C(u, l);
514
+ return t.setItem(a, p), u;
515
+ }, {
516
+ __middlewareType: m.CACHE,
517
+ storage: t
518
+ });
519
+ };
520
+ class re {
521
+ store;
522
+ constructor(e) {
523
+ return typeof e == "string" ? this.store = w(e) : (y(e.factory, e.key), this.store = w(e.key)), new Proxy(this, {
524
+ get(t, n) {
525
+ if (n in t)
526
+ return t[n];
527
+ const s = t.store[n];
528
+ return typeof s == "function" ? s.bind(t.store) : s;
259
529
  }
260
530
  });
261
531
  }
262
532
  /**
263
- * 清理所有过期的缓存
264
- * @returns 清理的缓存数量
533
+ * 设置缓存(自动包装成 ExpirableValue)
534
+ * @param key 缓存 key
535
+ * @param value 要缓存的值
536
+ * @param duration 过期时长(毫秒),默认 24 小时
265
537
  */
266
- clearExpired() {
267
- let e = 0;
268
- return this.keys().forEach((s) => {
269
- const n = this.getItem(s);
270
- n && m(n) && (this.removeItem(s), e++);
271
- }), e;
538
+ setCache(e, t, n = k) {
539
+ const s = C(t, n);
540
+ this.store.setItem(e, s);
272
541
  }
273
542
  /**
274
- * 更新缓存的过期时间(不改变值)
275
- * @param key 缓存键
276
- * @param duration 新的有效期(毫秒)
277
- * @returns 是否更新成功
543
+ * 获取缓存值(检查过期,如果过期返回 undefined)
544
+ * @param key 缓存 key
545
+ * @returns 未过期返回值,已过期返回 undefined
278
546
  */
279
- touch(e, t) {
280
- const s = this.getItem(e);
281
- if (!s) return !1;
282
- if (m(s))
283
- return this.removeItem(e), !1;
284
- const n = g(s);
285
- return this.set(e, n, t), !0;
286
- }
287
- }
288
- class D extends v {
289
- constructor() {
290
- super(...arguments);
291
- // 继承 MemoryStorage 的所有方法:getItem, setItem, removeItem, clear, length, keys, iterate
292
- // 从 BaseCacheStorage 继承扩展方法
293
- c(this, "get", l.prototype.get);
294
- c(this, "set", l.prototype.set);
295
- c(this, "delete", l.prototype.delete);
296
- c(this, "has", l.prototype.has);
297
- c(this, "size", l.prototype.size);
298
- c(this, "forEach", l.prototype.forEach);
299
- c(this, "clearExpired", l.prototype.clearExpired);
300
- c(this, "touch", l.prototype.touch);
547
+ getCache(e) {
548
+ const t = this.store.getItem(e);
549
+ if (t)
550
+ return x(t);
301
551
  }
302
- }
303
- class U extends k {
304
- constructor() {
305
- super(...arguments);
306
- // 继承 LocalStorage 的所有方法:getItem, setItem, removeItem, clear, length, keys, iterate
307
- // 从 BaseCacheStorage 继承扩展方法
308
- c(this, "get", l.prototype.get);
309
- c(this, "set", l.prototype.set);
310
- c(this, "delete", l.prototype.delete);
311
- c(this, "has", l.prototype.has);
312
- c(this, "size", l.prototype.size);
313
- c(this, "forEach", l.prototype.forEach);
314
- c(this, "clearExpired", l.prototype.clearExpired);
315
- c(this, "touch", l.prototype.touch);
552
+ /**
553
+ * 检查是否有有效的缓存(未过期)
554
+ * @param key 缓存 key
555
+ * @returns true 表示有有效缓存,false 表示无缓存或已过期
556
+ */
557
+ hasValidCache(e) {
558
+ const t = this.store.getItem(e);
559
+ return t ? !I(t) : !1;
316
560
  }
317
561
  }
318
- const B = (r) => {
319
- const e = { ...G, ...r }, t = e.persist ? new U() : new D(), s = (o) => typeof e.duration == "function" ? e.duration(o) : e.duration;
320
- return Object.assign(async ({ config: o, next: i }) => {
321
- const a = e.key({ config: o }), u = t.getItem(a);
322
- if (u) {
323
- if (!m(u) && await e.isValid({
324
- key: a,
325
- config: o,
326
- cachedData: u
327
- }))
328
- return g(u);
329
- t.removeItem(a);
330
- }
331
- const d = await i(), h = s({ key: a, config: o, cachedData: u, response: d }), C = w(d, h);
332
- return t.setItem(a, C), d;
333
- }, {
334
- __middlewareType: f.CACHE,
335
- storage: t
336
- });
337
- }, L = (r) => {
338
- const { config: e } = r, { method: t, url: s } = e;
339
- return [t, s].join("|");
340
- }, M = {
562
+ const ne = re, se = (r) => {
563
+ const { config: e } = r, { method: t, url: n } = e;
564
+ return [t, n].join("|");
565
+ }, oe = {
341
566
  suspense: !0,
342
- key: L,
567
+ key: se,
343
568
  duration: 24 * 60 * 60 * 1e3,
344
569
  isValid: () => !0,
345
- persist: !1
570
+ store: g.memory
346
571
  };
347
- function te(r) {
348
- const e = { ...M, ...r }, t = e.persist ? new k() : new v(), s = (o) => typeof e.duration == "function" ? e.duration(o) : e.duration;
572
+ function me(r) {
573
+ const e = { ...oe, ...r }, t = new ne(e.store), n = (o) => typeof e.duration == "function" ? e.duration(o) : e.duration;
349
574
  return Object.assign(({ config: o, next: i }) => {
350
- const a = e.key({ config: o }), u = t.getItem(a);
351
- if (u) {
352
- if (!m(u) && e.isValid({
575
+ const a = e.key({ config: o }), c = t.getCache(a);
576
+ if (c) {
577
+ if (e.isValid({
353
578
  key: a,
354
579
  config: o,
355
- cachedData: u
356
- }))
357
- return g(u);
580
+ cachedData: c
581
+ })) return c;
358
582
  t.removeItem(a);
359
583
  }
360
584
  if (e.suspense)
361
- throw (e.wrapSuspense ? e.wrapSuspense({ key: a, config: o, p: i() }) : i()).then((h) => {
362
- const C = s({ key: a, config: o, cachedData: u, response: h });
363
- return t.setItem(a, w(h, C)), h;
585
+ throw (e.wrapSuspense ? e.wrapSuspense({ key: a, config: o, p: i() }) : i()).then((l) => {
586
+ const p = n({ key: a, config: o, cachedData: c, response: l });
587
+ return t.setCache(a, l, p), l;
364
588
  });
365
- return i().then((d) => {
366
- const h = s({ key: a, config: o, cachedData: u, response: d });
367
- return t.setItem(a, w(d, h)), d;
589
+ return i().then((u) => {
590
+ const l = n({ key: a, config: o, cachedData: c, response: u });
591
+ return t.setCache(a, u, l), u;
368
592
  });
369
- }, { __middlewareType: f.SYNC });
593
+ }, { __middlewareType: m.SYNC });
370
594
  }
371
- const S = /* @__PURE__ */ new Map(), re = (r, e = I) => {
372
- S.set(e, r);
373
- }, Y = (r = I) => {
374
- const e = S.get(r);
595
+ const P = /* @__PURE__ */ new Map(), ye = (r, e = S) => {
596
+ P.set(e, r);
597
+ }, ae = (r = S) => {
598
+ const e = P.get(r);
375
599
  if (!e) throw new Error(`Requestor实例 ${String(r)} 未注册`);
376
600
  return e;
377
- }, E = {
601
+ }, V = {
378
602
  get: (r, e) => ({
379
603
  url: r,
380
- method: y.GET,
604
+ method: f.GET,
381
605
  ...e,
382
- params: e == null ? void 0 : e.params
606
+ params: e?.params
383
607
  }),
384
608
  post: (r, e, t) => ({
385
609
  url: r,
386
- method: y.POST,
610
+ method: f.POST,
387
611
  data: e,
388
612
  ...t
389
613
  }),
390
614
  delete: (r, e) => ({
391
615
  url: r,
392
- method: y.DELETE,
616
+ method: f.DELETE,
393
617
  ...e
394
618
  }),
395
619
  put: (r, e, t) => ({
396
620
  url: r,
397
- method: y.PUT,
621
+ method: f.PUT,
398
622
  data: e,
399
623
  ...t
400
624
  }),
401
625
  request: (r) => r
402
- }, X = Object.keys(E);
403
- function Z(r, e, t) {
404
- const s = {}, n = (o) => {
626
+ }, ie = Object.keys(V);
627
+ function ce(r, e, t) {
628
+ const n = {}, s = (o) => {
405
629
  if (o === e.length)
406
630
  return t(r);
407
631
  const i = e[o];
408
632
  return i({
409
633
  config: r,
410
- ctx: s,
411
- next: () => n(o + 1)
634
+ ctx: n,
635
+ next: () => s(o + 1)
412
636
  });
413
637
  };
414
- return n(0);
638
+ return s(0);
415
639
  }
416
- function H(r, e) {
417
- const t = {}, s = e ?? [];
418
- return X.forEach(
419
- (n) => {
420
- t[n] = (...o) => {
421
- const i = E[n](...o);
422
- return Z(
640
+ function ue(r, e) {
641
+ const t = {}, n = e ?? [];
642
+ return ie.forEach(
643
+ (s) => {
644
+ t[s] = (...o) => {
645
+ const i = V[s](...o);
646
+ return ce(
423
647
  i,
424
- s,
648
+ n,
425
649
  r
426
650
  );
427
651
  };
428
652
  }
429
653
  ), t;
430
654
  }
431
- function P(r) {
432
- const { extensions: e, instanceKey: t } = r ?? {}, s = Y(t);
433
- return H(
434
- s,
655
+ function O(r) {
656
+ const { extensions: e, instanceKey: t } = r ?? {}, n = ae(t);
657
+ return ue(
658
+ n,
435
659
  e
436
660
  );
437
661
  }
438
- function se(r) {
439
- const { instanceKey: e, key: t, duration: s, isValid: n, persist: o, ...i } = r;
440
- return P({
662
+ function ge(r) {
663
+ const { instanceKey: e, key: t, duration: n, isValid: s, store: o, ...i } = r;
664
+ return O({
441
665
  instanceKey: e,
442
666
  extensions: [
443
- b(i),
444
- B({ key: t, duration: s, isValid: n, persist: o })
667
+ q(i),
668
+ te({ key: t, duration: n, isValid: s, store: o })
445
669
  ]
446
670
  });
447
671
  }
448
- function ne(r) {
449
- const { instanceKey: e, parallelCount: t, createId: s, retries: n, delay: o, retryCondition: i } = r;
450
- return P({
672
+ function fe(r) {
673
+ const { instanceKey: e, parallelCount: t, createId: n, retries: s, delay: o, retryCondition: i } = r;
674
+ return O({
451
675
  instanceKey: e,
452
676
  extensions: [
453
- J({ parallelCount: t, createId: s }),
454
- V({ retries: n, delay: o, retryCondition: i })
677
+ K({ parallelCount: t, createId: n }),
678
+ F({ retries: s, delay: o, retryCondition: i })
455
679
  ]
456
680
  });
457
681
  }
458
682
  export {
459
- B as cache,
460
- J as concurrent,
461
- se as createCachedIdempotentRequestor,
462
- ne as createConcurrentRetryRequestor,
463
- P as createRequestor,
464
- b as idempotent,
465
- re as inject,
466
- V as retry,
467
- te as sync,
468
- Y as useRequestor
683
+ te as cache,
684
+ K as concurrent,
685
+ ge as createCachedIdempotentRequestor,
686
+ fe as createConcurrentRetryRequestor,
687
+ O as createRequestor,
688
+ q as idempotent,
689
+ ye as inject,
690
+ F as retry,
691
+ me as sync,
692
+ ae as useRequestor
469
693
  };
@@ -1 +1 @@
1
- (function(c,h){typeof exports=="object"&&typeof module<"u"?h(exports,require("id-queue")):typeof define=="function"&&define.amd?define(["exports","id-queue"],h):(c=typeof globalThis<"u"?globalThis:c||self,h(c.netVertCore={},c.idQueue))})(this,function(c,h){"use strict";var W=Object.defineProperty;var ee=(c,h,p)=>h in c?W(c,h,{enumerable:!0,configurable:!0,writable:!0,value:p}):c[h]=p;var u=(c,h,p)=>ee(c,typeof h!="symbol"?h+"":h,p);var p=(r=>(r.GET="get",r.POST="post",r.PUT="put",r.DELETE="delete",r))(p||{}),w=(r=>(r.CACHE="cache",r.RETRY="retry",r.IDEMPOTENT="idempotent",r.CONCURRENT="concurrent",r.SYNC="sync",r))(w||{});const q="default",N={retries:3,delay:0,retryCondition:()=>!0},S=r=>{const e={...N,...r};return Object.assign(async({config:s,next:n})=>{let o=0,i;for(;o<=e.retries;)try{return await n()}catch(a){if(i=a,o===e.retries)throw a;const l={config:s,lastResponse:a,attempt:o};if(!e.retryCondition(l))throw a;o++;const m=typeof e.delay=="function"?e.delay(l):e.delay;m>0&&await new Promise(f=>setTimeout(f,m))}throw i},{__middlewareType:w.RETRY})},b=()=>{const r=new Map;return{getPromise:o=>r.get(o),setPromise:(o,i)=>{r.set(o,i),i.finally(()=>r.delete(o))},delPromise:o=>r.delete(o),clearCache:()=>r.clear()}},z={key:r=>{const{config:e}=r,{method:t,url:s,data:n}=e;return[t,s,JSON.stringify(n)].join("|")}},T=r=>{const e={...z,...r},t=b();return Object.assign(({config:n,next:o})=>{const i=e.key({config:n}),a=t.getPromise(i);if(a)return a;const l=o();return t.setPromise(i,l),l},{__middlewareType:w.IDEMPOTENT,promiseCache:t})};class _{constructor(e=4){u(this,"parallelCount");u(this,"tasks");u(this,"runningCount");this.parallelCount=e,this.tasks=new h.TaskQueue,this.runningCount=0}add(e,t){return new Promise((s,n)=>{this.tasks.enqueue(e,{task:t,resolve:s,reject:n}),this._run()})}remove(e){this.tasks.remove(e)}execute(e){const{task:t,resolve:s,reject:n}=e;return t().then(s).catch(n).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)}}}let $=0;const J={parallelCount:4,createId:()=>$++},R=r=>{const{parallelCount:e,createId:t}={...J,...r},s=new _(e);return Object.assign(({config:o,next:i})=>{const a=t({config:o});return s.add(a,()=>i())},{__middlewareType:w.CONCURRENT,pool:s})};class E{constructor(){u(this,"store",new Map)}getItem(e){return this.store.get(e)}setItem(e,t){return this.store.set(e,t),t}removeItem(e){this.store.delete(e)}clear(){this.store.clear()}length(){return this.store.size}keys(){return Array.from(this.store.keys())}iterate(e){let t=0;for(const[s,n]of this.store.entries())e(n,s,t),t++}}const y=typeof window<"u"?window.localStorage:{};class P{constructor(){}getItem(e){const t=String(e),s=y.getItem(t);if(s!==null)try{return JSON.parse(s)}catch(n){console.error(`Failed to parse value for key: ${t}`,n);return}}setItem(e,t){const s=String(e);try{y.setItem(s,JSON.stringify(t))}catch(n){throw console.error(`Failed to set value for key: ${s}`,n),n}return t}removeItem(e){const t=String(e);y.removeItem(t)}clear(){y.clear()}length(){return y.length}keys(){const e=[];for(let t=0;t<y.length;t++){const s=y.key(t);s&&e.push(s)}return e}iterate(e){this.keys().forEach((s,n)=>{const o=this.getItem(s);o!==void 0&&e(o,s,n)})}}function I(r,e){return{value:r,expireAt:Date.now()+e}}function g(r,e=Date.now()){return r.expireAt<=e}function C(r){return r.value}const A=r=>{const{config:e}=r,{method:t,url:s,data:n}=e;return[t,s,JSON.stringify(n)].join("|")},F=()=>!0,j=24*60*60*1e3,G={key:A,duration:j,isValid:F,persist:!1};class d{get(e){const t=this.getItem(e);if(t){if(g(t)){this.removeItem(e);return}return C(t)}}set(e,t,s=j){const n=I(t,s);this.setItem(e,n)}delete(e){this.removeItem(e)}has(e){const t=this.getItem(e);return t?g(t)?(this.removeItem(e),!1):!0:!1}size(){return this.length()}forEach(e){let t=0;this.iterate((s,n,o)=>{if(g(s))this.removeItem(n);else{const i=C(s);e(i,n,t),t++}})}clearExpired(){let e=0;return this.keys().forEach(s=>{const n=this.getItem(s);n&&g(n)&&(this.removeItem(s),e++)}),e}touch(e,t){const s=this.getItem(e);if(!s)return!1;if(g(s))return this.removeItem(e),!1;const n=C(s);return this.set(e,n,t),!0}}class D extends E{constructor(){super(...arguments);u(this,"get",d.prototype.get);u(this,"set",d.prototype.set);u(this,"delete",d.prototype.delete);u(this,"has",d.prototype.has);u(this,"size",d.prototype.size);u(this,"forEach",d.prototype.forEach);u(this,"clearExpired",d.prototype.clearExpired);u(this,"touch",d.prototype.touch)}}class M extends P{constructor(){super(...arguments);u(this,"get",d.prototype.get);u(this,"set",d.prototype.set);u(this,"delete",d.prototype.delete);u(this,"has",d.prototype.has);u(this,"size",d.prototype.size);u(this,"forEach",d.prototype.forEach);u(this,"clearExpired",d.prototype.clearExpired);u(this,"touch",d.prototype.touch)}}const O=r=>{const e={...G,...r},t=e.persist?new M:new D,s=o=>typeof e.duration=="function"?e.duration(o):e.duration;return Object.assign(async({config:o,next:i})=>{const a=e.key({config:o}),l=t.getItem(a);if(l){if(!g(l)&&await e.isValid({key:a,config:o,cachedData:l}))return C(l);t.removeItem(a)}const m=await i(),f=s({key:a,config:o,cachedData:l,response:m}),k=I(m,f);return t.setItem(a,k),m},{__middlewareType:w.CACHE,storage:t})},U={suspense:!0,key:r=>{const{config:e}=r,{method:t,url:s}=e;return[t,s].join("|")},duration:24*60*60*1e3,isValid:()=>!0,persist:!1};function B(r){const e={...U,...r},t=e.persist?new P:new E,s=o=>typeof e.duration=="function"?e.duration(o):e.duration;return Object.assign(({config:o,next:i})=>{const a=e.key({config:o}),l=t.getItem(a);if(l){if(!g(l)&&e.isValid({key:a,config:o,cachedData:l}))return C(l);t.removeItem(a)}if(e.suspense)throw(e.wrapSuspense?e.wrapSuspense({key:a,config:o,p:i()}):i()).then(f=>{const k=s({key:a,config:o,cachedData:l,response:f});return t.setItem(a,I(f,k)),f});return i().then(m=>{const f=s({key:a,config:o,cachedData:l,response:m});return t.setItem(a,I(m,f)),m})},{__middlewareType:w.SYNC})}const x=new Map,L=(r,e=q)=>{x.set(e,r)},V=(r=q)=>{const e=x.get(r);if(!e)throw new Error(`Requestor实例 ${String(r)} 未注册`);return e},K={get:(r,e)=>({url:r,method:p.GET,...e,params:e==null?void 0:e.params}),post:(r,e,t)=>({url:r,method:p.POST,data:e,...t}),delete:(r,e)=>({url:r,method:p.DELETE,...e}),put:(r,e,t)=>({url:r,method:p.PUT,data:e,...t}),request:r=>r},Y=Object.keys(K);function X(r,e,t){const s={},n=o=>{if(o===e.length)return t(r);const i=e[o];return i({config:r,ctx:s,next:()=>n(o+1)})};return n(0)}function Z(r,e){const t={},s=e??[];return Y.forEach(n=>{t[n]=(...o)=>{const i=K[n](...o);return X(i,s,r)}}),t}function v(r){const{extensions:e,instanceKey:t}=r??{},s=V(t);return Z(s,e)}function H(r){const{instanceKey:e,key:t,duration:s,isValid:n,persist:o,...i}=r;return v({instanceKey:e,extensions:[T(i),O({key:t,duration:s,isValid:n,persist:o})]})}function Q(r){const{instanceKey:e,parallelCount:t,createId:s,retries:n,delay:o,retryCondition:i}=r;return v({instanceKey:e,extensions:[R({parallelCount:t,createId:s}),S({retries:n,delay:o,retryCondition:i})]})}c.cache=O,c.concurrent=R,c.createCachedIdempotentRequestor=H,c.createConcurrentRetryRequestor=Q,c.createRequestor=v,c.idempotent=T,c.inject=L,c.retry=S,c.sync=B,c.useRequestor=V,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})});
1
+ (function(u,w){typeof exports=="object"&&typeof module<"u"?w(exports,require("id-queue")):typeof define=="function"&&define.amd?define(["exports","id-queue"],w):(u=typeof globalThis<"u"?globalThis:u||self,w(u.netVertCore={},u.idQueue))})(this,function(u,w){"use strict";var p=(r=>(r.GET="get",r.POST="post",r.PUT="put",r.DELETE="delete",r))(p||{}),y=(r=>(r.CACHE="cache",r.RETRY="retry",r.IDEMPOTENT="idempotent",r.CONCURRENT="concurrent",r.SYNC="sync",r))(y||{});const N="default",E={retries:3,delay:0,retryCondition:()=>!0},P=r=>{const e={...E,...r};return Object.assign(async({config:n,next:s})=>{let o=0,a;for(;o<=e.retries;)try{return await s()}catch(i){if(a=i,o===e.retries)throw i;const c={config:n,lastResponse:i,attempt:o};if(!e.retryCondition(c))throw i;o++;const l=typeof e.delay=="function"?e.delay(c):e.delay;l>0&&await new Promise(d=>setTimeout(d,l))}throw a},{__middlewareType:y.RETRY})},B=()=>{const r=new Map;return{getPromise:o=>r.get(o),setPromise:(o,a)=>{r.set(o,a),a.finally(()=>r.delete(o))},delPromise:o=>r.delete(o),clearCache:()=>r.clear()}},K={key:r=>{const{config:e}=r,{method:t,url:n,data:s}=e;return[t,n,JSON.stringify(s)].join("|")}},V=r=>{const e={...K,...r},t=B();return Object.assign(({config:s,next:o})=>{const a=e.key({config:s}),i=t.getPromise(a);if(i)return i;const c=o();return t.setPromise(a,c),c},{__middlewareType:y.IDEMPOTENT,promiseCache:t})};class _{parallelCount;tasks;runningCount;constructor(e=4){this.parallelCount=e,this.tasks=new w.TaskQueue,this.runningCount=0}add(e,t){return new Promise((n,s)=>{this.tasks.enqueue(e,{task:t,resolve:n,reject:s}),this._run()})}remove(e){this.tasks.remove(e)}execute(e){const{task:t,resolve:n,reject:s}=e;return t().then(n).catch(s).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)}}}let A=0;const J={parallelCount:4,createId:()=>A++},x=r=>{const{parallelCount:e,createId:t}={...J,...r},n=new _(e);return Object.assign(({config:o,next:a})=>{const i=t({config:o});return n.add(i,()=>a())},{__middlewareType:y.CONCURRENT,pool:n})},O=new Map,f=(r,e)=>{O.set(e,r)};function z(r){const e=O.get(r);if(!e)throw new Error(`Store实例 ${String(r)} 未注册`);return e}class G{store=new Map;getItem(e){return this.store.get(e)}setItem(e,t){return this.store.set(e,t),t}removeItem(e){this.store.delete(e)}clear(){this.store.clear()}length(){return this.store.size}key(e){return Array.from(this.store.keys())[e]}keys(){return Array.from(this.store.keys())}iterate(e){let t=0;for(const[n,s]of this.store.entries())e(s,n,t),t++}}const U=r=>!!r&&(typeof r=="object"||typeof r=="function")&&typeof r.then=="function",q=r=>typeof window<"u"?r():{getItem(){return null},setItem(){},removeItem(){},clear(){},key(){return null},get length(){return 0}},h=q(()=>window.localStorage);class M{constructor(){}getItem(e){const t=String(e),n=h.getItem(t);if(n!==null)try{return JSON.parse(n)}catch(s){console.error(`Failed to parse value for key: ${t}`,s);return}}setItem(e,t){const n=String(e);try{h.setItem(n,JSON.stringify(t))}catch(s){throw console.error(`Failed to set value for key: ${n}`,s),s}return t}removeItem(e){const t=String(e);h.removeItem(t)}clear(){h.clear()}length(){return h.length}key(e){return h.key(e)}keys(){const e=[];for(let t=0;t<h.length;t++){const n=h.key(t);n&&e.push(n)}return e}iterate(e){this.keys().forEach((t,n)=>{const s=this.getItem(t);s!==void 0&&e(s,t,n)})}}const m=q(()=>window.sessionStorage);class Y{constructor(){}getItem(e){const t=String(e),n=m.getItem(t);if(n!==null)try{return JSON.parse(n)}catch(s){console.error(`Failed to parse value for key: ${t}`,s);return}}setItem(e,t){const n=String(e);try{m.setItem(n,JSON.stringify(t))}catch(s){throw console.error(`Failed to set value for key: ${n}`,s),s}return t}removeItem(e){const t=String(e);m.removeItem(t)}clear(){m.clear()}length(){return m.length}key(e){return m.key(e)}keys(){const e=[];for(let t=0;t<m.length;t++){const n=m.key(t);n&&e.push(n)}return e}iterate(e){this.keys().forEach((t,n)=>{const s=this.getItem(t);s!==void 0&&e(s,t,n)})}}class X{dbName;storeName;dbPromise=null;DB_VERSION=1;constructor(e,t){this.dbName=e,this.storeName=t,this.initDB()}initDB(){if(typeof window>"u"||!window.indexedDB){console.warn("IndexedDB is not available");return}this.dbPromise=new Promise((e,t)=>{const n=indexedDB.open(this.dbName,this.DB_VERSION);n.onerror=()=>{t(new Error(`Failed to open database: ${this.dbName}`))},n.onsuccess=()=>{e(n.result)},n.onupgradeneeded=s=>{const o=s.target.result;o.objectStoreNames.contains(this.storeName)||o.createObjectStore(this.storeName)}})}async getDB(){if(!this.dbPromise)throw new Error("IndexedDB is not initialized");return this.dbPromise}async withStore(e,t){const n=await this.getDB();return new Promise((s,o)=>{const a=n.transaction([this.storeName],e).objectStore(this.storeName),i=t(a);i.onsuccess=()=>{s(i.result)},i.onerror=()=>{o(i.error)}})}async getItem(e){try{const t=await this.withStore("readonly",n=>n.get(String(e)));return t===void 0?void 0:t}catch(t){console.error(`Failed to get value for key: ${String(e)}`,t);return}}async setItem(e,t){try{return await this.withStore("readwrite",n=>n.put(t,String(e))),t}catch(n){throw console.error(`Failed to set value for key: ${String(e)}`,n),n}}async removeItem(e){try{await this.withStore("readwrite",t=>t.delete(String(e)))}catch(t){throw console.error(`Failed to remove value for key: ${String(e)}`,t),t}}async clear(){try{await this.withStore("readwrite",e=>e.clear())}catch(e){throw console.error("Failed to clear storage",e),e}}async length(){try{return await this.withStore("readonly",e=>e.count())}catch(e){return console.error("Failed to get storage length",e),0}}async key(e){try{return(await this.withStore("readonly",t=>t.getAllKeys()))[e]}catch(t){console.error("Failed to get key",t);return}}async keys(){try{return await this.withStore("readonly",e=>e.getAllKeys())}catch(e){return console.error("Failed to get all keys",e),[]}}async iterate(e){try{const t=(await this.getDB()).transaction([this.storeName],"readonly").objectStore(this.storeName).openCursor();return new Promise((n,s)=>{let o=0;t.onsuccess=a=>{const i=a.target.result;if(i){const c=i.key,l=i.value;e(l,c,o),o++,i.continue()}else n()},t.onerror=()=>{s(t.error)}})}catch(t){console.error("Failed to iterate storage",t)}}}const g={memory:"memory",local:"local",session:"session",indexeddb:"indexeddb"};function j(r,e){Object.assign(r,e)}function Z(r){return j(r,{async getItemOrDefault(e,t){const n=await this.getItem(e);return n!==null?n:t},async hasItem(e){return await this.getItem(e)!==null},async removeItems(e){await Promise.all(e.map(t=>this.removeItem(t)))},async getItems(e){return await Promise.all(e.map(t=>this.getItem(t)))}}),r}function H(r){return j(r,{getItemOrDefault(e,t){const n=this.getItem(e);return n!==null?n:t},hasItem(e){return this.getItem(e)!==null},removeItems(e){e.forEach(t=>this.removeItem(t))},getItems(e){return e.map(t=>this.getItem(t))}}),r}function L(r){const e=r.getItem("");return U(e)?Z(r):H(r)}function C(r,...e){const t=z(r);let n;try{n=new t(...e)}catch{n=t(...e)}return L(n)}f(G,g.memory),f(M,g.local),f(Y,g.session),f(X,g.indexeddb);function I(r,e){return{value:r,expireAt:Date.now()+e}}function k(r,e=Date.now()){return r.expireAt<=e}function R(r,e=Date.now()){return k(r,e)?void 0:r.value}const Q=r=>{const{config:e}=r,{method:t,url:n,data:s}=e;return[t,n,JSON.stringify(s)].join("|")},W=()=>!0,S=24*60*60*1e3,ee={key:Q,duration:S,isValid:W,store:g.memory},te=class{store;constructor(e){return typeof e=="string"?this.store=C(e):(f(e.factory,e.key),this.store=C(e.key)),new Proxy(this,{get(t,n){if(n in t)return t[n];const s=t.store[n];return typeof s=="function"?s.bind(t.store):s}})}setCache(e,t,n=S){const s=I(t,n);this.store.setItem(e,s)}async getCache(e){const t=await this.store.getItem(e);if(t)return R(t)}async hasValidCache(e){const t=await this.store.getItem(e);return t?!k(t):!1}},T=r=>{const e={...ee,...r},t=new te(e.store),n=o=>typeof e.duration=="function"?e.duration(o):e.duration;return Object.assign(async({config:o,next:a})=>{const i=e.key({config:o}),c=await t.getCache(i);if(c){if(await e.isValid({key:i,config:o,cachedData:c}))return c;t.removeItem(i)}const l=await a(),d=n({key:i,config:o,cachedData:c,response:l}),v=I(l,d);return t.setItem(i,v),l},{__middlewareType:y.CACHE,storage:t})};class re{store;constructor(e){return typeof e=="string"?this.store=C(e):(f(e.factory,e.key),this.store=C(e.key)),new Proxy(this,{get(t,n){if(n in t)return t[n];const s=t.store[n];return typeof s=="function"?s.bind(t.store):s}})}setCache(e,t,n=S){const s=I(t,n);this.store.setItem(e,s)}getCache(e){const t=this.store.getItem(e);if(t)return R(t)}hasValidCache(e){const t=this.store.getItem(e);return t?!k(t):!1}}const ne=re,se={suspense:!0,key:r=>{const{config:e}=r,{method:t,url:n}=e;return[t,n].join("|")},duration:24*60*60*1e3,isValid:()=>!0,store:g.memory};function oe(r){const e={...se,...r},t=new ne(e.store),n=o=>typeof e.duration=="function"?e.duration(o):e.duration;return Object.assign(({config:o,next:a})=>{const i=e.key({config:o}),c=t.getCache(i);if(c){if(e.isValid({key:i,config:o,cachedData:c}))return c;t.removeItem(i)}if(e.suspense)throw(e.wrapSuspense?e.wrapSuspense({key:i,config:o,p:a()}):a()).then(d=>{const v=n({key:i,config:o,cachedData:c,response:d});return t.setCache(i,d,v),d});return a().then(l=>{const d=n({key:i,config:o,cachedData:c,response:l});return t.setCache(i,l,d),l})},{__middlewareType:y.SYNC})}const D=new Map,ie=(r,e=N)=>{D.set(e,r)},F=(r=N)=>{const e=D.get(r);if(!e)throw new Error(`Requestor实例 ${String(r)} 未注册`);return e},$={get:(r,e)=>({url:r,method:p.GET,...e,params:e?.params}),post:(r,e,t)=>({url:r,method:p.POST,data:e,...t}),delete:(r,e)=>({url:r,method:p.DELETE,...e}),put:(r,e,t)=>({url:r,method:p.PUT,data:e,...t}),request:r=>r},ae=Object.keys($);function ce(r,e,t){const n={},s=o=>{if(o===e.length)return t(r);const a=e[o];return a({config:r,ctx:n,next:()=>s(o+1)})};return s(0)}function ue(r,e){const t={},n=e??[];return ae.forEach(s=>{t[s]=(...o)=>{const a=$[s](...o);return ce(a,n,r)}}),t}function b(r){const{extensions:e,instanceKey:t}=r??{},n=F(t);return ue(n,e)}function le(r){const{instanceKey:e,key:t,duration:n,isValid:s,store:o,...a}=r;return b({instanceKey:e,extensions:[V(a),T({key:t,duration:n,isValid:s,store:o})]})}function de(r){const{instanceKey:e,parallelCount:t,createId:n,retries:s,delay:o,retryCondition:a}=r;return b({instanceKey:e,extensions:[x({parallelCount:t,createId:n}),P({retries:s,delay:o,retryCondition:a})]})}u.cache=T,u.concurrent=x,u.createCachedIdempotentRequestor=le,u.createConcurrentRetryRequestor=de,u.createRequestor=b,u.idempotent=V,u.inject=ie,u.retry=P,u.sync=oe,u.useRequestor=F,Object.defineProperty(u,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -1,39 +1,36 @@
1
1
  {
2
- "name": "@net-vert/core",
3
- "version": "1.0.0",
4
- "description": "Dependency Inversion Network Library with Type-Safe Injection.",
5
- "main": "dist/index",
6
- "type": "module",
7
- "types": "dist/index.d.ts",
8
- "scripts": {
9
- "test": "vitest run",
10
- "build": "run-p type-check build-only",
11
- "build-only": "vite build",
12
- "type-check": "tsc --noEmit"
13
- },
14
- "devDependencies": {
15
- "typescript": "^5.9.3"
16
- },
17
- "files": [
18
- "dist"
19
- ],
20
- "sideEffects": false,
21
- "keywords": [
22
- "dependency-injection",
23
- "di",
24
- "network-library",
25
- "adapter-pattern",
26
- "extensible",
27
- "http-client",
28
- "lightweight"
29
- ],
30
- "author": "yuzinan <1589937631@qq.com>",
31
- "license": "MIT",
32
- "publishConfig": {
33
- "access": "public"
34
- },
35
- "dependencies": {
36
- "id-queue": "^1.1.1",
37
- "localforage": "^1.10.0"
38
- }
2
+ "name": "@net-vert/core",
3
+ "version": "1.2.1",
4
+ "description": "Dependency Inversion Network Library with Type-Safe Injection.",
5
+ "main": "dist/index",
6
+ "type": "module",
7
+ "types": "dist/index.d.ts",
8
+ "scripts": {
9
+ "test": "vitest run",
10
+ "build": "run-p type-check build-only",
11
+ "build-only": "vite build",
12
+ "type-check": "tsc --noEmit"
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "sideEffects": false,
18
+ "keywords": [
19
+ "dependency-injection",
20
+ "di",
21
+ "network-library",
22
+ "adapter-pattern",
23
+ "extensible",
24
+ "http-client",
25
+ "lightweight"
26
+ ],
27
+ "author": "yuzinan <1589937631@qq.com>",
28
+ "license": "MIT",
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "dependencies": {
33
+ "id-queue": "^1.1.1",
34
+ "store-vert": "^0.2.0"
35
+ }
39
36
  }