@ahoo-wang/fetcher-react 3.3.9 → 3.4.1

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.zh-CN.md CHANGED
@@ -39,11 +39,16 @@
39
39
  - [useEventSubscription Hook](#useeventsubscription-hook)
40
40
  - [useKeyStorage Hook](#usekeystorage-hook)
41
41
  - [useImmerKeyStorage Hook](#useimmerkeystorage-hook)
42
- - [Wow 查询 Hooks](#wow-查询-hooks)
42
+ - [Wow 查询 Hooks](#wow-查询-hooks)
43
43
  - [useListQuery Hook](#uselistquery-hook)
44
44
  - [usePagedQuery Hook](#usepagedquery-hook)
45
45
  - [useSingleQuery Hook](#usesinglequery-hook)
46
46
  - [useCountQuery Hook](#usecountquery-hook)
47
+ - [useFetcherCountQuery Hook](#usefetchercountquery-hook)
48
+ - [useFetcherPagedQuery Hook](#usefetcherpagedquery-hook)
49
+ - [useFetcherListQuery Hook](#usefetcherlistquery-hook)
50
+ - [useFetcherListStreamQuery Hook](#usefetcherliststreamquery-hook)
51
+ - [useFetcherSingleQuery Hook](#usefetchersinglequery-hook)
47
52
  - [useListStreamQuery Hook](#useliststreamquery-hook)
48
53
  - [最佳实践](#最佳实践)
49
54
  - [API 参考](#api-参考)
@@ -512,6 +517,454 @@ const MyComponent = () => {
512
517
  };
513
518
  ```
514
519
 
520
+ ### useFetcherCountQuery Hook
521
+
522
+ `useFetcherCountQuery` hook 是使用 Fetcher 库执行计数查询的专用 React hook。它专为需要检索匹配特定条件的记录数量的场景而设计,返回表示计数的数字。
523
+
524
+ ```typescript jsx
525
+ import { useFetcherCountQuery } from '@ahoo-wang/fetcher-react';
526
+ import { all } from '@ahoo-wang/fetcher-wow';
527
+
528
+ function UserCountComponent() {
529
+ const { data: count, loading, error, execute } = useFetcherCountQuery({
530
+ url: '/api/users/count',
531
+ initialQuery: all(),
532
+ autoExecute: true,
533
+ });
534
+
535
+ if (loading) return <div>加载中...</div>;
536
+ if (error) return <div>错误: {error.message}</div>;
537
+
538
+ return (
539
+ <div>
540
+ <div>活跃用户总数: {count}</div>
541
+ <button onClick={execute}>刷新计数</button>
542
+ </div>
543
+ );
544
+ }
545
+ ```
546
+
547
+ #### 自动执行示例
548
+
549
+ ```typescript jsx
550
+ import { useFetcherCountQuery } from '@ahoo-wang/fetcher-react';
551
+
552
+ const MyComponent = () => {
553
+ const { data: count, loading, error, execute } = useFetcherCountQuery({
554
+ url: '/api/users/count',
555
+ initialQuery: { status: 'active' },
556
+ autoExecute: true, // 组件挂载时自动执行
557
+ });
558
+
559
+ // 查询将在组件挂载时自动执行
560
+
561
+ if (loading) return <div>加载中...</div>;
562
+ if (error) return <div>错误: {error.message}</div>;
563
+
564
+ return (
565
+ <div>
566
+ <p>活跃用户总数: {count}</p>
567
+ </div>
568
+ );
569
+ };
570
+ ```
571
+
572
+ ### useFetcherPagedQuery Hook
573
+
574
+ `useFetcherPagedQuery` hook 是使用 Fetcher 库执行分页查询的专用 React hook。它专为需要检索匹配查询条件的分页数据的场景而设计,返回包含当前页面项目以及分页元数据的 PagedList。
575
+
576
+ ```typescript jsx
577
+ import { useFetcherPagedQuery } from '@ahoo-wang/fetcher-react';
578
+ import { pagedQuery, contains, pagination, desc } from '@ahoo-wang/fetcher-wow';
579
+
580
+ interface User {
581
+ id: number;
582
+ name: string;
583
+ email: string;
584
+ }
585
+
586
+ function UserListComponent() {
587
+ const {
588
+ data: pagedList,
589
+ loading,
590
+ error,
591
+ execute,
592
+ setQuery,
593
+ getQuery
594
+ } = useFetcherPagedQuery<User, keyof User>({
595
+ url: '/api/users/paged',
596
+ initialQuery: pagedQuery({
597
+ condition: contains('name', 'John'),
598
+ sort: [desc('createdAt')],
599
+ pagination: pagination({ index: 1, size: 10 })
600
+ }),
601
+ autoExecute: true,
602
+ });
603
+
604
+ const goToPage = (page: number) => {
605
+ const currentQuery = getQuery();
606
+ setQuery({
607
+ ...currentQuery,
608
+ pagination: { ...currentQuery.pagination, index: page }
609
+ });
610
+ };
611
+
612
+ if (loading) return <div>加载中...</div>;
613
+ if (error) return <div>错误: {error.message}</div>;
614
+
615
+ return (
616
+ <div>
617
+ <h2>用户</h2>
618
+ <ul>
619
+ {pagedList.list.map(user => (
620
+ <li key={user.id}>{user.name} - {user.email}</li>
621
+ ))}
622
+ </ul>
623
+ <div>
624
+ <span>总数: {pagedList.total} 用户</span>
625
+ <button onClick={() => goToPage(1)} disabled={pagedList.pagination.index === 1}>
626
+ 第一页
627
+ </button>
628
+ <button onClick={() => goToPage(pagedList.pagination.index - 1)} disabled={pagedList.pagination.index === 1}>
629
+ 上一页
630
+ </button>
631
+ <span>第 {pagedList.pagination.index} 页</span>
632
+ <button onClick={() => goToPage(pagedList.pagination.index + 1)}>
633
+ 下一页
634
+ </button>
635
+ </div>
636
+ </div>
637
+ );
638
+ }
639
+ ```
640
+
641
+ #### 自动执行示例
642
+
643
+ ```typescript jsx
644
+ import { useFetcherPagedQuery } from '@ahoo-wang/fetcher-react';
645
+
646
+ const MyComponent = () => {
647
+ const { data: pagedList, loading, error, execute } = useFetcherPagedQuery({
648
+ url: '/api/products/paged',
649
+ initialQuery: {
650
+ condition: { category: 'electronics' },
651
+ pagination: { index: 1, size: 20 },
652
+ projection: {},
653
+ sort: []
654
+ },
655
+ autoExecute: true, // 组件挂载时自动执行
656
+ });
657
+
658
+ // 查询将在组件挂载时自动执行
659
+
660
+ if (loading) return <div>加载中...</div>;
661
+ if (error) return <div>错误: {error.message}</div>;
662
+
663
+ return (
664
+ <div>
665
+ <h2>产品</h2>
666
+ <div>总数: {pagedList.total}</div>
667
+ <ul>
668
+ {pagedList.list.map(product => (
669
+ <li key={product.id}>{product.name}</li>
670
+ ))}
671
+ </ul>
672
+ </div>
673
+ );
674
+ };
675
+ ```
676
+
677
+ ### useFetcherListQuery Hook
678
+
679
+ `useFetcherListQuery` hook 是使用 Fetcher 库执行列表查询的专用 React hook。它专为获取项目列表而设计,支持通过 ListQuery 类型进行过滤、排序和分页,返回结果数组。
680
+
681
+ ```typescript jsx
682
+ import { useFetcherListQuery } from '@ahoo-wang/fetcher-react';
683
+ import { listQuery, contains, desc } from '@ahoo-wang/fetcher-wow';
684
+
685
+ interface User {
686
+ id: string;
687
+ name: string;
688
+ email: string;
689
+ createdAt: string;
690
+ }
691
+
692
+ function UserListComponent() {
693
+ const {
694
+ loading,
695
+ result: users,
696
+ error,
697
+ execute,
698
+ setQuery,
699
+ getQuery,
700
+ } = useFetcherListQuery<User, keyof User>({
701
+ url: '/api/users/list',
702
+ initialQuery: listQuery({
703
+ condition: contains('name', 'John'),
704
+ sort: [desc('createdAt')],
705
+ limit: 10,
706
+ }),
707
+ autoExecute: true,
708
+ });
709
+
710
+ const loadMore = () => {
711
+ const currentQuery = getQuery();
712
+ setQuery({
713
+ ...currentQuery,
714
+ limit: (currentQuery.limit || 10) + 10,
715
+ });
716
+ };
717
+
718
+ if (loading) return <div>正在加载用户...</div>;
719
+ if (error) return <div>错误: {error.message}</div>;
720
+
721
+ return (
722
+ <div>
723
+ <h2>用户 ({users?.length || 0})</h2>
724
+ <ul>
725
+ {users?.map(user => (
726
+ <li key={user.id}>
727
+ {user.name} - {user.email}
728
+ </li>
729
+ ))}
730
+ </ul>
731
+ <button onClick={loadMore}>加载更多</button>
732
+ <button onClick={execute}>刷新列表</button>
733
+ </div>
734
+ );
735
+ }
736
+ ```
737
+
738
+ #### 自动执行示例
739
+
740
+ ```typescript jsx
741
+ import { useFetcherListQuery } from '@ahoo-wang/fetcher-react';
742
+
743
+ const MyComponent = () => {
744
+ const { result: products, loading, error, execute } = useFetcherListQuery({
745
+ url: '/api/products/list',
746
+ initialQuery: {
747
+ condition: { category: 'electronics' },
748
+ projection: {},
749
+ sort: [],
750
+ limit: 20
751
+ },
752
+ autoExecute: true, // 组件挂载时自动执行
753
+ });
754
+
755
+ // 查询将在组件挂载时自动执行
756
+
757
+ if (loading) return <div>加载中...</div>;
758
+ if (error) return <div>错误: {error.message}</div>;
759
+
760
+ return (
761
+ <div>
762
+ <h2>产品</h2>
763
+ <ul>
764
+ {products?.map(product => (
765
+ <li key={product.id}>{product.name}</li>
766
+ ))}
767
+ </ul>
768
+ </div>
769
+ );
770
+ };
771
+ ```
772
+
773
+ ### useFetcherListStreamQuery Hook
774
+
775
+ `useFetcherListStreamQuery` hook 是使用 Fetcher 库通过服务器发送事件执行列表流查询的专用 React hook。它专为需要检索匹配列表查询条件的数据流场景而设计,返回 JSON 服务器发送事件的 ReadableStream,用于实时数据流式传输。
776
+
777
+ ```typescript jsx
778
+ import { useFetcherListStreamQuery } from '@ahoo-wang/fetcher-react';
779
+ import { listQuery, contains } from '@ahoo-wang/fetcher-wow';
780
+ import { JsonServerSentEvent } from '@ahoo-wang/fetcher-eventstream';
781
+ import { useEffect, useRef } from 'react';
782
+
783
+ interface User {
784
+ id: number;
785
+ name: string;
786
+ }
787
+
788
+ function UserStreamComponent() {
789
+ const { data: stream, loading, error, execute } = useFetcherListStreamQuery<User, 'id' | 'name'>({
790
+ url: '/api/users/stream',
791
+ initialQuery: listQuery({
792
+ condition: contains('name', 'John'),
793
+ limit: 10,
794
+ }),
795
+ autoExecute: true,
796
+ });
797
+
798
+ const messagesRef = useRef<HTMLDivElement>(null);
799
+
800
+ useEffect(() => {
801
+ if (stream) {
802
+ const reader = stream.getReader();
803
+ const readStream = async () => {
804
+ try {
805
+ while (true) {
806
+ const { done, value } = await reader.read();
807
+ if (done) break;
808
+ // 处理 JsonServerSentEvent<User>
809
+ const newUser = value.data;
810
+ if (messagesRef.current) {
811
+ const div = document.createElement('div');
812
+ div.textContent = `新用户: ${newUser.name}`;
813
+ messagesRef.current.appendChild(div);
814
+ }
815
+ }
816
+ } catch (err) {
817
+ console.error('流错误:', err);
818
+ }
819
+ };
820
+ readStream();
821
+ }
822
+ }, [stream]);
823
+
824
+ if (loading) return <div>正在加载流...</div>;
825
+ if (error) return <div>错误: {error.message}</div>;
826
+
827
+ return (
828
+ <div>
829
+ <div ref={messagesRef}></div>
830
+ <button onClick={execute}>重新启动流</button>
831
+ </div>
832
+ );
833
+ }
834
+ ```
835
+
836
+ #### 自动执行示例
837
+
838
+ ```typescript jsx
839
+ import { useFetcherListStreamQuery } from '@ahoo-wang/fetcher-react';
840
+ import { useEffect, useRef } from 'react';
841
+
842
+ const MyComponent = () => {
843
+ const { data: stream, loading, error, execute } = useFetcherListStreamQuery({
844
+ url: '/api/notifications/stream',
845
+ initialQuery: {
846
+ condition: { type: 'important' },
847
+ limit: 50
848
+ },
849
+ autoExecute: true, // 组件挂载时自动执行
850
+ });
851
+
852
+ const notificationsRef = useRef<HTMLDivElement>(null);
853
+
854
+ useEffect(() => {
855
+ if (stream) {
856
+ const reader = stream.getReader();
857
+ const processStream = async () => {
858
+ try {
859
+ while (true) {
860
+ const { done, value } = await reader.read();
861
+ if (done) break;
862
+
863
+ const notification = value.data;
864
+ if (notificationsRef.current) {
865
+ const notificationDiv = document.createElement('div');
866
+ notificationDiv.textContent = `通知: ${notification.message}`;
867
+ notificationsRef.current.appendChild(notificationDiv);
868
+ }
869
+ }
870
+ } catch (err) {
871
+ console.error('流处理错误:', err);
872
+ }
873
+ };
874
+ processStream();
875
+ }
876
+ }, [stream]);
877
+
878
+ // 流将在组件挂载时自动启动
879
+
880
+ if (loading) return <div>加载中...</div>;
881
+ if (error) return <div>错误: {error.message}</div>;
882
+
883
+ return (
884
+ <div>
885
+ <h2>实时通知</h2>
886
+ <div ref={notificationsRef}></div>
887
+ </div>
888
+ );
889
+ };
890
+ ```
891
+
892
+ ### useFetcherSingleQuery Hook
893
+
894
+ `useFetcherSingleQuery` hook 是使用 Fetcher 库执行单个项目查询的专用 React hook。它专为获取单个项目而设计,支持通过 SingleQuery 类型进行过滤和排序,返回单个结果项目。
895
+
896
+ ```typescript jsx
897
+ import { useFetcherSingleQuery } from '@ahoo-wang/fetcher-react';
898
+ import { singleQuery, eq } from '@ahoo-wang/fetcher-wow';
899
+
900
+ interface User {
901
+ id: string;
902
+ name: string;
903
+ email: string;
904
+ createdAt: string;
905
+ }
906
+
907
+ function UserProfileComponent({ userId }: { userId: string }) {
908
+ const {
909
+ loading,
910
+ result: user,
911
+ error,
912
+ execute,
913
+ } = useFetcherSingleQuery<User, keyof User>({
914
+ url: `/api/users/${userId}`,
915
+ initialQuery: singleQuery({
916
+ condition: eq('id', userId),
917
+ }),
918
+ autoExecute: true,
919
+ });
920
+
921
+ if (loading) return <div>正在加载用户...</div>;
922
+ if (error) return <div>错误: {error.message}</div>;
923
+ if (!user) return <div>未找到用户</div>;
924
+
925
+ return (
926
+ <div>
927
+ <h2>{user.name}</h2>
928
+ <p>邮箱: {user.email}</p>
929
+ <p>创建时间: {user.createdAt}</p>
930
+ <button onClick={execute}>刷新</button>
931
+ </div>
932
+ );
933
+ }
934
+ ```
935
+
936
+ #### 自动执行示例
937
+
938
+ ```typescript jsx
939
+ import { useFetcherSingleQuery } from '@ahoo-wang/fetcher-react';
940
+
941
+ const MyComponent = () => {
942
+ const { result: product, loading, error, execute } = useFetcherSingleQuery({
943
+ url: '/api/products/featured',
944
+ initialQuery: {
945
+ condition: { featured: true },
946
+ projection: {},
947
+ sort: []
948
+ },
949
+ autoExecute: true, // 组件挂载时自动执行
950
+ });
951
+
952
+ // 查询将在组件挂载时自动执行
953
+
954
+ if (loading) return <div>加载中...</div>;
955
+ if (error) return <div>错误: {error.message}</div>;
956
+ if (!product) return <div>未找到产品</div>;
957
+
958
+ return (
959
+ <div>
960
+ <h2>特色产品</h2>
961
+ <div>{product.name}</div>
962
+ <div>{product.description}</div>
963
+ </div>
964
+ );
965
+ };
966
+ ```
967
+
515
968
  ### useListStreamQuery Hook
516
969
 
517
970
  `useListStreamQuery` hook 管理列表流查询,返回服务器发送事件的 readable stream。
@@ -1085,6 +1538,156 @@ function useCountQuery<FIELDS extends string = string, E = FetcherError>(
1085
1538
 
1086
1539
  包含 promise 状态、execute 函数以及条件设置器的对象。
1087
1540
 
1541
+ ### useFetcherCountQuery
1542
+
1543
+ ```typescript
1544
+ function useFetcherCountQuery<FIELDS extends string = string, E = FetcherError>(
1545
+ options: UseFetcherCountQueryOptions<FIELDS, E>,
1546
+ ): UseFetcherCountQueryReturn<FIELDS, E>;
1547
+ ```
1548
+
1549
+ 使用 Fetcher 库执行计数查询的 React hook。它包装了 useFetcherQuery hook 并专门用于计数操作,返回表示计数的数字。
1550
+
1551
+ **类型参数:**
1552
+
1553
+ - `FIELDS`: 可在条件中使用的字段的字符串联合类型
1554
+ - `E`: 可能抛出的错误类型(默认为 `FetcherError`)
1555
+
1556
+ **参数:**
1557
+
1558
+ - `options`: 计数查询的配置选项,包括条件、fetcher 实例和其他查询设置
1559
+ - `url`: 从中获取计数的 URL
1560
+ - `initialQuery`: 计数查询的初始条件
1561
+ - `autoExecute`: 是否在组件挂载时自动执行查询(默认为 false)
1562
+
1563
+ **返回值:**
1564
+
1565
+ 包含查询结果(作为数字的计数)、加载状态、错误状态和实用函数的对象。
1566
+
1567
+ ### useFetcherPagedQuery
1568
+
1569
+ ```typescript
1570
+ function useFetcherPagedQuery<
1571
+ R,
1572
+ FIELDS extends string = string,
1573
+ E = FetcherError,
1574
+ >(
1575
+ options: UseFetcherPagedQueryOptions<R, FIELDS, E>,
1576
+ ): UseFetcherPagedQueryReturn<R, FIELDS, E>;
1577
+ ```
1578
+
1579
+ 使用 Fetcher 库执行分页查询的 React hook。它包装了 useFetcherQuery hook 并专门用于分页操作,返回包含项目和分页元数据的 PagedList。
1580
+
1581
+ **类型参数:**
1582
+
1583
+ - `R`: 分页列表中每个项目包含的资源或实体的类型
1584
+ - `FIELDS`: 可在分页查询中使用的字段的字符串联合类型
1585
+ - `E`: 可能抛出的错误类型(默认为 `FetcherError`)
1586
+
1587
+ **参数:**
1588
+
1589
+ - `options`: 分页查询的配置选项,包括分页查询参数、fetcher 实例和其他查询设置
1590
+ - `url`: 从中获取分页数据的 URL
1591
+ - `initialQuery`: 初始分页查询配置
1592
+ - `autoExecute`: 是否在组件挂载时自动执行查询(默认为 false)
1593
+
1594
+ **返回值:**
1595
+
1596
+ 包含查询结果(包含项目和分页信息的 PagedList)、加载状态、错误状态和实用函数的对象。
1597
+
1598
+ ### useFetcherListQuery
1599
+
1600
+ ```typescript
1601
+ function useFetcherListQuery<
1602
+ R,
1603
+ FIELDS extends string = string,
1604
+ E = FetcherError,
1605
+ >(
1606
+ options: UseFetcherListQueryOptions<R, FIELDS, E>,
1607
+ ): UseFetcherListQueryReturn<R, FIELDS, E>;
1608
+ ```
1609
+
1610
+ 使用 fetcher 库在 wow 框架中执行列表查询的 React hook。它包装了 useFetcherQuery hook 并专门用于列表操作,返回结果数组,支持过滤、排序和分页。
1611
+
1612
+ **类型参数:**
1613
+
1614
+ - `R`: 结果数组中单个项目的类型(例如,User、Product)
1615
+ - `FIELDS`: 列表查询中可用于过滤、排序和分页的字段
1616
+ - `E`: 可能抛出的错误类型(默认为 `FetcherError`)
1617
+
1618
+ **参数:**
1619
+
1620
+ - `options`: 列表查询的配置选项,包括列表查询参数、fetcher 实例和其他查询设置
1621
+ - `url`: 从中获取列表数据的 URL
1622
+ - `initialQuery`: 初始列表查询配置
1623
+ - `autoExecute`: 是否在组件挂载时自动执行查询(默认为 false)
1624
+
1625
+ **返回值:**
1626
+
1627
+ 包含查询结果(项目数组)、加载状态、错误状态和实用函数的对象。
1628
+
1629
+ ### useFetcherListStreamQuery
1630
+
1631
+ ```typescript
1632
+ function useFetcherListStreamQuery<
1633
+ R,
1634
+ FIELDS extends string = string,
1635
+ E = FetcherError,
1636
+ >(
1637
+ options: UseFetcherListStreamQueryOptions<R, FIELDS, E>,
1638
+ ): UseFetcherListStreamQueryReturn<R, FIELDS, E>;
1639
+ ```
1640
+
1641
+ 使用 Fetcher 库通过服务器发送事件执行列表流查询的 React hook。它包装了 useFetcherQuery hook 并专门用于流式操作,返回 JSON 服务器发送事件的 ReadableStream,用于实时数据流式传输。
1642
+
1643
+ **类型参数:**
1644
+
1645
+ - `R`: 流中每个事件包含的资源或实体的类型
1646
+ - `FIELDS`: 列表查询中可用于过滤、排序和分页的字段
1647
+ - `E`: 可能抛出的错误类型(默认为 `FetcherError`)
1648
+
1649
+ **参数:**
1650
+
1651
+ - `options`: 列表流查询的配置选项,包括列表查询参数、fetcher 实例和其他查询设置
1652
+ - `url`: 从中获取流数据的 URL
1653
+ - `initialQuery`: 初始列表查询配置
1654
+ - `autoExecute`: 是否在组件挂载时自动执行查询(默认为 false)
1655
+
1656
+ **返回值:**
1657
+
1658
+ 包含查询结果(JSON 服务器发送事件的 ReadableStream)、加载状态、错误状态和实用函数的对象。
1659
+
1660
+ ### useFetcherSingleQuery
1661
+
1662
+ ```typescript
1663
+ function useFetcherSingleQuery<
1664
+ R,
1665
+ FIELDS extends string = string,
1666
+ E = FetcherError,
1667
+ >(
1668
+ options: UseFetcherSingleQueryOptions<R, FIELDS, E>,
1669
+ ): UseFetcherSingleQueryReturn<R, FIELDS, E>;
1670
+ ```
1671
+
1672
+ 使用 fetcher 库在 wow 框架中执行单个项目查询的 React hook。它包装了 useFetcherQuery hook 并专门用于单个项目操作,返回单个结果项目,支持过滤和排序。
1673
+
1674
+ **类型参数:**
1675
+
1676
+ - `R`: 结果项目的类型(例如,User、Product)
1677
+ - `FIELDS`: 单个查询中可用于过滤和排序的字段
1678
+ - `E`: 可能抛出的错误类型(默认为 `FetcherError`)
1679
+
1680
+ **参数:**
1681
+
1682
+ - `options`: 单个查询的配置选项,包括单个查询参数、fetcher 实例和其他查询设置
1683
+ - `url`: 从中获取单个项目的 URL
1684
+ - `initialQuery`: 初始单个查询配置
1685
+ - `autoExecute`: 是否在组件挂载时自动执行查询(默认为 false)
1686
+
1687
+ **返回值:**
1688
+
1689
+ 包含查询结果(单个项目)、加载状态、错误状态和实用函数的对象。
1690
+
1088
1691
  ### useListStreamQuery
1089
1692
 
1090
1693
  ```typescript