@ahoo-wang/fetcher-react 3.4.0 → 3.4.2

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 CHANGED
@@ -26,31 +26,41 @@ robust data fetching capabilities.
26
26
  ## Table of Contents
27
27
 
28
28
  - [Installation](#installation)
29
+ - [Quick Start](#quick-start)
29
30
  - [Usage](#usage)
30
- - [useFetcher Hook](#usefetcher-hook)
31
+ - [Core Hooks](#core-hooks)
32
+ - [useFetcher](#usefetcher-hook)
33
+ - [useExecutePromise](#useexecutepromise-hook)
34
+ - [usePromiseState](#usepromisestate-hook)
31
35
  - [Debounced Hooks](#debounced-hooks)
32
36
  - [useDebouncedCallback](#usedebouncedcallback)
33
37
  - [useDebouncedExecutePromise](#usedebouncedexecutepromise)
34
38
  - [useDebouncedFetcher](#usedebouncedfetcher)
35
- - [useExecutePromise Hook](#useexecutepromise-hook)
36
- - [usePromiseState Hook](#usepromisestate-hook)
37
- - [useRequestId Hook](#userequestid-hook)
38
- - [useLatest Hook](#uselatest-hook)
39
- - [useRefs Hook](#userefs-hook)
40
- - [useEventSubscription Hook](#useeventsubscription-hook)
41
- - [useKeyStorage Hook](#usekeystorage-hook)
42
- - [useImmerKeyStorage Hook](#useimmerkeystorage-hook)
43
- - [Wow Query Hooks](#wow-query-hooks)
44
- - [useListQuery Hook](#uselistquery-hook)
45
- - [usePagedQuery Hook](#usepagedquery-hook)
46
- - [useSingleQuery Hook](#usesinglequery-hook)
47
- - [useCountQuery Hook](#usecountquery-hook)
48
- - [useFetcherCountQuery Hook](#usefetchercountquery-hook)
49
- - [useFetcherPagedQuery Hook](#usefetcherpagedquery-hook)
50
- - [useFetcherListQuery Hook](#usefetcherlistquery-hook)
51
- - [useFetcherListStreamQuery Hook](#usefetcherliststreamquery-hook)
52
- - [useFetcherSingleQuery Hook](#usefetchersinglequery-hook)
53
- - [useListStreamQuery Hook](#useliststreamquery-hook)
39
+ - [useDebouncedFetcherQuery](#usedebouncedfetcherquery)
40
+ - [useDebouncedQuery](#usedebouncedquery)
41
+ - [Utility Hooks](#utility-hooks)
42
+ - [useRequestId](#userequestid-hook)
43
+ - [useLatest](#uselatest-hook)
44
+ - [useRefs](#userefs-hook)
45
+ - [Storage Hooks](#storage-hooks)
46
+ - [useKeyStorage](#usekeystorage-hook)
47
+ - [useImmerKeyStorage](#useimmerkeystorage-hook)
48
+ - [Event Hooks](#event-hooks)
49
+ - [useEventSubscription](#useeventsubscription-hook)
50
+ - [Wow Query Hooks](#wow-query-hooks)
51
+ - [Basic Query Hooks](#basic-query-hooks)
52
+ - [useListQuery](#uselistquery-hook)
53
+ - [usePagedQuery](#usepagedquery-hook)
54
+ - [useSingleQuery](#usesinglequery-hook)
55
+ - [useCountQuery](#usecountquery-hook)
56
+ - [Fetcher Query Hooks](#fetcher-query-hooks)
57
+ - [useFetcherListQuery](#usefetcherlistquery-hook)
58
+ - [useFetcherPagedQuery](#usefetcherpagedquery-hook)
59
+ - [useFetcherSingleQuery](#usefetchersinglequery-hook)
60
+ - [useFetcherCountQuery](#usefetchercountquery-hook)
61
+ - [Stream Query Hooks](#stream-query-hooks)
62
+ - [useListStreamQuery](#useliststreamquery-hook)
63
+ - [useFetcherListStreamQuery](#usefetcherliststreamquery-hook)
54
64
  - [Best Practices](#best-practices)
55
65
  - [API Reference](#api-reference)
56
66
  - [License](#license)
@@ -63,7 +73,7 @@ npm install @ahoo-wang/fetcher-react
63
73
 
64
74
  ### Requirements
65
75
 
66
- - React 16.8+ (hooks support)
76
+ - React 19.0+ (hooks support)
67
77
  - TypeScript 4.0+ (for full type safety)
68
78
 
69
79
  ## Quick Start
@@ -91,7 +101,9 @@ function App() {
91
101
 
92
102
  ## Usage
93
103
 
94
- ### useFetcher Hook
104
+ ### Core Hooks
105
+
106
+ #### useFetcher Hook
95
107
 
96
108
  The `useFetcher` hook provides complete data fetching capabilities with automatic state management, race condition
97
109
  protection, and flexible configuration options. It includes built-in AbortController support inherited from `useExecutePromise`.
@@ -273,6 +285,178 @@ const SearchInput = () => {
273
285
  - **Trailing Edge**: Execute after delay on last call (default behavior)
274
286
  - **Leading + Trailing**: Execute immediately, then again after delay if called again
275
287
 
288
+ #### useDebouncedFetcherQuery
289
+
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.
291
+
292
+ ```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
+ }
305
+
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
321
+ });
322
+
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
333
+ };
334
+
335
+ if (loading) return <div>Searching...</div>;
336
+ if (error) return <div>Error: {error.message}</div>;
337
+
338
+ return (
339
+ <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'}
347
+ </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
+ )}
357
+ </div>
358
+ );
359
+ };
360
+ ```
361
+
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
+ #### useDebouncedQuery
371
+
372
+ Combines general query execution with debouncing, perfect for custom query operations where you want to debounce execution based on query parameters.
373
+
374
+ ```typescript jsx
375
+ import { useDebouncedQuery } from '@ahoo-wang/fetcher-react';
376
+
377
+ interface SearchQuery {
378
+ keyword: string;
379
+ limit: number;
380
+ filters?: { category?: string };
381
+ }
382
+
383
+ interface SearchResult {
384
+ items: Array<{ id: string; title: string }>;
385
+ total: number;
386
+ }
387
+
388
+ const SearchComponent = () => {
389
+ const {
390
+ loading,
391
+ result,
392
+ error,
393
+ run,
394
+ cancel,
395
+ isPending,
396
+ setQuery,
397
+ getQuery,
398
+ } = useDebouncedQuery<SearchQuery, SearchResult>({
399
+ initialQuery: { keyword: '', limit: 10 },
400
+ execute: async (query) => {
401
+ const response = await fetch('/api/search', {
402
+ method: 'POST',
403
+ body: JSON.stringify(query),
404
+ headers: { 'Content-Type': 'application/json' },
405
+ });
406
+ return response.json();
407
+ },
408
+ debounce: { delay: 300 }, // Debounce for 300ms
409
+ autoExecute: false, // Don't execute on mount
410
+ });
411
+
412
+ const handleSearch = (keyword: string) => {
413
+ setQuery({ keyword, limit: 10 }); // This will trigger debounced execution if autoExecute was true
414
+ };
415
+
416
+ const handleManualSearch = () => {
417
+ run(); // Manual debounced execution with current query
418
+ };
419
+
420
+ const handleCancel = () => {
421
+ cancel(); // Cancel any pending debounced execution
422
+ };
423
+
424
+ if (loading) return <div>Searching...</div>;
425
+ if (error) return <div>Error: {error.message}</div>;
426
+
427
+ return (
428
+ <div>
429
+ <input
430
+ type="text"
431
+ onChange={(e) => handleSearch(e.target.value)}
432
+ placeholder="Search..."
433
+ />
434
+ <button onClick={handleManualSearch} disabled={isPending()}>
435
+ {isPending() ? 'Searching...' : 'Search'}
436
+ </button>
437
+ <button onClick={handleCancel}>Cancel</button>
438
+ {result && (
439
+ <div>
440
+ Found {result.total} items:
441
+ {result.items.map(item => (
442
+ <div key={item.id}>{item.title}</div>
443
+ ))}
444
+ </div>
445
+ )}
446
+ </div>
447
+ );
448
+ };
449
+ ```
450
+
451
+ **Key Features:**
452
+
453
+ - **Query State Management**: Automatic query parameter handling with `setQuery` and `getQuery`
454
+ - **Debounced Execution**: Prevents excessive operations during rapid query changes
455
+ - **Auto-Execution**: Optional automatic execution when query parameters change
456
+ - **Manual Control**: `run()` for manual execution, `cancel()` for cancellation
457
+ - **Pending State**: `isPending()` to check if a debounced call is queued
458
+ - **Custom Execution**: Flexible execute function for any query operation
459
+
276
460
  ### useExecutePromise Hook
277
461
 
278
462
  The `useExecutePromise` hook manages asynchronous operations with automatic state handling, built-in race condition
@@ -387,7 +571,9 @@ const MyComponent = () => {
387
571
  };
388
572
  ```
389
573
 
390
- ### useRequestId Hook
574
+ ### Utility Hooks
575
+
576
+ #### useRequestId Hook
391
577
 
392
578
  The `useRequestId` hook provides request ID management for preventing race conditions in async operations.
393
579
 
@@ -482,7 +668,9 @@ Key features:
482
668
  - **Automatic Cleanup**: Refs are cleared when component unmounts
483
669
  - **Type Safety**: Full TypeScript support for ref types
484
670
 
485
- ### useEventSubscription Hook
671
+ ### Event Hooks
672
+
673
+ #### useEventSubscription Hook
486
674
 
487
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.
488
676
 
@@ -523,7 +711,9 @@ Key features:
523
711
  - **Error Handling**: Logs warnings for failed subscription attempts
524
712
  - **Event Bus Integration**: Works seamlessly with `@ahoo-wang/fetcher-eventbus` TypedEventBus instances
525
713
 
526
- ### useKeyStorage Hook
714
+ ### Storage Hooks
715
+
716
+ #### useKeyStorage Hook
527
717
 
528
718
  The `useKeyStorage` hook provides reactive state management for a KeyStorage instance. It subscribes to storage changes and returns the current value along with a setter function. Optionally accepts a default value to use when the storage is empty.
529
719
 
@@ -863,7 +1053,9 @@ The Wow Query Hooks provide advanced data querying capabilities with built-in st
863
1053
  projections, sorting, pagination, and limits. These hooks are designed to work with the `@ahoo-wang/fetcher-wow` package
864
1054
  for complex query operations.
865
1055
 
866
- ### useListQuery Hook
1056
+ ### Basic Query Hooks
1057
+
1058
+ #### useListQuery Hook
867
1059
 
868
1060
  The `useListQuery` hook manages list queries with state management for conditions, projections, sorting, and limits.
869
1061
 
@@ -1134,7 +1326,9 @@ const MyComponent = () => {
1134
1326
  };
1135
1327
  ```
1136
1328
 
1137
- ### useFetcherCountQuery Hook
1329
+ ### Fetcher Query Hooks
1330
+
1331
+ #### useFetcherCountQuery Hook
1138
1332
 
1139
1333
  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.
1140
1334
 
@@ -1575,7 +1769,9 @@ const MyComponent = () => {
1575
1769
  };
1576
1770
  ```
1577
1771
 
1578
- ### useListStreamQuery Hook
1772
+ ### Stream Query Hooks
1773
+
1774
+ #### useListStreamQuery Hook
1579
1775
 
1580
1776
  The `useListStreamQuery` hook manages list stream queries that return a readable stream of server-sent events.
1581
1777
 
@@ -2266,6 +2462,88 @@ An object containing:
2266
2462
  - `cancel`: Function to cancel any pending debounced execution
2267
2463
  - `isPending`: Boolean indicating if a debounced call is pending
2268
2464
 
2465
+ #### useDebouncedFetcherQuery
2466
+
2467
+ ```typescript
2468
+ function useDebouncedFetcherQuery<Q, R, E = FetcherError>(
2469
+ options: UseDebouncedFetcherQueryOptions<Q, R, E>,
2470
+ ): UseDebouncedFetcherQueryReturn<Q, R, E>;
2471
+ ```
2472
+
2473
+ Combines query-based HTTP fetching with debouncing, perfect for search inputs and dynamic query scenarios.
2474
+
2475
+ **Type Parameters:**
2476
+
2477
+ - `Q`: The type of the query parameters
2478
+ - `R`: The type of the fetch result
2479
+ - `E`: The type of the error (defaults to FetcherError)
2480
+
2481
+ **Parameters:**
2482
+
2483
+ - `options`: Configuration object extending `UseFetcherQueryOptions` and `DebounceCapable`
2484
+ - `url`: The API endpoint URL (required)
2485
+ - `initialQuery`: Initial query parameters (required)
2486
+ - `autoExecute?`: Whether to execute automatically on mount or query changes
2487
+ - `debounce`: Debounce configuration (delay, leading, trailing)
2488
+ - HTTP request options (method, headers, timeout, etc.)
2489
+
2490
+ **Returns:**
2491
+
2492
+ An object containing:
2493
+
2494
+ - `loading`: Boolean indicating if the fetch is currently executing
2495
+ - `result`: The resolved value of the fetch
2496
+ - `error`: Any error that occurred during execution
2497
+ - `status`: Current execution status
2498
+ - `reset`: Function to reset the fetcher state
2499
+ - `abort`: Function to abort the current operation
2500
+ - `getQuery`: Function to get the current query parameters
2501
+ - `setQuery`: Function to update query parameters
2502
+ - `run`: Function to execute the debounced fetch with current query
2503
+ - `cancel`: Function to cancel any pending debounced execution
2504
+ - `isPending`: Function that returns true if a debounced execution is currently pending
2505
+
2506
+ #### useDebouncedQuery
2507
+
2508
+ ```typescript
2509
+ function useDebouncedQuery<Q, R, E = FetcherError>(
2510
+ options: UseDebouncedQueryOptions<Q, R, E>,
2511
+ ): UseDebouncedQueryReturn<Q, R, E>;
2512
+ ```
2513
+
2514
+ Combines general query execution with debouncing, perfect for custom query operations.
2515
+
2516
+ **Type Parameters:**
2517
+
2518
+ - `Q`: The type of the query parameters
2519
+ - `R`: The type of the result
2520
+ - `E`: The type of the error (defaults to FetcherError)
2521
+
2522
+ **Parameters:**
2523
+
2524
+ - `options`: Configuration object extending `UseQueryOptions` and `DebounceCapable`
2525
+ - `initialQuery`: Initial query parameters (required)
2526
+ - `execute`: Function to execute the query with parameters
2527
+ - `autoExecute?`: Whether to execute automatically on mount or query changes
2528
+ - `debounce`: Debounce configuration (delay, leading, trailing)
2529
+ - All options from `UseExecutePromiseOptions`
2530
+
2531
+ **Returns:**
2532
+
2533
+ An object containing:
2534
+
2535
+ - `loading`: Boolean indicating if the query is currently executing
2536
+ - `result`: The resolved value of the query
2537
+ - `error`: Any error that occurred during execution
2538
+ - `status`: Current execution status
2539
+ - `reset`: Function to reset the query state
2540
+ - `abort`: Function to abort the current operation
2541
+ - `getQuery`: Function to get the current query parameters
2542
+ - `setQuery`: Function to update query parameters
2543
+ - `run`: Function to execute the debounced query with current parameters
2544
+ - `cancel`: Function to cancel any pending debounced execution
2545
+ - `isPending`: Function that returns true if a debounced execution is currently pending
2546
+
2269
2547
  ### useFetcher
2270
2548
 
2271
2549
  ```typescript