rxtutils 1.1.1 → 1.1.2-beta.10
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 +547 -0
- package/cjs/index.cjs +28 -0
- package/{dist/types → cjs}/index.d.ts +4 -1
- package/cjs/request/index.cjs +150 -0
- package/{dist/types → cjs}/request/index.d.ts +11 -8
- package/cjs/store/createGetter/index.cjs +45 -0
- package/cjs/store/createGetter/index.d.ts +30 -0
- package/cjs/validator/decorators.cjs +246 -0
- package/cjs/validator/decorators.d.ts +159 -0
- package/cjs/validator/validator.cjs +179 -0
- package/cjs/validator/validator.d.ts +89 -0
- package/es/cache/index.d.ts +135 -0
- package/es/cache/indexDB.d.ts +52 -0
- package/es/index.d.ts +7 -0
- package/es/index.mjs +6 -0
- package/es/request/error.d.ts +31 -0
- package/es/request/index.d.ts +139 -0
- package/es/request/index.mjs +148 -0
- package/es/store/createGetter/index.d.ts +30 -0
- package/es/store/createGetter/index.mjs +42 -0
- package/es/store/createStateStore/index.d.ts +42 -0
- package/es/validator/decorators.d.ts +159 -0
- package/es/validator/decorators.mjs +234 -0
- package/es/validator/validator.d.ts +89 -0
- package/es/validator/validator.mjs +177 -0
- package/package.json +11 -8
- package/dist/cjs/index.cjs +0 -11
- package/dist/cjs/request/index.cjs +0 -129
- package/dist/es/index.mjs +0 -3
- package/dist/es/request/index.mjs +0 -127
- /package/{dist/cjs → cjs}/cache/index.cjs +0 -0
- /package/{dist/types → cjs}/cache/index.d.ts +0 -0
- /package/{dist/cjs → cjs}/cache/indexDB.cjs +0 -0
- /package/{dist/types → cjs}/cache/indexDB.d.ts +0 -0
- /package/{dist/cjs → cjs}/defaultEquals.cjs +0 -0
- /package/{dist/cjs → cjs}/request/defaultHandlers.cjs +0 -0
- /package/{dist/cjs → cjs}/request/error.cjs +0 -0
- /package/{dist/types → cjs}/request/error.d.ts +0 -0
- /package/{dist/cjs → cjs/store}/createStateStore/index.cjs +0 -0
- /package/{dist/types → cjs/store}/createStateStore/index.d.ts +0 -0
- /package/{dist/es → es}/cache/index.mjs +0 -0
- /package/{dist/es → es}/cache/indexDB.mjs +0 -0
- /package/{dist/es → es}/defaultEquals.mjs +0 -0
- /package/{dist/es → es}/request/defaultHandlers.mjs +0 -0
- /package/{dist/es → es}/request/error.mjs +0 -0
- /package/{dist/es → es/store}/createStateStore/index.mjs +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,547 @@
|
|
|
1
|
+
# RUtils
|
|
2
|
+
|
|
3
|
+
一个功能丰富的 TypeScript 工具库,提供缓存管理、HTTP 请求和状态管理等功能。
|
|
4
|
+
|
|
5
|
+
## 📦 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install rxtutils
|
|
9
|
+
# 或
|
|
10
|
+
yarn add rxtutils
|
|
11
|
+
# 或
|
|
12
|
+
pnpm add rxtutils
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## 🚀 功能特性
|
|
16
|
+
|
|
17
|
+
- **缓存管理** - 支持内存、localStorage、sessionStorage 和 IndexedDB 多种存储方式
|
|
18
|
+
- **HTTP 请求** - 基于 axios 的请求封装,支持错误处理和缓存
|
|
19
|
+
- **状态管理** - 轻量级的状态管理解决方案,支持 React Hook
|
|
20
|
+
- **数据验证** - 基于装饰器的数据验证系统,支持多种验证规则
|
|
21
|
+
- **TypeScript** - 完整的 TypeScript 类型支持
|
|
22
|
+
|
|
23
|
+
## 📚 模块介绍
|
|
24
|
+
|
|
25
|
+
### 1. 缓存管理 (Cache)
|
|
26
|
+
|
|
27
|
+
提供灵活的缓存管理功能,支持多种存储方式。
|
|
28
|
+
|
|
29
|
+
#### 基本用法
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { Cache } from 'rxtutils';
|
|
33
|
+
|
|
34
|
+
// 创建内存缓存
|
|
35
|
+
const memoryCache = new Cache<string, any>();
|
|
36
|
+
|
|
37
|
+
// 创建 localStorage 缓存
|
|
38
|
+
const localCache = new Cache<string, any>('localStorage', 'myCache', 300);
|
|
39
|
+
|
|
40
|
+
// 创建 IndexedDB 缓存
|
|
41
|
+
const dbCache = new Cache<string, any>('indexedDB', 'dbCache', 600, 'myDatabase');
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
#### 缓存操作
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
// 设置缓存
|
|
48
|
+
cache.setCache('key1', { data: 'value1' });
|
|
49
|
+
cache.setCache('key2', { data: 'value2' }, { cacheTime: 120 }); // 2分钟过期
|
|
50
|
+
|
|
51
|
+
// 获取缓存
|
|
52
|
+
const data = cache.getCache('key1');
|
|
53
|
+
console.log(data); // { data: 'value1' }
|
|
54
|
+
|
|
55
|
+
// 清空缓存
|
|
56
|
+
cache.clear();
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
#### 高级配置
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
import { Cache } from 'rxtutils';
|
|
63
|
+
|
|
64
|
+
// 自定义比较函数
|
|
65
|
+
const customCache = new Cache<{ id: number; name: string }, any>(
|
|
66
|
+
'localStorage',
|
|
67
|
+
'customCache',
|
|
68
|
+
300,
|
|
69
|
+
'customDB',
|
|
70
|
+
(prev, next) => prev.id === next.id // 只比较 id 字段
|
|
71
|
+
);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 2. HTTP 请求 (createBaseRequest)
|
|
75
|
+
|
|
76
|
+
基于 axios 的请求封装,支持错误处理、缓存和自定义配置。
|
|
77
|
+
|
|
78
|
+
#### 基本用法
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
import { createBaseRequest } from 'rxtutils';
|
|
82
|
+
|
|
83
|
+
// 创建请求实例
|
|
84
|
+
const request = createBaseRequest({
|
|
85
|
+
baseURL: 'https://api.example.com',
|
|
86
|
+
throwError: true,
|
|
87
|
+
defaultMessageShower: (message) => console.log(message)
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// 创建具体请求
|
|
91
|
+
const getUserInfo = request<{ id: number }, { name: string; email: string }>({
|
|
92
|
+
method: 'GET',
|
|
93
|
+
url: '/user/:id'
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// 发送请求
|
|
97
|
+
const userInfo = await getUserInfo({ params: { id: 123 } });
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
#### 错误处理
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
const request = createBaseRequest({
|
|
104
|
+
baseURL: 'https://api.example.com',
|
|
105
|
+
errorCodeMap: {
|
|
106
|
+
'400': '请求参数错误',
|
|
107
|
+
'401': '未授权,请重新登录',
|
|
108
|
+
'500': (code, data, res) => ({
|
|
109
|
+
replaceResData: { error: '服务器内部错误' },
|
|
110
|
+
throwError: false
|
|
111
|
+
})
|
|
112
|
+
},
|
|
113
|
+
httpErrorCodeMap: {
|
|
114
|
+
404: '资源不存在',
|
|
115
|
+
500: '服务器错误'
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
#### 缓存功能
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
const request = createBaseRequest({
|
|
124
|
+
baseURL: 'https://api.example.com',
|
|
125
|
+
enableCache: true,
|
|
126
|
+
cacheData: true,
|
|
127
|
+
cacheDataInStorage: 'localStorage',
|
|
128
|
+
cacheDataKey: 'api-cache',
|
|
129
|
+
cacheTime: 300
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// 第一次请求会从服务器获取数据
|
|
133
|
+
const data1 = await getUserInfo({ params: { id: 123 } });
|
|
134
|
+
|
|
135
|
+
// 第二次请求会从缓存获取数据
|
|
136
|
+
const data2 = await getUserInfo({ params: { id: 123 } });
|
|
137
|
+
|
|
138
|
+
// 清空缓存
|
|
139
|
+
getUserInfo.clearCache();
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### 3. 状态管理 (createStateStore)
|
|
143
|
+
|
|
144
|
+
轻量级的状态管理解决方案,支持组件间状态共享。
|
|
145
|
+
|
|
146
|
+
#### 基本用法
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
import { createStateStore } from 'rxtutils';
|
|
150
|
+
|
|
151
|
+
// 创建状态存储
|
|
152
|
+
const userStore = createStateStore({
|
|
153
|
+
name: '',
|
|
154
|
+
email: '',
|
|
155
|
+
isLoggedIn: false
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// 在组件中使用
|
|
159
|
+
function UserComponent() {
|
|
160
|
+
const [user, setUser] = userStore.use();
|
|
161
|
+
|
|
162
|
+
const handleLogin = () => {
|
|
163
|
+
setUser({
|
|
164
|
+
name: 'John Doe',
|
|
165
|
+
email: 'john@example.com',
|
|
166
|
+
isLoggedIn: true
|
|
167
|
+
});
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
return (
|
|
171
|
+
<div>
|
|
172
|
+
<p>用户名: {user.name}</p>
|
|
173
|
+
<p>邮箱: {user.email}</p>
|
|
174
|
+
<button onClick={handleLogin}>登录</button>
|
|
175
|
+
</div>
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
#### 状态监听
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
// 监听状态变化
|
|
184
|
+
const unsubscribe = userStore.watch((state) => {
|
|
185
|
+
console.log('状态已更新:', state);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// 取消监听
|
|
189
|
+
unsubscribe();
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
#### 直接访问和设置
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
// 直接获取状态
|
|
196
|
+
const currentUser = userStore.get();
|
|
197
|
+
|
|
198
|
+
// 直接设置状态
|
|
199
|
+
userStore.set({ name: 'Jane Doe', email: 'jane@example.com', isLoggedIn: true });
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### 4. 数据验证 (Validator)
|
|
203
|
+
|
|
204
|
+
基于装饰器的数据验证系统,提供多种验证规则和自定义验证能力。
|
|
205
|
+
|
|
206
|
+
#### 基本用法
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
import { BaseValidator, VString, VNumber, VRequired, VEmail, VMinLength } from 'rxtutils';
|
|
210
|
+
|
|
211
|
+
// 创建验证模型
|
|
212
|
+
class User extends BaseValidator {
|
|
213
|
+
@VString('用户名必须为字符串')
|
|
214
|
+
@(VRequired()('用户名不能为空'))
|
|
215
|
+
name?: string;
|
|
216
|
+
|
|
217
|
+
@VNumber('年龄必须为数字')
|
|
218
|
+
@(VRequired()('年龄不能为空'))
|
|
219
|
+
age?: number;
|
|
220
|
+
|
|
221
|
+
@VEmail('邮箱格式不正确')
|
|
222
|
+
@(VRequired()('邮箱不能为空'))
|
|
223
|
+
email?: string;
|
|
224
|
+
|
|
225
|
+
@(VMinLength(6)('密码长度不能少于6位'))
|
|
226
|
+
@(VRequired()('密码不能为空'))
|
|
227
|
+
password?: string;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// 使用验证
|
|
231
|
+
const user = new User();
|
|
232
|
+
user.name = '张三';
|
|
233
|
+
user.age = 25;
|
|
234
|
+
user.email = 'invalid-email'; // 无效的邮箱格式
|
|
235
|
+
user.password = '123'; // 密码长度不足
|
|
236
|
+
|
|
237
|
+
// 验证单个字段
|
|
238
|
+
const emailErrors = user.validate('email');
|
|
239
|
+
console.log(emailErrors); // [{ status: false, message: '邮箱格式不正确' }]
|
|
240
|
+
|
|
241
|
+
// 验证所有字段
|
|
242
|
+
const allErrors = user.validateAll();
|
|
243
|
+
console.log(allErrors); // 返回所有验证错误
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
#### 内置验证装饰器
|
|
247
|
+
|
|
248
|
+
```typescript
|
|
249
|
+
// 基本类型验证
|
|
250
|
+
@VString('必须为字符串')
|
|
251
|
+
@VNumber('必须为数字')
|
|
252
|
+
@VBoolean('必须为布尔值')
|
|
253
|
+
@VArray('必须为数组')
|
|
254
|
+
|
|
255
|
+
// 必填验证
|
|
256
|
+
@(VRequired()('不能为空'))
|
|
257
|
+
|
|
258
|
+
// 范围验证
|
|
259
|
+
@(VMin(18)('必须大于等于18'))
|
|
260
|
+
@(VMax(100)('必须小于等于100'))
|
|
261
|
+
|
|
262
|
+
// 长度验证
|
|
263
|
+
@(VMinLength(6)('长度不能少于6位'))
|
|
264
|
+
@(VMaxLength(20)('长度不能超过20位'))
|
|
265
|
+
|
|
266
|
+
// 格式验证
|
|
267
|
+
@VEmail('邮箱格式不正确')
|
|
268
|
+
@(VPattern(/^1[3-9]\d{9}$/)('手机号格式不正确'))
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
#### 自定义验证装饰器
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
import { BaseValidator } from 'rxtutils';
|
|
275
|
+
|
|
276
|
+
// 创建自定义验证装饰器
|
|
277
|
+
const VCustom = BaseValidator.decoratorCreator(
|
|
278
|
+
(val) => {
|
|
279
|
+
// 自定义验证逻辑
|
|
280
|
+
return typeof val === 'string' && val.startsWith('custom-');
|
|
281
|
+
}
|
|
282
|
+
);
|
|
283
|
+
|
|
284
|
+
// 使用自定义验证装饰器
|
|
285
|
+
class Product extends BaseValidator {
|
|
286
|
+
@VCustom('产品编码必须以 custom- 开头')
|
|
287
|
+
code?: string;
|
|
288
|
+
}
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
#### 验证方法
|
|
292
|
+
|
|
293
|
+
BaseValidator 类提供了两个主要的验证方法:
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
// 验证单个字段
|
|
297
|
+
validate(itemKey: string, itemAll: boolean = false): { status: boolean; message?: string }[] | null;
|
|
298
|
+
|
|
299
|
+
// 验证多个或所有字段
|
|
300
|
+
validateAll(itemAll: boolean = false, everyItem: boolean = false, order?: string[]): { status: boolean; message?: string }[] | null;
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
参数说明:
|
|
304
|
+
|
|
305
|
+
- `itemKey`: 要验证的字段名
|
|
306
|
+
- `itemAll`: 是否验证该字段的所有规则,为 true 时会验证所有规则,为 false 时遇到第一个失败的规则就停止
|
|
307
|
+
- `everyItem`: 是否验证所有字段,为 true 时会验证所有字段,为 false 时遇到第一个失败的字段就停止
|
|
308
|
+
- `order`: 验证字段的顺序,可以指定验证的字段名数组及其顺序
|
|
309
|
+
|
|
310
|
+
使用示例:
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
// 创建验证模型
|
|
314
|
+
class LoginForm extends BaseValidator {
|
|
315
|
+
@VString('用户名必须为字符串')
|
|
316
|
+
@(VRequired()('用户名不能为空'))
|
|
317
|
+
@(VMinLength(3)('用户名长度不能少于3位'))
|
|
318
|
+
@(VMaxLength(20)('用户名长度不能超过20位'))
|
|
319
|
+
username?: string;
|
|
320
|
+
|
|
321
|
+
@(VRequired()('密码不能为空'))
|
|
322
|
+
@(VMinLength(6)('密码长度不能少于6位'))
|
|
323
|
+
password?: string;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
const form = new LoginForm();
|
|
327
|
+
form.username = 'ab'; // 长度不足
|
|
328
|
+
form.password = '123456';
|
|
329
|
+
|
|
330
|
+
// 验证单个字段的所有规则
|
|
331
|
+
const usernameErrors = form.validate('username', true);
|
|
332
|
+
console.log(usernameErrors);
|
|
333
|
+
// [{ status: false, message: '用户名长度不能少于3位' }]
|
|
334
|
+
|
|
335
|
+
// 验证所有字段,每个字段遇到第一个错误就停止
|
|
336
|
+
const allErrors = form.validateAll(false, true);
|
|
337
|
+
console.log(allErrors);
|
|
338
|
+
|
|
339
|
+
// 按指定顺序验证字段,并验证每个字段的所有规则
|
|
340
|
+
const orderedErrors = form.validateAll(true, true, ['password', 'username']);
|
|
341
|
+
console.log(orderedErrors);
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### 5. 状态计算器 (createStoreGetter)
|
|
345
|
+
|
|
346
|
+
为状态存储提供计算属性和派生状态。
|
|
347
|
+
|
|
348
|
+
#### 基本用法
|
|
349
|
+
|
|
350
|
+
```typescript
|
|
351
|
+
import { createStoreGetter, createStoreGetterMemo } from 'rxtutils';
|
|
352
|
+
|
|
353
|
+
const userStore = createStateStore({
|
|
354
|
+
firstName: 'John',
|
|
355
|
+
lastName: 'Doe',
|
|
356
|
+
age: 30
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
// 创建 getter 函数
|
|
360
|
+
const getters = {
|
|
361
|
+
fullName: (state) => `${state.firstName} ${state.lastName}`,
|
|
362
|
+
isAdult: (state) => state.age >= 18,
|
|
363
|
+
displayName: (state) => state.firstName
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
// 创建 getter 名称映射
|
|
367
|
+
const getterNameMaps = {
|
|
368
|
+
fullName: 'fullName',
|
|
369
|
+
isAdult: 'isAdult',
|
|
370
|
+
displayName: 'displayName'
|
|
371
|
+
};
|
|
372
|
+
|
|
373
|
+
// 创建 getter 对象(非响应式)
|
|
374
|
+
const userGetters = createStoreGetter(userStore, getters, getterNameMaps);
|
|
375
|
+
console.log(userGetters.fullName); // "John Doe"
|
|
376
|
+
|
|
377
|
+
// 创建 getter memo hook(响应式)
|
|
378
|
+
const useUserGetters = createStoreGetterMemo(userStore, getters, getterNameMaps);
|
|
379
|
+
|
|
380
|
+
function UserProfile() {
|
|
381
|
+
const { fullName, isAdult, displayName } = useUserGetters();
|
|
382
|
+
|
|
383
|
+
return (
|
|
384
|
+
<div>
|
|
385
|
+
<h1>{fullName}</h1>
|
|
386
|
+
<p>成年人: {isAdult ? '是' : '否'}</p>
|
|
387
|
+
<p>显示名: {displayName}</p>
|
|
388
|
+
</div>
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
## 🔧 配置选项
|
|
394
|
+
|
|
395
|
+
### Cache 配置
|
|
396
|
+
|
|
397
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
398
|
+
|------|------|--------|------|
|
|
399
|
+
| `storageType` | `'sessionStorage' \| 'localStorage' \| 'indexedDB'` | `undefined` | 存储类型 |
|
|
400
|
+
| `cacheKey` | `string` | `undefined` | 缓存键名 |
|
|
401
|
+
| `cacheTime` | `number` | `60` | 缓存时间(秒) |
|
|
402
|
+
| `indexDBName` | `string` | `'__apiCacheDatabase__'` | IndexedDB 数据库名称 |
|
|
403
|
+
| `cacheKeyEquals` | `function` | `defaultEquals` | 缓存键比较函数 |
|
|
404
|
+
|
|
405
|
+
### Request 配置
|
|
406
|
+
|
|
407
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
408
|
+
|------|------|--------|------|
|
|
409
|
+
| `baseURL` | `string` | `''` | 请求基础URL |
|
|
410
|
+
| `throwError` | `boolean` | `true` | 是否抛出错误 |
|
|
411
|
+
| `enableCache` | `boolean` | `false` | 是否启用缓存 |
|
|
412
|
+
| `cacheData` | `boolean` | `false` | 是否缓存数据 |
|
|
413
|
+
| `cacheTime` | `number` | `60` | 缓存时间(秒) |
|
|
414
|
+
| `cacheDataInStorage` | `StorageType` | `undefined` | 缓存存储类型 |
|
|
415
|
+
| `errorCodePath` | `string` | `'code'` | 错误码路径 |
|
|
416
|
+
| `successCodes` | `string[]` | `['0', '200']` | 成功状态码 |
|
|
417
|
+
|
|
418
|
+
## 📝 类型定义
|
|
419
|
+
|
|
420
|
+
### 缓存相关类型
|
|
421
|
+
|
|
422
|
+
```typescript
|
|
423
|
+
// 缓存项接口
|
|
424
|
+
interface ICache<Param, Data> {
|
|
425
|
+
params: Param;
|
|
426
|
+
data: Data;
|
|
427
|
+
expireTime: string;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// 缓存选项接口
|
|
431
|
+
interface ICacheOptions<Param> {
|
|
432
|
+
storageType?: StorageType;
|
|
433
|
+
cacheKey?: string;
|
|
434
|
+
cacheTime?: number;
|
|
435
|
+
cacheKeyEquals: (prev: Param, next: Param) => boolean;
|
|
436
|
+
indexDBName?: string;
|
|
437
|
+
}
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### 请求相关类型
|
|
441
|
+
|
|
442
|
+
```typescript
|
|
443
|
+
// 请求配置接口
|
|
444
|
+
interface Options<Params, Data> {
|
|
445
|
+
baseURL?: string;
|
|
446
|
+
throwError?: boolean;
|
|
447
|
+
enableCache?: boolean;
|
|
448
|
+
cacheData?: boolean;
|
|
449
|
+
cacheTime?: number;
|
|
450
|
+
errorCodeMap?: Record<string, string | Function>;
|
|
451
|
+
httpErrorCodeMap?: Record<string, string | Function>;
|
|
452
|
+
// ... 更多配置选项
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// 请求参数接口
|
|
456
|
+
interface RequestOptions<Param> {
|
|
457
|
+
method: Method;
|
|
458
|
+
url: string;
|
|
459
|
+
data?: Param;
|
|
460
|
+
params?: Param;
|
|
461
|
+
}
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
### 状态管理相关类型
|
|
465
|
+
|
|
466
|
+
```typescript
|
|
467
|
+
// 状态存储接口
|
|
468
|
+
interface StateStore<S> {
|
|
469
|
+
use: () => [S, (state: IHookStateSetAction<S>) => void];
|
|
470
|
+
get: () => S;
|
|
471
|
+
set: (state: IHookStateSetAction<S>) => void;
|
|
472
|
+
watch: (callback: (state: S) => void) => () => void;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// 状态设置动作类型
|
|
476
|
+
type IHookStateSetAction<S> = S | IHookStateSetter<S>;
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
## 🎯 使用场景
|
|
480
|
+
|
|
481
|
+
### 1. API 数据缓存
|
|
482
|
+
|
|
483
|
+
```typescript
|
|
484
|
+
// 创建带缓存的 API 请求
|
|
485
|
+
const apiRequest = createBaseRequest({
|
|
486
|
+
baseURL: 'https://api.example.com',
|
|
487
|
+
enableCache: true,
|
|
488
|
+
cacheData: true,
|
|
489
|
+
cacheDataInStorage: 'localStorage',
|
|
490
|
+
cacheTime: 300
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
const getProductList = apiRequest<{ page: number }, { products: Product[] }>({
|
|
494
|
+
method: 'GET',
|
|
495
|
+
url: '/products'
|
|
496
|
+
});
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
### 2. 用户状态管理
|
|
500
|
+
|
|
501
|
+
```typescript
|
|
502
|
+
// 创建用户状态存储
|
|
503
|
+
const userStore = createStateStore({
|
|
504
|
+
user: null,
|
|
505
|
+
permissions: [],
|
|
506
|
+
theme: 'light'
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
// 创建用户相关的计算属性
|
|
510
|
+
const userGetters = createStoreGetter(userStore, {
|
|
511
|
+
isLoggedIn: (state) => !!state.user,
|
|
512
|
+
canEdit: (state) => state.permissions.includes('edit'),
|
|
513
|
+
isDarkTheme: (state) => state.theme === 'dark'
|
|
514
|
+
}, {
|
|
515
|
+
isLoggedIn: 'isLoggedIn',
|
|
516
|
+
canEdit: 'canEdit',
|
|
517
|
+
isDarkTheme: 'isDarkTheme'
|
|
518
|
+
});
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
### 3. 表单数据缓存
|
|
522
|
+
|
|
523
|
+
```typescript
|
|
524
|
+
// 创建表单缓存
|
|
525
|
+
const formCache = new Cache<string, FormData>('sessionStorage', 'form-cache', 1800);
|
|
526
|
+
|
|
527
|
+
// 保存表单数据
|
|
528
|
+
formCache.setCache('user-form', formData);
|
|
529
|
+
|
|
530
|
+
// 恢复表单数据
|
|
531
|
+
const savedData = formCache.getCache('user-form');
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
## 🤝 贡献
|
|
535
|
+
|
|
536
|
+
欢迎提交 Issue 和 Pull Request 来帮助改进这个项目。
|
|
537
|
+
|
|
538
|
+
## 📄 许可证
|
|
539
|
+
|
|
540
|
+
MIT License
|
|
541
|
+
|
|
542
|
+
## 🔗 相关链接
|
|
543
|
+
|
|
544
|
+
- [TypeScript](https://www.typescriptlang.org/)
|
|
545
|
+
- [React](https://reactjs.org/)
|
|
546
|
+
- [Axios](https://axios-http.com/)
|
|
547
|
+
- [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API)
|
package/cjs/index.cjs
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var index = require('./cache/index.cjs');
|
|
4
|
+
var index$1 = require('./request/index.cjs');
|
|
5
|
+
var index$3 = require('./store/createGetter/index.cjs');
|
|
6
|
+
var index$2 = require('./store/createStateStore/index.cjs');
|
|
7
|
+
var validator = require('./validator/validator.cjs');
|
|
8
|
+
var decorators = require('./validator/decorators.cjs');
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
exports.Cache = index.default;
|
|
13
|
+
exports.createBaseRequest = index$1;
|
|
14
|
+
exports.createStoreGetter = index$3.createStoreGetter;
|
|
15
|
+
exports.createStoreGetterMemo = index$3.createStoreGetterMemo;
|
|
16
|
+
exports.createStateStore = index$2.default;
|
|
17
|
+
exports.BaseValidator = validator.BaseValidator;
|
|
18
|
+
exports.VArray = decorators.VArray;
|
|
19
|
+
exports.VBoolean = decorators.VBoolean;
|
|
20
|
+
exports.VEmail = decorators.VEmail;
|
|
21
|
+
exports.VMax = decorators.VMax;
|
|
22
|
+
exports.VMaxLength = decorators.VMaxLength;
|
|
23
|
+
exports.VMin = decorators.VMin;
|
|
24
|
+
exports.VMinLength = decorators.VMinLength;
|
|
25
|
+
exports.VNumber = decorators.VNumber;
|
|
26
|
+
exports.VPattern = decorators.VPattern;
|
|
27
|
+
exports.VRequired = decorators.VRequired;
|
|
28
|
+
exports.VString = decorators.VString;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export { default as Cache, ICache, ICacheOptions, StorageMap, StorageType } from './cache/index.js';
|
|
2
2
|
export { ErrorHandlerReturnType, Options, RequestOptions, default as createBaseRequest } from './request/index.js';
|
|
3
|
-
export {
|
|
3
|
+
export { createStoreGetter, createStoreGetterMemo } from './store/createGetter/index.js';
|
|
4
|
+
export { IHookStateInitAction, IHookStateInitialSetter, IHookStateResolvable, IHookStateSetAction, IHookStateSetter, default as createStateStore } from './store/createStateStore/index.js';
|
|
5
|
+
export { BaseValidator } from './validator/validator.js';
|
|
6
|
+
export { VArray, VBoolean, VEmail, VMax, VMaxLength, VMin, VMinLength, VNumber, VPattern, VRequired, VString } from './validator/decorators.js';
|
|
4
7
|
export { default as RequestError, RequestErrorType } from './request/error.js';
|