@ahoo-wang/fetcher-react 2.6.10 → 2.6.13

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
@@ -19,6 +19,7 @@ automatic re-rendering and loading states.
19
19
  - ⚡ **Performance**: Optimized with useMemo, useCallback, and smart dependency management
20
20
  - 🎯 **Options Flexibility**: Support for both static options and dynamic option suppliers
21
21
  - 🔧 **Developer Experience**: Built-in loading states, error handling, and automatic re-rendering
22
+ - 📊 **Advanced Query Hooks**: Specialized hooks for list, paged, single, count, and stream queries with state management
22
23
 
23
24
  ## Table of Contents
24
25
 
@@ -30,6 +31,12 @@ automatic re-rendering and loading states.
30
31
  - [useRequestId Hook](#userequestid-hook)
31
32
  - [useLatest Hook](#uselatest-hook)
32
33
  - [useKeyStorage Hook](#usekeystorage-hook)
34
+ - [Wow Query Hooks](#wow-query-hooks)
35
+ - [useListQuery Hook](#uselistquery-hook)
36
+ - [usePagedQuery Hook](#usepagedquery-hook)
37
+ - [useSingleQuery Hook](#usesinglequery-hook)
38
+ - [useCountQuery Hook](#usecountquery-hook)
39
+ - [useListStreamQuery Hook](#useliststreamquery-hook)
33
40
  - [API Reference](#api-reference)
34
41
  - [License](#license)
35
42
 
@@ -77,15 +84,34 @@ const MyComponent = () => {
77
84
 
78
85
  const handleFetch = () => {
79
86
  execute({ url: '/api/users', method: 'GET' });
80
- };
87
+ };
88
+ ```
89
+
90
+ #### Auto Execute Example
91
+
92
+ ```typescript jsx
93
+ import { useListQuery } from '@ahoo-wang/fetcher-react';
94
+
95
+ const MyComponent = () => {
96
+ const { result, loading, error, execute, setCondition } = useListQuery({
97
+ initialQuery: { condition: {}, projection: {}, sort: [], limit: 10 },
98
+ list: async (listQuery) => fetchListData(listQuery),
99
+ autoExecute: true, // Automatically execute on component mount
100
+ });
101
+
102
+ // The query will execute automatically when the component mounts
103
+ // You can still manually trigger it with execute() or update conditions
81
104
 
82
105
  if (loading) return <div>Loading...</div>;
83
106
  if (error) return <div>Error: {error.message}</div>;
84
107
 
85
108
  return (
86
109
  <div>
87
- <pre>{JSON.stringify(result, null, 2)}</pre>
88
- <button onClick={handleFetch}>Fetch Data</button>
110
+ <ul>
111
+ {result?.map((item, index) => (
112
+ <li key={index}>{item.name}</li>
113
+ ))}
114
+ </ul>
89
115
  </div>
90
116
  );
91
117
  };
@@ -298,12 +324,379 @@ const userStorage = new KeyStorage<User>({ key: 'current-user' });
298
324
  const [user, setUser] = useKeyStorage(userStorage);
299
325
  ```
300
326
 
327
+ ## Wow Query Hooks
328
+
329
+ The Wow Query Hooks provide advanced data querying capabilities with built-in state management for conditions,
330
+ projections, sorting, pagination, and limits. These hooks are designed to work with the `@ahoo-wang/fetcher-wow` package
331
+ for complex query operations.
332
+
333
+ ### useListQuery Hook
334
+
335
+ The `useListQuery` hook manages list queries with state management for conditions, projections, sorting, and limits.
336
+
337
+ ```typescript jsx
338
+ import { useListQuery } from '@ahoo-wang/fetcher-react';
339
+
340
+ const MyComponent = () => {
341
+ const { result, loading, error, execute, setCondition, setLimit } = useListQuery({
342
+ initialQuery: { condition: {}, projection: {}, sort: [], limit: 10 },
343
+ list: async (listQuery) => {
344
+ // Your list fetching logic here
345
+ return fetchListData(listQuery);
346
+ },
347
+ });
348
+
349
+ const handleSearch = (searchTerm: string) => {
350
+ setCondition({ name: { $regex: searchTerm } });
351
+ execute();
352
+ };
353
+
354
+ if (loading) return <div>Loading...</div>;
355
+ if (error) return <div>Error: {error.message}</div>;
356
+
357
+ return (
358
+ <div>
359
+ <input onChange={(e) => handleSearch(e.target.value)} placeholder="Search..." />
360
+ <ul>
361
+ {result?.map((item, index) => (
362
+ <li key={index}>{item.name}</li>
363
+ ))}
364
+ </ul>
365
+ </div>
366
+ );
367
+ };
368
+ ```
369
+
370
+ #### Auto Execute Example
371
+
372
+ ```typescript jsx
373
+ import { useListQuery } from '@ahoo-wang/fetcher-react';
374
+
375
+ const MyComponent = () => {
376
+ const { result, loading, error, execute, setCondition } = useListQuery({
377
+ initialQuery: { condition: {}, projection: {}, sort: [], limit: 10 },
378
+ list: async (listQuery) => fetchListData(listQuery),
379
+ autoExecute: true, // Automatically execute on component mount
380
+ });
381
+
382
+ // The query will execute automatically when the component mounts
383
+ // You can still manually trigger it with execute() or update conditions
384
+
385
+ if (loading) return <div>Loading...</div>;
386
+ if (error) return <div>Error: {error.message}</div>;
387
+
388
+ return (
389
+ <div>
390
+ <ul>
391
+ {result?.map((item, index) => (
392
+ <li key={index}>{item.name}</li>
393
+ ))}
394
+ </ul>
395
+ </div>
396
+ );
397
+ };
398
+ ```
399
+
400
+ ### usePagedQuery Hook
401
+
402
+ The `usePagedQuery` hook manages paged queries with state management for conditions, projections, pagination, and
403
+ sorting.
404
+
405
+ ```typescript jsx
406
+ import { usePagedQuery } from '@ahoo-wang/fetcher-react';
407
+
408
+ const MyComponent = () => {
409
+ const { result, loading, error, execute, setCondition, setPagination } = usePagedQuery({
410
+ initialQuery: {
411
+ condition: {},
412
+ pagination: { index: 1, size: 10 },
413
+ projection: {},
414
+ sort: []
415
+ },
416
+ query: async (pagedQuery) => {
417
+ // Your paged fetching logic here
418
+ return fetchPagedData(pagedQuery);
419
+ },
420
+ });
421
+
422
+ const handlePageChange = (page: number) => {
423
+ setPagination({ index: page, size: 10 });
424
+ execute();
425
+ };
426
+
427
+ if (loading) return <div>Loading...</div>;
428
+ if (error) return <div>Error: {error.message}</div>;
429
+
430
+ return (
431
+ <div>
432
+ <ul>
433
+ {result?.data?.map((item, index) => (
434
+ <li key={index}>{item.name}</li>
435
+ ))}
436
+ </ul>
437
+ <button onClick={() => handlePageChange(result?.pagination?.index! - 1)} disabled={result?.pagination?.index === 1}>
438
+ Previous
439
+ </button>
440
+ <button onClick={() => handlePageChange(result?.pagination?.index! + 1)}>
441
+ Next
442
+ </button>
443
+ </div>
444
+ );
445
+ };
446
+ ```
447
+
448
+ #### Auto Execute Example
449
+
450
+ ```typescript jsx
451
+ import { usePagedQuery } from '@ahoo-wang/fetcher-react';
452
+
453
+ const MyComponent = () => {
454
+ const { result, loading, error, execute, setCondition, setPagination } = usePagedQuery({
455
+ initialQuery: {
456
+ condition: {},
457
+ pagination: { index: 1, size: 10 },
458
+ projection: {},
459
+ sort: []
460
+ },
461
+ query: async (pagedQuery) => fetchPagedData(pagedQuery),
462
+ autoExecute: true, // Automatically execute on component mount
463
+ });
464
+
465
+ // The query will execute automatically when the component mounts
466
+
467
+ if (loading) return <div>Loading...</div>;
468
+ if (error) return <div>Error: {error.message}</div>;
469
+
470
+ return (
471
+ <div>
472
+ <ul>
473
+ {result?.data?.map((item, index) => (
474
+ <li key={index}>{item.name}</li>
475
+ ))}
476
+ </ul>
477
+ <button onClick={() => setPagination({ index: result?.pagination?.index! - 1, size: 10 })} disabled={result?.pagination?.index === 1}>
478
+ Previous
479
+ </button>
480
+ <button onClick={() => setPagination({ index: result?.pagination?.index! + 1, size: 10 })}>
481
+ Next
482
+ </button>
483
+ </div>
484
+ );
485
+ };
486
+ ```
487
+
488
+ ### useSingleQuery Hook
489
+
490
+ The `useSingleQuery` hook manages single item queries with state management for conditions, projections, and sorting.
491
+
492
+ ```typescript jsx
493
+ import { useSingleQuery } from '@ahoo-wang/fetcher-react';
494
+
495
+ const MyComponent = () => {
496
+ const { result, loading, error, execute, setCondition } = useSingleQuery({
497
+ initialQuery: { condition: {}, projection: {}, sort: [] },
498
+ query: async (singleQuery) => {
499
+ // Your single item fetching logic here
500
+ return fetchSingleData(singleQuery);
501
+ },
502
+ });
503
+
504
+ const handleFetchUser = (userId: string) => {
505
+ setCondition({ id: userId });
506
+ execute();
507
+ };
508
+
509
+ if (loading) return <div>Loading...</div>;
510
+ if (error) return <div>Error: {error.message}</div>;
511
+
512
+ return (
513
+ <div>
514
+ <button onClick={() => handleFetchUser('123')}>Fetch User</button>
515
+ {result && <p>User: {result.name}</p>}
516
+ </div>
517
+ );
518
+ };
519
+ ```
520
+
521
+ #### Auto Execute Example
522
+
523
+ ```typescript jsx
524
+ import { useSingleQuery } from '@ahoo-wang/fetcher-react';
525
+
526
+ const MyComponent = () => {
527
+ const { result, loading, error, execute, setCondition } = useSingleQuery({
528
+ initialQuery: { condition: {}, projection: {}, sort: [] },
529
+ query: async (singleQuery) => fetchSingleData(singleQuery),
530
+ autoExecute: true, // Automatically execute on component mount
531
+ });
532
+
533
+ // The query will execute automatically when the component mounts
534
+
535
+ if (loading) return <div>Loading...</div>;
536
+ if (error) return <div>Error: {error.message}</div>;
537
+
538
+ return (
539
+ <div>
540
+ {result && <p>User: {result.name}</p>}
541
+ </div>
542
+ );
543
+ };
544
+ ```
545
+
546
+ ### useCountQuery Hook
547
+
548
+ The `useCountQuery` hook manages count queries with state management for conditions.
549
+
550
+ ```typescript jsx
551
+ import { useCountQuery } from '@ahoo-wang/fetcher-react';
552
+
553
+ const MyComponent = () => {
554
+ const { result, loading, error, execute, setCondition } = useCountQuery({
555
+ initialCondition: {},
556
+ count: async (condition) => {
557
+ // Your count fetching logic here
558
+ return fetchCount(condition);
559
+ },
560
+ });
561
+
562
+ const handleCountActive = () => {
563
+ setCondition({ status: 'active' });
564
+ execute();
565
+ };
566
+
567
+ if (loading) return <div>Loading...</div>;
568
+ if (error) return <div>Error: {error.message}</div>;
569
+
570
+ return (
571
+ <div>
572
+ <button onClick={handleCountActive}>Count Active Items</button>
573
+ <p>Total: {result}</p>
574
+ </div>
575
+ );
576
+ };
577
+ ```
578
+
579
+ #### Auto Execute Example
580
+
581
+ ```typescript jsx
582
+ import { useCountQuery } from '@ahoo-wang/fetcher-react';
583
+
584
+ const MyComponent = () => {
585
+ const { result, loading, error, execute, setCondition } = useCountQuery({
586
+ initialCondition: {},
587
+ count: async (condition) => fetchCount(condition),
588
+ autoExecute: true, // Automatically execute on component mount
589
+ });
590
+
591
+ // The query will execute automatically when the component mounts
592
+
593
+ if (loading) return <div>Loading...</div>;
594
+ if (error) return <div>Error: {error.message}</div>;
595
+
596
+ return (
597
+ <div>
598
+ <p>Total: {result}</p>
599
+ </div>
600
+ );
601
+ };
602
+ ```
603
+
604
+ ### useListStreamQuery Hook
605
+
606
+ The `useListStreamQuery` hook manages list stream queries that return a readable stream of server-sent events.
607
+
608
+ ```typescript jsx
609
+ import { useListStreamQuery } from '@ahoo-wang/fetcher-react';
610
+
611
+ const MyComponent = () => {
612
+ const { result, loading, error, execute, setCondition } = useListStreamQuery({
613
+ initialQuery: { condition: {}, projection: {}, sort: [], limit: 100 },
614
+ listStream: async (listQuery) => {
615
+ // Your stream fetching logic here
616
+ return fetchListStream(listQuery);
617
+ },
618
+ });
619
+
620
+ useEffect(() => {
621
+ if (result) {
622
+ const reader = result.getReader();
623
+ const readStream = async () => {
624
+ try {
625
+ while (true) {
626
+ const { done, value } = await reader.read();
627
+ if (done) break;
628
+ console.log('Received:', value);
629
+ // Process the stream event
630
+ }
631
+ } catch (error) {
632
+ console.error('Stream error:', error);
633
+ }
634
+ };
635
+ readStream();
636
+ }
637
+ }, [result]);
638
+
639
+ if (loading) return <div>Loading...</div>;
640
+ if (error) return <div>Error: {error.message}</div>;
641
+
642
+ return (
643
+ <div>
644
+ <button onClick={execute}>Start Stream</button>
645
+ </div>
646
+ );
647
+ };
648
+ ```
649
+
650
+ #### Auto Execute Example
651
+
652
+ ```typescript jsx
653
+ import { useListStreamQuery } from '@ahoo-wang/fetcher-react';
654
+
655
+ const MyComponent = () => {
656
+ const { result, loading, error, execute, setCondition } = useListStreamQuery({
657
+ initialQuery: { condition: {}, projection: {}, sort: [], limit: 100 },
658
+ listStream: async (listQuery) => fetchListStream(listQuery),
659
+ autoExecute: true, // Automatically execute on component mount
660
+ });
661
+
662
+ useEffect(() => {
663
+ if (result) {
664
+ const reader = result.getReader();
665
+ const readStream = async () => {
666
+ try {
667
+ while (true) {
668
+ const { done, value } = await reader.read();
669
+ if (done) break;
670
+ console.log('Received:', value);
671
+ // Process the stream event
672
+ }
673
+ } catch (error) {
674
+ console.error('Stream error:', error);
675
+ }
676
+ };
677
+ readStream();
678
+ }
679
+ }, [result]);
680
+
681
+ // The query will execute automatically when the component mounts
682
+
683
+ if (loading) return <div>Loading...</div>;
684
+ if (error) return <div>Error: {error.message}</div>;
685
+
686
+ return (
687
+ <div>
688
+ {/* Stream is already started automatically */}
689
+ </div>
690
+ );
691
+ };
692
+ ```
693
+
301
694
  ## API Reference
302
695
 
303
696
  ### useFetcher
304
697
 
305
698
  ```typescript
306
- function useFetcher<R = unknown, E = unknown>(
699
+ function useFetcher<R = unknown, E = FetcherError>(
307
700
  options?: UseFetcherOptions<R, E> | UseFetcherOptionsSupplier<R, E>,
308
701
  ): UseFetcherReturn<R, E>;
309
702
  ```
@@ -314,7 +707,7 @@ flexible configuration.
314
707
  **Type Parameters:**
315
708
 
316
709
  - `R`: The type of the result
317
- - `E`: The type of the error (defaults to `unknown`)
710
+ - `E`: The type of the error (defaults to `FetcherError`)
318
711
 
319
712
  **Parameters:**
320
713
 
@@ -338,7 +731,7 @@ An object containing:
338
731
  ### useExecutePromise
339
732
 
340
733
  ```typescript
341
- function useExecutePromise<R = unknown, E = unknown>(
734
+ function useExecutePromise<R = unknown, E = FetcherError>(
342
735
  options?: UseExecutePromiseOptions<R, E>,
343
736
  ): UseExecutePromiseReturn<R, E>;
344
737
  ```
@@ -349,7 +742,7 @@ state options.
349
742
  **Type Parameters:**
350
743
 
351
744
  - `R`: The type of the result
352
- - `E`: The type of the error (defaults to `unknown`)
745
+ - `E`: The type of the error (defaults to `FetcherError`)
353
746
 
354
747
  **Parameters:**
355
748
 
@@ -372,7 +765,7 @@ An object containing:
372
765
  ### usePromiseState
373
766
 
374
767
  ```typescript
375
- function usePromiseState<R = unknown, E = unknown>(
768
+ function usePromiseState<R = unknown, E = FetcherError>(
376
769
  options?: UsePromiseStateOptions<R, E> | UsePromiseStateOptionsSupplier<R, E>,
377
770
  ): UsePromiseStateReturn<R, E>;
378
771
  ```
@@ -383,7 +776,7 @@ suppliers.
383
776
  **Type Parameters:**
384
777
 
385
778
  - `R`: The type of the result
386
- - `E`: The type of the error (defaults to `unknown`)
779
+ - `E`: The type of the error (defaults to `FetcherError`)
387
780
 
388
781
  **Parameters:**
389
782
 
@@ -462,6 +855,135 @@ A React hook that provides state management for a KeyStorage instance.
462
855
 
463
856
  - A tuple containing the current stored value and a function to update it
464
857
 
858
+ ### useListQuery
859
+
860
+ ```typescript
861
+ function useListQuery<R, FIELDS extends string = string, E = FetcherError>(
862
+ options: UseListQueryOptions<R, FIELDS, E>,
863
+ ): UseListQueryReturn<R, FIELDS, E>;
864
+ ```
865
+
866
+ A React hook for managing list queries with state management for conditions, projections, sorting, and limits.
867
+
868
+ **Type Parameters:**
869
+
870
+ - `R`: The type of the result items in the list
871
+ - `FIELDS`: The type of the fields used in conditions and projections
872
+ - `E`: The type of the error (defaults to `FetcherError`)
873
+
874
+ **Parameters:**
875
+
876
+ - `options`: Configuration options including initialQuery and list function
877
+ - `autoExecute`: Whether to automatically execute the query on component mount (defaults to false)
878
+
879
+ **Returns:**
880
+
881
+ An object containing promise state, execute function, and setters for condition, projection, sort, and limit.
882
+
883
+ ### usePagedQuery
884
+
885
+ ```typescript
886
+ function usePagedQuery<R, FIELDS extends string = string, E = FetcherError>(
887
+ options: UsePagedQueryOptions<R, FIELDS, E>,
888
+ ): UsePagedQueryReturn<R, FIELDS, E>;
889
+ ```
890
+
891
+ A React hook for managing paged queries with state management for conditions, projections, pagination, and sorting.
892
+
893
+ **Type Parameters:**
894
+
895
+ - `R`: The type of the result items in the paged list
896
+ - `FIELDS`: The type of the fields used in conditions and projections
897
+ - `E`: The type of the error (defaults to `FetcherError`)
898
+
899
+ **Parameters:**
900
+
901
+ - `options`: Configuration options including initialQuery and query function
902
+ - `autoExecute`: Whether to automatically execute the query on component mount (defaults to false)
903
+
904
+ **Returns:**
905
+
906
+ An object containing promise state, execute function, and setters for condition, projection, pagination, and sort.
907
+
908
+ ### useSingleQuery
909
+
910
+ ```typescript
911
+ function useSingleQuery<R, FIELDS extends string = string, E = FetcherError>(
912
+ options: UseSingleQueryOptions<R, FIELDS, E>,
913
+ ): UseSingleQueryReturn<R, FIELDS, E>;
914
+ ```
915
+
916
+ A React hook for managing single queries with state management for conditions, projections, and sorting.
917
+
918
+ **Type Parameters:**
919
+
920
+ - `R`: The type of the result
921
+ - `FIELDS`: The type of the fields used in conditions and projections
922
+ - `E`: The type of the error (defaults to `FetcherError`)
923
+
924
+ **Parameters:**
925
+
926
+ - `options`: Configuration options including initialQuery and query function
927
+ - `autoExecute`: Whether to automatically execute the query on component mount (defaults to false)
928
+
929
+ **Returns:**
930
+
931
+ An object containing promise state, execute function, and setters for condition, projection, and sort.
932
+
933
+ ### useCountQuery
934
+
935
+ ```typescript
936
+ function useCountQuery<FIELDS extends string = string, E = FetcherError>(
937
+ options: UseCountQueryOptions<FIELDS, E>,
938
+ ): UseCountQueryReturn<FIELDS, E>;
939
+ ```
940
+
941
+ A React hook for managing count queries with state management for conditions.
942
+
943
+ **Type Parameters:**
944
+
945
+ - `FIELDS`: The type of the fields used in conditions
946
+ - `E`: The type of the error (defaults to `FetcherError`)
947
+
948
+ **Parameters:**
949
+
950
+ - `options`: Configuration options including initialCondition and count function
951
+ - `autoExecute`: Whether to automatically execute the query on component mount (defaults to false)
952
+
953
+ **Returns:**
954
+
955
+ An object containing promise state, execute function, and setter for condition.
956
+
957
+ ### useListStreamQuery
958
+
959
+ ```typescript
960
+ function useListStreamQuery<
961
+ R,
962
+ FIELDS extends string = string,
963
+ E = FetcherError,
964
+ >(
965
+ options: UseListStreamQueryOptions<R, FIELDS, E>,
966
+ ): UseListStreamQueryReturn<R, FIELDS, E>;
967
+ ```
968
+
969
+ A React hook for managing list stream queries with state management for conditions, projections, sorting, and limits.
970
+ Returns a readable stream of JSON server-sent events.
971
+
972
+ **Type Parameters:**
973
+
974
+ - `R`: The type of the result items in the stream events
975
+ - `FIELDS`: The type of the fields used in conditions and projections
976
+ - `E`: The type of the error (defaults to `FetcherError`)
977
+
978
+ **Parameters:**
979
+
980
+ - `options`: Configuration options including initialQuery and listStream function
981
+ - `autoExecute`: Whether to automatically execute the query on component mount (defaults to false)
982
+
983
+ **Returns:**
984
+
985
+ An object containing promise state, execute function, and setters for condition, projection, sort, and limit.
986
+
465
987
  ## License
466
988
 
467
989
  [Apache 2.0](https://github.com/Ahoo-Wang/fetcher/blob/main/LICENSE)