@ahoo-wang/fetcher-react 3.5.6 → 3.6.0

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.
Files changed (82) hide show
  1. package/README.md +869 -483
  2. package/README.zh-CN.md +2139 -605
  3. package/dist/core/debounced/index.d.ts +4 -0
  4. package/dist/core/debounced/index.d.ts.map +1 -0
  5. package/dist/core/debounced/useDebouncedCallback.d.ts.map +1 -0
  6. package/dist/core/{useDebouncedExecutePromise.d.ts → debounced/useDebouncedExecutePromise.d.ts} +1 -1
  7. package/dist/core/debounced/useDebouncedExecutePromise.d.ts.map +1 -0
  8. package/dist/{wow/debounce → core/debounced}/useDebouncedQuery.d.ts +1 -2
  9. package/dist/core/debounced/useDebouncedQuery.d.ts.map +1 -0
  10. package/dist/core/index.d.ts +3 -2
  11. package/dist/core/index.d.ts.map +1 -1
  12. package/dist/{wow → core}/useQuery.d.ts +2 -2
  13. package/dist/core/useQuery.d.ts.map +1 -0
  14. package/dist/{wow → core}/useQueryState.d.ts +1 -1
  15. package/dist/core/useQueryState.d.ts.map +1 -0
  16. package/dist/cosec/RouteGuard.d.ts +49 -0
  17. package/dist/cosec/RouteGuard.d.ts.map +1 -0
  18. package/dist/cosec/SecurityContext.d.ts +47 -14
  19. package/dist/cosec/SecurityContext.d.ts.map +1 -1
  20. package/dist/cosec/index.d.ts +1 -0
  21. package/dist/cosec/index.d.ts.map +1 -1
  22. package/dist/cosec/useSecurity.d.ts +60 -8
  23. package/dist/cosec/useSecurity.d.ts.map +1 -1
  24. package/dist/fetcher/debounced/index.d.ts +3 -0
  25. package/dist/fetcher/debounced/index.d.ts.map +1 -0
  26. package/dist/fetcher/{useDebouncedFetcher.d.ts → debounced/useDebouncedFetcher.d.ts} +2 -2
  27. package/dist/fetcher/debounced/useDebouncedFetcher.d.ts.map +1 -0
  28. package/dist/{wow/debounce → fetcher/debounced}/useDebouncedFetcherQuery.d.ts +1 -1
  29. package/dist/fetcher/debounced/useDebouncedFetcherQuery.d.ts.map +1 -0
  30. package/dist/fetcher/index.d.ts +2 -1
  31. package/dist/fetcher/index.d.ts.map +1 -1
  32. package/dist/{wow → fetcher}/useFetcherQuery.d.ts +3 -3
  33. package/dist/fetcher/useFetcherQuery.d.ts.map +1 -0
  34. package/dist/index.es.js +567 -538
  35. package/dist/index.es.js.map +1 -1
  36. package/dist/index.umd.js +1 -1
  37. package/dist/index.umd.js.map +1 -1
  38. package/dist/types.d.ts +6 -0
  39. package/dist/types.d.ts.map +1 -1
  40. package/dist/wow/fetcher/index.d.ts +6 -0
  41. package/dist/wow/fetcher/index.d.ts.map +1 -0
  42. package/dist/wow/{useFetcherCountQuery.d.ts → fetcher/useFetcherCountQuery.d.ts} +2 -2
  43. package/dist/wow/fetcher/useFetcherCountQuery.d.ts.map +1 -0
  44. package/dist/wow/{useFetcherListQuery.d.ts → fetcher/useFetcherListQuery.d.ts} +2 -2
  45. package/dist/wow/fetcher/useFetcherListQuery.d.ts.map +1 -0
  46. package/dist/wow/{useFetcherListStreamQuery.d.ts → fetcher/useFetcherListStreamQuery.d.ts} +2 -2
  47. package/dist/wow/fetcher/useFetcherListStreamQuery.d.ts.map +1 -0
  48. package/dist/wow/{useFetcherPagedQuery.d.ts → fetcher/useFetcherPagedQuery.d.ts} +2 -2
  49. package/dist/wow/fetcher/useFetcherPagedQuery.d.ts.map +1 -0
  50. package/dist/wow/{useFetcherSingleQuery.d.ts → fetcher/useFetcherSingleQuery.d.ts} +2 -2
  51. package/dist/wow/fetcher/useFetcherSingleQuery.d.ts.map +1 -0
  52. package/dist/wow/index.d.ts +1 -10
  53. package/dist/wow/index.d.ts.map +1 -1
  54. package/dist/wow/useCountQuery.d.ts +1 -1
  55. package/dist/wow/useCountQuery.d.ts.map +1 -1
  56. package/dist/wow/useListQuery.d.ts +1 -1
  57. package/dist/wow/useListQuery.d.ts.map +1 -1
  58. package/dist/wow/useListStreamQuery.d.ts +1 -1
  59. package/dist/wow/useListStreamQuery.d.ts.map +1 -1
  60. package/dist/wow/usePagedQuery.d.ts +1 -1
  61. package/dist/wow/usePagedQuery.d.ts.map +1 -1
  62. package/dist/wow/useSingleQuery.d.ts +1 -1
  63. package/dist/wow/useSingleQuery.d.ts.map +1 -1
  64. package/package.json +1 -1
  65. package/dist/core/useDebouncedCallback.d.ts.map +0 -1
  66. package/dist/core/useDebouncedExecutePromise.d.ts.map +0 -1
  67. package/dist/fetcher/useDebouncedFetcher.d.ts.map +0 -1
  68. package/dist/wow/debounce/index.d.ts +0 -3
  69. package/dist/wow/debounce/index.d.ts.map +0 -1
  70. package/dist/wow/debounce/useDebouncedFetcherQuery.d.ts.map +0 -1
  71. package/dist/wow/debounce/useDebouncedQuery.d.ts.map +0 -1
  72. package/dist/wow/types.d.ts +0 -7
  73. package/dist/wow/types.d.ts.map +0 -1
  74. package/dist/wow/useFetcherCountQuery.d.ts.map +0 -1
  75. package/dist/wow/useFetcherListQuery.d.ts.map +0 -1
  76. package/dist/wow/useFetcherListStreamQuery.d.ts.map +0 -1
  77. package/dist/wow/useFetcherPagedQuery.d.ts.map +0 -1
  78. package/dist/wow/useFetcherQuery.d.ts.map +0 -1
  79. package/dist/wow/useFetcherSingleQuery.d.ts.map +0 -1
  80. package/dist/wow/useQuery.d.ts.map +0 -1
  81. package/dist/wow/useQueryState.d.ts.map +0 -1
  82. /package/dist/core/{useDebouncedCallback.d.ts → debounced/useDebouncedCallback.d.ts} +0 -0
