@ahoo-wang/fetcher-react 2.5.6 → 2.5.9
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 +157 -52
- package/README.zh-CN.md +156 -50
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/useExecutePromise.d.ts +3 -8
- package/dist/core/useExecutePromise.d.ts.map +1 -1
- package/dist/core/usePromiseState.d.ts +7 -7
- package/dist/core/usePromiseState.d.ts.map +1 -1
- package/dist/core/useRequestId.d.ts +56 -0
- package/dist/core/useRequestId.d.ts.map +1 -0
- package/dist/fetcher/useFetcher.d.ts +2 -2
- package/dist/fetcher/useFetcher.d.ts.map +1 -1
- package/dist/index.es.js +100 -79
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,6 +17,7 @@ automatic re-rendering and loading states.
|
|
|
17
17
|
- 🌐 **TypeScript Support**: Full TypeScript support with comprehensive type definitions
|
|
18
18
|
- 🚀 **Modern**: Built with modern React patterns and best practices
|
|
19
19
|
- 🧠 **Smart Caching**: Built-in caching and automatic revalidation
|
|
20
|
+
- ⚡ **Promise State Management**: Hooks for managing async operations and promise states
|
|
20
21
|
|
|
21
22
|
## Installation
|
|
22
23
|
|
|
@@ -26,83 +27,127 @@ npm install @ahoo-wang/fetcher-react
|
|
|
26
27
|
|
|
27
28
|
## Usage
|
|
28
29
|
|
|
29
|
-
###
|
|
30
|
+
### usePromiseState Hook
|
|
30
31
|
|
|
31
|
-
The `
|
|
32
|
-
loading, error, and result states.
|
|
32
|
+
The `usePromiseState` hook provides state management for promise operations without execution logic.
|
|
33
33
|
|
|
34
34
|
```typescript jsx
|
|
35
|
-
import {
|
|
35
|
+
import { usePromiseState, PromiseStatus } from '@ahoo-wang/fetcher-react';
|
|
36
36
|
|
|
37
37
|
const MyComponent = () => {
|
|
38
|
-
const { loading, error,
|
|
39
|
-
url: '/api/users',
|
|
40
|
-
method: 'GET'
|
|
41
|
-
});
|
|
38
|
+
const { status, loading, result, error, setSuccess, setError, setIdle } = usePromiseState<string>();
|
|
42
39
|
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
const handleSuccess = () => setSuccess('Data loaded');
|
|
41
|
+
const handleError = () => setError(new Error('Failed to load'));
|
|
45
42
|
|
|
46
43
|
return (
|
|
47
44
|
<div>
|
|
48
|
-
<
|
|
49
|
-
<button onClick={
|
|
50
|
-
<button onClick={
|
|
45
|
+
<button onClick={handleSuccess}>Set Success</button>
|
|
46
|
+
<button onClick={handleError}>Set Error</button>
|
|
47
|
+
<button onClick={setIdle}>Reset</button>
|
|
48
|
+
<p>Status: {status}</p>
|
|
49
|
+
{loading && <p>Loading...</p>}
|
|
50
|
+
{result && <p>Result: {result}</p>}
|
|
51
|
+
{error && <p>Error: {error.message}</p>}
|
|
51
52
|
</div>
|
|
52
53
|
);
|
|
53
54
|
};
|
|
54
55
|
```
|
|
55
56
|
|
|
56
|
-
###
|
|
57
|
+
### useExecutePromise Hook
|
|
57
58
|
|
|
58
|
-
|
|
59
|
+
The `useExecutePromise` hook manages asynchronous operations with automatic state handling and built-in race condition
|
|
60
|
+
protection.
|
|
59
61
|
|
|
60
62
|
```typescript jsx
|
|
61
|
-
import {
|
|
63
|
+
import { useExecutePromise } from '@ahoo-wang/fetcher-react';
|
|
62
64
|
|
|
63
65
|
const MyComponent = () => {
|
|
64
|
-
const { loading,
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const handleSubmit = async () => {
|
|
71
|
-
await execute();
|
|
66
|
+
const { loading, result, error, execute, reset } = useExecutePromise<string>();
|
|
67
|
+
|
|
68
|
+
const fetchData = async () => {
|
|
69
|
+
const response = await fetch('/api/data');
|
|
70
|
+
return response.text();
|
|
72
71
|
};
|
|
73
72
|
|
|
74
|
-
|
|
73
|
+
const handleFetch = () => {
|
|
74
|
+
execute(fetchData); // Using a promise supplier
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const handleDirectPromise = () => {
|
|
78
|
+
const promise = fetch('/api/data').then(res => res.text());
|
|
79
|
+
execute(promise); // Using a direct promise
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
if (loading) return <div>Loading...</div>;
|
|
75
83
|
if (error) return <div>Error: {error.message}</div>;
|
|
84
|
+
return (
|
|
85
|
+
<div>
|
|
86
|
+
<button onClick={handleFetch}>Fetch with Supplier</button>
|
|
87
|
+
<button onClick={handleDirectPromise}>Fetch with Promise</button>
|
|
88
|
+
<button onClick={reset}>Reset</button>
|
|
89
|
+
{result && <p>{result}</p>}
|
|
90
|
+
</div>
|
|
91
|
+
);
|
|
92
|
+
};
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### useRequestId Hook
|
|
96
|
+
|
|
97
|
+
The `useRequestId` hook provides request ID management for preventing race conditions in async operations.
|
|
98
|
+
|
|
99
|
+
```typescript jsx
|
|
100
|
+
import { useRequestId } from '@ahoo-wang/fetcher-react';
|
|
101
|
+
|
|
102
|
+
const MyComponent = () => {
|
|
103
|
+
const { generate, isLatest, invalidate } = useRequestId();
|
|
104
|
+
|
|
105
|
+
const handleFetch = async () => {
|
|
106
|
+
const requestId = generate();
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
const result = await fetchData();
|
|
110
|
+
|
|
111
|
+
if (isLatest(requestId)) {
|
|
112
|
+
setData(result);
|
|
113
|
+
}
|
|
114
|
+
} catch (error) {
|
|
115
|
+
if (isLatest(requestId)) {
|
|
116
|
+
setError(error);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
};
|
|
76
120
|
|
|
77
121
|
return (
|
|
78
122
|
<div>
|
|
79
|
-
{
|
|
80
|
-
<button onClick={
|
|
123
|
+
<button onClick={handleFetch}>Fetch Data</button>
|
|
124
|
+
<button onClick={invalidate}>Cancel Ongoing</button>
|
|
81
125
|
</div>
|
|
82
126
|
);
|
|
83
127
|
};
|
|
84
128
|
```
|
|
85
129
|
|
|
86
|
-
###
|
|
130
|
+
### useFetcher Hook
|
|
87
131
|
|
|
88
|
-
|
|
132
|
+
The `useFetcher` hook provides data fetching capabilities with automatic state management.
|
|
89
133
|
|
|
90
134
|
```typescript jsx
|
|
91
135
|
import { useFetcher } from '@ahoo-wang/fetcher-react';
|
|
92
136
|
|
|
93
|
-
const
|
|
94
|
-
const { loading, error, result } = useFetcher(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
137
|
+
const MyComponent = () => {
|
|
138
|
+
const { loading, error, result, execute } = useFetcher<string>();
|
|
139
|
+
|
|
140
|
+
const handleFetch = () => {
|
|
141
|
+
execute({ url: '/api/users', method: 'GET' });
|
|
142
|
+
};
|
|
98
143
|
|
|
99
144
|
if (loading) return <div>Loading...</div>;
|
|
100
145
|
if (error) return <div>Error: {error.message}</div>;
|
|
101
146
|
|
|
102
147
|
return (
|
|
103
148
|
<div>
|
|
104
|
-
<
|
|
105
|
-
<
|
|
149
|
+
<pre>{JSON.stringify(result, null, 2)}</pre>
|
|
150
|
+
<button onClick={handleFetch}>Fetch Data</button>
|
|
106
151
|
</div>
|
|
107
152
|
);
|
|
108
153
|
};
|
|
@@ -159,36 +204,96 @@ const [user, setUser] = useKeyStorage(userStorage);
|
|
|
159
204
|
|
|
160
205
|
## API Reference
|
|
161
206
|
|
|
207
|
+
### usePromiseState
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
function usePromiseState<R = unknown>(
|
|
211
|
+
options?: UsePromiseStateOptions<R>,
|
|
212
|
+
): UsePromiseStateReturn<R>;
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
A React hook for managing promise state without execution logic.
|
|
216
|
+
|
|
217
|
+
**Parameters:**
|
|
218
|
+
|
|
219
|
+
- `options`: Configuration options
|
|
220
|
+
- `initialStatus`: Initial status, defaults to IDLE
|
|
221
|
+
- `onSuccess`: Callback invoked on success
|
|
222
|
+
- `onError`: Callback invoked on error
|
|
223
|
+
|
|
224
|
+
**Returns:**
|
|
225
|
+
|
|
226
|
+
An object containing:
|
|
227
|
+
|
|
228
|
+
- `status`: Current status (IDLE, LOADING, SUCCESS, ERROR)
|
|
229
|
+
- `loading`: Indicates if currently loading
|
|
230
|
+
- `result`: The result value
|
|
231
|
+
- `error`: The error value
|
|
232
|
+
- `setLoading`: Set status to LOADING
|
|
233
|
+
- `setSuccess`: Set status to SUCCESS with result
|
|
234
|
+
- `setError`: Set status to ERROR with error
|
|
235
|
+
- `setIdle`: Set status to IDLE
|
|
236
|
+
|
|
237
|
+
### useExecutePromise
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
function useExecutePromise<R = unknown>(): UseExecutePromiseReturn<R>;
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
A React hook for managing asynchronous operations with proper state handling.
|
|
244
|
+
|
|
245
|
+
**Returns:**
|
|
246
|
+
|
|
247
|
+
An object containing:
|
|
248
|
+
|
|
249
|
+
- `status`: Current status
|
|
250
|
+
- `loading`: Indicates if currently loading
|
|
251
|
+
- `result`: The result value
|
|
252
|
+
- `error`: The error value
|
|
253
|
+
- `execute`: Function to execute a promise supplier or promise
|
|
254
|
+
- `reset`: Function to reset the state to initial values
|
|
255
|
+
|
|
256
|
+
### useRequestId
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
function useRequestId(): UseRequestIdReturn;
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
A React hook for managing request IDs and race condition protection.
|
|
263
|
+
|
|
264
|
+
**Returns:**
|
|
265
|
+
|
|
266
|
+
An object containing:
|
|
267
|
+
|
|
268
|
+
- `generate`: Generate a new request ID and get the current one
|
|
269
|
+
- `current`: Get the current request ID without generating a new one
|
|
270
|
+
- `isLatest`: Check if a given request ID is the latest
|
|
271
|
+
- `invalidate`: Invalidate current request ID (mark as stale)
|
|
272
|
+
- `reset`: Reset request ID counter
|
|
273
|
+
|
|
162
274
|
### useFetcher
|
|
163
275
|
|
|
164
276
|
```typescript
|
|
165
|
-
function useFetcher<R>(
|
|
166
|
-
request: FetchRequest,
|
|
167
|
-
options?: UseFetcherOptions,
|
|
168
|
-
): UseFetcherResult<R>;
|
|
277
|
+
function useFetcher<R>(options?: UseFetcherOptions): UseFetcherReturn<R>;
|
|
169
278
|
```
|
|
170
279
|
|
|
171
|
-
A React hook
|
|
280
|
+
A React hook for managing asynchronous fetch operations with proper state handling.
|
|
172
281
|
|
|
173
282
|
**Parameters:**
|
|
174
283
|
|
|
175
|
-
- `
|
|
176
|
-
- `options`: Configuration options for the fetch operation
|
|
177
|
-
- `deps`: Dependencies list for the fetch operation. When provided, the hook will re-fetch when any of these values
|
|
178
|
-
change.
|
|
179
|
-
- `immediate`: Whether the fetch operation should execute immediately upon component mount. Defaults to `true`.
|
|
284
|
+
- `options`: Configuration options
|
|
180
285
|
- `fetcher`: Custom fetcher instance to use. Defaults to the default fetcher.
|
|
181
286
|
|
|
182
287
|
**Returns:**
|
|
183
288
|
|
|
184
289
|
An object containing:
|
|
185
290
|
|
|
186
|
-
- `
|
|
187
|
-
- `
|
|
188
|
-
- `result`: The
|
|
189
|
-
- `error`:
|
|
190
|
-
- `
|
|
191
|
-
- `
|
|
291
|
+
- `status`: Current status
|
|
292
|
+
- `loading`: Indicates if currently loading
|
|
293
|
+
- `result`: The result value
|
|
294
|
+
- `error`: The error value
|
|
295
|
+
- `exchange`: The FetchExchange object
|
|
296
|
+
- `execute`: Function to execute a fetch request
|
|
192
297
|
|
|
193
298
|
### useKeyStorage
|
|
194
299
|
|
package/README.zh-CN.md
CHANGED
|
@@ -16,6 +16,7 @@ Fetcher 生态的 React 集成包。提供 React Hooks 和组件,实现无缝
|
|
|
16
16
|
- 🌐 **TypeScript 支持**: 完整的 TypeScript 支持和全面的类型定义
|
|
17
17
|
- 🚀 **现代化**: 使用现代 React 模式和最佳实践构建
|
|
18
18
|
- 🧠 **智能缓存**: 内置缓存和自动重新验证
|
|
19
|
+
- ⚡ **Promise 状态管理**: 用于管理异步操作和 promise 状态的 hooks
|
|
19
20
|
|
|
20
21
|
## 安装
|
|
21
22
|
|
|
@@ -25,82 +26,126 @@ npm install @ahoo-wang/fetcher-react
|
|
|
25
26
|
|
|
26
27
|
## 使用方法
|
|
27
28
|
|
|
28
|
-
###
|
|
29
|
+
### usePromiseState Hook
|
|
29
30
|
|
|
30
|
-
`
|
|
31
|
+
`usePromiseState` hook 提供 promise 操作的状态管理,无执行逻辑。
|
|
31
32
|
|
|
32
33
|
```typescript jsx
|
|
33
|
-
import {
|
|
34
|
+
import { usePromiseState, PromiseStatus } from '@ahoo-wang/fetcher-react';
|
|
34
35
|
|
|
35
36
|
const MyComponent = () => {
|
|
36
|
-
const { loading, error,
|
|
37
|
-
url: '/api/users',
|
|
38
|
-
method: 'GET'
|
|
39
|
-
});
|
|
37
|
+
const { status, loading, result, error, setSuccess, setError, setIdle } = usePromiseState<string>();
|
|
40
38
|
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
const handleSuccess = () => setSuccess('数据加载成功');
|
|
40
|
+
const handleError = () => setError(new Error('加载失败'));
|
|
43
41
|
|
|
44
42
|
return (
|
|
45
43
|
<div>
|
|
46
|
-
<
|
|
47
|
-
<button onClick={
|
|
48
|
-
<button onClick={
|
|
44
|
+
<button onClick={handleSuccess}>设置成功</button>
|
|
45
|
+
<button onClick={handleError}>设置错误</button>
|
|
46
|
+
<button onClick={setIdle}>重置</button>
|
|
47
|
+
<p>状态: {status}</p>
|
|
48
|
+
{loading && <p>加载中...</p>}
|
|
49
|
+
{result && <p>结果: {result}</p>}
|
|
50
|
+
{error && <p>错误: {error.message}</p>}
|
|
49
51
|
</div>
|
|
50
52
|
);
|
|
51
53
|
};
|
|
52
54
|
```
|
|
53
55
|
|
|
54
|
-
###
|
|
56
|
+
### useExecutePromise Hook
|
|
55
57
|
|
|
56
|
-
|
|
58
|
+
`useExecutePromise` hook 管理异步操作,具有自动状态处理和内置竞态条件保护。
|
|
57
59
|
|
|
58
60
|
```typescript jsx
|
|
59
|
-
import {
|
|
61
|
+
import { useExecutePromise } from '@ahoo-wang/fetcher-react';
|
|
60
62
|
|
|
61
63
|
const MyComponent = () => {
|
|
62
|
-
const { loading,
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const handleSubmit = async () => {
|
|
69
|
-
await execute();
|
|
64
|
+
const { loading, result, error, execute, reset } = useExecutePromise<string>();
|
|
65
|
+
|
|
66
|
+
const fetchData = async () => {
|
|
67
|
+
const response = await fetch('/api/data');
|
|
68
|
+
return response.text();
|
|
70
69
|
};
|
|
71
70
|
|
|
72
|
-
|
|
71
|
+
const handleFetch = () => {
|
|
72
|
+
execute(fetchData); // 使用 promise supplier
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const handleDirectPromise = () => {
|
|
76
|
+
const promise = fetch('/api/data').then(res => res.text());
|
|
77
|
+
execute(promise); // 使用直接 promise
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
if (loading) return <div>加载中...</div>;
|
|
73
81
|
if (error) return <div>错误: {error.message}</div>;
|
|
82
|
+
return (
|
|
83
|
+
<div>
|
|
84
|
+
<button onClick={handleFetch}>使用 Supplier 获取</button>
|
|
85
|
+
<button onClick={handleDirectPromise}>使用 Promise 获取</button>
|
|
86
|
+
<button onClick={reset}>重置</button>
|
|
87
|
+
{result && <p>{result}</p>}
|
|
88
|
+
</div>
|
|
89
|
+
);
|
|
90
|
+
};
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### useRequestId Hook
|
|
94
|
+
|
|
95
|
+
`useRequestId` hook 提供请求ID管理,用于防止异步操作中的竞态条件。
|
|
96
|
+
|
|
97
|
+
```typescript jsx
|
|
98
|
+
import { useRequestId } from '@ahoo-wang/fetcher-react';
|
|
99
|
+
|
|
100
|
+
const MyComponent = () => {
|
|
101
|
+
const { generate, isLatest, invalidate } = useRequestId();
|
|
102
|
+
|
|
103
|
+
const handleFetch = async () => {
|
|
104
|
+
const requestId = generate();
|
|
105
|
+
|
|
106
|
+
try {
|
|
107
|
+
const result = await fetchData();
|
|
108
|
+
|
|
109
|
+
if (isLatest(requestId)) {
|
|
110
|
+
setData(result);
|
|
111
|
+
}
|
|
112
|
+
} catch (error) {
|
|
113
|
+
if (isLatest(requestId)) {
|
|
114
|
+
setError(error);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
};
|
|
74
118
|
|
|
75
119
|
return (
|
|
76
120
|
<div>
|
|
77
|
-
|
|
78
|
-
<button onClick={
|
|
121
|
+
<button onClick={handleFetch}>获取数据</button>
|
|
122
|
+
<button onClick={invalidate}>取消进行中</button>
|
|
79
123
|
</div>
|
|
80
124
|
);
|
|
81
125
|
};
|
|
82
126
|
```
|
|
83
127
|
|
|
84
|
-
###
|
|
128
|
+
### useFetcher Hook
|
|
85
129
|
|
|
86
|
-
|
|
130
|
+
`useFetcher` hook 提供数据获取功能,具有自动状态管理。
|
|
87
131
|
|
|
88
132
|
```typescript jsx
|
|
89
133
|
import { useFetcher } from '@ahoo-wang/fetcher-react';
|
|
90
134
|
|
|
91
|
-
const
|
|
92
|
-
const { loading, error, result } = useFetcher(
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
135
|
+
const MyComponent = () => {
|
|
136
|
+
const { loading, error, result, execute } = useFetcher<string>();
|
|
137
|
+
|
|
138
|
+
const handleFetch = () => {
|
|
139
|
+
execute({ url: '/api/users', method: 'GET' });
|
|
140
|
+
};
|
|
96
141
|
|
|
97
142
|
if (loading) return <div>加载中...</div>;
|
|
98
143
|
if (error) return <div>错误: {error.message}</div>;
|
|
99
144
|
|
|
100
145
|
return (
|
|
101
146
|
<div>
|
|
102
|
-
<
|
|
103
|
-
<
|
|
147
|
+
<pre>{JSON.stringify(result, null, 2)}</pre>
|
|
148
|
+
<button onClick={handleFetch}>获取数据</button>
|
|
104
149
|
</div>
|
|
105
150
|
);
|
|
106
151
|
};
|
|
@@ -153,35 +198,96 @@ const [user, setUser] = useKeyStorage(userStorage);
|
|
|
153
198
|
|
|
154
199
|
## API 参考
|
|
155
200
|
|
|
201
|
+
### usePromiseState
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
function usePromiseState<R = unknown>(
|
|
205
|
+
options?: UsePromiseStateOptions<R>,
|
|
206
|
+
): UsePromiseStateReturn<R>;
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
用于管理 promise 状态的 React hook,无执行逻辑。
|
|
210
|
+
|
|
211
|
+
**参数:**
|
|
212
|
+
|
|
213
|
+
- `options`: 配置选项
|
|
214
|
+
- `initialStatus`: 初始状态,默认为 IDLE
|
|
215
|
+
- `onSuccess`: 成功时调用的回调
|
|
216
|
+
- `onError`: 错误时调用的回调
|
|
217
|
+
|
|
218
|
+
**返回值:**
|
|
219
|
+
|
|
220
|
+
包含以下属性的对象:
|
|
221
|
+
|
|
222
|
+
- `status`: 当前状态 (IDLE, LOADING, SUCCESS, ERROR)
|
|
223
|
+
- `loading`: 指示当前是否加载中
|
|
224
|
+
- `result`: 结果值
|
|
225
|
+
- `error`: 错误值
|
|
226
|
+
- `setLoading`: 设置状态为 LOADING
|
|
227
|
+
- `setSuccess`: 设置状态为 SUCCESS 并提供结果
|
|
228
|
+
- `setError`: 设置状态为 ERROR 并提供错误
|
|
229
|
+
- `setIdle`: 设置状态为 IDLE
|
|
230
|
+
|
|
231
|
+
### useExecutePromise
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
function useExecutePromise<R = unknown>(): UseExecutePromiseReturn<R>;
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
用于管理异步操作的 React hook,具有适当的状态处理。
|
|
238
|
+
|
|
239
|
+
**返回值:**
|
|
240
|
+
|
|
241
|
+
包含以下属性的对象:
|
|
242
|
+
|
|
243
|
+
- `status`: 当前状态
|
|
244
|
+
- `loading`: 指示当前是否加载中
|
|
245
|
+
- `result`: 结果值
|
|
246
|
+
- `error`: 错误值
|
|
247
|
+
- `execute`: 执行 promise supplier 或 promise 的函数
|
|
248
|
+
- `reset`: 重置状态到初始值的函数
|
|
249
|
+
|
|
250
|
+
### useRequestId
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
function useRequestId(): UseRequestIdReturn;
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
用于管理请求ID和竞态条件保护的 React hook。
|
|
257
|
+
|
|
258
|
+
**返回值:**
|
|
259
|
+
|
|
260
|
+
包含以下属性的对象:
|
|
261
|
+
|
|
262
|
+
- `generate`: 生成新请求ID并获取当前ID
|
|
263
|
+
- `current`: 获取当前请求ID而不生成新ID
|
|
264
|
+
- `isLatest`: 检查给定请求ID是否为最新
|
|
265
|
+
- `invalidate`: 使当前请求ID失效(标记为过时)
|
|
266
|
+
- `reset`: 重置请求ID计数器
|
|
267
|
+
|
|
156
268
|
### useFetcher
|
|
157
269
|
|
|
158
270
|
```typescript
|
|
159
|
-
function useFetcher<R>(
|
|
160
|
-
request: FetchRequest,
|
|
161
|
-
options?: UseFetcherOptions,
|
|
162
|
-
): UseFetcherResult<R>;
|
|
271
|
+
function useFetcher<R>(options?: UseFetcherOptions): UseFetcherReturn<R>;
|
|
163
272
|
```
|
|
164
273
|
|
|
165
|
-
|
|
274
|
+
用于管理异步获取操作的 React hook,具有适当的状态处理。
|
|
166
275
|
|
|
167
276
|
**参数:**
|
|
168
277
|
|
|
169
|
-
- `
|
|
170
|
-
- `options`: 获取数据操作的配置选项
|
|
171
|
-
- `deps`: 获取数据操作的依赖项列表。提供时,当这些值中的任何一个发生变化时,hook 将重新获取数据。
|
|
172
|
-
- `immediate`: 获取数据操作是否应在组件挂载时立即执行。默认为 `true`。
|
|
278
|
+
- `options`: 配置选项
|
|
173
279
|
- `fetcher`: 要使用的自定义获取器实例。默认为默认获取器。
|
|
174
280
|
|
|
175
281
|
**返回值:**
|
|
176
282
|
|
|
177
283
|
包含以下属性的对象:
|
|
178
284
|
|
|
179
|
-
- `
|
|
180
|
-
- `
|
|
181
|
-
- `result`:
|
|
182
|
-
- `error`:
|
|
183
|
-
- `
|
|
184
|
-
- `
|
|
285
|
+
- `status`: 当前状态
|
|
286
|
+
- `loading`: 指示当前是否加载中
|
|
287
|
+
- `result`: 结果值
|
|
288
|
+
- `error`: 错误值
|
|
289
|
+
- `exchange`: FetchExchange 对象
|
|
290
|
+
- `execute`: 执行获取请求的函数
|
|
185
291
|
|
|
186
292
|
### useKeyStorage
|
|
187
293
|
|
package/dist/core/index.d.ts
CHANGED
package/dist/core/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAaA,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAaA,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC"}
|
|
@@ -7,15 +7,10 @@ export type PromiseSupplier<R> = () => Promise<R>;
|
|
|
7
7
|
/**
|
|
8
8
|
* Interface defining the return type of useExecutePromise hook
|
|
9
9
|
* @template R - The type of the result value
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* ```typescript
|
|
13
|
-
* const { loading, result, error, execute, reset } = useExecutePromise<string>();
|
|
14
|
-
* ```
|
|
15
10
|
*/
|
|
16
|
-
export interface UseExecutePromiseReturn<R> extends PromiseState<R> {
|
|
17
|
-
/** Function to execute a promise supplier */
|
|
18
|
-
execute: (
|
|
11
|
+
export interface UseExecutePromiseReturn<R, E = unknown> extends PromiseState<R, E> {
|
|
12
|
+
/** Function to execute a promise supplier or promise */
|
|
13
|
+
execute: (input: PromiseSupplier<R> | Promise<R>) => Promise<R>;
|
|
19
14
|
/** Function to reset the state to initial values */
|
|
20
15
|
reset: () => void;
|
|
21
16
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useExecutePromise.d.ts","sourceRoot":"","sources":["../../src/core/useExecutePromise.ts"],"names":[],"mappings":"AAeA,OAAO,EAAmB,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"useExecutePromise.d.ts","sourceRoot":"","sources":["../../src/core/useExecutePromise.ts"],"names":[],"mappings":"AAeA,OAAO,EAAmB,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGlE;;;GAGG;AACH,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;AAElD;;;GAGG;AACH,MAAM,WAAW,uBAAuB,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CACrD,SAAQ,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC;IAC1B,wDAAwD;IACxD,OAAO,EAAE,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAChE,oDAAoD;IACpD,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,GAAG,OAAO,KAAK,uBAAuB,CAAC,CAAC,CAAC,CAuD3E"}
|
|
@@ -7,7 +7,7 @@ export declare enum PromiseStatus {
|
|
|
7
7
|
SUCCESS = "success",
|
|
8
8
|
ERROR = "error"
|
|
9
9
|
}
|
|
10
|
-
export interface PromiseState<R> {
|
|
10
|
+
export interface PromiseState<R, E = unknown> {
|
|
11
11
|
/** Current status of the promise */
|
|
12
12
|
status: PromiseStatus;
|
|
13
13
|
/** Indicates if currently loading */
|
|
@@ -15,7 +15,7 @@ export interface PromiseState<R> {
|
|
|
15
15
|
/** The result value */
|
|
16
16
|
result: R | undefined;
|
|
17
17
|
/** The error value */
|
|
18
|
-
error:
|
|
18
|
+
error: E | undefined;
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
21
|
* Options for configuring usePromiseState behavior
|
|
@@ -30,25 +30,25 @@ export interface PromiseState<R> {
|
|
|
30
30
|
* };
|
|
31
31
|
* ```
|
|
32
32
|
*/
|
|
33
|
-
export interface UsePromiseStateOptions<R> {
|
|
33
|
+
export interface UsePromiseStateOptions<R, E = unknown> {
|
|
34
34
|
/** Initial status, defaults to IDLE */
|
|
35
35
|
initialStatus?: PromiseStatus;
|
|
36
36
|
/** Callback invoked on success */
|
|
37
37
|
onSuccess?: (result: R) => void;
|
|
38
38
|
/** Callback invoked on error */
|
|
39
|
-
onError?: (error:
|
|
39
|
+
onError?: (error: E) => void;
|
|
40
40
|
}
|
|
41
41
|
/**
|
|
42
42
|
* Return type for usePromiseState hook
|
|
43
43
|
* @template R - The type of result
|
|
44
44
|
*/
|
|
45
|
-
export interface UsePromiseStateReturn<R> extends PromiseState<R> {
|
|
45
|
+
export interface UsePromiseStateReturn<R, E = unknown> extends PromiseState<R, E> {
|
|
46
46
|
/** Set status to LOADING */
|
|
47
47
|
setLoading: () => void;
|
|
48
48
|
/** Set status to SUCCESS with result */
|
|
49
49
|
setSuccess: (result: R) => void;
|
|
50
50
|
/** Set status to ERROR with error */
|
|
51
|
-
setError: (error:
|
|
51
|
+
setError: (error: E) => void;
|
|
52
52
|
/** Set status to IDLE */
|
|
53
53
|
setIdle: () => void;
|
|
54
54
|
}
|
|
@@ -82,5 +82,5 @@ export interface UsePromiseStateReturn<R> extends PromiseState<R> {
|
|
|
82
82
|
* }
|
|
83
83
|
* ```
|
|
84
84
|
*/
|
|
85
|
-
export declare function usePromiseState<R = unknown>(options?: UsePromiseStateOptions<R>): UsePromiseStateReturn<R>;
|
|
85
|
+
export declare function usePromiseState<R = unknown, E = unknown>(options?: UsePromiseStateOptions<R, E>): UsePromiseStateReturn<R, E>;
|
|
86
86
|
//# sourceMappingURL=usePromiseState.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePromiseState.d.ts","sourceRoot":"","sources":["../../src/core/usePromiseState.ts"],"names":[],"mappings":"AAgBA;;GAEG;AACH,oBAAY,aAAa;IACvB,IAAI,SAAS;IACb,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,KAAK,UAAU;CAChB;AAED,MAAM,WAAW,YAAY,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"usePromiseState.d.ts","sourceRoot":"","sources":["../../src/core/usePromiseState.ts"],"names":[],"mappings":"AAgBA;;GAEG;AACH,oBAAY,aAAa;IACvB,IAAI,SAAS;IACb,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,KAAK,UAAU;CAChB;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO;IAC1C,oCAAoC;IACpC,MAAM,EAAE,aAAa,CAAC;IACtB,qCAAqC;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,uBAAuB;IACvB,MAAM,EAAE,CAAC,GAAG,SAAS,CAAC;IACtB,sBAAsB;IACtB,KAAK,EAAE,CAAC,GAAG,SAAS,CAAC;CACtB;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,sBAAsB,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO;IACpD,uCAAuC;IACvC,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,kCAAkC;IAClC,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC;IAChC,gCAAgC;IAChC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAE,SAAQ,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC;IAC/E,4BAA4B;IAC5B,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,wCAAwC;IACxC,UAAU,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC;IAChC,qCAAqC;IACrC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC7B,yBAAyB;IACzB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,eAAe,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EACtD,OAAO,CAAC,EAAE,sBAAsB,CAAC,CAAC,EAAE,CAAC,CAAC,GACrC,qBAAqB,CAAC,CAAC,EAAE,CAAC,CAAC,CAwD7B"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Return type for useRequestId hook
|
|
3
|
+
*/
|
|
4
|
+
export interface UseRequestIdReturn {
|
|
5
|
+
/** Generate a new request ID and get the current one */
|
|
6
|
+
generate: () => number;
|
|
7
|
+
/** Get the current request ID without generating a new one */
|
|
8
|
+
current: () => number;
|
|
9
|
+
/** Check if a given request ID is the latest */
|
|
10
|
+
isLatest: (requestId: number) => boolean;
|
|
11
|
+
/** Invalidate current request ID (mark as stale) */
|
|
12
|
+
invalidate: () => void;
|
|
13
|
+
/** Reset request ID counter */
|
|
14
|
+
reset: () => void;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A React hook for managing request IDs and race condition protection
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* // Basic usage
|
|
22
|
+
* const requestId = useRequestId();
|
|
23
|
+
*
|
|
24
|
+
* const execute = async () => {
|
|
25
|
+
* const id = requestId.generate();
|
|
26
|
+
*
|
|
27
|
+
* try {
|
|
28
|
+
* const result = await someAsyncOperation();
|
|
29
|
+
*
|
|
30
|
+
* // Check if this is still the latest request
|
|
31
|
+
* if (requestId.isLatest(id)) {
|
|
32
|
+
* setState(result);
|
|
33
|
+
* }
|
|
34
|
+
* } catch (error) {
|
|
35
|
+
* if (requestId.isLatest(id)) {
|
|
36
|
+
* setError(error);
|
|
37
|
+
* }
|
|
38
|
+
* }
|
|
39
|
+
* };
|
|
40
|
+
*
|
|
41
|
+
* // Manual cancellation
|
|
42
|
+
* const handleCancel = () => {
|
|
43
|
+
* requestId.invalidate(); // All ongoing requests will be ignored
|
|
44
|
+
* };
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* // With async operation wrapper
|
|
50
|
+
* const { execute, cancel } = useAsyncOperation(async (data) => {
|
|
51
|
+
* return await apiCall(data);
|
|
52
|
+
* }, [requestId]);
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare function useRequestId(): UseRequestIdReturn;
|
|
56
|
+
//# sourceMappingURL=useRequestId.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRequestId.d.ts","sourceRoot":"","sources":["../../src/core/useRequestId.ts"],"names":[],"mappings":"AAeA;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,wDAAwD;IACxD,QAAQ,EAAE,MAAM,MAAM,CAAC;IACvB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,MAAM,CAAC;IACtB,gDAAgD;IAChD,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;IACzC,oDAAoD;IACpD,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,+BAA+B;IAC/B,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,YAAY,IAAI,kBAAkB,CA8BjD"}
|
|
@@ -6,7 +6,7 @@ import { PromiseState } from '../core';
|
|
|
6
6
|
*/
|
|
7
7
|
export interface UseFetcherOptions extends RequestOptions, FetcherCapable {
|
|
8
8
|
}
|
|
9
|
-
export interface UseFetcherReturn<R> extends PromiseState<R> {
|
|
9
|
+
export interface UseFetcherReturn<R, E = unknown> extends PromiseState<R, E> {
|
|
10
10
|
/** The FetchExchange object representing the ongoing fetch operation */
|
|
11
11
|
exchange?: FetchExchange;
|
|
12
12
|
execute: (request: FetchRequest) => Promise<void>;
|
|
@@ -38,5 +38,5 @@ export interface UseFetcherReturn<R> extends PromiseState<R> {
|
|
|
38
38
|
* }
|
|
39
39
|
* ```
|
|
40
40
|
*/
|
|
41
|
-
export declare function useFetcher<R>(options?: UseFetcherOptions): UseFetcherReturn<R>;
|
|
41
|
+
export declare function useFetcher<R, E = unknown>(options?: UseFetcherOptions): UseFetcherReturn<R, E>;
|
|
42
42
|
//# sourceMappingURL=useFetcher.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFetcher.d.ts","sourceRoot":"","sources":["../../src/fetcher/useFetcher.ts"],"names":[],"mappings":"AAaA,OAAO,EAEL,cAAc,EACd,aAAa,EACb,YAAY,EAEZ,cAAc,EACf,MAAM,oBAAoB,CAAC;AAG5B,OAAO,
|
|
1
|
+
{"version":3,"file":"useFetcher.d.ts","sourceRoot":"","sources":["../../src/fetcher/useFetcher.ts"],"names":[],"mappings":"AAaA,OAAO,EAEL,cAAc,EACd,aAAa,EACb,YAAY,EAEZ,cAAc,EACf,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,YAAY,EAAiC,MAAM,SAAS,CAAC;AAEtE;;;GAGG;AACH,MAAM,WAAW,iBAAkB,SAAQ,cAAc,EAAE,cAAc;CACxE;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAE,SAAQ,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC;IAC1E,wEAAwE;IACxE,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,OAAO,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACnD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,EACvC,OAAO,CAAC,EAAE,iBAAiB,GAC1B,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,CAgExB"}
|
package/dist/index.es.js
CHANGED
|
@@ -1,130 +1,151 @@
|
|
|
1
|
-
import { useRef as
|
|
2
|
-
import { fetcher as
|
|
3
|
-
function
|
|
4
|
-
var t =
|
|
1
|
+
import { useRef as h, useCallback as c, useEffect as L, useState as E, useMemo as I, useSyncExternalStore as x } from "react";
|
|
2
|
+
import { fetcher as S, getFetcher as C } from "@ahoo-wang/fetcher";
|
|
3
|
+
function v() {
|
|
4
|
+
var t = h(!1), r = c(function() {
|
|
5
5
|
return t.current;
|
|
6
6
|
}, []);
|
|
7
|
-
return
|
|
7
|
+
return L(function() {
|
|
8
8
|
return t.current = !0, function() {
|
|
9
9
|
t.current = !1;
|
|
10
10
|
};
|
|
11
|
-
}, []),
|
|
11
|
+
}, []), r;
|
|
12
12
|
}
|
|
13
|
-
var
|
|
14
|
-
function
|
|
15
|
-
const [
|
|
13
|
+
var w = /* @__PURE__ */ ((t) => (t.IDLE = "idle", t.LOADING = "loading", t.SUCCESS = "success", t.ERROR = "error", t))(w || {});
|
|
14
|
+
function R(t) {
|
|
15
|
+
const [r, e] = E(
|
|
16
16
|
t?.initialStatus ?? "idle"
|
|
17
17
|
/* IDLE */
|
|
18
|
-
), [
|
|
19
|
-
o() && (
|
|
18
|
+
), [i, u] = E(void 0), [n, s] = E(void 0), o = v(), d = c(() => {
|
|
19
|
+
o() && (e(
|
|
20
20
|
"loading"
|
|
21
21
|
/* LOADING */
|
|
22
22
|
), s(void 0));
|
|
23
|
-
}, [o]),
|
|
24
|
-
(
|
|
25
|
-
o() && (u(
|
|
23
|
+
}, [o]), g = c(
|
|
24
|
+
(a) => {
|
|
25
|
+
o() && (u(a), e(
|
|
26
26
|
"success"
|
|
27
27
|
/* SUCCESS */
|
|
28
|
-
), s(void 0), t?.onSuccess?.(
|
|
28
|
+
), s(void 0), t?.onSuccess?.(a));
|
|
29
29
|
},
|
|
30
30
|
[o, t]
|
|
31
|
-
),
|
|
32
|
-
(
|
|
33
|
-
o() && (s(
|
|
31
|
+
), f = c(
|
|
32
|
+
(a) => {
|
|
33
|
+
o() && (s(a), e(
|
|
34
34
|
"error"
|
|
35
35
|
/* ERROR */
|
|
36
|
-
), u(void 0), t?.onError?.(
|
|
36
|
+
), u(void 0), t?.onError?.(a));
|
|
37
37
|
},
|
|
38
38
|
[o, t]
|
|
39
|
-
),
|
|
40
|
-
o() && (
|
|
39
|
+
), l = c(() => {
|
|
40
|
+
o() && (e(
|
|
41
41
|
"idle"
|
|
42
42
|
/* IDLE */
|
|
43
43
|
), s(void 0), u(void 0));
|
|
44
44
|
}, [o]);
|
|
45
|
+
return I(() => ({
|
|
46
|
+
status: r,
|
|
47
|
+
loading: r === "loading",
|
|
48
|
+
result: i,
|
|
49
|
+
error: n,
|
|
50
|
+
setLoading: d,
|
|
51
|
+
setSuccess: g,
|
|
52
|
+
setError: f,
|
|
53
|
+
setIdle: l
|
|
54
|
+
}), [r, i, n, d, g, f, l]);
|
|
55
|
+
}
|
|
56
|
+
function b() {
|
|
57
|
+
const t = h(0), r = c(() => ++t.current, []), e = c(() => t.current, []), i = c((s) => s === t.current, []), u = c(() => {
|
|
58
|
+
t.current++;
|
|
59
|
+
}, []), n = c(() => {
|
|
60
|
+
t.current = 0;
|
|
61
|
+
}, []);
|
|
45
62
|
return {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
setSuccess: l,
|
|
52
|
-
setError: i,
|
|
53
|
-
setIdle: h
|
|
63
|
+
generate: r,
|
|
64
|
+
current: e,
|
|
65
|
+
isLatest: i,
|
|
66
|
+
invalidate: u,
|
|
67
|
+
reset: n
|
|
54
68
|
};
|
|
55
69
|
}
|
|
56
|
-
function
|
|
57
|
-
const t =
|
|
58
|
-
async (
|
|
59
|
-
if (!
|
|
70
|
+
function q() {
|
|
71
|
+
const t = R(), r = v(), e = b(), i = c(
|
|
72
|
+
async (n) => {
|
|
73
|
+
if (!r())
|
|
60
74
|
throw new Error("Component is unmounted");
|
|
75
|
+
const s = e.generate();
|
|
61
76
|
t.setLoading();
|
|
62
77
|
try {
|
|
63
|
-
const
|
|
64
|
-
return
|
|
65
|
-
} catch (
|
|
66
|
-
throw
|
|
78
|
+
const d = await (typeof n == "function" ? n() : n);
|
|
79
|
+
return r() && e.isLatest(s) && t.setSuccess(d), d;
|
|
80
|
+
} catch (o) {
|
|
81
|
+
throw r() && e.isLatest(s) && t.setError(o), o;
|
|
67
82
|
}
|
|
68
83
|
},
|
|
69
|
-
[t,
|
|
70
|
-
),
|
|
71
|
-
|
|
72
|
-
}, [t,
|
|
73
|
-
return
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
84
|
+
[t, r, e]
|
|
85
|
+
), u = c(() => {
|
|
86
|
+
r() && t.setIdle();
|
|
87
|
+
}, [t, r]);
|
|
88
|
+
return I(
|
|
89
|
+
() => ({
|
|
90
|
+
loading: t.loading,
|
|
91
|
+
result: t.result,
|
|
92
|
+
error: t.error,
|
|
93
|
+
execute: i,
|
|
94
|
+
reset: u,
|
|
95
|
+
status: t.status
|
|
96
|
+
}),
|
|
97
|
+
[t.loading, t.result, t.error, i, u, t.status]
|
|
98
|
+
);
|
|
81
99
|
}
|
|
82
|
-
function
|
|
83
|
-
const
|
|
84
|
-
(
|
|
100
|
+
function y(t) {
|
|
101
|
+
const r = c(
|
|
102
|
+
(n) => t.addListener(n),
|
|
85
103
|
[t]
|
|
86
|
-
),
|
|
87
|
-
(
|
|
104
|
+
), e = c(() => t.get(), [t]), i = x(r, e, e), u = c(
|
|
105
|
+
(n) => t.set(n),
|
|
88
106
|
[t]
|
|
89
107
|
);
|
|
90
|
-
return [
|
|
108
|
+
return [i, u];
|
|
91
109
|
}
|
|
92
|
-
function
|
|
93
|
-
const { fetcher:
|
|
110
|
+
function A(t) {
|
|
111
|
+
const { fetcher: r = S } = t || {}, e = R(), [i, u] = E(
|
|
94
112
|
void 0
|
|
95
|
-
),
|
|
96
|
-
async (
|
|
97
|
-
s.current && s.current.abort(), s.current =
|
|
113
|
+
), n = v(), s = h(), o = b(), d = C(r), g = c(
|
|
114
|
+
async (f) => {
|
|
115
|
+
s.current && s.current.abort(), s.current = f.abortController ?? new AbortController(), f.abortController = s.current;
|
|
116
|
+
const l = o.generate();
|
|
117
|
+
e.setLoading();
|
|
98
118
|
try {
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
} catch (
|
|
104
|
-
if (
|
|
105
|
-
|
|
119
|
+
const a = await d.exchange(f, t);
|
|
120
|
+
n() && o.isLatest(l) && u(a);
|
|
121
|
+
const m = await a.extractResult();
|
|
122
|
+
n() && o.isLatest(l) && e.setSuccess(m);
|
|
123
|
+
} catch (a) {
|
|
124
|
+
if (a instanceof Error && a.name === "AbortError") {
|
|
125
|
+
n() && e.setIdle();
|
|
106
126
|
return;
|
|
107
127
|
}
|
|
108
|
-
|
|
128
|
+
n() && o.isLatest(l) && e.setError(a);
|
|
109
129
|
} finally {
|
|
110
|
-
s.current ===
|
|
130
|
+
s.current === f.abortController && (s.current = void 0);
|
|
111
131
|
}
|
|
112
132
|
},
|
|
113
|
-
[
|
|
133
|
+
[d, n, t, e, o]
|
|
114
134
|
);
|
|
115
|
-
return
|
|
135
|
+
return L(() => () => {
|
|
116
136
|
s.current?.abort(), s.current = void 0;
|
|
117
137
|
}, []), {
|
|
118
|
-
...
|
|
119
|
-
exchange:
|
|
120
|
-
execute:
|
|
138
|
+
...e,
|
|
139
|
+
exchange: i,
|
|
140
|
+
execute: g
|
|
121
141
|
};
|
|
122
142
|
}
|
|
123
143
|
export {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
144
|
+
w as PromiseStatus,
|
|
145
|
+
q as useExecutePromise,
|
|
146
|
+
A as useFetcher,
|
|
147
|
+
y as useKeyStorage,
|
|
148
|
+
R as usePromiseState,
|
|
149
|
+
b as useRequestId
|
|
129
150
|
};
|
|
130
151
|
//# sourceMappingURL=index.es.js.map
|
package/dist/index.es.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.es.js","sources":["../../../node_modules/.pnpm/react-use@17.6.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/react-use/esm/useMountedState.js","../src/core/usePromiseState.ts","../src/core/useExecutePromise.ts","../src/storage/useKeyStorage.ts","../src/fetcher/useFetcher.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\nexport default function useMountedState() {\n var mountedRef = useRef(false);\n var get = useCallback(function () { return mountedRef.current; }, []);\n useEffect(function () {\n mountedRef.current = true;\n return function () {\n mountedRef.current = false;\n };\n }, []);\n return get;\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback, useState } from 'react';\nimport { useMountedState } from 'react-use';\n\n/**\n * Enumeration of possible promise execution states\n */\nexport enum PromiseStatus {\n IDLE = 'idle',\n LOADING = 'loading',\n SUCCESS = 'success',\n ERROR = 'error',\n}\n\nexport interface PromiseState<R> {\n /** Current status of the promise */\n status: PromiseStatus;\n /** Indicates if currently loading */\n loading: boolean;\n /** The result value */\n result: R | undefined;\n /** The error value */\n error: unknown | undefined;\n}\n\n/**\n * Options for configuring usePromiseState behavior\n * @template R - The type of result\n *\n * @example\n * ```typescript\n * const options: UsePromiseStateOptions<string> = {\n * initialStatus: PromiseStatus.IDLE,\n * onSuccess: (result) => console.log('Success:', result),\n * onError: (error) => console.error('Error:', error),\n * };\n * ```\n */\nexport interface UsePromiseStateOptions<R> {\n /** Initial status, defaults to IDLE */\n initialStatus?: PromiseStatus;\n /** Callback invoked on success */\n onSuccess?: (result: R) => void;\n /** Callback invoked on error */\n onError?: (error: unknown) => void;\n}\n\n/**\n * Return type for usePromiseState hook\n * @template R - The type of result\n */\nexport interface UsePromiseStateReturn<R> extends PromiseState<R> {\n /** Set status to LOADING */\n setLoading: () => void;\n /** Set status to SUCCESS with result */\n setSuccess: (result: R) => void;\n /** Set status to ERROR with error */\n setError: (error: unknown) => void;\n /** Set status to IDLE */\n setIdle: () => void;\n}\n\n/**\n * A React hook for managing promise state without execution logic\n * @template R - The type of result\n * @param options - Configuration options\n * @returns State management object\n *\n * @example\n * ```typescript\n * import { usePromiseState, PromiseStatus } from '@ahoo-wang/fetcher-react';\n *\n * function MyComponent() {\n * const { status, loading, result, error, setSuccess, setError, setIdle } = usePromiseState<string>();\n *\n * const handleSuccess = () => setSuccess('Data loaded');\n * const handleError = () => setError(new Error('Failed to load'));\n *\n * return (\n * <div>\n * <button onClick={handleSuccess}>Set Success</button>\n * <button onClick={handleError}>Set Error</button>\n * <button onClick={setIdle}>Reset</button>\n * <p>Status: {status}</p>\n * {loading && <p>Loading...</p>}\n * {result && <p>Result: {result}</p>}\n * {error && <p>Error: {error.message}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function usePromiseState<R = unknown>(\n options?: UsePromiseStateOptions<R>,\n): UsePromiseStateReturn<R> {\n const [status, setStatus] = useState<PromiseStatus>(\n options?.initialStatus ?? PromiseStatus.IDLE,\n );\n const [result, setResult] = useState<R | undefined>(undefined);\n const [error, setErrorState] = useState<unknown | undefined>(undefined);\n const isMounted = useMountedState();\n\n const setLoadingFn = useCallback(() => {\n if (isMounted()) {\n setStatus(PromiseStatus.LOADING);\n setErrorState(undefined);\n }\n }, [isMounted]);\n\n const setSuccessFn = useCallback(\n (result: R) => {\n if (isMounted()) {\n setResult(result);\n setStatus(PromiseStatus.SUCCESS);\n setErrorState(undefined);\n options?.onSuccess?.(result);\n }\n },\n [isMounted, options],\n );\n\n const setErrorFn = useCallback(\n (error: unknown) => {\n if (isMounted()) {\n setErrorState(error);\n setStatus(PromiseStatus.ERROR);\n setResult(undefined);\n options?.onError?.(error);\n }\n },\n [isMounted, options],\n );\n\n const setIdleFn = useCallback(() => {\n if (isMounted()) {\n setStatus(PromiseStatus.IDLE);\n setErrorState(undefined);\n setResult(undefined);\n }\n }, [isMounted]);\n\n return {\n status,\n loading: status === PromiseStatus.LOADING,\n result,\n error,\n setLoading: setLoadingFn,\n setSuccess: setSuccessFn,\n setError: setErrorFn,\n setIdle: setIdleFn,\n };\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback } from 'react';\nimport { useMountedState } from 'react-use';\nimport { usePromiseState, PromiseState } from './usePromiseState';\n\n/**\n * Type definition for a function that returns a Promise\n * @template R - The type of value the promise will resolve to\n */\nexport type PromiseSupplier<R> = () => Promise<R>;\n\n/**\n * Interface defining the return type of useExecutePromise hook\n * @template R - The type of the result value\n *\n * @example\n * ```typescript\n * const { loading, result, error, execute, reset } = useExecutePromise<string>();\n * ```\n */\nexport interface UseExecutePromiseReturn<R> extends PromiseState<R> {\n /** Function to execute a promise supplier */\n execute: (provider: PromiseSupplier<R>) => Promise<R>;\n /** Function to reset the state to initial values */\n reset: () => void;\n}\n\n/**\n * A React hook for managing asynchronous operations with proper state handling\n * @template R - The type of the result value\n * @returns An object containing the current state and control functions\n *\n * @example\n * ```typescript\n * import { useExecutePromise } from '@ahoo-wang/fetcher-react';\n *\n * function MyComponent() {\n * const { loading, result, error, execute, reset } = useExecutePromise<string>();\n *\n * const fetchData = async () => {\n * const response = await fetch('/api/data');\n * return response.text();\n * };\n *\n * const handleFetch = () => {\n * execute(fetchData);\n * };\n *\n * const handleReset = () => {\n * reset();\n * };\n *\n * if (loading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * return (\n * <div>\n * <button onClick={handleFetch}>Fetch Data</button>\n * <button onClick={handleReset}>Reset</button>\n * {result && <p>{result}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function useExecutePromise<R = unknown>(): UseExecutePromiseReturn<R> {\n const state = usePromiseState<R>();\n const isMounted = useMountedState();\n\n /**\n * Execute a promise supplier and manage its state\n * @param provider - A function that returns a Promise to be executed\n * @returns A Promise that resolves with the result of the executed promise\n */\n const execute = useCallback(\n async (provider: PromiseSupplier<R>): Promise<R> => {\n if (!isMounted()) {\n throw new Error('Component is unmounted');\n }\n state.setLoading();\n try {\n const data = await provider();\n\n if (isMounted()) {\n state.setSuccess(data);\n }\n return data;\n } catch (err) {\n if (isMounted()) {\n state.setError(err);\n }\n throw err;\n }\n },\n [state, isMounted],\n );\n\n /**\n * Reset the state to initial values\n */\n const reset = useCallback(() => {\n if (isMounted()) {\n state.setIdle();\n }\n }, [state, isMounted]);\n\n return {\n loading: state.loading,\n result: state.result,\n error: state.error,\n execute,\n reset,\n status: state.status,\n };\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback, useSyncExternalStore } from 'react';\nimport { KeyStorage } from '@ahoo-wang/fetcher-storage';\n\n/**\n * A React hook that provides state management for a KeyStorage instance.\n * Subscribes to storage changes and returns the current value along with a setter function.\n *\n * @template T - The type of value stored in the key storage\n * @param keyStorage - The KeyStorage instance to subscribe to and manage\n * @returns A tuple containing the current stored value and a function to update it\n */\nexport function useKeyStorage<T>(\n keyStorage: KeyStorage<T>,\n): [T | null, (value: T) => void] {\n const subscribe = useCallback(\n (callback: () => void) => keyStorage.addListener(callback),\n [keyStorage],\n );\n const getSnapshot = useCallback(() => keyStorage.get(), [keyStorage]);\n const value = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n const setValue = useCallback(\n (value: T) => keyStorage.set(value),\n [keyStorage],\n );\n return [value, setValue];\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n fetcher as defaultFetcher,\n FetcherCapable,\n FetchExchange,\n FetchRequest,\n getFetcher,\n RequestOptions,\n} from '@ahoo-wang/fetcher';\nimport { useRef, useCallback, useEffect, useState } from 'react';\nimport { useMountedState } from 'react-use';\nimport {\n PromiseState,\n usePromiseState,\n} from '../core';\n\n/**\n * Configuration options for the useFetcher hook.\n * Extends RequestOptions and FetcherCapable interfaces.\n */\nexport interface UseFetcherOptions extends RequestOptions, FetcherCapable {\n}\n\nexport interface UseFetcherReturn<R> extends PromiseState<R> {\n /** The FetchExchange object representing the ongoing fetch operation */\n exchange?: FetchExchange;\n execute: (request: FetchRequest) => Promise<void>;\n}\n\n/**\n * A React hook for managing asynchronous operations with proper state handling\n * @param options - Configuration options for the fetcher\n * @returns An object containing the current state and control functions\n *\n * @example\n * ```typescript\n * import { useFetcher } from '@ahoo-wang/fetcher-react';\n *\n * function MyComponent() {\n * const { loading, result, error, execute } = useFetcher<string>();\n *\n * const handleFetch = () => {\n * execute({ url: '/api/data', method: 'GET' });\n * };\n *\n * if (loading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * return (\n * <div>\n * <button onClick={handleFetch}>Fetch Data</button>\n * {result && <p>{result}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function useFetcher<R>(\n options?: UseFetcherOptions,\n): UseFetcherReturn<R> {\n const { fetcher = defaultFetcher } = options || {};\n const state = usePromiseState<R>();\n const [exchange, setExchange] = useState<FetchExchange | undefined>(\n undefined,\n );\n const isMounted = useMountedState();\n const abortControllerRef = useRef<AbortController | undefined>();\n\n const currentFetcher = getFetcher(fetcher);\n /**\n * Execute the fetch operation.\n * Cancels any ongoing fetch before starting a new one.\n */\n const execute = useCallback(\n async (request: FetchRequest) => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n abortControllerRef.current =\n request.abortController ?? new AbortController();\n request.abortController = abortControllerRef.current;\n state.setLoading();\n try {\n const exchange = await currentFetcher.exchange(request, options);\n if (isMounted()) {\n setExchange(exchange);\n }\n const result = await exchange.extractResult<R>();\n if (isMounted()) {\n state.setSuccess(result);\n }\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n if (isMounted()) {\n state.setIdle();\n }\n return;\n }\n if (isMounted()) {\n state.setError(error);\n }\n } finally {\n if (abortControllerRef.current === request.abortController) {\n abortControllerRef.current = undefined;\n }\n }\n },\n [currentFetcher, isMounted, options, state],\n );\n\n useEffect(() => {\n return () => {\n abortControllerRef.current?.abort();\n abortControllerRef.current = undefined;\n };\n }, []);\n return {\n ...state,\n exchange,\n execute,\n };\n}\n"],"names":["useMountedState","mountedRef","useRef","get","useCallback","useEffect","PromiseStatus","usePromiseState","options","status","setStatus","useState","result","setResult","error","setErrorState","isMounted","setLoadingFn","setSuccessFn","setErrorFn","setIdleFn","useExecutePromise","state","execute","provider","data","err","reset","useKeyStorage","keyStorage","subscribe","callback","getSnapshot","value","useSyncExternalStore","setValue","useFetcher","fetcher","defaultFetcher","exchange","setExchange","abortControllerRef","currentFetcher","getFetcher","request"],"mappings":"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","x_google_ignoreList":[0]}
|
|
1
|
+
{"version":3,"file":"index.es.js","sources":["../../../node_modules/.pnpm/react-use@17.6.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/react-use/esm/useMountedState.js","../src/core/usePromiseState.ts","../src/core/useRequestId.ts","../src/core/useExecutePromise.ts","../src/storage/useKeyStorage.ts","../src/fetcher/useFetcher.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\nexport default function useMountedState() {\n var mountedRef = useRef(false);\n var get = useCallback(function () { return mountedRef.current; }, []);\n useEffect(function () {\n mountedRef.current = true;\n return function () {\n mountedRef.current = false;\n };\n }, []);\n return get;\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback, useMemo, useState } from 'react';\nimport { useMountedState } from 'react-use';\n\n/**\n * Enumeration of possible promise execution states\n */\nexport enum PromiseStatus {\n IDLE = 'idle',\n LOADING = 'loading',\n SUCCESS = 'success',\n ERROR = 'error',\n}\n\nexport interface PromiseState<R, E = unknown> {\n /** Current status of the promise */\n status: PromiseStatus;\n /** Indicates if currently loading */\n loading: boolean;\n /** The result value */\n result: R | undefined;\n /** The error value */\n error: E | undefined;\n}\n\n/**\n * Options for configuring usePromiseState behavior\n * @template R - The type of result\n *\n * @example\n * ```typescript\n * const options: UsePromiseStateOptions<string> = {\n * initialStatus: PromiseStatus.IDLE,\n * onSuccess: (result) => console.log('Success:', result),\n * onError: (error) => console.error('Error:', error),\n * };\n * ```\n */\nexport interface UsePromiseStateOptions<R, E = unknown> {\n /** Initial status, defaults to IDLE */\n initialStatus?: PromiseStatus;\n /** Callback invoked on success */\n onSuccess?: (result: R) => void;\n /** Callback invoked on error */\n onError?: (error: E) => void;\n}\n\n/**\n * Return type for usePromiseState hook\n * @template R - The type of result\n */\nexport interface UsePromiseStateReturn<R, E = unknown> extends PromiseState<R, E> {\n /** Set status to LOADING */\n setLoading: () => void;\n /** Set status to SUCCESS with result */\n setSuccess: (result: R) => void;\n /** Set status to ERROR with error */\n setError: (error: E) => void;\n /** Set status to IDLE */\n setIdle: () => void;\n}\n\n/**\n * A React hook for managing promise state without execution logic\n * @template R - The type of result\n * @param options - Configuration options\n * @returns State management object\n *\n * @example\n * ```typescript\n * import { usePromiseState, PromiseStatus } from '@ahoo-wang/fetcher-react';\n *\n * function MyComponent() {\n * const { status, loading, result, error, setSuccess, setError, setIdle } = usePromiseState<string>();\n *\n * const handleSuccess = () => setSuccess('Data loaded');\n * const handleError = () => setError(new Error('Failed to load'));\n *\n * return (\n * <div>\n * <button onClick={handleSuccess}>Set Success</button>\n * <button onClick={handleError}>Set Error</button>\n * <button onClick={setIdle}>Reset</button>\n * <p>Status: {status}</p>\n * {loading && <p>Loading...</p>}\n * {result && <p>Result: {result}</p>}\n * {error && <p>Error: {error.message}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function usePromiseState<R = unknown, E = unknown>(\n options?: UsePromiseStateOptions<R, E>,\n): UsePromiseStateReturn<R, E> {\n const [status, setStatus] = useState<PromiseStatus>(\n options?.initialStatus ?? PromiseStatus.IDLE,\n );\n const [result, setResult] = useState<R | undefined>(undefined);\n const [error, setErrorState] = useState<E | undefined>(undefined);\n const isMounted = useMountedState();\n\n const setLoadingFn = useCallback(() => {\n if (isMounted()) {\n setStatus(PromiseStatus.LOADING);\n setErrorState(undefined);\n }\n }, [isMounted]);\n\n const setSuccessFn = useCallback(\n (result: R) => {\n if (isMounted()) {\n setResult(result);\n setStatus(PromiseStatus.SUCCESS);\n setErrorState(undefined);\n options?.onSuccess?.(result);\n }\n },\n [isMounted, options],\n );\n\n const setErrorFn = useCallback(\n (error: E) => {\n if (isMounted()) {\n setErrorState(error);\n setStatus(PromiseStatus.ERROR);\n setResult(undefined);\n options?.onError?.(error);\n }\n },\n [isMounted, options],\n );\n\n const setIdleFn = useCallback(() => {\n if (isMounted()) {\n setStatus(PromiseStatus.IDLE);\n setErrorState(undefined);\n setResult(undefined);\n }\n }, [isMounted]);\n return useMemo(() => ({\n status,\n loading: status === PromiseStatus.LOADING,\n result,\n error,\n setLoading: setLoadingFn,\n setSuccess: setSuccessFn,\n setError: setErrorFn,\n setIdle: setIdleFn,\n }), [status, result, error, setLoadingFn, setSuccessFn, setErrorFn, setIdleFn]);\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useRef, useCallback } from 'react';\n\n/**\n * Return type for useRequestId hook\n */\nexport interface UseRequestIdReturn {\n /** Generate a new request ID and get the current one */\n generate: () => number;\n /** Get the current request ID without generating a new one */\n current: () => number;\n /** Check if a given request ID is the latest */\n isLatest: (requestId: number) => boolean;\n /** Invalidate current request ID (mark as stale) */\n invalidate: () => void;\n /** Reset request ID counter */\n reset: () => void;\n}\n\n/**\n * A React hook for managing request IDs and race condition protection\n *\n * @example\n * ```typescript\n * // Basic usage\n * const requestId = useRequestId();\n *\n * const execute = async () => {\n * const id = requestId.generate();\n *\n * try {\n * const result = await someAsyncOperation();\n *\n * // Check if this is still the latest request\n * if (requestId.isLatest(id)) {\n * setState(result);\n * }\n * } catch (error) {\n * if (requestId.isLatest(id)) {\n * setError(error);\n * }\n * }\n * };\n *\n * // Manual cancellation\n * const handleCancel = () => {\n * requestId.invalidate(); // All ongoing requests will be ignored\n * };\n * ```\n *\n * @example\n * ```typescript\n * // With async operation wrapper\n * const { execute, cancel } = useAsyncOperation(async (data) => {\n * return await apiCall(data);\n * }, [requestId]);\n * ```\n */\nexport function useRequestId(): UseRequestIdReturn {\n const requestIdRef = useRef<number>(0);\n\n const generate = useCallback((): number => {\n return ++requestIdRef.current;\n }, []);\n\n const current = useCallback((): number => {\n return requestIdRef.current;\n }, []);\n\n const isLatest = useCallback((requestId: number): boolean => {\n return requestId === requestIdRef.current;\n }, []);\n\n const invalidate = useCallback((): void => {\n requestIdRef.current++;\n }, []);\n\n const reset = useCallback((): void => {\n requestIdRef.current = 0;\n }, []);\n\n return {\n generate,\n current,\n isLatest,\n invalidate,\n reset,\n };\n}","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback, useMemo } from 'react';\nimport { useMountedState } from 'react-use';\nimport { usePromiseState, PromiseState } from './usePromiseState';\nimport { useRequestId } from './useRequestId';\n\n/**\n * Type definition for a function that returns a Promise\n * @template R - The type of value the promise will resolve to\n */\nexport type PromiseSupplier<R> = () => Promise<R>;\n\n/**\n * Interface defining the return type of useExecutePromise hook\n * @template R - The type of the result value\n */\nexport interface UseExecutePromiseReturn<R, E = unknown>\n extends PromiseState<R, E> {\n /** Function to execute a promise supplier or promise */\n execute: (input: PromiseSupplier<R> | Promise<R>) => Promise<R>;\n /** Function to reset the state to initial values */\n reset: () => void;\n}\n\n/**\n * A React hook for managing asynchronous operations with proper state handling\n * @template R - The type of the result value\n * @returns An object containing the current state and control functions\n *\n * @example\n * ```typescript\n * import { useExecutePromise } from '@ahoo-wang/fetcher-react';\n *\n * function MyComponent() {\n * const { loading, result, error, execute, reset } = useExecutePromise<string>();\n *\n * const fetchData = async () => {\n * const response = await fetch('/api/data');\n * return response.text();\n * };\n *\n * const handleFetch = () => {\n * execute(fetchData);\n * };\n *\n * const handleReset = () => {\n * reset();\n * };\n *\n * if (loading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * return (\n * <div>\n * <button onClick={handleFetch}>Fetch Data</button>\n * <button onClick={handleReset}>Reset</button>\n * {result && <p>{result}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function useExecutePromise<R = unknown>(): UseExecutePromiseReturn<R> {\n const state = usePromiseState<R>();\n const isMounted = useMountedState();\n const requestId = useRequestId();\n\n /**\n * Execute a promise supplier or promise and manage its state\n * @param input - A function that returns a Promise or a Promise to be executed\n * @returns A Promise that resolves with the result of the executed promise\n */\n const execute = useCallback(\n async (input: PromiseSupplier<R> | Promise<R>): Promise<R> => {\n if (!isMounted()) {\n throw new Error('Component is unmounted');\n }\n const currentRequestId = requestId.generate();\n state.setLoading();\n try {\n const promise = typeof input === 'function' ? input() : input;\n const data = await promise;\n\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n state.setSuccess(data);\n }\n return data;\n } catch (err) {\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n state.setError(err);\n }\n throw err;\n }\n },\n [state, isMounted, requestId],\n );\n\n /**\n * Reset the state to initial values\n */\n const reset = useCallback(() => {\n if (isMounted()) {\n state.setIdle();\n }\n }, [state, isMounted]);\n\n return useMemo(\n () => ({\n loading: state.loading,\n result: state.result,\n error: state.error,\n execute,\n reset,\n status: state.status,\n }),\n [state.loading, state.result, state.error, execute, reset, state.status],\n );\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback, useSyncExternalStore } from 'react';\nimport { KeyStorage } from '@ahoo-wang/fetcher-storage';\n\n/**\n * A React hook that provides state management for a KeyStorage instance.\n * Subscribes to storage changes and returns the current value along with a setter function.\n *\n * @template T - The type of value stored in the key storage\n * @param keyStorage - The KeyStorage instance to subscribe to and manage\n * @returns A tuple containing the current stored value and a function to update it\n */\nexport function useKeyStorage<T>(\n keyStorage: KeyStorage<T>,\n): [T | null, (value: T) => void] {\n const subscribe = useCallback(\n (callback: () => void) => keyStorage.addListener(callback),\n [keyStorage],\n );\n const getSnapshot = useCallback(() => keyStorage.get(), [keyStorage]);\n const value = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n const setValue = useCallback(\n (value: T) => keyStorage.set(value),\n [keyStorage],\n );\n return [value, setValue];\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n fetcher as defaultFetcher,\n FetcherCapable,\n FetchExchange,\n FetchRequest,\n getFetcher,\n RequestOptions,\n} from '@ahoo-wang/fetcher';\nimport { useRef, useCallback, useEffect, useState } from 'react';\nimport { useMountedState } from 'react-use';\nimport { PromiseState, usePromiseState, useRequestId } from '../core';\n\n/**\n * Configuration options for the useFetcher hook.\n * Extends RequestOptions and FetcherCapable interfaces.\n */\nexport interface UseFetcherOptions extends RequestOptions, FetcherCapable {\n}\n\nexport interface UseFetcherReturn<R, E = unknown> extends PromiseState<R, E> {\n /** The FetchExchange object representing the ongoing fetch operation */\n exchange?: FetchExchange;\n execute: (request: FetchRequest) => Promise<void>;\n}\n\n/**\n * A React hook for managing asynchronous operations with proper state handling\n * @param options - Configuration options for the fetcher\n * @returns An object containing the current state and control functions\n *\n * @example\n * ```typescript\n * import { useFetcher } from '@ahoo-wang/fetcher-react';\n *\n * function MyComponent() {\n * const { loading, result, error, execute } = useFetcher<string>();\n *\n * const handleFetch = () => {\n * execute({ url: '/api/data', method: 'GET' });\n * };\n *\n * if (loading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * return (\n * <div>\n * <button onClick={handleFetch}>Fetch Data</button>\n * {result && <p>{result}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function useFetcher<R, E = unknown>(\n options?: UseFetcherOptions,\n): UseFetcherReturn<R, E> {\n const { fetcher = defaultFetcher } = options || {};\n const state = usePromiseState<R, E>();\n const [exchange, setExchange] = useState<FetchExchange | undefined>(\n undefined,\n );\n const isMounted = useMountedState();\n const abortControllerRef = useRef<AbortController | undefined>();\n const requestId = useRequestId();\n\n const currentFetcher = getFetcher(fetcher);\n /**\n * Execute the fetch operation.\n * Cancels any ongoing fetch before starting a new one.\n */\n const execute = useCallback(\n async (request: FetchRequest) => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n abortControllerRef.current =\n request.abortController ?? new AbortController();\n request.abortController = abortControllerRef.current;\n const currentRequestId = requestId.generate();\n state.setLoading();\n try {\n const exchange = await currentFetcher.exchange(request, options);\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n setExchange(exchange);\n }\n const result = await exchange.extractResult<R>();\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n state.setSuccess(result);\n }\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n if (isMounted()) {\n state.setIdle();\n }\n return;\n }\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n state.setError(error as E);\n }\n } finally {\n if (abortControllerRef.current === request.abortController) {\n abortControllerRef.current = undefined;\n }\n }\n },\n [currentFetcher, isMounted, options, state, requestId],\n );\n\n useEffect(() => {\n return () => {\n abortControllerRef.current?.abort();\n abortControllerRef.current = undefined;\n };\n }, []);\n return {\n ...state,\n exchange,\n execute,\n };\n}\n"],"names":["useMountedState","mountedRef","useRef","get","useCallback","useEffect","PromiseStatus","usePromiseState","options","status","setStatus","useState","result","setResult","error","setErrorState","isMounted","setLoadingFn","setSuccessFn","setErrorFn","setIdleFn","useMemo","useRequestId","requestIdRef","generate","current","isLatest","requestId","invalidate","reset","useExecutePromise","state","execute","input","currentRequestId","data","err","useKeyStorage","keyStorage","subscribe","callback","getSnapshot","value","useSyncExternalStore","setValue","useFetcher","fetcher","defaultFetcher","exchange","setExchange","abortControllerRef","currentFetcher","getFetcher","request"],"mappings":"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","x_google_ignoreList":[0]}
|
package/dist/index.umd.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(c,t){typeof exports=="object"&&typeof module<"u"?t(exports,require("react"),require("@ahoo-wang/fetcher")):typeof define=="function"&&define.amd?define(["exports","react","@ahoo-wang/fetcher"],t):(c=typeof globalThis<"u"?globalThis:c||self,t(c.FetcherReact={},c.React,c.Fetcher))})(this,(function(c,t,S){"use strict";function C(){var e=t.useRef(!1),s=t.useCallback(function(){return e.current},[]);return t.useEffect(function(){return e.current=!0,function(){e.current=!1}},[]),s}var v=(e=>(e.IDLE="idle",e.LOADING="loading",e.SUCCESS="success",e.ERROR="error",e))(v||{});function g(e){const[s,r]=t.useState(e?.initialStatus??"idle"),[l,i]=t.useState(void 0),[n,u]=t.useState(void 0),o=C(),d=t.useCallback(()=>{o()&&(r("loading"),u(void 0))},[o]),h=t.useCallback(a=>{o()&&(i(a),r("success"),u(void 0),e?.onSuccess?.(a))},[o,e]),f=t.useCallback(a=>{o()&&(u(a),r("error"),i(void 0),e?.onError?.(a))},[o,e]),b=t.useCallback(()=>{o()&&(r("idle"),u(void 0),i(void 0))},[o]);return t.useMemo(()=>({status:s,loading:s==="loading",result:l,error:n,setLoading:d,setSuccess:h,setError:f,setIdle:b}),[s,l,n,d,h,f,b])}function E(){const e=t.useRef(0),s=t.useCallback(()=>++e.current,[]),r=t.useCallback(()=>e.current,[]),l=t.useCallback(u=>u===e.current,[]),i=t.useCallback(()=>{e.current++},[]),n=t.useCallback(()=>{e.current=0},[]);return{generate:s,current:r,isLatest:l,invalidate:i,reset:n}}function m(){const e=g(),s=C(),r=E(),l=t.useCallback(async n=>{if(!s())throw new Error("Component is unmounted");const u=r.generate();e.setLoading();try{const d=await(typeof n=="function"?n():n);return s()&&r.isLatest(u)&&e.setSuccess(d),d}catch(o){throw s()&&r.isLatest(u)&&e.setError(o),o}},[e,s,r]),i=t.useCallback(()=>{s()&&e.setIdle()},[e,s]);return t.useMemo(()=>({loading:e.loading,result:e.result,error:e.error,execute:l,reset:i,status:e.status}),[e.loading,e.result,e.error,l,i,e.status])}function I(e){const s=t.useCallback(n=>e.addListener(n),[e]),r=t.useCallback(()=>e.get(),[e]),l=t.useSyncExternalStore(s,r,r),i=t.useCallback(n=>e.set(n),[e]);return[l,i]}function L(e){const{fetcher:s=S.fetcher}=e||{},r=g(),[l,i]=t.useState(void 0),n=C(),u=t.useRef(),o=E(),d=S.getFetcher(s),h=t.useCallback(async f=>{u.current&&u.current.abort(),u.current=f.abortController??new AbortController,f.abortController=u.current;const b=o.generate();r.setLoading();try{const a=await d.exchange(f,e);n()&&o.isLatest(b)&&i(a);const k=await a.extractResult();n()&&o.isLatest(b)&&r.setSuccess(k)}catch(a){if(a instanceof Error&&a.name==="AbortError"){n()&&r.setIdle();return}n()&&o.isLatest(b)&&r.setError(a)}finally{u.current===f.abortController&&(u.current=void 0)}},[d,n,e,r,o]);return t.useEffect(()=>()=>{u.current?.abort(),u.current=void 0},[]),{...r,exchange:l,execute:h}}c.PromiseStatus=v,c.useExecutePromise=m,c.useFetcher=L,c.useKeyStorage=I,c.usePromiseState=g,c.useRequestId=E,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})}));
|
|
2
2
|
//# sourceMappingURL=index.umd.js.map
|
package/dist/index.umd.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.umd.js","sources":["../../../node_modules/.pnpm/react-use@17.6.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/react-use/esm/useMountedState.js","../src/core/usePromiseState.ts","../src/core/useExecutePromise.ts","../src/storage/useKeyStorage.ts","../src/fetcher/useFetcher.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\nexport default function useMountedState() {\n var mountedRef = useRef(false);\n var get = useCallback(function () { return mountedRef.current; }, []);\n useEffect(function () {\n mountedRef.current = true;\n return function () {\n mountedRef.current = false;\n };\n }, []);\n return get;\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback, useState } from 'react';\nimport { useMountedState } from 'react-use';\n\n/**\n * Enumeration of possible promise execution states\n */\nexport enum PromiseStatus {\n IDLE = 'idle',\n LOADING = 'loading',\n SUCCESS = 'success',\n ERROR = 'error',\n}\n\nexport interface PromiseState<R> {\n /** Current status of the promise */\n status: PromiseStatus;\n /** Indicates if currently loading */\n loading: boolean;\n /** The result value */\n result: R | undefined;\n /** The error value */\n error: unknown | undefined;\n}\n\n/**\n * Options for configuring usePromiseState behavior\n * @template R - The type of result\n *\n * @example\n * ```typescript\n * const options: UsePromiseStateOptions<string> = {\n * initialStatus: PromiseStatus.IDLE,\n * onSuccess: (result) => console.log('Success:', result),\n * onError: (error) => console.error('Error:', error),\n * };\n * ```\n */\nexport interface UsePromiseStateOptions<R> {\n /** Initial status, defaults to IDLE */\n initialStatus?: PromiseStatus;\n /** Callback invoked on success */\n onSuccess?: (result: R) => void;\n /** Callback invoked on error */\n onError?: (error: unknown) => void;\n}\n\n/**\n * Return type for usePromiseState hook\n * @template R - The type of result\n */\nexport interface UsePromiseStateReturn<R> extends PromiseState<R> {\n /** Set status to LOADING */\n setLoading: () => void;\n /** Set status to SUCCESS with result */\n setSuccess: (result: R) => void;\n /** Set status to ERROR with error */\n setError: (error: unknown) => void;\n /** Set status to IDLE */\n setIdle: () => void;\n}\n\n/**\n * A React hook for managing promise state without execution logic\n * @template R - The type of result\n * @param options - Configuration options\n * @returns State management object\n *\n * @example\n * ```typescript\n * import { usePromiseState, PromiseStatus } from '@ahoo-wang/fetcher-react';\n *\n * function MyComponent() {\n * const { status, loading, result, error, setSuccess, setError, setIdle } = usePromiseState<string>();\n *\n * const handleSuccess = () => setSuccess('Data loaded');\n * const handleError = () => setError(new Error('Failed to load'));\n *\n * return (\n * <div>\n * <button onClick={handleSuccess}>Set Success</button>\n * <button onClick={handleError}>Set Error</button>\n * <button onClick={setIdle}>Reset</button>\n * <p>Status: {status}</p>\n * {loading && <p>Loading...</p>}\n * {result && <p>Result: {result}</p>}\n * {error && <p>Error: {error.message}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function usePromiseState<R = unknown>(\n options?: UsePromiseStateOptions<R>,\n): UsePromiseStateReturn<R> {\n const [status, setStatus] = useState<PromiseStatus>(\n options?.initialStatus ?? PromiseStatus.IDLE,\n );\n const [result, setResult] = useState<R | undefined>(undefined);\n const [error, setErrorState] = useState<unknown | undefined>(undefined);\n const isMounted = useMountedState();\n\n const setLoadingFn = useCallback(() => {\n if (isMounted()) {\n setStatus(PromiseStatus.LOADING);\n setErrorState(undefined);\n }\n }, [isMounted]);\n\n const setSuccessFn = useCallback(\n (result: R) => {\n if (isMounted()) {\n setResult(result);\n setStatus(PromiseStatus.SUCCESS);\n setErrorState(undefined);\n options?.onSuccess?.(result);\n }\n },\n [isMounted, options],\n );\n\n const setErrorFn = useCallback(\n (error: unknown) => {\n if (isMounted()) {\n setErrorState(error);\n setStatus(PromiseStatus.ERROR);\n setResult(undefined);\n options?.onError?.(error);\n }\n },\n [isMounted, options],\n );\n\n const setIdleFn = useCallback(() => {\n if (isMounted()) {\n setStatus(PromiseStatus.IDLE);\n setErrorState(undefined);\n setResult(undefined);\n }\n }, [isMounted]);\n\n return {\n status,\n loading: status === PromiseStatus.LOADING,\n result,\n error,\n setLoading: setLoadingFn,\n setSuccess: setSuccessFn,\n setError: setErrorFn,\n setIdle: setIdleFn,\n };\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback } from 'react';\nimport { useMountedState } from 'react-use';\nimport { usePromiseState, PromiseState } from './usePromiseState';\n\n/**\n * Type definition for a function that returns a Promise\n * @template R - The type of value the promise will resolve to\n */\nexport type PromiseSupplier<R> = () => Promise<R>;\n\n/**\n * Interface defining the return type of useExecutePromise hook\n * @template R - The type of the result value\n *\n * @example\n * ```typescript\n * const { loading, result, error, execute, reset } = useExecutePromise<string>();\n * ```\n */\nexport interface UseExecutePromiseReturn<R> extends PromiseState<R> {\n /** Function to execute a promise supplier */\n execute: (provider: PromiseSupplier<R>) => Promise<R>;\n /** Function to reset the state to initial values */\n reset: () => void;\n}\n\n/**\n * A React hook for managing asynchronous operations with proper state handling\n * @template R - The type of the result value\n * @returns An object containing the current state and control functions\n *\n * @example\n * ```typescript\n * import { useExecutePromise } from '@ahoo-wang/fetcher-react';\n *\n * function MyComponent() {\n * const { loading, result, error, execute, reset } = useExecutePromise<string>();\n *\n * const fetchData = async () => {\n * const response = await fetch('/api/data');\n * return response.text();\n * };\n *\n * const handleFetch = () => {\n * execute(fetchData);\n * };\n *\n * const handleReset = () => {\n * reset();\n * };\n *\n * if (loading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * return (\n * <div>\n * <button onClick={handleFetch}>Fetch Data</button>\n * <button onClick={handleReset}>Reset</button>\n * {result && <p>{result}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function useExecutePromise<R = unknown>(): UseExecutePromiseReturn<R> {\n const state = usePromiseState<R>();\n const isMounted = useMountedState();\n\n /**\n * Execute a promise supplier and manage its state\n * @param provider - A function that returns a Promise to be executed\n * @returns A Promise that resolves with the result of the executed promise\n */\n const execute = useCallback(\n async (provider: PromiseSupplier<R>): Promise<R> => {\n if (!isMounted()) {\n throw new Error('Component is unmounted');\n }\n state.setLoading();\n try {\n const data = await provider();\n\n if (isMounted()) {\n state.setSuccess(data);\n }\n return data;\n } catch (err) {\n if (isMounted()) {\n state.setError(err);\n }\n throw err;\n }\n },\n [state, isMounted],\n );\n\n /**\n * Reset the state to initial values\n */\n const reset = useCallback(() => {\n if (isMounted()) {\n state.setIdle();\n }\n }, [state, isMounted]);\n\n return {\n loading: state.loading,\n result: state.result,\n error: state.error,\n execute,\n reset,\n status: state.status,\n };\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback, useSyncExternalStore } from 'react';\nimport { KeyStorage } from '@ahoo-wang/fetcher-storage';\n\n/**\n * A React hook that provides state management for a KeyStorage instance.\n * Subscribes to storage changes and returns the current value along with a setter function.\n *\n * @template T - The type of value stored in the key storage\n * @param keyStorage - The KeyStorage instance to subscribe to and manage\n * @returns A tuple containing the current stored value and a function to update it\n */\nexport function useKeyStorage<T>(\n keyStorage: KeyStorage<T>,\n): [T | null, (value: T) => void] {\n const subscribe = useCallback(\n (callback: () => void) => keyStorage.addListener(callback),\n [keyStorage],\n );\n const getSnapshot = useCallback(() => keyStorage.get(), [keyStorage]);\n const value = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n const setValue = useCallback(\n (value: T) => keyStorage.set(value),\n [keyStorage],\n );\n return [value, setValue];\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n fetcher as defaultFetcher,\n FetcherCapable,\n FetchExchange,\n FetchRequest,\n getFetcher,\n RequestOptions,\n} from '@ahoo-wang/fetcher';\nimport { useRef, useCallback, useEffect, useState } from 'react';\nimport { useMountedState } from 'react-use';\nimport {\n PromiseState,\n usePromiseState,\n} from '../core';\n\n/**\n * Configuration options for the useFetcher hook.\n * Extends RequestOptions and FetcherCapable interfaces.\n */\nexport interface UseFetcherOptions extends RequestOptions, FetcherCapable {\n}\n\nexport interface UseFetcherReturn<R> extends PromiseState<R> {\n /** The FetchExchange object representing the ongoing fetch operation */\n exchange?: FetchExchange;\n execute: (request: FetchRequest) => Promise<void>;\n}\n\n/**\n * A React hook for managing asynchronous operations with proper state handling\n * @param options - Configuration options for the fetcher\n * @returns An object containing the current state and control functions\n *\n * @example\n * ```typescript\n * import { useFetcher } from '@ahoo-wang/fetcher-react';\n *\n * function MyComponent() {\n * const { loading, result, error, execute } = useFetcher<string>();\n *\n * const handleFetch = () => {\n * execute({ url: '/api/data', method: 'GET' });\n * };\n *\n * if (loading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * return (\n * <div>\n * <button onClick={handleFetch}>Fetch Data</button>\n * {result && <p>{result}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function useFetcher<R>(\n options?: UseFetcherOptions,\n): UseFetcherReturn<R> {\n const { fetcher = defaultFetcher } = options || {};\n const state = usePromiseState<R>();\n const [exchange, setExchange] = useState<FetchExchange | undefined>(\n undefined,\n );\n const isMounted = useMountedState();\n const abortControllerRef = useRef<AbortController | undefined>();\n\n const currentFetcher = getFetcher(fetcher);\n /**\n * Execute the fetch operation.\n * Cancels any ongoing fetch before starting a new one.\n */\n const execute = useCallback(\n async (request: FetchRequest) => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n abortControllerRef.current =\n request.abortController ?? new AbortController();\n request.abortController = abortControllerRef.current;\n state.setLoading();\n try {\n const exchange = await currentFetcher.exchange(request, options);\n if (isMounted()) {\n setExchange(exchange);\n }\n const result = await exchange.extractResult<R>();\n if (isMounted()) {\n state.setSuccess(result);\n }\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n if (isMounted()) {\n state.setIdle();\n }\n return;\n }\n if (isMounted()) {\n state.setError(error);\n }\n } finally {\n if (abortControllerRef.current === request.abortController) {\n abortControllerRef.current = undefined;\n }\n }\n },\n [currentFetcher, isMounted, options, state],\n );\n\n useEffect(() => {\n return () => {\n abortControllerRef.current?.abort();\n abortControllerRef.current = undefined;\n };\n }, []);\n return {\n ...state,\n exchange,\n execute,\n };\n}\n"],"names":["useMountedState","mountedRef","useRef","get","useCallback","useEffect","PromiseStatus","usePromiseState","options","status","setStatus","useState","result","setResult","error","setErrorState","isMounted","setLoadingFn","setSuccessFn","setErrorFn","setIdleFn","useExecutePromise","state","execute","provider","data","err","reset","useKeyStorage","keyStorage","subscribe","callback","getSnapshot","value","useSyncExternalStore","setValue","useFetcher","fetcher","defaultFetcher","exchange","setExchange","abortControllerRef","currentFetcher","getFetcher","request"],"mappings":"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","x_google_ignoreList":[0]}
|
|
1
|
+
{"version":3,"file":"index.umd.js","sources":["../../../node_modules/.pnpm/react-use@17.6.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/react-use/esm/useMountedState.js","../src/core/usePromiseState.ts","../src/core/useRequestId.ts","../src/core/useExecutePromise.ts","../src/storage/useKeyStorage.ts","../src/fetcher/useFetcher.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\nexport default function useMountedState() {\n var mountedRef = useRef(false);\n var get = useCallback(function () { return mountedRef.current; }, []);\n useEffect(function () {\n mountedRef.current = true;\n return function () {\n mountedRef.current = false;\n };\n }, []);\n return get;\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback, useMemo, useState } from 'react';\nimport { useMountedState } from 'react-use';\n\n/**\n * Enumeration of possible promise execution states\n */\nexport enum PromiseStatus {\n IDLE = 'idle',\n LOADING = 'loading',\n SUCCESS = 'success',\n ERROR = 'error',\n}\n\nexport interface PromiseState<R, E = unknown> {\n /** Current status of the promise */\n status: PromiseStatus;\n /** Indicates if currently loading */\n loading: boolean;\n /** The result value */\n result: R | undefined;\n /** The error value */\n error: E | undefined;\n}\n\n/**\n * Options for configuring usePromiseState behavior\n * @template R - The type of result\n *\n * @example\n * ```typescript\n * const options: UsePromiseStateOptions<string> = {\n * initialStatus: PromiseStatus.IDLE,\n * onSuccess: (result) => console.log('Success:', result),\n * onError: (error) => console.error('Error:', error),\n * };\n * ```\n */\nexport interface UsePromiseStateOptions<R, E = unknown> {\n /** Initial status, defaults to IDLE */\n initialStatus?: PromiseStatus;\n /** Callback invoked on success */\n onSuccess?: (result: R) => void;\n /** Callback invoked on error */\n onError?: (error: E) => void;\n}\n\n/**\n * Return type for usePromiseState hook\n * @template R - The type of result\n */\nexport interface UsePromiseStateReturn<R, E = unknown> extends PromiseState<R, E> {\n /** Set status to LOADING */\n setLoading: () => void;\n /** Set status to SUCCESS with result */\n setSuccess: (result: R) => void;\n /** Set status to ERROR with error */\n setError: (error: E) => void;\n /** Set status to IDLE */\n setIdle: () => void;\n}\n\n/**\n * A React hook for managing promise state without execution logic\n * @template R - The type of result\n * @param options - Configuration options\n * @returns State management object\n *\n * @example\n * ```typescript\n * import { usePromiseState, PromiseStatus } from '@ahoo-wang/fetcher-react';\n *\n * function MyComponent() {\n * const { status, loading, result, error, setSuccess, setError, setIdle } = usePromiseState<string>();\n *\n * const handleSuccess = () => setSuccess('Data loaded');\n * const handleError = () => setError(new Error('Failed to load'));\n *\n * return (\n * <div>\n * <button onClick={handleSuccess}>Set Success</button>\n * <button onClick={handleError}>Set Error</button>\n * <button onClick={setIdle}>Reset</button>\n * <p>Status: {status}</p>\n * {loading && <p>Loading...</p>}\n * {result && <p>Result: {result}</p>}\n * {error && <p>Error: {error.message}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function usePromiseState<R = unknown, E = unknown>(\n options?: UsePromiseStateOptions<R, E>,\n): UsePromiseStateReturn<R, E> {\n const [status, setStatus] = useState<PromiseStatus>(\n options?.initialStatus ?? PromiseStatus.IDLE,\n );\n const [result, setResult] = useState<R | undefined>(undefined);\n const [error, setErrorState] = useState<E | undefined>(undefined);\n const isMounted = useMountedState();\n\n const setLoadingFn = useCallback(() => {\n if (isMounted()) {\n setStatus(PromiseStatus.LOADING);\n setErrorState(undefined);\n }\n }, [isMounted]);\n\n const setSuccessFn = useCallback(\n (result: R) => {\n if (isMounted()) {\n setResult(result);\n setStatus(PromiseStatus.SUCCESS);\n setErrorState(undefined);\n options?.onSuccess?.(result);\n }\n },\n [isMounted, options],\n );\n\n const setErrorFn = useCallback(\n (error: E) => {\n if (isMounted()) {\n setErrorState(error);\n setStatus(PromiseStatus.ERROR);\n setResult(undefined);\n options?.onError?.(error);\n }\n },\n [isMounted, options],\n );\n\n const setIdleFn = useCallback(() => {\n if (isMounted()) {\n setStatus(PromiseStatus.IDLE);\n setErrorState(undefined);\n setResult(undefined);\n }\n }, [isMounted]);\n return useMemo(() => ({\n status,\n loading: status === PromiseStatus.LOADING,\n result,\n error,\n setLoading: setLoadingFn,\n setSuccess: setSuccessFn,\n setError: setErrorFn,\n setIdle: setIdleFn,\n }), [status, result, error, setLoadingFn, setSuccessFn, setErrorFn, setIdleFn]);\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useRef, useCallback } from 'react';\n\n/**\n * Return type for useRequestId hook\n */\nexport interface UseRequestIdReturn {\n /** Generate a new request ID and get the current one */\n generate: () => number;\n /** Get the current request ID without generating a new one */\n current: () => number;\n /** Check if a given request ID is the latest */\n isLatest: (requestId: number) => boolean;\n /** Invalidate current request ID (mark as stale) */\n invalidate: () => void;\n /** Reset request ID counter */\n reset: () => void;\n}\n\n/**\n * A React hook for managing request IDs and race condition protection\n *\n * @example\n * ```typescript\n * // Basic usage\n * const requestId = useRequestId();\n *\n * const execute = async () => {\n * const id = requestId.generate();\n *\n * try {\n * const result = await someAsyncOperation();\n *\n * // Check if this is still the latest request\n * if (requestId.isLatest(id)) {\n * setState(result);\n * }\n * } catch (error) {\n * if (requestId.isLatest(id)) {\n * setError(error);\n * }\n * }\n * };\n *\n * // Manual cancellation\n * const handleCancel = () => {\n * requestId.invalidate(); // All ongoing requests will be ignored\n * };\n * ```\n *\n * @example\n * ```typescript\n * // With async operation wrapper\n * const { execute, cancel } = useAsyncOperation(async (data) => {\n * return await apiCall(data);\n * }, [requestId]);\n * ```\n */\nexport function useRequestId(): UseRequestIdReturn {\n const requestIdRef = useRef<number>(0);\n\n const generate = useCallback((): number => {\n return ++requestIdRef.current;\n }, []);\n\n const current = useCallback((): number => {\n return requestIdRef.current;\n }, []);\n\n const isLatest = useCallback((requestId: number): boolean => {\n return requestId === requestIdRef.current;\n }, []);\n\n const invalidate = useCallback((): void => {\n requestIdRef.current++;\n }, []);\n\n const reset = useCallback((): void => {\n requestIdRef.current = 0;\n }, []);\n\n return {\n generate,\n current,\n isLatest,\n invalidate,\n reset,\n };\n}","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback, useMemo } from 'react';\nimport { useMountedState } from 'react-use';\nimport { usePromiseState, PromiseState } from './usePromiseState';\nimport { useRequestId } from './useRequestId';\n\n/**\n * Type definition for a function that returns a Promise\n * @template R - The type of value the promise will resolve to\n */\nexport type PromiseSupplier<R> = () => Promise<R>;\n\n/**\n * Interface defining the return type of useExecutePromise hook\n * @template R - The type of the result value\n */\nexport interface UseExecutePromiseReturn<R, E = unknown>\n extends PromiseState<R, E> {\n /** Function to execute a promise supplier or promise */\n execute: (input: PromiseSupplier<R> | Promise<R>) => Promise<R>;\n /** Function to reset the state to initial values */\n reset: () => void;\n}\n\n/**\n * A React hook for managing asynchronous operations with proper state handling\n * @template R - The type of the result value\n * @returns An object containing the current state and control functions\n *\n * @example\n * ```typescript\n * import { useExecutePromise } from '@ahoo-wang/fetcher-react';\n *\n * function MyComponent() {\n * const { loading, result, error, execute, reset } = useExecutePromise<string>();\n *\n * const fetchData = async () => {\n * const response = await fetch('/api/data');\n * return response.text();\n * };\n *\n * const handleFetch = () => {\n * execute(fetchData);\n * };\n *\n * const handleReset = () => {\n * reset();\n * };\n *\n * if (loading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * return (\n * <div>\n * <button onClick={handleFetch}>Fetch Data</button>\n * <button onClick={handleReset}>Reset</button>\n * {result && <p>{result}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function useExecutePromise<R = unknown>(): UseExecutePromiseReturn<R> {\n const state = usePromiseState<R>();\n const isMounted = useMountedState();\n const requestId = useRequestId();\n\n /**\n * Execute a promise supplier or promise and manage its state\n * @param input - A function that returns a Promise or a Promise to be executed\n * @returns A Promise that resolves with the result of the executed promise\n */\n const execute = useCallback(\n async (input: PromiseSupplier<R> | Promise<R>): Promise<R> => {\n if (!isMounted()) {\n throw new Error('Component is unmounted');\n }\n const currentRequestId = requestId.generate();\n state.setLoading();\n try {\n const promise = typeof input === 'function' ? input() : input;\n const data = await promise;\n\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n state.setSuccess(data);\n }\n return data;\n } catch (err) {\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n state.setError(err);\n }\n throw err;\n }\n },\n [state, isMounted, requestId],\n );\n\n /**\n * Reset the state to initial values\n */\n const reset = useCallback(() => {\n if (isMounted()) {\n state.setIdle();\n }\n }, [state, isMounted]);\n\n return useMemo(\n () => ({\n loading: state.loading,\n result: state.result,\n error: state.error,\n execute,\n reset,\n status: state.status,\n }),\n [state.loading, state.result, state.error, execute, reset, state.status],\n );\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback, useSyncExternalStore } from 'react';\nimport { KeyStorage } from '@ahoo-wang/fetcher-storage';\n\n/**\n * A React hook that provides state management for a KeyStorage instance.\n * Subscribes to storage changes and returns the current value along with a setter function.\n *\n * @template T - The type of value stored in the key storage\n * @param keyStorage - The KeyStorage instance to subscribe to and manage\n * @returns A tuple containing the current stored value and a function to update it\n */\nexport function useKeyStorage<T>(\n keyStorage: KeyStorage<T>,\n): [T | null, (value: T) => void] {\n const subscribe = useCallback(\n (callback: () => void) => keyStorage.addListener(callback),\n [keyStorage],\n );\n const getSnapshot = useCallback(() => keyStorage.get(), [keyStorage]);\n const value = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n const setValue = useCallback(\n (value: T) => keyStorage.set(value),\n [keyStorage],\n );\n return [value, setValue];\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n fetcher as defaultFetcher,\n FetcherCapable,\n FetchExchange,\n FetchRequest,\n getFetcher,\n RequestOptions,\n} from '@ahoo-wang/fetcher';\nimport { useRef, useCallback, useEffect, useState } from 'react';\nimport { useMountedState } from 'react-use';\nimport { PromiseState, usePromiseState, useRequestId } from '../core';\n\n/**\n * Configuration options for the useFetcher hook.\n * Extends RequestOptions and FetcherCapable interfaces.\n */\nexport interface UseFetcherOptions extends RequestOptions, FetcherCapable {\n}\n\nexport interface UseFetcherReturn<R, E = unknown> extends PromiseState<R, E> {\n /** The FetchExchange object representing the ongoing fetch operation */\n exchange?: FetchExchange;\n execute: (request: FetchRequest) => Promise<void>;\n}\n\n/**\n * A React hook for managing asynchronous operations with proper state handling\n * @param options - Configuration options for the fetcher\n * @returns An object containing the current state and control functions\n *\n * @example\n * ```typescript\n * import { useFetcher } from '@ahoo-wang/fetcher-react';\n *\n * function MyComponent() {\n * const { loading, result, error, execute } = useFetcher<string>();\n *\n * const handleFetch = () => {\n * execute({ url: '/api/data', method: 'GET' });\n * };\n *\n * if (loading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * return (\n * <div>\n * <button onClick={handleFetch}>Fetch Data</button>\n * {result && <p>{result}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function useFetcher<R, E = unknown>(\n options?: UseFetcherOptions,\n): UseFetcherReturn<R, E> {\n const { fetcher = defaultFetcher } = options || {};\n const state = usePromiseState<R, E>();\n const [exchange, setExchange] = useState<FetchExchange | undefined>(\n undefined,\n );\n const isMounted = useMountedState();\n const abortControllerRef = useRef<AbortController | undefined>();\n const requestId = useRequestId();\n\n const currentFetcher = getFetcher(fetcher);\n /**\n * Execute the fetch operation.\n * Cancels any ongoing fetch before starting a new one.\n */\n const execute = useCallback(\n async (request: FetchRequest) => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n abortControllerRef.current =\n request.abortController ?? new AbortController();\n request.abortController = abortControllerRef.current;\n const currentRequestId = requestId.generate();\n state.setLoading();\n try {\n const exchange = await currentFetcher.exchange(request, options);\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n setExchange(exchange);\n }\n const result = await exchange.extractResult<R>();\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n state.setSuccess(result);\n }\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n if (isMounted()) {\n state.setIdle();\n }\n return;\n }\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n state.setError(error as E);\n }\n } finally {\n if (abortControllerRef.current === request.abortController) {\n abortControllerRef.current = undefined;\n }\n }\n },\n [currentFetcher, isMounted, options, state, requestId],\n );\n\n useEffect(() => {\n return () => {\n abortControllerRef.current?.abort();\n abortControllerRef.current = undefined;\n };\n }, []);\n return {\n ...state,\n exchange,\n execute,\n };\n}\n"],"names":["useMountedState","mountedRef","useRef","get","useCallback","useEffect","PromiseStatus","usePromiseState","options","status","setStatus","useState","result","setResult","error","setErrorState","isMounted","setLoadingFn","setSuccessFn","setErrorFn","setIdleFn","useMemo","useRequestId","requestIdRef","generate","current","isLatest","requestId","invalidate","reset","useExecutePromise","state","execute","input","currentRequestId","data","err","useKeyStorage","keyStorage","subscribe","callback","getSnapshot","value","useSyncExternalStore","setValue","useFetcher","fetcher","defaultFetcher","exchange","setExchange","abortControllerRef","currentFetcher","getFetcher","request"],"mappings":"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","x_google_ignoreList":[0]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ahoo-wang/fetcher-react",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.9",
|
|
4
4
|
"description": "React integration for Fetcher HTTP client. Provides React Hooks and components for seamless data fetching with automatic re-rendering and loading states.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fetch",
|