package/README.md CHANGED
@@ -29,37 +29,47 @@ robust data fetching capabilities.
29
29
  - [Quick Start](#quick-start)
30
30
  - [Usage](#usage)
31
31
  - [Core Hooks](#core-hooks)
32
- - [useFetcher](#usefetcher-hook)
33
32
  - [useExecutePromise](#useexecutepromise-hook)
34
33
  - [usePromiseState](#usepromisestate-hook)
35
- - [Debounced Hooks](#debounced-hooks)
36
- - [useDebouncedCallback](#usedebouncedcallback)
37
- - [useDebouncedExecutePromise](#usedebouncedexecutepromise)
38
- - [useDebouncedFetcher](#usedebouncedfetcher)
39
- - [useDebouncedFetcherQuery](#usedebouncedfetcherquery)
40
- - [useDebouncedQuery](#usedebouncedquery)
41
- - [Utility Hooks](#utility-hooks)
42
34
  - [useRequestId](#userequestid-hook)
43
35
  - [useLatest](#uselatest-hook)
44
36
  - [useRefs](#userefs-hook)
37
+ - [useQuery](#usequery-hook)
38
+ - [useQueryState](#usequerystate-hook)
39
+ - [useMounted](#usemounted-hook)
40
+ - [useForceUpdate](#useforceupdate-hook)
41
+ - [Debounced Hooks](#debounced-hooks)
42
+ - [useDebouncedCallback](#usedebouncedcallback)
43
+ - [useDebouncedExecutePromise](#usedebouncedexecutepromise)
44
+ - [useDebouncedQuery](#usedebouncedquery)
45
+ - [Fetcher Hooks](#fetcher-hooks)
46
+ - [useFetcher](#usefetcher-hook)
47
+ - [useFetcherQuery](#usefetcherquery-hook)
48
+ - [Debounced Fetcher Hooks](#debounced-fetcher-hooks)
49
+ - [useDebouncedFetcher](#usedebouncedfetcher)
50
+ - [useDebouncedFetcherQuery](#usedebouncedfetcherquery)
45
51
  - [Storage Hooks](#storage-hooks)
46
52
  - [useKeyStorage](#usekeystorage-hook)
47
53
  - [useImmerKeyStorage](#useimmerkeystorage-hook)
48
54
  - [Event Hooks](#event-hooks)
49
55
  - [useEventSubscription](#useeventsubscription-hook)
56
+ - [CoSec Security Hooks](#cosec-security-hooks)
57
+ - [useSecurity](#usesecurity-hook)
58
+ - [SecurityProvider](#securityprovider)
59
+ - [useSecurityContext](#usesecuritycontext-hook)
60
+ - [RouteGuard](#routeguard)
50
61
  - [Wow Query Hooks](#wow-query-hooks)
51
62
  - [Basic Query Hooks](#basic-query-hooks)
52
63
  - [useListQuery](#uselistquery-hook)
53
64
  - [usePagedQuery](#usepagedquery-hook)
54
65
  - [useSingleQuery](#usesinglequery-hook)
55
66
  - [useCountQuery](#usecountquery-hook)
67
+ - [useListStreamQuery](#useliststreamquery-hook)
56
68
  - [Fetcher Query Hooks](#fetcher-query-hooks)
57
69
  - [useFetcherListQuery](#usefetcherlistquery-hook)
58
70
  - [useFetcherPagedQuery](#usefetcherpagedquery-hook)
59
71
  - [useFetcherSingleQuery](#usefetchersinglequery-hook)
60
72
  - [useFetcherCountQuery](#usefetchercountquery-hook)
61
- - [Stream Query Hooks](#stream-query-hooks)
62
- - [useListStreamQuery](#useliststreamquery-hook)
63
73
  - [useFetcherListStreamQuery](#usefetcherliststreamquery-hook)
64
74
  - [Best Practices](#best-practices)
65
75
  - [API Reference](#api-reference)
@@ -103,270 +113,429 @@ function App() {
103
113
 
104
114
  ### Core Hooks
105
115
 
106
- #### useFetcher Hook
116
+ #### useExecutePromise Hook
107
117
 
108
- The `useFetcher` hook provides complete data fetching capabilities with automatic state management, race condition
109
- protection, and flexible configuration options. It includes built-in AbortController support inherited from `useExecutePromise`.
118
+ The `useExecutePromise` hook manages asynchronous operations with automatic state handling, built-in race condition
119
+ protection, and support for promise state options. It includes automatic AbortController support for canceling operations.
110
120
 
111
121
  ```typescript jsx
112
- import { useFetcher } from '@ahoo-wang/fetcher-react';
122
+ import { useExecutePromise } from '@ahoo-wang/fetcher-react';
113
123
 
114
124
  const MyComponent = () => {
115
- const { loading, error, result, execute, abort } = useFetcher<string>({
125
+ const { loading, result, error, execute, reset, abort } = useExecutePromise<string>({
116
126
  onAbort: () => {
117
- console.log('Fetch operation was aborted');
127
+ console.log('Operation was aborted');
118
128
  }
119
129
  });
120
130
 
131
+ const fetchData = async () => {
132
+ const response = await fetch('/api/data');
133
+ return response.text();
134
+ };
135
+
121
136
  const handleFetch = () => {
122
- execute({ url: '/api/users', method: 'GET' });
137
+ execute(fetchData); // Using a promise supplier
138
+ };
139
+
140
+ const handleDirectPromise = () => {
141
+ const promise = fetch('/api/data').then(res => res.text());
142
+ execute(promise); // Using a direct promise
123
143
  };
124
144
 
125
145
  const handleAbort = () => {
126
- abort(); // Cancel the current fetch operation
146
+ abort(); // Manually abort the current operation
127
147
  };
148
+
149
+ if (loading) return <div>Loading...</div>;
150
+ if (error) return <div>Error: {error.message}</div>;
151
+ return (
152
+ <div>
153
+ <button onClick={handleFetch}>Fetch with Supplier</button>
154
+ <button onClick={handleDirectPromise}>Fetch with Promise</button>
155
+ <button onClick={handleAbort} disabled={!loading}>Abort</button>
156
+ <button onClick={reset}>Reset</button>
157
+ {result && <p>{result}</p>}
158
+ </div>
159
+ );
160
+ };
128
161
  ```
129
162
 
130
- #### Auto Execute Example
163
+ ##### Abort Controller Support
164
+
165
+ The hook automatically creates an AbortController for each operation and provides methods to manage cancellation:
166
+
167
+ - **Automatic Cleanup**: Operations are automatically aborted when the component unmounts
168
+ - **Manual Abort**: Use the `abort()` method to cancel ongoing operations
169
+ - **onAbort Callback**: Configure a callback that fires when an operation is aborted (manually or automatically)
170
+ - **AbortController Access**: The AbortController is passed to promise suppliers for advanced cancellation handling
171
+
172
+ #### usePromiseState Hook
173
+
174
+ The `usePromiseState` hook provides state management for promise operations without execution logic. Supports both
175
+ static options and dynamic option suppliers.
131
176
 
132
177
  ```typescript jsx
133
- import { useListQuery } from '@ahoo-wang/fetcher-react';
178
+ import { usePromiseState, PromiseStatus } from '@ahoo-wang/fetcher-react';
134
179
 
135
180
  const MyComponent = () => {
136
- const { result, loading, error, execute, setCondition } = useListQuery({
137
- initialQuery: { condition: {}, projection: {}, sort: [], limit: 10 },
138
- list: async (listQuery) => fetchListData(listQuery),
139
- autoExecute: true, // Automatically execute on component mount
140
- });
181
+ const { status, loading, result, error, setSuccess, setError, setIdle } = usePromiseState<string>();
141
182
 
142
- // The query will execute automatically when the component mounts
143
- // You can still manually trigger it with execute() or update conditions
183
+ const handleSuccess = () => setSuccess('Data loaded');
184
+ const handleError = () => setError(new Error('Failed to load'));
144
185
 
145
- if (loading) return <div>Loading...</div>;
146
- if (error) return <div>Error: {error.message}</div>;
186
+ return (
187
+ <div>
188
+ <button onClick={handleSuccess}>Set Success</button>
189
+ <button onClick={handleError}>Set Error</button>
190
+ <button onClick={setIdle}>Reset</button>
191
+ <p>Status: {status}</p>
192
+ {loading && <p>Loading...</p>}
193
+ {result && <p>Result: {result}</p>}
194
+ {error && <p>Error: {error.message}</p>}
195
+ </div>
196
+ );
197
+ };
198
+ ```
199
+
200
+ ##### usePromiseState with Options Supplier
201
+
202
+ ```typescript jsx
203
+ import { usePromiseState, PromiseStatus } from '@ahoo-wang/fetcher-react';
204
+
205
+ const MyComponent = () => {
206
+ // Using options supplier for dynamic configuration
207
+ const optionsSupplier = () => ({
208
+ initialStatus: PromiseStatus.IDLE,
209
+ onSuccess: async (result: string) => {
210
+ await saveToAnalytics(result);
211
+ console.log('Success:', result);
212
+ },
213
+ onError: async (error) => {
214
+ await logErrorToServer(error);
215
+ console.error('Error:', error);
216
+ },
217
+ });
218
+
219
+ const { setSuccess, setError } = usePromiseState<string>(optionsSupplier);
147
220
 
148
221
  return (
149
222
  <div>
150
- <ul>
151
- {result?.map((item, index) => (
152
- <li key={index}>{item.name}</li>
153
- ))}
154
- </ul>
223
+ <button onClick={() => setSuccess('Dynamic success!')}>Set Success</button>
224
+ <button onClick={() => setError(new Error('Dynamic error!'))}>Set Error</button>
155
225
  </div>
156
226
  );
157
227
  };
158
228
  ```
159
229
 
160
- ### Debounced Hooks
230
+ #### useRequestId Hook
161
231
 
162
- 🚀 **Advanced Debouncing for React Applications** - Powerful hooks that combine debouncing with async operations, providing seamless rate limiting for API calls, user interactions, and promise execution.
232
+ The `useRequestId` hook provides request ID management for preventing race conditions in async operations.
163
233
 
164
- #### useDebouncedCallback
234
+ ```typescript jsx
235
+ import { useRequestId } from '@ahoo-wang/fetcher-react';
165
236
 
166
- A React hook that provides a debounced version of any callback function with leading/trailing edge execution options.
237
+ const MyComponent = () => {
238
+ const { generate, isLatest, invalidate } = useRequestId();
239
+
240
+ const handleFetch = async () => {
241
+ const requestId = generate();
242
+
243
+ try {
244
+ const result = await fetchData();
245
+
246
+ if (isLatest(requestId)) {
247
+ setData(result);
248
+ }
249
+ } catch (error) {
250
+ if (isLatest(requestId)) {
251
+ setError(error);
252
+ }
253
+ }
254
+ };
255
+
256
+ return (
257
+ <div>
258
+ <button onClick={handleFetch}>Fetch Data</button>
259
+ <button onClick={invalidate}>Cancel Ongoing</button>
260
+ </div>
261
+ );
262
+ };
263
+ ```
264
+
265
+ #### useLatest Hook
266
+
267
+ The `useLatest` hook returns a ref containing the latest value, useful for accessing the current value in async
268
+ callbacks.
167
269
 
168
270
  ```typescript jsx
169
- import { useDebouncedCallback } from '@ahoo-wang/fetcher-react';
271
+ import { useLatest } from '@ahoo-wang/fetcher-react';
170
272
 
171
- const SearchComponent = () => {
172
- const { run: debouncedSearch, cancel, isPending } = useDebouncedCallback(
173
- async (query: string) => {
174
- const response = await fetch(`/api/search?q=${query}`);
175
- const results = await response.json();
176
- console.log('Search results:', results);
177
- },
178
- { delay: 300 }
273
+ const MyComponent = () => {
274
+ const [count, setCount] = useState(0);
275
+ const latestCount = useLatest(count);
276
+
277
+ const handleAsync = async () => {
278
+ await someAsyncOperation();
279
+ console.log('Latest count:', latestCount.current); // Always the latest
280
+ };
281
+
282
+ return (
283
+ <div>
284
+ <p>Count: {count}</p>
285
+ <button onClick={() => setCount(c => c + 1)}>Increment</button>
286
+ <button onClick={handleAsync}>Async Log</button>
287
+ </div>
179
288
  );
289
+ };
290
+ ```
180
291
 
181
- const handleSearch = (query: string) => {
182
- if (query.trim()) {
183
- debouncedSearch(query);
184
- } else {
185
- cancel(); // Cancel any pending search
186
- }
292
+ #### useRefs Hook
293
+
294
+ The `useRefs` hook provides a Map-like interface for managing multiple React refs dynamically. It allows registering, retrieving, and managing refs by key, with automatic cleanup on component unmount.
295
+
296
+ ```typescript jsx
297
+ import { useRefs } from '@ahoo-wang/fetcher-react';
298
+
299
+ const MyComponent = () => {
300
+ const refs = useRefs<HTMLDivElement>();
301
+
302
+ const handleFocus = (key: string) => {
303
+ const element = refs.get(key);
304
+ element?.focus();
187
305
  };
188
306
 
189
307
  return (
190
308
  <div>
191
- <input
192
- type="text"
193
- placeholder="Search..."
194
- onChange={(e) => handleSearch(e.target.value)}
195
- />
196
- {isPending() && <div>Searching...</div>}
309
+ <div ref={refs.register('first')} tabIndex={0}>First Element</div>
310
+ <div ref={refs.register('second')} tabIndex={0}>Second Element</div>
311
+ <button onClick={() => handleFocus('first')}>Focus First</button>
312
+ <button onClick={() => handleFocus('second')}>Focus Second</button>
197
313
  </div>
198
314
  );
199
315
  };
200
316
  ```
201
317
 
202
- **Configuration Options:**
318
+ Key features:
203
319
 
204
- - `delay`: Delay in milliseconds before execution (required, positive number)
205
- - `leading`: Execute immediately on first call (default: false)
206
- - `trailing`: Execute after delay on last call (default: true)
320
+ - **Dynamic Registration**: Register refs with string, number, or symbol keys
321
+ - **Map-like API**: Full Map interface with get, set, has, delete, etc.
322
+ - **Automatic Cleanup**: Refs are cleared when component unmounts
323
+ - **Type Safety**: Full TypeScript support for ref types
207
324
 
208
- #### useDebouncedExecutePromise
325
+ #### useQuery Hook
209
326
 
210
- Combines promise execution with debouncing functionality, perfect for API calls and async operations.
327
+ The `useQuery` hook provides a complete solution for managing query-based asynchronous operations with automatic state management and execution control.
211
328
 
212
329
  ```typescript jsx
213
- import { useDebouncedExecutePromise } from '@ahoo-wang/fetcher-react';
330
+ import { useQuery } from '@ahoo-wang/fetcher-react';
214
331
 
215
- const DataFetcher = () => {
216
- const { loading, result, error, run } = useDebouncedExecutePromise({
217
- debounce: { delay: 300 },
218
- });
332
+ interface UserQuery {
333
+ id: string;
334
+ }
219
335
 
220
- const handleLoadUser = (userId: string) => {
221
- run(async () => {
222
- const response = await fetch(`/api/users/${userId}`);
336
+ interface User {
337
+ id: string;
338
+ name: string;
339
+ }
340
+
341
+ function UserComponent() {
342
+ const { loading, result, error, execute, setQuery } = useQuery<UserQuery, User>({
343
+ initialQuery: { id: '1' },
344
+ execute: async (query) => {
345
+ const response = await fetch(`/api/users/${query.id}`);
223
346
  return response.json();
224
- });
347
+ },
348
+ autoExecute: true,
349
+ });
350
+
351
+ const handleUserChange = (userId: string) => {
352
+ setQuery({ id: userId }); // Automatically executes if autoExecute is true
225
353
  };
226
354
 
355
+ if (loading) return <div>Loading...</div>;
356
+ if (error) return <div>Error: {error.message}</div>;
227
357
  return (
228
358
  <div>
229
- <button onClick={() => handleLoadUser('user123')}>
230
- Load User
359
+ <button onClick={() => handleUserChange('2')}>Load User 2</button>
360
+ {result && <p>User: {result.name}</p>}
361
+ </div>
362
+ );
363
+ }
364
+ ```
365
+
366
+ #### useQueryState Hook
367
+
368
+ The `useQueryState` hook provides state management for query parameters with automatic execution capabilities.
369
+
370
+ ```typescript jsx
371
+ import { useQueryState } from '@ahoo-wang/fetcher-react';
372
+
373
+ interface UserQuery {
374
+ id: string;
375
+ name?: string;
376
+ }
377
+
378
+ function UserComponent() {
379
+ const executeQuery = async (query: UserQuery) => {
380
+ // Perform query execution logic here
381
+ console.log('Executing query:', query);
382
+ };
383
+
384
+ const { getQuery, setQuery } = useQueryState<UserQuery>({
385
+ initialQuery: { id: '1' },
386
+ autoExecute: true,
387
+ execute: executeQuery,
388
+ });
389
+
390
+ const handleQueryChange = (newQuery: UserQuery) => {
391
+ setQuery(newQuery); // Will automatically execute if autoExecute is true
392
+ };
393
+
394
+ const currentQuery = getQuery(); // Get current query parameters
395
+
396
+ return (
397
+ <div>
398
+ <button onClick={() => handleQueryChange({ id: '2', name: 'John' })}>
399
+ Update Query
231
400
  </button>
232
- {loading && <div>Loading...</div>}
233
- {error && <div>Error: {error.message}</div>}
234
- {result && <div>User: {result.name}</div>}
235
401
  </div>
236
402
  );
237
- };
403
+ }
238
404
  ```
239
405
 
240
- #### useDebouncedFetcher
406
+ #### useMounted Hook
241
407
 
242
- Specialized hook combining HTTP fetching with debouncing, built on top of the core fetcher library.
408
+ The `useMounted` hook provides a way to check if a component is still mounted, useful for avoiding state updates on unmounted components.
243
409
 
244
410
  ```typescript jsx
245
- import { useDebouncedFetcher } from '@ahoo-wang/fetcher-react';
411
+ import { useMounted } from '@ahoo-wang/fetcher-react';
246
412
 
247
- const SearchInput = () => {
248
- const [query, setQuery] = useState('');
249
- const { loading, result, error, run } = useDebouncedFetcher({
250
- debounce: { delay: 300 },
251
- onSuccess: (data) => {
252
- setSearchResults(data.results);
413
+ const MyComponent = () => {
414
+ const isMounted = useMounted();
415
+
416
+ const handleAsyncOperation = async () => {
417
+ const result = await someAsyncOperation();
418
+
419
+ // Check if component is still mounted before updating state
420
+ if (isMounted()) {
421
+ setData(result);
253
422
  }
254
- });
423
+ };
255
424
 
256
- const handleChange = (value: string) => {
257
- setQuery(value);
258
- if (value.trim()) {
259
- run({
260
- url: '/api/search',
261
- method: 'GET',
262
- params: { q: value }
263
- });
425
+ return (
426
+ <div>
427
+ <button onClick={handleAsyncOperation}>Perform Async Operation</button>
428
+ </div>
429
+ );
430
+ };
431
+ ```
432
+
433
+ #### useForceUpdate Hook
434
+
435
+ The `useForceUpdate` hook provides a way to force a component to re-render, useful when you need to trigger a render based on external changes.
436
+
437
+ ```typescript jsx
438
+ import { useForceUpdate } from '@ahoo-wang/fetcher-react';
439
+
440
+ const MyComponent = () => {
441
+ const forceUpdate = useForceUpdate();
442
+
443
+ const handleExternalChange = () => {
444
+ // Perform some external operation that doesn't trigger a re-render
445
+ updateExternalState();
446
+
447
+ // Force the component to re-render to reflect the changes
448
+ forceUpdate();
449
+ };
450
+
451
+ return (
452
+ <div>
453
+ <button onClick={handleExternalChange}>Force Update</button>
454
+ </div>
455
+ );
456
+ };
457
+ ```
458
+
459
+ ### Debounced Hooks
460
+
461
+ 🚀 **Advanced Debouncing for React Applications** - Powerful hooks that combine debouncing with async operations, providing seamless rate limiting for API calls, user interactions, and promise execution.
462
+
463
+ #### useDebouncedCallback
464
+
465
+ A React hook that provides a debounced version of any callback function with leading/trailing edge execution options.
466
+
467
+ ```typescript jsx
468
+ import { useDebouncedCallback } from '@ahoo-wang/fetcher-react';
469
+
470
+ const SearchComponent = () => {
471
+ const { run: debouncedSearch, cancel, isPending } = useDebouncedCallback(
472
+ async (query: string) => {
473
+ const response = await fetch(`/api/search?q=${query}`);
474
+ const results = await response.json();
475
+ console.log('Search results:', results);
476
+ },
477
+ { delay: 300 }
478
+ );
479
+
480
+ const handleSearch = (query: string) => {
481
+ if (query.trim()) {
482
+ debouncedSearch(query);
483
+ } else {
484
+ cancel(); // Cancel any pending search
264
485
  }
265
486
  };
266
487
 
267
488
  return (
268
489
  <div>
269
490
  <input
270
- value={query}
271
- onChange={(e) => handleChange(e.target.value)}
491
+ type="text"
272
492
  placeholder="Search..."
493
+ onChange={(e) => handleSearch(e.target.value)}
273
494
  />
274
- {loading && <div>Searching...</div>}
275
- {error && <div>Error: {error.message}</div>}
276
- {result && <SearchResults data={result} />}
495
+ {isPending() && <div>Searching...</div>}
277
496
  </div>
278
497
  );
279
498
  };
280
499
  ```
281
500
 
282
- **Debouncing Strategies:**
501
+ **Configuration Options:**
283
502
 
284
- - **Leading Edge**: Execute immediately on first call, then debounce subsequent calls
285
- - **Trailing Edge**: Execute after delay on last call (default behavior)
286
- - **Leading + Trailing**: Execute immediately, then again after delay if called again
503
+ - `delay`: Delay in milliseconds before execution (required, positive number)
504
+ - `leading`: Execute immediately on first call (default: false)
505
+ - `trailing`: Execute after delay on last call (default: true)
287
506
 
288
- #### useDebouncedFetcherQuery
507
+ #### useDebouncedExecutePromise
289
508
 
290
- Combines query-based HTTP fetching with debouncing, perfect for search inputs and dynamic query scenarios where you want to debounce API calls based on query parameters.
509
+ Combines promise execution with debouncing functionality, perfect for API calls and async operations.
291
510
 
292
511
  ```typescript jsx
293
- import { useDebouncedFetcherQuery } from '@ahoo-wang/fetcher-react';
294
-
295
- interface SearchQuery {
296
- keyword: string;
297
- limit: number;
298
- filters?: { category?: string };
299
- }
300
-
301
- interface SearchResult {
302
- items: Array<{ id: string; title: string }>;
303
- total: number;
304
- }
512
+ import { useDebouncedExecutePromise } from '@ahoo-wang/fetcher-react';
305
513
 
306
- const SearchComponent = () => {
307
- const {
308
- loading,
309
- result,
310
- error,
311
- run,
312
- cancel,
313
- isPending,
314
- setQuery,
315
- getQuery,
316
- } = useDebouncedFetcherQuery<SearchQuery, SearchResult>({
317
- url: '/api/search',
318
- initialQuery: { keyword: '', limit: 10 },
319
- debounce: { delay: 300 }, // Debounce for 300ms
320
- autoExecute: false, // Don't execute on mount
514
+ const DataFetcher = () => {
515
+ const { loading, result, error, run } = useDebouncedExecutePromise({
516
+ debounce: { delay: 300 },
321
517
  });
322
518
 
323
- const handleSearch = (keyword: string) => {
324
- setQuery({ keyword, limit: 10 }); // This will trigger debounced execution if autoExecute was true
325
- };
326
-
327
- const handleManualSearch = () => {
328
- run(); // Manual debounced execution with current query
329
- };
330
-
331
- const handleCancel = () => {
332
- cancel(); // Cancel any pending debounced execution
519
+ const handleLoadUser = (userId: string) => {
520
+ run(async () => {
521
+ const response = await fetch(`/api/users/${userId}`);
522
+ return response.json();
523
+ });
333
524
  };
334
525
 
335
- if (loading) return <div>Searching...</div>;
336
- if (error) return <div>Error: {error.message}</div>;
337
-
338
526
  return (
339
527
  <div>
340
- <input
341
- type="text"
342
- onChange={(e) => handleSearch(e.target.value)}
343
- placeholder="Search..."
344
- />
345
- <button onClick={handleManualSearch} disabled={isPending()}>
346
- {isPending() ? 'Searching...' : 'Search'}
528
+ <button onClick={() => handleLoadUser('user123')}>
529
+ Load User
347
530
  </button>
348
- <button onClick={handleCancel}>Cancel</button>
349
- {result && (
350
- <div>
351
- Found {result.total} items:
352
- {result.items.map(item => (
353
- <div key={item.id}>{item.title}</div>
354
- ))}
355
- </div>
356
- )}
531
+ {loading && <div>Loading...</div>}
532
+ {error && <div>Error: {error.message}</div>}
533
+ {result && <div>User: {result.name}</div>}
357
534
  </div>
358
535
  );
359
536
  };
360
537
  ```
361
538
 
362
- **Key Features:**
363
-
364
- - **Query State Management**: Automatic query parameter handling with `setQuery` and `getQuery`
365
- - **Debounced Execution**: Prevents excessive API calls during rapid user input
366
- - **Auto-Execution**: Optional automatic execution when query parameters change
367
- - **Manual Control**: `run()` for manual execution, `cancel()` for cancellation
368
- - **Pending State**: `isPending()` to check if a debounced call is queued
369
-
370
539
  #### useDebouncedQuery
371
540
 
372
541
  Combines general query execution with debouncing, perfect for custom query operations where you want to debounce execution based on query parameters.
@@ -457,259 +626,222 @@ const SearchComponent = () => {
457
626
  - **Pending State**: `isPending()` to check if a debounced call is queued
458
627
  - **Custom Execution**: Flexible execute function for any query operation
459
628
 
460
- ### useExecutePromise Hook
629
+ ### Fetcher Hooks
461
630
 
462
- The `useExecutePromise` hook manages asynchronous operations with automatic state handling, built-in race condition
463
- protection, and support for promise state options. It includes automatic AbortController support for canceling operations.
631
+ #### useFetcher Hook
632
+
633
+ The `useFetcher` hook provides complete data fetching capabilities with automatic state management, race condition
634
+ protection, and flexible configuration options. It includes built-in AbortController support inherited from `useExecutePromise`.
464
635
 
465
636
  ```typescript jsx
466
- import { useExecutePromise } from '@ahoo-wang/fetcher-react';
637
+ import { useFetcher } from '@ahoo-wang/fetcher-react';
467
638
 
468
639
  const MyComponent = () => {
469
- const { loading, result, error, execute, reset, abort } = useExecutePromise<string>({
640
+ const { loading, error, result, execute, abort } = useFetcher<string>({
470
641
  onAbort: () => {
471
- console.log('Operation was aborted');
642
+ console.log('Fetch operation was aborted');
472
643
  }
473
644
  });
474
645
 
475
- const fetchData = async () => {
476
- const response = await fetch('/api/data');
477
- return response.text();
478
- };
479
-
480
646
  const handleFetch = () => {
481
- execute(fetchData); // Using a promise supplier
482
- };
483
-
484
- const handleDirectPromise = () => {
485
- const promise = fetch('/api/data').then(res => res.text());
486
- execute(promise); // Using a direct promise
647
+ execute({ url: '/api/users', method: 'GET' });
487
648
  };
488
649
 
489
650
  const handleAbort = () => {
490
- abort(); // Manually abort the current operation
651
+ abort(); // Cancel the current fetch operation
491
652
  };
492
-
493
- if (loading) return <div>Loading...</div>;
494
- if (error) return <div>Error: {error.message}</div>;
495
- return (
496
- <div>
497
- <button onClick={handleFetch}>Fetch with Supplier</button>
498
- <button onClick={handleDirectPromise}>Fetch with Promise</button>
499
- <button onClick={handleAbort} disabled={!loading}>Abort</button>
500
- <button onClick={reset}>Reset</button>
501
- {result && <p>{result}</p>}
502
- </div>
503
- );
504
- };
505
- ```
506
-
507
- #### Abort Controller Support
508
-
509
- The hook automatically creates an AbortController for each operation and provides methods to manage cancellation:
510
-
511
- - **Automatic Cleanup**: Operations are automatically aborted when the component unmounts
512
- - **Manual Abort**: Use the `abort()` method to cancel ongoing operations
513
- - **onAbort Callback**: Configure a callback that fires when an operation is aborted (manually or automatically)
514
- - **AbortController Access**: The AbortController is passed to promise suppliers for advanced cancellation handling
515
-
516
- ### usePromiseState Hook
517
-
518
- The `usePromiseState` hook provides state management for promise operations without execution logic. Supports both
519
- static options and dynamic option suppliers.
520
-
521
- ```typescript jsx
522
- import { usePromiseState, PromiseStatus } from '@ahoo-wang/fetcher-react';
523
-
524
- const MyComponent = () => {
525
- const { status, loading, result, error, setSuccess, setError, setIdle } = usePromiseState<string>();
526
-
527
- const handleSuccess = () => setSuccess('Data loaded');
528
- const handleError = () => setError(new Error('Failed to load'));
529
-
530
- return (
531
- <div>
532
- <button onClick={handleSuccess}>Set Success</button>
533
- <button onClick={handleError}>Set Error</button>
534
- <button onClick={setIdle}>Reset</button>
535
- <p>Status: {status}</p>
536
- {loading && <p>Loading...</p>}
537
- {result && <p>Result: {result}</p>}
538
- {error && <p>Error: {error.message}</p>}
539
- </div>
540
- );
541
- };
542
653
  ```
543
654
 
544
- #### usePromiseState with Options Supplier
655
+ #### Auto Execute Example
545
656
 
546
657
  ```typescript jsx
547
- import { usePromiseState, PromiseStatus } from '@ahoo-wang/fetcher-react';
658
+ import { useListQuery } from '@ahoo-wang/fetcher-react';
548
659
 
549
660
  const MyComponent = () => {
550
- // Using options supplier for dynamic configuration
551
- const optionsSupplier = () => ({
552
- initialStatus: PromiseStatus.IDLE,
553
- onSuccess: async (result: string) => {
554
- await saveToAnalytics(result);
555
- console.log('Success:', result);
556
- },
557
- onError: async (error) => {
558
- await logErrorToServer(error);
559
- console.error('Error:', error);
560
- },
661
+ const { result, loading, error, execute, setCondition } = useListQuery({
662
+ initialQuery: { condition: {}, projection: {}, sort: [], limit: 10 },
663
+ list: async (listQuery) => fetchListData(listQuery),
664
+ autoExecute: true, // Automatically execute on component mount
561
665
  });
562
666
 
563
- const { setSuccess, setError } = usePromiseState<string>(optionsSupplier);
564
-
565
- return (
566
- <div>
567
- <button onClick={() => setSuccess('Dynamic success!')}>Set Success</button>
568
- <button onClick={() => setError(new Error('Dynamic error!'))}>Set Error</button>
569
- </div>
570
- );
571
- };
572
- ```
573
-
574
- ### Utility Hooks
575
-
576
- #### useRequestId Hook
577
-
578
- The `useRequestId` hook provides request ID management for preventing race conditions in async operations.
579
-
580
- ```typescript jsx
581
- import { useRequestId } from '@ahoo-wang/fetcher-react';
582
-
583
- const MyComponent = () => {
584
- const { generate, isLatest, invalidate } = useRequestId();
585
-
586
- const handleFetch = async () => {
587
- const requestId = generate();
588
-
589
- try {
590
- const result = await fetchData();
667
+ // The query will execute automatically when the component mounts
668
+ // You can still manually trigger it with execute() or update conditions
591
669
 
592
- if (isLatest(requestId)) {
593
- setData(result);
594
- }
595
- } catch (error) {
596
- if (isLatest(requestId)) {
597
- setError(error);
598
- }
599
- }
600
- };
670
+ if (loading) return <div>Loading...</div>;
671
+ if (error) return <div>Error: {error.message}</div>;
601
672
 
602
673
  return (
603
674
  <div>
604
- <button onClick={handleFetch}>Fetch Data</button>
605
- <button onClick={invalidate}>Cancel Ongoing</button>
675
+ <ul>
676
+ {result?.map((item, index) => (
677
+ <li key={index}>{item.name}</li>
678
+ ))}
679
+ </ul>
606
680
  </div>
607
681
  );
608
682
  };
609
683
  ```
610
684
 
611
- ### useLatest Hook
685
+ #### useFetcherQuery Hook
612
686
 
613
- The `useLatest` hook returns a ref containing the latest value, useful for accessing the current value in async
614
- callbacks.
687
+ The `useFetcherQuery` hook provides a foundation for building specialized query hooks that integrate with the Fetcher library.
615
688
 
616
689
  ```typescript jsx
617
- import { useLatest } from '@ahoo-wang/fetcher-react';
690
+ import { useFetcherQuery } from '@ahoo-wang/fetcher-react';
618
691
 
619
692
  const MyComponent = () => {
620
- const [count, setCount] = useState(0);
621
- const latestCount = useLatest(count);
693
+ const { data, loading, error, execute } = useFetcherQuery({
694
+ url: '/api/data',
695
+ initialQuery: { /* query parameters */ },
696
+ execute: async (query) => {
697
+ // Custom execution logic
698
+ return fetchData(query);
699
+ },
700
+ autoExecute: true,
701
+ });
622
702
 
623
- const handleAsync = async () => {
624
- await someAsyncOperation();
625
- console.log('Latest count:', latestCount.current); // Always the latest
626
- };
703
+ if (loading) return <div>Loading...</div>;
704
+ if (error) return <div>Error: {error.message}</div>;
627
705
 
628
706
  return (
629
707
  <div>
630
- <p>Count: {count}</p>
631
- <button onClick={() => setCount(c => c + 1)}>Increment</button>
632
- <button onClick={handleAsync}>Async Log</button>
708
+ <pre>{JSON.stringify(data, null, 2)}</pre>
633
709
  </div>
634
710
  );
635
711
  };
636
712
  ```
637
713
 
638
- ### useRefs Hook
714
+ ### Debounced Fetcher Hooks
639
715
 
640
- The `useRefs` hook provides a Map-like interface for managing multiple React refs dynamically. It allows registering, retrieving, and managing refs by key, with automatic cleanup on component unmount.
716
+ #### useDebouncedFetcher
717
+
718
+ Specialized hook combining HTTP fetching with debouncing, built on top of the core fetcher library.
641
719
 
642
720
  ```typescript jsx
643
- import { useRefs } from '@ahoo-wang/fetcher-react';
721
+ import { useDebouncedFetcher } from '@ahoo-wang/fetcher-react';
644
722
 
645
- const MyComponent = () => {
646
- const refs = useRefs<HTMLDivElement>();
723
+ const SearchInput = () => {
724
+ const [query, setQuery] = useState('');
725
+ const { loading, result, error, run } = useDebouncedFetcher({
726
+ debounce: { delay: 300 },
727
+ onSuccess: (data) => {
728
+ setSearchResults(data.results);
729
+ }
730
+ });
647
731
 
648
- const handleFocus = (key: string) => {
649
- const element = refs.get(key);
650
- element?.focus();
732
+ const handleChange = (value: string) => {
733
+ setQuery(value);
734
+ if (value.trim()) {
735
+ run({
736
+ url: '/api/search',
737
+ method: 'GET',
738
+ params: { q: value }
739
+ });
740
+ }
651
741
  };
652
742
 
653
743
  return (
654
744
  <div>
655
- <div ref={refs.register('first')} tabIndex={0}>First Element</div>
656
- <div ref={refs.register('second')} tabIndex={0}>Second Element</div>
657
- <button onClick={() => handleFocus('first')}>Focus First</button>
658
- <button onClick={() => handleFocus('second')}>Focus Second</button>
745
+ <input
746
+ value={query}
747
+ onChange={(e) => handleChange(e.target.value)}
748
+ placeholder="Search..."
749
+ />
750
+ {loading && <div>Searching...</div>}
751
+ {error && <div>Error: {error.message}</div>}
752
+ {result && <SearchResults data={result} />}
659
753
  </div>
660
754
  );
661
755
  };
662
756
  ```
663
757
 
664
- Key features:
665
-
666
- - **Dynamic Registration**: Register refs with string, number, or symbol keys
667
- - **Map-like API**: Full Map interface with get, set, has, delete, etc.
668
- - **Automatic Cleanup**: Refs are cleared when component unmounts
669
- - **Type Safety**: Full TypeScript support for ref types
758
+ **Debouncing Strategies:**
670
759
 
671
- ### Event Hooks
760
+ - **Leading Edge**: Execute immediately on first call, then debounce subsequent calls
761
+ - **Trailing Edge**: Execute after delay on last call (default behavior)
762
+ - **Leading + Trailing**: Execute immediately, then again after delay if called again
672
763
 
673
- #### useEventSubscription Hook
764
+ #### useDebouncedFetcherQuery
674
765
 
675
- The `useEventSubscription` hook provides a React interface for subscribing to typed event buses. It automatically manages subscription lifecycle while offering manual control functions for additional flexibility.
766
+ Combines query-based HTTP fetching with debouncing, perfect for search inputs and dynamic query scenarios where you want to debounce API calls based on query parameters.
676
767
 
677
768
  ```typescript jsx
678
- import { useEventSubscription } from '@ahoo-wang/fetcher-react';
679
- import { eventBus } from './eventBus';
769
+ import { useDebouncedFetcherQuery } from '@ahoo-wang/fetcher-react';
680
770
 
681
- function MyComponent() {
682
- const { subscribe, unsubscribe } = useEventSubscription({
683
- bus: eventBus,
684
- handler: {
685
- name: 'myEvent',
686
- handle: (event) => {
687
- console.log('Received event:', event);
688
- }
689
- }
771
+ interface SearchQuery {
772
+ keyword: string;
773
+ limit: number;
774
+ filters?: { category?: string };
775
+ }
776
+
777
+ interface SearchResult {
778
+ items: Array<{ id: string; title: string }>;
779
+ total: number;
780
+ }
781
+
782
+ const SearchComponent = () => {
783
+ const {
784
+ loading,
785
+ result,
786
+ error,
787
+ run,
788
+ cancel,
789
+ isPending,
790
+ setQuery,
791
+ getQuery,
792
+ } = useDebouncedFetcherQuery<SearchQuery, SearchResult>({
793
+ url: '/api/search',
794
+ initialQuery: { keyword: '', limit: 10 },
795
+ debounce: { delay: 300 }, // Debounce for 300ms
796
+ autoExecute: false, // Don't execute on mount
690
797
  });
691
798
 
692
- // The hook automatically subscribes on mount and unsubscribes on unmount
693
- // You can also manually control subscription if needed
694
- const handleToggleSubscription = () => {
695
- if (someCondition) {
696
- subscribe();
697
- } else {
698
- unsubscribe();
699
- }
799
+ const handleSearch = (keyword: string) => {
800
+ setQuery({ keyword, limit: 10 }); // This will trigger debounced execution if autoExecute was true
700
801
  };
701
802
 
702
- return <div>My Component</div>;
703
- }
803
+ const handleManualSearch = () => {
804
+ run(); // Manual debounced execution with current query
805
+ };
806
+
807
+ const handleCancel = () => {
808
+ cancel(); // Cancel any pending debounced execution
809
+ };
810
+
811
+ if (loading) return <div>Searching...</div>;
812
+ if (error) return <div>Error: {error.message}</div>;
813
+
814
+ return (
815
+ <div>
816
+ <input
817
+ type="text"
818
+ onChange={(e) => handleSearch(e.target.value)}
819
+ placeholder="Search..."
820
+ />
821
+ <button onClick={handleManualSearch} disabled={isPending()}>
822
+ {isPending() ? 'Searching...' : 'Search'}
823
+ </button>
824
+ <button onClick={handleCancel}>Cancel</button>
825
+ {result && (
826
+ <div>
827
+ Found {result.total} items:
828
+ {result.items.map(item => (
829
+ <div key={item.id}>{item.title}</div>
830
+ ))}
831
+ </div>
832
+ )}
833
+ </div>
834
+ );
835
+ };
704
836
  ```
705
837
 
706
- Key features:
838
+ **Key Features:**
707
839
 
708
- - **Automatic Lifecycle Management**: Automatically subscribes on component mount and unsubscribes on unmount
709
- - **Manual Control**: Provides `subscribe` and `unsubscribe` functions for additional control
710
- - **Type Safety**: Full TypeScript support with generic event types
711
- - **Error Handling**: Logs warnings for failed subscription attempts
712
- - **Event Bus Integration**: Works seamlessly with `@ahoo-wang/fetcher-eventbus` TypedEventBus instances
840
+ - **Query State Management**: Automatic query parameter handling with `setQuery` and `getQuery`
841
+ - **Debounced Execution**: Prevents excessive API calls during rapid user input
842
+ - **Auto-Execution**: Optional automatic execution when query parameters change
843
+ - **Manual Control**: `run()` for manual execution, `cancel()` for cancellation
844
+ - **Pending State**: `isPending()` to check if a debounced call is queued
713
845
 
714
846
  ### Storage Hooks
715
847
 
@@ -1040,22 +1172,188 @@ const prefsStorage = new KeyStorage<UserPreferences>({
1040
1172
  key: 'user-prefs',
1041
1173
  });
1042
1174
 
1043
- // TypeScript will catch invalid updates
1044
- const [prefs, updatePrefs] = useImmerKeyStorage(prefsStorage);
1175
+ // TypeScript will catch invalid updates
1176
+ const [prefs, updatePrefs] = useImmerKeyStorage(prefsStorage);
1177
+
1178
+ // This will cause a TypeScript error:
1179
+ // updatePrefs(draft => { draft.theme = 'invalid'; });
1180
+ ```
1181
+
1182
+ ### Event Hooks
1183
+
1184
+ #### useEventSubscription Hook
1185
+
1186
+ The `useEventSubscription` hook provides a React interface for subscribing to typed event buses. It automatically manages subscription lifecycle while offering manual control functions for additional flexibility.
1187
+
1188
+ ```typescript jsx
1189
+ import { useEventSubscription } from '@ahoo-wang/fetcher-react';
1190
+ import { eventBus } from './eventBus';
1191
+
1192
+ function MyComponent() {
1193
+ const { subscribe, unsubscribe } = useEventSubscription({
1194
+ bus: eventBus,
1195
+ handler: {
1196
+ name: 'myEvent',
1197
+ handle: (event) => {
1198
+ console.log('Received event:', event);
1199
+ }
1200
+ }
1201
+ });
1202
+
1203
+ // The hook automatically subscribes on mount and unsubscribes on unmount
1204
+ // You can also manually control subscription if needed
1205
+ const handleToggleSubscription = () => {
1206
+ if (someCondition) {
1207
+ subscribe();
1208
+ } else {
1209
+ unsubscribe();
1210
+ }
1211
+ };
1212
+
1213
+ return <div>My Component</div>;
1214
+ }
1215
+ ```
1216
+
1217
+ Key features:
1218
+
1219
+ - **Automatic Lifecycle Management**: Automatically subscribes on component mount and unsubscribes on unmount
1220
+ - **Manual Control**: Provides `subscribe` and `unsubscribe` functions for additional control
1221
+ - **Type Safety**: Full TypeScript support with generic event types
1222
+ - **Error Handling**: Logs warnings for failed subscription attempts
1223
+ - **Event Bus Integration**: Works seamlessly with `@ahoo-wang/fetcher-eventbus` TypedEventBus instances
1224
+
1225
+ ### CoSec Security Hooks
1226
+
1227
+ 🛡️ **Enterprise Security Integration** - Powerful React hooks for managing authentication state with CoSec tokens, providing seamless integration with enterprise security systems and automatic token lifecycle management.
1228
+
1229
+ #### useSecurity Hook
1230
+
1231
+ The `useSecurity` hook provides reactive access to authentication state and operations using CoSec tokens. It integrates with TokenStorage to persist tokens and updates state reactively when tokens change.
1232
+
1233
+ ```typescript jsx
1234
+ import { useSecurity } from '@ahoo-wang/fetcher-react';
1235
+ import { tokenStorage } from './tokenStorage';
1236
+ import { useNavigate } from 'react-router-dom';
1237
+
1238
+ function App() {
1239
+ const navigate = useNavigate();
1240
+
1241
+ const { currentUser, authenticated, signIn, signOut } = useSecurity(tokenStorage, {
1242
+ onSignIn: () => {
1243
+ // Redirect to dashboard after successful login
1244
+ navigate('/dashboard');
1245
+ },
1246
+ onSignOut: () => {
1247
+ // Redirect to login page after logout
1248
+ navigate('/login');
1249
+ }
1250
+ });
1251
+
1252
+ const handleSignIn = async () => {
1253
+ // Direct token
1254
+ await signIn(compositeToken);
1255
+
1256
+ // Or async function
1257
+ await signIn(async () => {
1258
+ const response = await fetch('/api/auth/login', {
1259
+ method: 'POST',
1260
+ body: JSON.stringify({ username, password })
1261
+ });
1262
+ return response.json();
1263
+ });
1264
+ };
1265
+
1266
+ if (!authenticated) {
1267
+ return <button onClick={handleSignIn}>Sign In</button>;
1268
+ }
1269
+
1270
+ return (
1271
+ <div>
1272
+ <p>Welcome, {currentUser.sub}!</p>
1273
+ <button onClick={signOut}>Sign Out</button>
1274
+ </div>
1275
+ );
1276
+ }
1277
+ ```
1278
+
1279
+ **Key Features:**
1280
+
1281
+ - **Reactive Authentication State**: Automatically updates when tokens change
1282
+ - **Flexible Sign-in Methods**: Supports both direct tokens and async token providers
1283
+ - **Lifecycle Callbacks**: Configurable callbacks for sign-in and sign-out events
1284
+ - **Type Safety**: Full TypeScript support with CoSec JWT payload types
1285
+ - **Token Persistence**: Integrates with TokenStorage for cross-session persistence
1286
+
1287
+ #### SecurityProvider
1288
+
1289
+ The `SecurityProvider` component wraps your application to provide authentication context through React context. It internally uses the `useSecurity` hook and makes authentication state available to all child components via the `useSecurityContext` hook.
1290
+
1291
+ ```tsx
1292
+ import { SecurityProvider } from '@ahoo-wang/fetcher-react';
1293
+ import { tokenStorage } from './tokenStorage';
1294
+ import { useNavigate } from 'react-router-dom';
1295
+
1296
+ function App() {
1297
+ const navigate = useNavigate();
1298
+
1299
+ return (
1300
+ <SecurityProvider
1301
+ tokenStorage={tokenStorage}
1302
+ onSignIn={() => navigate('/dashboard')}
1303
+ onSignOut={() => navigate('/login')}
1304
+ >
1305
+ <MyApp />
1306
+ </SecurityProvider>
1307
+ );
1308
+ }
1309
+ ```
1310
+
1311
+ **Configuration Options:**
1312
+
1313
+ - `tokenStorage`: TokenStorage instance for managing authentication tokens
1314
+ - `onSignIn`: Callback function invoked when sign in is successful
1315
+ - `onSignOut`: Callback function invoked when sign out occurs
1316
+ - `children`: Child components that will have access to security context
1317
+
1318
+ #### useSecurityContext Hook
1319
+
1320
+ The `useSecurityContext` hook provides access to authentication state and methods within components wrapped by `SecurityProvider`. It offers the same interface as `useSecurity` but through React context.
1321
+
1322
+ ```tsx
1323
+ import { useSecurityContext } from '@ahoo-wang/fetcher-react';
1045
1324
 
1046
- // This will cause a TypeScript error:
1047
- // updatePrefs(draft => { draft.theme = 'invalid'; });
1325
+ function UserProfile() {
1326
+ const { currentUser, authenticated, signOut } = useSecurityContext();
1327
+
1328
+ if (!authenticated) {
1329
+ return <div>Please sign in</div>;
1330
+ }
1331
+
1332
+ return (
1333
+ <div>
1334
+ <p>Welcome, {currentUser.sub}!</p>
1335
+ <button onClick={signOut}>Sign Out</button>
1336
+ </div>
1337
+ );
1338
+ }
1048
1339
  ```
1049
1340
 
1050
- ## Wow Query Hooks
1341
+ **Context Benefits:**
1342
+
1343
+ - **Prop Drilling Elimination**: Access authentication state without passing props
1344
+ - **Component Isolation**: Components can access auth state regardless of component tree depth
1345
+ - **Centralized State**: Single source of truth for authentication across the application
1346
+ - **Automatic Re-rendering**: Components automatically re-render when authentication state changes
1347
+
1348
+ ### Wow Query Hooks
1051
1349
 
1052
1350
  The Wow Query Hooks provide advanced data querying capabilities with built-in state management for conditions,
1053
1351
  projections, sorting, pagination, and limits. These hooks are designed to work with the `@ahoo-wang/fetcher-wow` package
1054
1352
  for complex query operations.
1055
1353
 
1056
- ### Basic Query Hooks
1354
+ #### Basic Query Hooks
1057
1355
 
1058
- #### useListQuery Hook
1356
+ ##### useListQuery Hook
1059
1357
 
1060
1358
  The `useListQuery` hook manages list queries with state management for conditions, projections, sorting, and limits.
1061
1359
 
@@ -1092,7 +1390,7 @@ const MyComponent = () => {
1092
1390
  };
1093
1391
  ```
1094
1392
 
1095
- #### Auto Execute Example
1393
+ ##### Auto Execute Example
1096
1394
 
1097
1395
  ```typescript jsx
1098
1396
  import { useListQuery } from '@ahoo-wang/fetcher-react';
@@ -1122,7 +1420,7 @@ const MyComponent = () => {
1122
1420
  };
1123
1421
  ```
1124
1422
 
1125
- ### usePagedQuery Hook
1423
+ ##### usePagedQuery Hook
1126
1424
 
1127
1425
  The `usePagedQuery` hook manages paged queries with state management for conditions, projections, pagination, and
1128
1426
  sorting.
@@ -1170,7 +1468,7 @@ const MyComponent = () => {
1170
1468
  };
1171
1469
  ```
1172
1470
 
1173
- #### Auto Execute Example
1471
+ ###### Auto Execute Example
1174
1472
 
1175
1473
  ```typescript jsx
1176
1474
  import { usePagedQuery } from '@ahoo-wang/fetcher-react';
@@ -1210,7 +1508,7 @@ const MyComponent = () => {
1210
1508
  };
1211
1509
  ```
1212
1510
 
1213
- ### useSingleQuery Hook
1511
+ ##### useSingleQuery Hook
1214
1512
 
1215
1513
  The `useSingleQuery` hook manages single item queries with state management for conditions, projections, and sorting.
1216
1514
 
@@ -1243,7 +1541,7 @@ const MyComponent = () => {
1243
1541
  };
1244
1542
  ```
1245
1543
 
1246
- #### Auto Execute Example
1544
+ ###### Auto Execute Example
1247
1545
 
1248
1546
  ```typescript jsx
1249
1547
  import { useSingleQuery } from '@ahoo-wang/fetcher-react';
@@ -1268,7 +1566,7 @@ const MyComponent = () => {
1268
1566
  };
1269
1567
  ```
1270
1568
 
1271
- ### useCountQuery Hook
1569
+ ##### useCountQuery Hook
1272
1570
 
1273
1571
  The `useCountQuery` hook manages count queries with state management for conditions.
1274
1572
 
@@ -1301,7 +1599,7 @@ const MyComponent = () => {
1301
1599
  };
1302
1600
  ```
1303
1601
 
1304
- #### Auto Execute Example
1602
+ ###### Auto Execute Example
1305
1603
 
1306
1604
  ```typescript jsx
1307
1605
  import { useCountQuery } from '@ahoo-wang/fetcher-react';
@@ -1326,9 +1624,99 @@ const MyComponent = () => {
1326
1624
  };
1327
1625
  ```
1328
1626
 
1329
- ### Fetcher Query Hooks
1627
+ ##### useListStreamQuery Hook
1628
+
1629
+ The `useListStreamQuery` hook manages list stream queries that return a readable stream of server-sent events.
1630
+
1631
+ ```typescript jsx
1632
+ import { useListStreamQuery } from '@ahoo-wang/fetcher-react';
1633
+
1634
+ const MyComponent = () => {
1635
+ const { result, loading, error, execute, setCondition } = useListStreamQuery({
1636
+ initialQuery: { condition: {}, projection: {}, sort: [], limit: 100 },
1637
+ execute: async (listQuery) => {
1638
+ // Your stream fetching logic here
1639
+ return fetchListStream(listQuery);
1640
+ },
1641
+ });
1642
+
1643
+ useEffect(() => {
1644
+ if (result) {
1645
+ const reader = result.getReader();
1646
+ const readStream = async () => {
1647
+ try {
1648
+ while (true) {
1649
+ const { done, value } = await reader.read();
1650
+ if (done) break;
1651
+ console.log('Received:', value);
1652
+ // Process the stream event
1653
+ }
1654
+ } catch (error) {
1655
+ console.error('Stream error:', error);
1656
+ }
1657
+ };
1658
+ readStream();
1659
+ }
1660
+ }, [result]);
1661
+
1662
+ if (loading) return <div>Loading...</div>;
1663
+ if (error) return <div>Error: {error.message}</div>;
1664
+
1665
+ return (
1666
+ <div>
1667
+ <button onClick={execute}>Start Stream</button>
1668
+ </div>
1669
+ );
1670
+ };
1671
+ ```
1672
+
1673
+ ###### Auto Execute Example
1674
+
1675
+ ```typescript jsx
1676
+ import { useListStreamQuery } from '@ahoo-wang/fetcher-react';
1677
+
1678
+ const MyComponent = () => {
1679
+ const { result, loading, error, execute, setCondition } = useListStreamQuery({
1680
+ initialQuery: { condition: {}, projection: {}, sort: [], limit: 100 },
1681
+ execute: async (listQuery) => fetchListStream(listQuery),
1682
+ autoExecute: true, // Automatically execute on component mount
1683
+ });
1684
+
1685
+ useEffect(() => {
1686
+ if (result) {
1687
+ const reader = result.getReader();
1688
+ const readStream = async () => {
1689
+ try {
1690
+ while (true) {
1691
+ const { done, value } = await reader.read();
1692
+ if (done) break;
1693
+ console.log('Received:', value);
1694
+ // Process the stream event
1695
+ }
1696
+ } catch (error) {
1697
+ console.error('Stream error:', error);
1698
+ }
1699
+ };
1700
+ readStream();
1701
+ }
1702
+ }, [result]);
1703
+
1704
+ // The query will execute automatically when the component mounts
1705
+
1706
+ if (loading) return <div>Loading...</div>;
1707
+ if (error) return <div>Error: {error.message}</div>;
1708
+
1709
+ return (
1710
+ <div>
1711
+ {/* Stream is already started automatically */}
1712
+ </div>
1713
+ );
1714
+ };
1715
+ ```
1716
+
1717
+ #### Fetcher Query Hooks
1330
1718
 
1331
- #### useFetcherCountQuery Hook
1719
+ ##### useFetcherCountQuery Hook
1332
1720
 
1333
1721
  The `useFetcherCountQuery` hook is a specialized React hook for performing count queries using the Fetcher library. It is designed for scenarios where you need to retrieve the count of records that match a specific condition, returning a number representing the count.
1334
1722
 
@@ -1352,7 +1740,7 @@ function UserCountComponent() {
1352
1740
  }
1353
1741
  ```
1354
1742
 
1355
- #### Auto Execute Example
1743
+ ###### Auto Execute Example
1356
1744
 
1357
1745
  ```typescript jsx
1358
1746
  import { useFetcherCountQuery } from '@ahoo-wang/fetcher-react';
@@ -1373,7 +1761,7 @@ const MyComponent = () => {
1373
1761
  };
1374
1762
  ```
1375
1763
 
1376
- ### useFetcherPagedQuery Hook
1764
+ ##### useFetcherPagedQuery Hook
1377
1765
 
1378
1766
  The `useFetcherPagedQuery` hook is a specialized React hook for performing paged queries using the Fetcher library. It is designed for scenarios where you need to retrieve paginated data that matches a query condition, returning a PagedList containing the items for the current page along with pagination metadata.
1379
1767
 
@@ -1442,7 +1830,7 @@ function UserListComponent() {
1442
1830
  }
1443
1831
  ```
1444
1832
 
1445
- #### Auto Execute Example
1833
+ ###### Auto Execute Example
1446
1834
 
1447
1835
  ```typescript jsx
1448
1836
  import { useFetcherPagedQuery } from '@ahoo-wang/fetcher-react';
@@ -1478,7 +1866,7 @@ const MyComponent = () => {
1478
1866
  };
1479
1867
  ```
1480
1868
 
1481
- ### useFetcherListQuery Hook
1869
+ ##### useFetcherListQuery Hook
1482
1870
 
1483
1871
  The `useFetcherListQuery` hook is a specialized React hook for performing list queries using the Fetcher library. It is designed for fetching lists of items with support for filtering, sorting, and pagination through the ListQuery type, returning an array of results.
1484
1872
 
@@ -1539,7 +1927,7 @@ function UserListComponent() {
1539
1927
  }
1540
1928
  ```
1541
1929
 
1542
- #### Auto Execute Example
1930
+ ###### Auto Execute Example
1543
1931
 
1544
1932
  ```typescript jsx
1545
1933
  import { useFetcherListQuery } from '@ahoo-wang/fetcher-react';
@@ -1574,7 +1962,7 @@ const MyComponent = () => {
1574
1962
  };
1575
1963
  ```
1576
1964
 
1577
- ### useFetcherListStreamQuery Hook
1965
+ ##### useFetcherListStreamQuery Hook
1578
1966
 
1579
1967
  The `useFetcherListStreamQuery` hook is a specialized React hook for performing list stream queries using the Fetcher library with server-sent events. It is designed for scenarios where you need to retrieve a stream of data that matches a list query condition, returning a ReadableStream of JSON server-sent events for real-time data streaming.
1580
1968
 
@@ -1637,7 +2025,7 @@ function UserStreamComponent() {
1637
2025
  }
1638
2026
  ```
1639
2027
 
1640
- #### Auto Execute Example
2028
+ ###### Auto Execute Example
1641
2029
 
1642
2030
  ```typescript jsx
1643
2031
  import { useFetcherListStreamQuery } from '@ahoo-wang/fetcher-react';
@@ -1693,7 +2081,7 @@ const MyComponent = () => {
1693
2081
  };
1694
2082
  ```
1695
2083
 
1696
- ### useFetcherSingleQuery Hook
2084
+ ##### useFetcherSingleQuery Hook
1697
2085
 
1698
2086
  The `useFetcherSingleQuery` hook is a specialized React hook for performing single item queries using the Fetcher library. It is designed for fetching a single item with support for filtering and sorting through the SingleQuery type, returning a single result item.
1699
2087
 
@@ -1737,7 +2125,7 @@ function UserProfileComponent({ userId }: { userId: string }) {
1737
2125
  }
1738
2126
  ```
1739
2127
 
1740
- #### Auto Execute Example
2128
+ ###### Auto Execute Example
1741
2129
 
1742
2130
  ```typescript jsx
1743
2131
  import { useFetcherSingleQuery } from '@ahoo-wang/fetcher-react';
@@ -1769,103 +2157,11 @@ const MyComponent = () => {
1769
2157
  };
1770
2158
  ```
1771
2159
 
1772
- ### Stream Query Hooks
1773
-
1774
- #### useListStreamQuery Hook
1775
-
1776
- The `useListStreamQuery` hook manages list stream queries that return a readable stream of server-sent events.
1777
-
1778
- ```typescript jsx
1779
- import { useListStreamQuery } from '@ahoo-wang/fetcher-react';
1780
-
1781
- const MyComponent = () => {
1782
- const { result, loading, error, execute, setCondition } = useListStreamQuery({
1783
- initialQuery: { condition: {}, projection: {}, sort: [], limit: 100 },
1784
- execute: async (listQuery) => {
1785
- // Your stream fetching logic here
1786
- return fetchListStream(listQuery);
1787
- },
1788
- });
1789
-
1790
- useEffect(() => {
1791
- if (result) {
1792
- const reader = result.getReader();
1793
- const readStream = async () => {
1794
- try {
1795
- while (true) {
1796
- const { done, value } = await reader.read();
1797
- if (done) break;
1798
- console.log('Received:', value);
1799
- // Process the stream event
1800
- }
1801
- } catch (error) {
1802
- console.error('Stream error:', error);
1803
- }
1804
- };
1805
- readStream();
1806
- }
1807
- }, [result]);
1808
-
1809
- if (loading) return <div>Loading...</div>;
1810
- if (error) return <div>Error: {error.message}</div>;
1811
-
1812
- return (
1813
- <div>
1814
- <button onClick={execute}>Start Stream</button>
1815
- </div>
1816
- );
1817
- };
1818
- ```
1819
-
1820
- #### Auto Execute Example
1821
-
1822
- ```typescript jsx
1823
- import { useListStreamQuery } from '@ahoo-wang/fetcher-react';
1824
-
1825
- const MyComponent = () => {
1826
- const { result, loading, error, execute, setCondition } = useListStreamQuery({
1827
- initialQuery: { condition: {}, projection: {}, sort: [], limit: 100 },
1828
- execute: async (listQuery) => fetchListStream(listQuery),
1829
- autoExecute: true, // Automatically execute on component mount
1830
- });
1831
-
1832
- useEffect(() => {
1833
- if (result) {
1834
- const reader = result.getReader();
1835
- const readStream = async () => {
1836
- try {
1837
- while (true) {
1838
- const { done, value } = await reader.read();
1839
- if (done) break;
1840
- console.log('Received:', value);
1841
- // Process the stream event
1842
- }
1843
- } catch (error) {
1844
- console.error('Stream error:', error);
1845
- }
1846
- };
1847
- readStream();
1848
- }
1849
- }, [result]);
1850
-
1851
- // The query will execute automatically when the component mounts
1852
-
1853
- if (loading) return <div>Loading...</div>;
1854
- if (error) return <div>Error: {error.message}</div>;
1855
-
1856
- return (
1857
- <div>
1858
- {/* Stream is already started automatically */}
1859
- </div>
1860
- );
1861
- };
1862
- ```
1863
-
1864
2160
  ## Best Practices
1865
2161
 
1866
2162
  ### Performance Optimization
1867
2163
 
1868
- - Use `autoExecute: true` sparingly to avoid unnecessary requests on mount
2164
+ - Use `autoExecute: false` when you need to control when queries execute
1869
2165
  - Leverage `setQuery` for query updates when `autoExecute` is enabled to trigger automatic re-execution
1870
2166
  - Memoize expensive computations in your `execute` functions
1871
2167
 
@@ -1943,7 +2239,7 @@ import { Component, ErrorInfo, ReactNode } from 'react';
1943
2239
  class FetchErrorBoundary extends Component<
1944
2240
  { children: ReactNode; fallback?: ReactNode },
1945
2241
  { hasError: boolean; error?: Error }
1946
- > {
2242
+ > {
1947
2243
  constructor(props: { children: ReactNode; fallback?: ReactNode }) {
1948
2244
  super(props);
1949
2245
  this.state = { hasError: false };
@@ -2725,6 +3021,96 @@ An object implementing `UseRefsReturn<T>` with:
2725
3021
  - `RefKey = string | number | symbol`
2726
3022
  - `UseRefsReturn<T> extends Iterable<[RefKey, T]>`
2727
3023
 
3024
+ ### useQuery
3025
+
3026
+ ```typescript
3027
+ function useQuery<Q, R, E = FetcherError>(
3028
+ options: UseQueryOptions<Q, R, E>,
3029
+ ): UseQueryReturn<Q, R, E>;
3030
+ ```
3031
+
3032
+ A React hook for managing query-based asynchronous operations with automatic state management and execution control.
3033
+
3034
+ **Type Parameters:**
3035
+
3036
+ - `Q`: The type of the query parameters
3037
+ - `R`: The type of the result value
3038
+ - `E`: The type of the error value (defaults to FetcherError)
3039
+
3040
+ **Parameters:**
3041
+
3042
+ - `options`: Configuration options for the query
3043
+ - `initialQuery`: The initial query parameters
3044
+ - `execute`: Function to execute the query with given parameters and optional attributes
3045
+ - `autoExecute?`: Whether to automatically execute the query on mount and when query changes
3046
+ - All options from `UseExecutePromiseOptions`
3047
+
3048
+ **Returns:**
3049
+
3050
+ An object containing the query state and control functions:
3051
+
3052
+ - `loading`: Boolean indicating if the query is currently executing
3053
+ - `result`: The resolved value of the query
3054
+ - `error`: Any error that occurred during execution
3055
+ - `status`: Current execution status
3056
+ - `execute`: Function to execute the query with current parameters
3057
+ - `reset`: Function to reset the promise state
3058
+ - `abort`: Function to abort the current operation
3059
+ - `getQuery`: Function to retrieve the current query parameters
3060
+ - `setQuery`: Function to update the query parameters
3061
+
3062
+ ### useQueryState
3063
+
3064
+ ```typescript
3065
+ function useQueryState<Q>(
3066
+ options: UseQueryStateOptions<Q>,
3067
+ ): UseQueryStateReturn<Q>;
3068
+ ```
3069
+
3070
+ A React hook for managing query state with automatic execution capabilities.
3071
+
3072
+ **Type Parameters:**
3073
+
3074
+ - `Q`: The type of the query parameters
3075
+
3076
+ **Parameters:**
3077
+
3078
+ - `options`: Configuration options for the hook
3079
+ - `initialQuery`: The initial query parameters to be stored and managed
3080
+ - `autoExecute?`: Whether to automatically execute when the query changes or on component mount
3081
+ - `execute`: Function to execute with the current query parameters
3082
+
3083
+ **Returns:**
3084
+
3085
+ An object containing:
3086
+
3087
+ - `getQuery`: Function to retrieve the current query parameters
3088
+ - `setQuery`: Function to update the query parameters. Triggers execution if autoExecute is true
3089
+
3090
+ ### useMounted
3091
+
3092
+ ```typescript
3093
+ function useMounted(): () => boolean;
3094
+ ```
3095
+
3096
+ A React hook that returns a function to check if the component is still mounted.
3097
+
3098
+ **Returns:**
3099
+
3100
+ A function that returns `true` if the component is still mounted, `false` otherwise.
3101
+
3102
+ ### useForceUpdate
3103
+
3104
+ ```typescript
3105
+ function useForceUpdate(): () => void;
3106
+ ```
3107
+
3108
+ A React hook that returns a function to force a component to re-render.
3109
+
3110
+ **Returns:**
3111
+
3112
+ A function that forces the component to re-render when called.
3113
+
2728
3114
  ### useEventSubscription
2729
3115
 
2730
3116
  ```typescript
@@ -2886,7 +3272,7 @@ A React hook for managing list queries with state management for conditions, pro
2886
3272
  **Parameters:**
2887
3273
 
2888
3274
  - `options`: Configuration options including initialQuery and list function
2889
- - `autoExecute`: Whether to automatically execute the query on component mount (defaults to false)
3275
+ - `autoExecute`: Whether to automatically execute the query on component mount (defaults to true)
2890
3276
 
2891
3277
  **Returns:**
2892
3278
 
@@ -2911,7 +3297,7 @@ A React hook for managing paged queries with state management for conditions, pr
2911
3297
  **Parameters:**
2912
3298
 
2913
3299
  - `options`: Configuration options including initialQuery and query function
2914
- - `autoExecute`: Whether to automatically execute the query on component mount (defaults to false)
3300
+ - `autoExecute`: Whether to automatically execute the query on component mount (defaults to true)
2915
3301
 
2916
3302
  **Returns:**
2917
3303
 
@@ -2936,7 +3322,7 @@ A React hook for managing single queries with state management for conditions, p
2936
3322
  **Parameters:**
2937
3323
 
2938
3324
  - `options`: Configuration options including initialQuery and query function
2939
- - `autoExecute`: Whether to automatically execute the query on component mount (defaults to false)
3325
+ - `autoExecute`: Whether to automatically execute the query on component mount (defaults to true)
2940
3326
 
2941
3327
  **Returns:**
2942
3328
 
@@ -2960,7 +3346,7 @@ A React hook for managing count queries with state management for conditions.
2960
3346
  **Parameters:**
2961
3347
 
2962
3348
  - `options`: Configuration options including initialQuery and execute function
2963
- - `autoExecute`: Whether to automatically execute the query on component mount (defaults to false)
3349
+ - `autoExecute`: Whether to automatically execute the query on component mount (defaults to true)
2964
3350
 
2965
3351
  **Returns:**
2966
3352
 
@@ -2986,7 +3372,7 @@ A React hook for performing count queries using the Fetcher library. It wraps th
2986
3372
  - `options`: Configuration options for the count query, including the condition, fetcher instance, and other query settings
2987
3373
  - `url`: The URL to fetch the count from
2988
3374
  - `initialQuery`: The initial condition for the count query
2989
- - `autoExecute`: Whether to automatically execute the query on component mount (defaults to false)
3375
+ - `autoExecute`: Whether to automatically execute the query on component mount (defaults to true)
2990
3376
 
2991
3377
  **Returns:**
2992
3378
 
@@ -3017,7 +3403,7 @@ A React hook for performing paged queries using the Fetcher library. It wraps th
3017
3403
  - `options`: Configuration options for the paged query, including the paged query parameters, fetcher instance, and other query settings
3018
3404
  - `url`: The URL to fetch the paged data from
3019
3405
  - `initialQuery`: The initial paged query configuration
3020
- - `autoExecute`: Whether to automatically execute the query on component mount (defaults to false)
3406
+ - `autoExecute`: Whether to automatically execute the query on component mount (defaults to true)
3021
3407
 
3022
3408
  **Returns:**
3023
3409
 
@@ -3048,7 +3434,7 @@ A React hook for executing list queries using the fetcher library within the wow
3048
3434
  - `options`: Configuration options for the list query, including the list query parameters, fetcher instance, and other query settings
3049
3435
  - `url`: The URL to fetch the list data from
3050
3436
  - `initialQuery`: The initial list query configuration
3051
- - `autoExecute`: Whether to automatically execute the query on component mount (defaults to false)
3437
+ - `autoExecute`: Whether to automatically execute the query on component mount (defaults to true)
3052
3438
 
3053
3439
  **Returns:**
3054
3440
 
@@ -3079,7 +3465,7 @@ A React hook for performing list stream queries using the Fetcher library with s
3079
3465
  - `options`: Configuration options for the list stream query, including the list query parameters, fetcher instance, and other query settings
3080
3466
  - `url`: The URL to fetch the stream data from
3081
3467
  - `initialQuery`: The initial list query configuration
3082
- - `autoExecute`: Whether to automatically execute the query on component mount (defaults to false)
3468
+ - `autoExecute`: Whether to automatically execute the query on component mount (defaults to true)
3083
3469
 
3084
3470
  **Returns:**
3085
3471
 
@@ -3110,7 +3496,7 @@ A React hook for executing single item queries using the fetcher library within
3110
3496
  - `options`: Configuration options for the single query, including the single query parameters, fetcher instance, and other query settings
3111
3497
  - `url`: The URL to fetch the single item from
3112
3498
  - `initialQuery`: The initial single query configuration
3113
- - `autoExecute`: Whether to automatically execute the query on component mount (defaults to false)
3499
+ - `autoExecute`: Whether to automatically execute the query on component mount (defaults to true)
3114
3500
 
3115
3501
  **Returns:**
3116
3502
 
@@ -3140,7 +3526,7 @@ Returns a readable stream of JSON server-sent events.
3140
3526
  **Parameters:**
3141
3527
 
3142
3528
  - `options`: Configuration options including initialQuery and listStream function
3143
- - `autoExecute`: Whether to automatically execute the query on component mount (defaults to false)
3529
+ - `autoExecute`: Whether to automatically execute the query on component mount (defaults to true)
3144
3530
 
3145
3531
  **Returns:**
3146
3532