@ahoo-wang/fetcher-react 2.6.16 → 2.6.19

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
@@ -1,7 +1,8 @@
1
1
  # @ahoo-wang/fetcher-react
2
2
 
3
- React Integration Package Fetcher Ecosystem. Provides React Hooks and components for seamless data fetching with
4
- automatic re-rendering and loading states.
3
+ 🚀 **Powerful React Data Fetching Library** - Seamlessly integrate HTTP requests with React hooks, featuring automatic
4
+ state management, race condition protection, and TypeScript support. Perfect for modern React applications requiring
5
+ robust data fetching capabilities.
5
6
 
6
7
  [![npm version](https://img.shields.io/npm/v/@ahoo-wang/fetcher-react.svg)](https://www.npmjs.com/package/@ahoo-wang/fetcher-react)
7
8
  [![Build Status](https://github.com/Ahoo-Wang/fetcher/actions/workflows/ci.yml/badge.svg)](https://github.com/Ahoo-Wang/fetcher/actions)
@@ -37,6 +38,7 @@ automatic re-rendering and loading states.
37
38
  - [useSingleQuery Hook](#usesinglequery-hook)
38
39
  - [useCountQuery Hook](#usecountquery-hook)
39
40
  - [useListStreamQuery Hook](#useliststreamquery-hook)
41
+ - [Best Practices](#best-practices)
40
42
  - [API Reference](#api-reference)
41
43
  - [License](#license)
42
44
 
@@ -46,6 +48,11 @@ automatic re-rendering and loading states.
46
48
  npm install @ahoo-wang/fetcher-react
47
49
  ```
48
50
 
51
+ ### Requirements
52
+
53
+ - React 16.8+ (hooks support)
54
+ - TypeScript 4.0+ (for full type safety)
55
+
49
56
  ## Quick Start
50
57
 
51
58
  Get started with `@ahoo-wang/fetcher-react` in just a few lines:
@@ -340,7 +347,7 @@ import { useListQuery } from '@ahoo-wang/fetcher-react';
340
347
  const MyComponent = () => {
341
348
  const { result, loading, error, execute, setCondition, setLimit } = useListQuery({
342
349
  initialQuery: { condition: {}, projection: {}, sort: [], limit: 10 },
343
- list: async (listQuery) => {
350
+ execute: async (listQuery) => {
344
351
  // Your list fetching logic here
345
352
  return fetchListData(listQuery);
346
353
  },
@@ -375,7 +382,7 @@ import { useListQuery } from '@ahoo-wang/fetcher-react';
375
382
  const MyComponent = () => {
376
383
  const { result, loading, error, execute, setCondition } = useListQuery({
377
384
  initialQuery: { condition: {}, projection: {}, sort: [], limit: 10 },
378
- list: async (listQuery) => fetchListData(listQuery),
385
+ execute: async (listQuery) => fetchListData(listQuery),
379
386
  autoExecute: true, // Automatically execute on component mount
380
387
  });
381
388
 
@@ -413,7 +420,7 @@ const MyComponent = () => {
413
420
  projection: {},
414
421
  sort: []
415
422
  },
416
- query: async (pagedQuery) => {
423
+ execute: async (pagedQuery) => {
417
424
  // Your paged fetching logic here
418
425
  return fetchPagedData(pagedQuery);
419
426
  },
@@ -430,7 +437,7 @@ const MyComponent = () => {
430
437
  return (
431
438
  <div>
432
439
  <ul>
433
- {result?.data?.map((item, index) => (
440
+ {result?.list?.map((item, index) => (
434
441
  <li key={index}>{item.name}</li>
435
442
  ))}
436
443
  </ul>
@@ -458,7 +465,7 @@ const MyComponent = () => {
458
465
  projection: {},
459
466
  sort: []
460
467
  },
461
- query: async (pagedQuery) => fetchPagedData(pagedQuery),
468
+ execute: async (pagedQuery) => fetchPagedData(pagedQuery),
462
469
  autoExecute: true, // Automatically execute on component mount
463
470
  });
464
471
 
@@ -470,7 +477,7 @@ const MyComponent = () => {
470
477
  return (
471
478
  <div>
472
479
  <ul>
473
- {result?.data?.map((item, index) => (
480
+ {result?.list?.map((item, index) => (
474
481
  <li key={index}>{item.name}</li>
475
482
  ))}
476
483
  </ul>
@@ -495,7 +502,7 @@ import { useSingleQuery } from '@ahoo-wang/fetcher-react';
495
502
  const MyComponent = () => {
496
503
  const { result, loading, error, execute, setCondition } = useSingleQuery({
497
504
  initialQuery: { condition: {}, projection: {}, sort: [] },
498
- query: async (singleQuery) => {
505
+ execute: async (singleQuery) => {
499
506
  // Your single item fetching logic here
500
507
  return fetchSingleData(singleQuery);
501
508
  },
@@ -526,7 +533,7 @@ import { useSingleQuery } from '@ahoo-wang/fetcher-react';
526
533
  const MyComponent = () => {
527
534
  const { result, loading, error, execute, setCondition } = useSingleQuery({
528
535
  initialQuery: { condition: {}, projection: {}, sort: [] },
529
- query: async (singleQuery) => fetchSingleData(singleQuery),
536
+ execute: async (singleQuery) => fetchSingleData(singleQuery),
530
537
  autoExecute: true, // Automatically execute on component mount
531
538
  });
532
539
 
@@ -552,8 +559,8 @@ import { useCountQuery } from '@ahoo-wang/fetcher-react';
552
559
 
553
560
  const MyComponent = () => {
554
561
  const { result, loading, error, execute, setCondition } = useCountQuery({
555
- initialCondition: {},
556
- count: async (condition) => {
562
+ initialQuery: {},
563
+ execute: async (condition) => {
557
564
  // Your count fetching logic here
558
565
  return fetchCount(condition);
559
566
  },
@@ -583,8 +590,8 @@ import { useCountQuery } from '@ahoo-wang/fetcher-react';
583
590
 
584
591
  const MyComponent = () => {
585
592
  const { result, loading, error, execute, setCondition } = useCountQuery({
586
- initialCondition: {},
587
- count: async (condition) => fetchCount(condition),
593
+ initialQuery: {},
594
+ execute: async (condition) => fetchCount(condition),
588
595
  autoExecute: true, // Automatically execute on component mount
589
596
  });
590
597
 
@@ -611,7 +618,7 @@ import { useListStreamQuery } from '@ahoo-wang/fetcher-react';
611
618
  const MyComponent = () => {
612
619
  const { result, loading, error, execute, setCondition } = useListStreamQuery({
613
620
  initialQuery: { condition: {}, projection: {}, sort: [], limit: 100 },
614
- listStream: async (listQuery) => {
621
+ execute: async (listQuery) => {
615
622
  // Your stream fetching logic here
616
623
  return fetchListStream(listQuery);
617
624
  },
@@ -655,7 +662,7 @@ import { useListStreamQuery } from '@ahoo-wang/fetcher-react';
655
662
  const MyComponent = () => {
656
663
  const { result, loading, error, execute, setCondition } = useListStreamQuery({
657
664
  initialQuery: { condition: {}, projection: {}, sort: [], limit: 100 },
658
- listStream: async (listQuery) => fetchListStream(listQuery),
665
+ execute: async (listQuery) => fetchListStream(listQuery),
659
666
  autoExecute: true, // Automatically execute on component mount
660
667
  });
661
668
 
@@ -691,6 +698,32 @@ const MyComponent = () => {
691
698
  };
692
699
  ```
693
700
 
701
+ ## Best Practices
702
+
703
+ ### Performance Optimization
704
+
705
+ - Use `autoExecute: true` sparingly to avoid unnecessary requests on mount
706
+ - Leverage `setQuery` for query updates when `autoExecute` is enabled to trigger automatic re-execution
707
+ - Memoize expensive computations in your `execute` functions
708
+
709
+ ### Error Handling
710
+
711
+ - Always handle loading and error states in your components
712
+ - Use custom error types for better error categorization
713
+ - Implement retry logic for transient failures
714
+
715
+ ### Type Safety
716
+
717
+ - Define strict interfaces for your query parameters and results
718
+ - Use generic types consistently across your application
719
+ - Enable strict TypeScript mode for maximum safety
720
+
721
+ ### State Management
722
+
723
+ - Combine with global state management (Redux, Zustand) for complex apps
724
+ - Use `useKeyStorage` for persistent client-side data
725
+ - Implement optimistic updates for better UX
726
+
694
727
  ## API Reference
695
728
 
696
729
  ### useFetcher
@@ -947,7 +980,7 @@ A React hook for managing count queries with state management for conditions.
947
980
 
948
981
  **Parameters:**
949
982
 
950
- - `options`: Configuration options including initialCondition and count function
983
+ - `options`: Configuration options including initialQuery and execute function
951
984
  - `autoExecute`: Whether to automatically execute the query on component mount (defaults to false)
952
985
 
953
986
  **Returns:**
package/README.zh-CN.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @ahoo-wang/fetcher-react
2
2
 
3
- Fetcher 生态的 React 集成包。提供 React Hooks 和组件,实现无缝的数据获取,支持自动重新渲染和加载状态。
3
+ 🚀 **强大的 React 数据获取库** - 无缝集成 HTTP 请求与 React hooks,具备自动状态管理、竞态条件保护和 TypeScript 支持。非常适合需要强大数据获取能力的现代 React 应用程序。
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/@ahoo-wang/fetcher-react.svg)](https://www.npmjs.com/package/@ahoo-wang/fetcher-react)
6
6
  [![Build Status](https://github.com/Ahoo-Wang/fetcher/actions/workflows/ci.yml/badge.svg)](https://github.com/Ahoo-Wang/fetcher/actions)
@@ -37,6 +37,7 @@ Fetcher 生态的 React 集成包。提供 React Hooks 和组件,实现无缝
37
37
  - [useSingleQuery Hook](#usesinglequery-hook)
38
38
  - [useCountQuery Hook](#usecountquery-hook)
39
39
  - [useListStreamQuery Hook](#useliststreamquery-hook)
40
+ - [最佳实践](#最佳实践)
40
41
  - [API 参考](#api-参考)
41
42
  - [许可证](#许可证)
42
43
 
@@ -46,6 +47,11 @@ Fetcher 生态的 React 集成包。提供 React Hooks 和组件,实现无缝
46
47
  npm install @ahoo-wang/fetcher-react
47
48
  ```
48
49
 
50
+ ### 要求
51
+
52
+ - React 16.8+ (hooks 支持)
53
+ - TypeScript 4.0+ (完整类型安全)
54
+
49
55
  ## 快速开始
50
56
 
51
57
  只需几行代码即可开始使用 `@ahoo-wang/fetcher-react`:
@@ -94,7 +100,7 @@ import { useListQuery } from '@ahoo-wang/fetcher-react';
94
100
  const MyComponent = () => {
95
101
  const { result, loading, error, execute, setCondition } = useListQuery({
96
102
  initialQuery: { condition: {}, projection: {}, sort: [], limit: 10 },
97
- list: async (listQuery) => fetchListData(listQuery),
103
+ execute: async (listQuery) => fetchListData(listQuery),
98
104
  autoExecute: true, // 在组件挂载时自动执行
99
105
  });
100
106
 
@@ -330,8 +336,8 @@ import { useListQuery } from '@ahoo-wang/fetcher-react';
330
336
  const MyComponent = () => {
331
337
  const { result, loading, error, execute, setCondition, setLimit } = useListQuery({
332
338
  initialQuery: { condition: {}, projection: {}, sort: [], limit: 10 },
333
- list: async (listQuery) => {
334
- // 您的列表获取逻辑
339
+ execute: async (listQuery) => {
340
+ // Your list fetching logic here
335
341
  return fetchListData(listQuery);
336
342
  },
337
343
  });
@@ -372,8 +378,8 @@ const MyComponent = () => {
372
378
  projection: {},
373
379
  sort: []
374
380
  },
375
- query: async (pagedQuery) => {
376
- // 您的分页获取逻辑
381
+ execute: async (pagedQuery) => {
382
+ // Your paged fetching logic here
377
383
  return fetchPagedData(pagedQuery);
378
384
  },
379
385
  });
@@ -389,7 +395,7 @@ const MyComponent = () => {
389
395
  return (
390
396
  <div>
391
397
  <ul>
392
- {result?.data?.map((item, index) => (
398
+ {result?.list?.map((item, index) => (
393
399
  <li key={index}>{item.name}</li>
394
400
  ))}
395
401
  </ul>
@@ -414,7 +420,7 @@ import { useSingleQuery } from '@ahoo-wang/fetcher-react';
414
420
  const MyComponent = () => {
415
421
  const { result, loading, error, execute, setCondition } = useSingleQuery({
416
422
  initialQuery: { condition: {}, projection: {}, sort: [] },
417
- query: async (singleQuery) => {
423
+ execute: async (singleQuery) => {
418
424
  // 您的单个获取逻辑
419
425
  return fetchSingleData(singleQuery);
420
426
  },
@@ -446,8 +452,8 @@ import { useCountQuery } from '@ahoo-wang/fetcher-react';
446
452
 
447
453
  const MyComponent = () => {
448
454
  const { result, loading, error, execute, setCondition } = useCountQuery({
449
- initialCondition: {},
450
- count: async (condition) => {
455
+ initialQuery: {},
456
+ execute: async (condition) => {
451
457
  // 您的计数获取逻辑
452
458
  return fetchCount(condition);
453
459
  },
@@ -480,7 +486,7 @@ import { useListStreamQuery } from '@ahoo-wang/fetcher-react';
480
486
  const MyComponent = () => {
481
487
  const { result, loading, error, execute, setCondition } = useListStreamQuery({
482
488
  initialQuery: { condition: {}, projection: {}, sort: [], limit: 100 },
483
- listStream: async (listQuery) => {
489
+ execute: async (listQuery) => {
484
490
  // 您的流获取逻辑
485
491
  return fetchListStream(listQuery);
486
492
  },
@@ -516,6 +522,32 @@ const MyComponent = () => {
516
522
  };
517
523
  ```
518
524
 
525
+ ## 最佳实践
526
+
527
+ ### 性能优化
528
+
529
+ - 谨慎使用 `autoExecute: true`,避免在挂载时进行不必要的请求
530
+ - 当启用 `autoExecute` 时,使用 `setQuery` 更新查询以触发自动重新执行
531
+ - 在 `execute` 函数中记忆化昂贵的计算
532
+
533
+ ### 错误处理
534
+
535
+ - 始终在组件中处理加载和错误状态
536
+ - 使用自定义错误类型以更好地分类错误
537
+ - 为瞬时故障实现重试逻辑
538
+
539
+ ### 类型安全
540
+
541
+ - 为查询参数和结果定义严格的接口
542
+ - 在整个应用程序中一致使用泛型类型
543
+ - 启用严格 TypeScript 模式以获得最大安全性
544
+
545
+ ### 状态管理
546
+
547
+ - 与全局状态管理结合使用(Redux、Zustand)以处理复杂应用
548
+ - 使用 `useKeyStorage` 进行持久化的客户端数据存储
549
+ - 实现乐观更新以改善用户体验
550
+
519
551
  ## API 参考
520
552
 
521
553
  ### useFetcher
@@ -768,7 +800,7 @@ function useCountQuery<FIELDS extends string = string, E = FetcherError>(
768
800
 
769
801
  **参数:**
770
802
 
771
- - `options`: 包含 initialConditioncount 函数的配置选项
803
+ - `options`: 包含 initialQueryexecute 函数的配置选项
772
804
  - `autoExecute`: 是否在组件挂载时自动执行查询(默认为 false)
773
805
 
774
806
  **返回值:**
@@ -1,3 +1,4 @@
1
+ import { MutableRefObject } from 'react';
1
2
  /**
2
3
  * A React hook that returns a ref containing the latest value, useful for accessing the current value in async callbacks.
3
4
  *
@@ -28,5 +29,5 @@
28
29
  * };
29
30
  * ```
30
31
  */
31
- export declare function useLatest<T>(value: T): import('react').MutableRefObject<T>;
32
+ export declare function useLatest<T>(value: T): MutableRefObject<T>;
32
33
  //# sourceMappingURL=useLatest.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useLatest.d.ts","sourceRoot":"","sources":["../../src/core/useLatest.ts"],"names":[],"mappings":"AAeA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,uCAIpC"}
1
+ {"version":3,"file":"useLatest.d.ts","sourceRoot":"","sources":["../../src/core/useLatest.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,gBAAgB,EAAU,MAAM,OAAO,CAAC;AAEjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAI1D"}
package/dist/index.es.js CHANGED
@@ -1,205 +1,206 @@
1
- import { useRef as S, useCallback as o, useEffect as m, useState as L, useMemo as b, useSyncExternalStore as p } from "react";
1
+ import { useRef as S, useCallback as u, useEffect as m, useState as L, useMemo as x, useSyncExternalStore as Q } from "react";
2
2
  import { fetcherRegistrar as F, getFetcher as M } from "@ahoo-wang/fetcher";
3
3
  function R() {
4
- const t = S(!1), s = o(() => t.current, []);
4
+ const t = S(!1), c = u(() => t.current, []);
5
5
  return m(() => (t.current = !0, () => {
6
6
  t.current = !1;
7
- }), []), s;
7
+ }), []), c;
8
8
  }
9
9
  function w(t) {
10
- const s = S(t);
11
- return s.current = t, s;
10
+ const c = S(t);
11
+ return c.current = t, c;
12
12
  }
13
13
  var O = /* @__PURE__ */ ((t) => (t.IDLE = "idle", t.LOADING = "loading", t.SUCCESS = "success", t.ERROR = "error", t))(O || {});
14
- function C(t) {
15
- const [s, e] = L(
14
+ function p(t) {
15
+ const [c, e] = L(
16
16
  t?.initialStatus ?? "idle"
17
17
  /* IDLE */
18
- ), [u, a] = L(void 0), [r, n] = L(void 0), c = R(), i = w(t), l = o(() => {
19
- c() && (e(
18
+ ), [a, o] = L(void 0), [n, s] = L(void 0), r = R(), f = w(t), i = u(() => {
19
+ r() && (e(
20
20
  "loading"
21
21
  /* LOADING */
22
- ), n(void 0));
23
- }, [c]), d = o(
24
- async (f) => {
25
- if (c()) {
26
- a(f), e(
22
+ ), s(void 0));
23
+ }, [r]), d = u(
24
+ async (l) => {
25
+ if (r()) {
26
+ o(l), e(
27
27
  "success"
28
28
  /* SUCCESS */
29
- ), n(void 0);
29
+ ), s(void 0);
30
30
  try {
31
- await i.current?.onSuccess?.(f);
31
+ await f.current?.onSuccess?.(l);
32
32
  } catch (y) {
33
33
  console.warn("PromiseState onSuccess callback error:", y);
34
34
  }
35
35
  }
36
36
  },
37
- [c, i]
38
- ), E = o(
39
- async (f) => {
40
- if (c()) {
41
- n(f), e(
37
+ [r, f]
38
+ ), E = u(
39
+ async (l) => {
40
+ if (r()) {
41
+ s(l), e(
42
42
  "error"
43
43
  /* ERROR */
44
- ), a(void 0);
44
+ ), o(void 0);
45
45
  try {
46
- await i.current?.onError?.(f);
46
+ await f.current?.onError?.(l);
47
47
  } catch (y) {
48
48
  console.warn("PromiseState onError callback error:", y);
49
49
  }
50
50
  }
51
51
  },
52
- [c, i]
53
- ), g = o(() => {
54
- c() && (e(
52
+ [r, f]
53
+ ), g = u(() => {
54
+ r() && (e(
55
55
  "idle"
56
56
  /* IDLE */
57
- ), n(void 0), a(void 0));
58
- }, [c]);
59
- return b(
57
+ ), s(void 0), o(void 0));
58
+ }, [r]);
59
+ return x(
60
60
  () => ({
61
- status: s,
62
- loading: s === "loading",
63
- result: u,
64
- error: r,
65
- setLoading: l,
61
+ status: c,
62
+ loading: c === "loading",
63
+ result: a,
64
+ error: n,
65
+ setLoading: i,
66
66
  setSuccess: d,
67
67
  setError: E,
68
68
  setIdle: g
69
69
  }),
70
- [s, u, r, l, d, E, g]
70
+ [c, a, n, i, d, E, g]
71
71
  );
72
72
  }
73
- function Q() {
74
- const t = S(0), s = o(() => ++t.current, []), e = o(() => t.current, []), u = o((n) => n === t.current, []), a = o(() => {
73
+ function C() {
74
+ const t = S(0), c = u(() => ++t.current, []), e = u(() => t.current, []), a = u((s) => s === t.current, []), o = u(() => {
75
75
  t.current++;
76
- }, []), r = o(() => {
76
+ }, []), n = u(() => {
77
77
  t.current = 0;
78
78
  }, []);
79
- return b(() => ({
80
- generate: s,
79
+ return x(() => ({
80
+ generate: c,
81
81
  current: e,
82
- isLatest: u,
83
- invalidate: a,
84
- reset: r
85
- }), [s, e, u, a, r]);
82
+ isLatest: a,
83
+ invalidate: o,
84
+ reset: n
85
+ }), [c, e, a, o, n]);
86
86
  }
87
87
  function q(t) {
88
- const { loading: s, result: e, error: u, status: a, setLoading: r, setSuccess: n, setError: c, setIdle: i } = C(t), l = R(), d = Q(), E = t?.propagateError, g = o(
88
+ const { loading: c, result: e, error: a, status: o, setLoading: n, setSuccess: s, setError: r, setIdle: f } = p(t), i = R(), d = C(), E = t?.propagateError, g = u(
89
89
  async (y) => {
90
- if (!l())
90
+ if (!i())
91
91
  throw new Error("Component is unmounted");
92
92
  const v = d.generate();
93
- r();
93
+ n();
94
94
  try {
95
95
  const I = await (typeof y == "function" ? y() : y);
96
- return l() && d.isLatest(v) && await n(I), I;
97
- } catch (x) {
98
- if (l() && d.isLatest(v) && await c(x), E)
99
- throw x;
100
- return x;
96
+ return i() && d.isLatest(v) && await s(I), I;
97
+ } catch (h) {
98
+ if (i() && d.isLatest(v) && await r(h), E)
99
+ throw h;
100
+ return h;
101
101
  }
102
102
  },
103
- [r, n, c, l, d, E]
104
- ), f = o(() => {
105
- l() && i();
106
- }, [i, l]);
107
- return b(
103
+ [n, s, r, i, d, E]
104
+ ), l = u(() => {
105
+ i() && f();
106
+ }, [f, i]);
107
+ return x(
108
108
  () => ({
109
- loading: s,
109
+ loading: c,
110
110
  result: e,
111
- error: u,
111
+ error: a,
112
112
  execute: g,
113
- reset: f,
114
- status: a
113
+ reset: l,
114
+ status: o
115
115
  }),
116
- [s, e, u, g, f, a]
116
+ [c, e, a, g, l, o]
117
117
  );
118
118
  }
119
119
  function P(t) {
120
- const s = o(
121
- (r) => t.addListener(r),
120
+ const c = u(
121
+ (n) => t.addListener(n),
122
122
  [t]
123
- ), e = o(() => t.get(), [t]), u = p(s, e, e), a = o(
124
- (r) => t.set(r),
123
+ ), e = u(() => t.get(), [t]), a = Q(c, e, e), o = u(
124
+ (n) => t.set(n),
125
125
  [t]
126
126
  );
127
- return [u, a];
127
+ return [a, o];
128
128
  }
129
129
  function G(t) {
130
- const { fetcher: s = F.default } = t || {}, e = C(t), [u, a] = L(
130
+ const { fetcher: c = F.default } = t || {}, e = p(t), [a, o] = L(
131
131
  void 0
132
- ), r = R(), n = S(), c = Q(), i = w(t), l = M(s), d = o(
132
+ ), n = R(), s = S(), r = C(), f = w(t), i = M(c), d = u(
133
133
  async (E) => {
134
- n.current && n.current.abort(), n.current = E.abortController ?? new AbortController(), E.abortController = n.current;
135
- const g = c.generate();
134
+ s.current && s.current.abort(), s.current = E.abortController ?? new AbortController(), E.abortController = s.current;
135
+ const g = r.generate();
136
136
  e.setLoading();
137
137
  try {
138
- const f = await l.exchange(
138
+ const l = await i.exchange(
139
139
  E,
140
- i.current
140
+ f.current
141
141
  );
142
- r() && c.isLatest(g) && a(f);
143
- const y = await f.extractResult();
144
- r() && c.isLatest(g) && await e.setSuccess(y);
145
- } catch (f) {
146
- if (f instanceof Error && f.name === "AbortError") {
147
- r() && e.setIdle();
142
+ n() && r.isLatest(g) && o(l);
143
+ const y = await l.extractResult();
144
+ n() && r.isLatest(g) && await e.setSuccess(y);
145
+ } catch (l) {
146
+ if (l instanceof Error && l.name === "AbortError") {
147
+ n() && e.setIdle();
148
148
  return;
149
149
  }
150
- r() && c.isLatest(g) && await e.setError(f);
150
+ n() && r.isLatest(g) && await e.setError(l);
151
151
  } finally {
152
- n.current === E.abortController && (n.current = void 0);
152
+ s.current === E.abortController && (s.current = void 0);
153
153
  }
154
154
  },
155
- [l, r, i, e, c]
155
+ [i, n, f, e, r]
156
156
  );
157
157
  return m(() => () => {
158
- n.current?.abort(), n.current = void 0;
159
- }, []), b(
158
+ s.current?.abort(), s.current = void 0;
159
+ }, []), x(
160
160
  () => ({
161
161
  ...e,
162
- exchange: u,
162
+ exchange: a,
163
163
  execute: d
164
164
  }),
165
- [e, u, d]
165
+ [e, a, d]
166
166
  );
167
167
  }
168
- function h(t) {
169
- const { initialQuery: s } = t, e = q(t), u = w(s), a = w(t), r = o(async () => a.current.execute(
170
- u.current,
171
- a.current.attributes
172
- ), [u, a]), n = o(
168
+ function b(t) {
169
+ const { initialQuery: c } = t, e = w(t), a = q(e.current), o = w(c), n = u(async () => e.current.execute(
170
+ o.current,
171
+ e.current.attributes
172
+ ), [o, e]), { execute: s } = a, r = u(() => s(n), [s, n]), f = u(() => o.current, [o]), i = u(
173
173
  (d) => {
174
- u.current = d;
174
+ o.current = d, e.current.autoExecute && r();
175
175
  },
176
- [u]
177
- ), { execute: c } = e, i = o(() => c(r), [c, r]), { autoExecute: l } = t;
176
+ [o, e, r]
177
+ );
178
178
  return m(() => {
179
- l && i();
180
- }, [l, i]), b(
179
+ e.current.autoExecute && r();
180
+ }, [e, r]), x(
181
181
  () => ({
182
- ...e,
183
- execute: i,
184
- setQuery: n
182
+ ...a,
183
+ execute: r,
184
+ getQuery: f,
185
+ setQuery: i
185
186
  }),
186
- [e, i, n]
187
+ [a, r, f, i]
187
188
  );
188
189
  }
189
190
  function K(t) {
190
- return h(t);
191
+ return b(t);
191
192
  }
192
193
  function N(t) {
193
- return h(t);
194
+ return b(t);
194
195
  }
195
196
  function U(t) {
196
- return h(t);
197
+ return b(t);
197
198
  }
198
199
  function V(t) {
199
- return h(t);
200
+ return b(t);
200
201
  }
201
202
  function j(t) {
202
- return h(
203
+ return b(
203
204
  t
204
205
  );
205
206
  }
@@ -214,9 +215,9 @@ export {
214
215
  j as useListStreamQuery,
215
216
  R as useMounted,
216
217
  K as usePagedQuery,
217
- C as usePromiseState,
218
- h as useQuery,
219
- Q as useRequestId,
218
+ p as usePromiseState,
219
+ b as useQuery,
220
+ C as useRequestId,
220
221
  N as useSingleQuery
221
222
  };
222
223
  //# sourceMappingURL=index.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../src/core/useMounted.ts","../src/core/useLatest.ts","../src/core/usePromiseState.ts","../src/core/useRequestId.ts","../src/core/useExecutePromise.ts","../src/storage/useKeyStorage.ts","../src/fetcher/useFetcher.ts","../src/wow/useQuery.ts","../src/wow/usePagedQuery.ts","../src/wow/useSingleQuery.ts","../src/wow/useCountQuery.ts","../src/wow/useListQuery.ts","../src/wow/useListStreamQuery.ts"],"sourcesContent":["/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useRef, useEffect, useCallback } from 'react';\n\n/**\n * A React hook that returns a function to check if the component is mounted.\n *\n * @returns A function that returns true if the component is mounted, false otherwise\n *\n * @example\n * ```typescript\n * import { useMounted } from '@ahoo-wang/fetcher-react';\n *\n * const MyComponent = () => {\n * const isMounted = useMounted();\n *\n * useEffect(() => {\n * someAsyncOperation().then(() => {\n * if (isMounted()) {\n * setState(result);\n * }\n * });\n * }, []);\n *\n * return <div>My Component</div>;\n * };\n * ```\n */\nexport function useMounted() {\n const isMountedRef = useRef(false);\n const isMountedFn = useCallback(() => isMountedRef.current, []);\n useEffect(() => {\n isMountedRef.current = true;\n return () => {\n isMountedRef.current = false;\n };\n }, []);\n\n return isMountedFn;\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useRef } from 'react';\n\n/**\n * A React hook that returns a ref containing the latest value, useful for accessing the current value in async callbacks.\n *\n * @template T - The type of the value\n * @param value - The value to track\n * @returns A ref object containing the latest value\n *\n * @example\n * ```typescript\n * import { useLatest } from '@ahoo-wang/fetcher-react';\n *\n * const MyComponent = () => {\n * const [count, setCount] = useState(0);\n * const latestCount = useLatest(count);\n *\n * const handleAsync = async () => {\n * await someAsyncOperation();\n * console.log('Latest count:', latestCount.current); // Always the latest\n * };\n *\n * return (\n * <div>\n * <p>Count: {count}</p>\n * <button onClick={() => setCount(c => c + 1)}>Increment</button>\n * <button onClick={handleAsync}>Async Log</button>\n * </div>\n * );\n * };\n * ```\n */\nexport function useLatest<T>(value: T) {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback, useMemo, useState } from 'react';\nimport { useMounted } from './useMounted';\nimport { useLatest } from './useLatest';\nimport { FetcherError } from '@ahoo-wang/fetcher';\n\n/**\n * Enumeration of possible promise execution states\n */\nexport enum PromiseStatus {\n IDLE = 'idle',\n LOADING = 'loading',\n SUCCESS = 'success',\n ERROR = 'error',\n}\n\nexport interface PromiseState<R, E = unknown> {\n /** Current status of the promise */\n status: PromiseStatus;\n /** Indicates if currently loading */\n loading: boolean;\n /** The result value */\n result: R | undefined;\n /** The error value */\n error: E | undefined;\n}\n\nexport interface PromiseStateCallbacks<R, E = unknown> {\n /** Callback invoked on success (can be async) */\n onSuccess?: (result: R) => void | Promise<void>;\n /** Callback invoked on error (can be async) */\n onError?: (error: E) => void | Promise<void>;\n}\n\n/**\n * Options for configuring usePromiseState behavior\n * @template R - The type of result\n *\n * @example\n * ```typescript\n * const options: UsePromiseStateOptions<string> = {\n * initialStatus: PromiseStatus.IDLE,\n * onSuccess: (result) => console.log('Success:', result),\n * onError: async (error) => {\n * await logErrorToServer(error);\n * console.error('Error:', error);\n * },\n * };\n * ```\n */\nexport interface UsePromiseStateOptions<R, E = FetcherError>\n extends PromiseStateCallbacks<R, E> {\n /** Initial status, defaults to IDLE */\n initialStatus?: PromiseStatus;\n}\n\n/**\n * Return type for usePromiseState hook\n * @template R - The type of result\n */\nexport interface UsePromiseStateReturn<R, E = FetcherError>\n extends PromiseState<R, E> {\n /** Set status to LOADING */\n setLoading: () => void;\n /** Set status to SUCCESS with result */\n setSuccess: (result: R) => Promise<void>;\n /** Set status to ERROR with error */\n setError: (error: E) => Promise<void>;\n /** Set status to IDLE */\n setIdle: () => void;\n}\n\n/**\n * A React hook for managing promise state without execution logic\n * @template R - The type of result\n * @param options - Configuration options\n * @returns State management object\n *\n * @example\n * ```typescript\n * import { usePromiseState, PromiseStatus } from '@ahoo-wang/fetcher-react';\n *\n * function MyComponent() {\n * const { status, loading, result, error, setSuccess, setError, setIdle } = usePromiseState<string>();\n *\n * const handleSuccess = () => setSuccess('Data loaded');\n * const handleError = () => setError(new Error('Failed to load'));\n *\n * return (\n * <div>\n * <button onClick={handleSuccess}>Set Success</button>\n * <button onClick={handleError}>Set Error</button>\n * <button onClick={setIdle}>Reset</button>\n * <p>Status: {status}</p>\n * {loading && <p>Loading...</p>}\n * {result && <p>Result: {result}</p>}\n * {error && <p>Error: {error.message}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function usePromiseState<R = unknown, E = FetcherError>(\n options?: UsePromiseStateOptions<R, E>,\n): UsePromiseStateReturn<R, E> {\n const [status, setStatus] = useState<PromiseStatus>(\n options?.initialStatus ?? PromiseStatus.IDLE,\n );\n const [result, setResult] = useState<R | undefined>(undefined);\n const [error, setErrorState] = useState<E | undefined>(undefined);\n const isMounted = useMounted();\n const latestOptions = useLatest(options);\n const setLoadingFn = useCallback(() => {\n if (isMounted()) {\n setStatus(PromiseStatus.LOADING);\n setErrorState(undefined);\n }\n }, [isMounted]);\n\n const setSuccessFn = useCallback(\n async (result: R) => {\n if (isMounted()) {\n setResult(result);\n setStatus(PromiseStatus.SUCCESS);\n setErrorState(undefined);\n try {\n await latestOptions.current?.onSuccess?.(result);\n } catch (callbackError) {\n // Log callback errors but don't affect state\n console.warn('PromiseState onSuccess callback error:', callbackError);\n }\n }\n },\n [isMounted, latestOptions],\n );\n\n const setErrorFn = useCallback(\n async (error: E) => {\n if (isMounted()) {\n setErrorState(error);\n setStatus(PromiseStatus.ERROR);\n setResult(undefined);\n try {\n await latestOptions.current?.onError?.(error);\n } catch (callbackError) {\n // Log callback errors but don't affect state\n console.warn('PromiseState onError callback error:', callbackError);\n }\n }\n },\n [isMounted, latestOptions],\n );\n\n const setIdleFn = useCallback(() => {\n if (isMounted()) {\n setStatus(PromiseStatus.IDLE);\n setErrorState(undefined);\n setResult(undefined);\n }\n }, [isMounted]);\n return useMemo(\n () => ({\n status,\n loading: status === PromiseStatus.LOADING,\n result,\n error,\n setLoading: setLoadingFn,\n setSuccess: setSuccessFn,\n setError: setErrorFn,\n setIdle: setIdleFn,\n }),\n [status, result, error, setLoadingFn, setSuccessFn, setErrorFn, setIdleFn],\n );\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useRef, useCallback, useMemo } from 'react';\n\n/**\n * Return type for useRequestId hook\n */\nexport interface UseRequestIdReturn {\n /** Generate a new request ID and get the current one */\n generate: () => number;\n /** Get the current request ID without generating a new one */\n current: () => number;\n /** Check if a given request ID is the latest */\n isLatest: (requestId: number) => boolean;\n /** Invalidate current request ID (mark as stale) */\n invalidate: () => void;\n /** Reset request ID counter */\n reset: () => void;\n}\n\n/**\n * A React hook for managing request IDs and race condition protection\n *\n * @example\n * ```typescript\n * // Basic usage\n * const requestId = useRequestId();\n *\n * const execute = async () => {\n * const id = requestId.generate();\n *\n * try {\n * const result = await someAsyncOperation();\n *\n * // Check if this is still the latest request\n * if (requestId.isLatest(id)) {\n * setState(result);\n * }\n * } catch (error) {\n * if (requestId.isLatest(id)) {\n * setError(error);\n * }\n * }\n * };\n *\n * // Manual cancellation\n * const handleCancel = () => {\n * requestId.invalidate(); // All ongoing requests will be ignored\n * };\n * ```\n *\n * @example\n * ```typescript\n * // With async operation wrapper\n * const { execute, cancel } = useAsyncOperation(async (data) => {\n * return await apiCall(data);\n * }, [requestId]);\n * ```\n */\nexport function useRequestId(): UseRequestIdReturn {\n const requestIdRef = useRef<number>(0);\n\n const generate = useCallback((): number => {\n return ++requestIdRef.current;\n }, []);\n\n const current = useCallback((): number => {\n return requestIdRef.current;\n }, []);\n\n const isLatest = useCallback((requestId: number): boolean => {\n return requestId === requestIdRef.current;\n }, []);\n\n const invalidate = useCallback((): void => {\n requestIdRef.current++;\n }, []);\n\n const reset = useCallback((): void => {\n requestIdRef.current = 0;\n }, []);\n return useMemo(() => {\n return {\n generate,\n current,\n isLatest,\n invalidate,\n reset,\n };\n }, [generate, current, isLatest, invalidate, reset]);\n}","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback, useMemo } from 'react';\nimport { useMounted } from './useMounted';\nimport {\n usePromiseState,\n PromiseState,\n UsePromiseStateOptions,\n} from './usePromiseState';\nimport { useRequestId } from './useRequestId';\nimport { FetcherError } from '@ahoo-wang/fetcher';\n\nexport interface UseExecutePromiseOptions<R, E = unknown>\n extends UsePromiseStateOptions<R, E> {\n /**\n * Whether to propagate errors thrown by the promise.\n * If true, the execute function will throw errors.\n * If false (default), the execute function will return the error as the result instead of throwing.\n */\n propagateError?: boolean;\n}\n\n/**\n * Type definition for a function that returns a Promise\n * @template R - The type of value the promise will resolve to\n */\nexport type PromiseSupplier<R> = () => Promise<R>;\n\n/**\n * Interface defining the return type of useExecutePromise hook\n * @template R - The type of the result value\n */\nexport interface UseExecutePromiseReturn<R, E = FetcherError>\n extends PromiseState<R, E> {\n /**\n * Function to execute a promise supplier or promise.\n * Returns a promise that resolves to the result on success, or the error if propagateError is false.\n */\n execute: (input: PromiseSupplier<R> | Promise<R>) => Promise<R | E>;\n /** Function to reset the state to initial values */\n reset: () => void;\n}\n\n/**\n * A React hook for managing asynchronous operations with proper state handling\n * @template R - The type of the result value\n * @template E - The type of the error value\n * @param options - Configuration options for the hook\n * @returns An object containing the current state and control functions\n *\n * @example\n * ```typescript\n * import { useExecutePromise } from '@ahoo-wang/fetcher-react';\n *\n * function MyComponent() {\n * const { loading, result, error, execute, reset } = useExecutePromise<string>();\n *\n * const fetchData = async () => {\n * const response = await fetch('/api/data');\n * return response.text();\n * };\n *\n * const handleFetch = () => {\n * execute(fetchData);\n * };\n *\n * const handleReset = () => {\n * reset();\n * };\n *\n * if (loading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * return (\n * <div>\n * <button onClick={handleFetch}>Fetch Data</button>\n * <button onClick={handleReset}>Reset</button>\n * {result && <p>{result}</p>}\n * </div>\n * );\n * }\n *\n * // Example with propagateError set to true\n * const { execute } = useExecutePromise<string>({ propagateError: true });\n * try {\n * await execute(fetchData);\n * } catch (err) {\n * console.error('Error occurred:', err);\n * }\n * ```\n */\nexport function useExecutePromise<R = unknown, E = FetcherError>(\n options?: UseExecutePromiseOptions<R, E>,\n): UseExecutePromiseReturn<R, E> {\n const { loading, result, error, status, setLoading, setSuccess, setError, setIdle } = usePromiseState<R, E>(options);\n const isMounted = useMounted();\n const requestId = useRequestId();\n const propagateError = options?.propagateError;\n /**\n * Execute a promise supplier or promise and manage its state\n * @param input - A function that returns a Promise or a Promise to be executed\n * @returns A Promise that resolves with the result on success, or the error if propagateError is false\n */\n const execute = useCallback(\n async (input: PromiseSupplier<R> | Promise<R>): Promise<R | E> => {\n if (!isMounted()) {\n throw new Error('Component is unmounted');\n }\n const currentRequestId = requestId.generate();\n setLoading();\n try {\n const promise = typeof input === 'function' ? input() : input;\n const data = await promise;\n\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n await setSuccess(data);\n }\n return data;\n } catch (err) {\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n await setError(err as E);\n }\n if (propagateError) {\n throw err;\n }\n return err as E;\n }\n },\n [setLoading, setSuccess, setError, isMounted, requestId, propagateError],\n );\n\n /**\n * Reset the state to initial values\n */\n const reset = useCallback(() => {\n if (isMounted()) {\n setIdle();\n }\n }, [setIdle, isMounted]);\n\n return useMemo(\n () => ({\n loading: loading,\n result: result,\n error: error,\n execute,\n reset,\n status: status,\n }),\n [loading, result, error, execute, reset, status],\n );\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback, useSyncExternalStore } from 'react';\nimport { KeyStorage } from '@ahoo-wang/fetcher-storage';\n\n/**\n * A React hook that provides state management for a KeyStorage instance.\n * Subscribes to storage changes and returns the current value along with a setter function.\n *\n * @template T - The type of value stored in the key storage\n * @param keyStorage - The KeyStorage instance to subscribe to and manage\n * @returns A tuple containing the current stored value and a function to update it\n */\nexport function useKeyStorage<T>(\n keyStorage: KeyStorage<T>,\n): [T | null, (value: T) => void] {\n const subscribe = useCallback(\n (callback: () => void) => keyStorage.addListener(callback),\n [keyStorage],\n );\n const getSnapshot = useCallback(() => keyStorage.get(), [keyStorage]);\n const value = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n const setValue = useCallback(\n (value: T) => keyStorage.set(value),\n [keyStorage],\n );\n return [value, setValue];\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n fetcherRegistrar,\n FetcherCapable,\n FetchExchange,\n FetchRequest,\n getFetcher,\n RequestOptions, FetcherError,\n} from '@ahoo-wang/fetcher';\nimport { useMounted } from '../core';\nimport { useRef, useCallback, useEffect, useState, useMemo } from 'react';\nimport {\n PromiseState,\n useLatest,\n usePromiseState,\n UsePromiseStateOptions,\n useRequestId,\n} from '../core';\n\n/**\n * Configuration options for the useFetcher hook.\n * Extends RequestOptions and FetcherCapable interfaces.\n */\nexport interface UseFetcherOptions<R, E = FetcherError>\n extends RequestOptions,\n FetcherCapable,\n UsePromiseStateOptions<R, E> {\n}\n\nexport interface UseFetcherReturn<R, E = FetcherError> extends PromiseState<R, E> {\n /** The FetchExchange object representing the ongoing fetch operation */\n exchange?: FetchExchange;\n execute: (request: FetchRequest) => Promise<void>;\n}\n\n/**\n * A React hook for managing asynchronous operations with proper state handling\n * @param options - Configuration options for the fetcher\n * @returns An object containing the current state and control functions\n *\n * @example\n * ```typescript\n * import { useFetcher } from '@ahoo-wang/fetcher-react';\n *\n * function MyComponent() {\n * const { loading, result, error, execute } = useFetcher<string>();\n *\n * const handleFetch = () => {\n * execute({ url: '/api/data', method: 'GET' });\n * };\n *\n * if (loading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * return (\n * <div>\n * <button onClick={handleFetch}>Fetch Data</button>\n * {result && <p>{result}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function useFetcher<R, E = FetcherError>(\n options?: UseFetcherOptions<R, E>,\n): UseFetcherReturn<R, E> {\n const { fetcher = fetcherRegistrar.default } = options || {};\n const state = usePromiseState<R, E>(options);\n const [exchange, setExchange] = useState<FetchExchange | undefined>(\n undefined,\n );\n const isMounted = useMounted();\n const abortControllerRef = useRef<AbortController | undefined>();\n const requestId = useRequestId();\n const latestOptions = useLatest(options);\n const currentFetcher = getFetcher(fetcher);\n /**\n * Execute the fetch operation.\n * Cancels any ongoing fetch before starting a new one.\n */\n const execute = useCallback(\n async (request: FetchRequest) => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n abortControllerRef.current =\n request.abortController ?? new AbortController();\n request.abortController = abortControllerRef.current;\n const currentRequestId = requestId.generate();\n state.setLoading();\n try {\n const exchange = await currentFetcher.exchange(\n request,\n latestOptions.current,\n );\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n setExchange(exchange);\n }\n const result = await exchange.extractResult<R>();\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n await state.setSuccess(result);\n }\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n if (isMounted()) {\n state.setIdle();\n }\n return;\n }\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n await state.setError(error as E);\n }\n } finally {\n if (abortControllerRef.current === request.abortController) {\n abortControllerRef.current = undefined;\n }\n }\n },\n [currentFetcher, isMounted, latestOptions, state, requestId],\n );\n\n useEffect(() => {\n return () => {\n abortControllerRef.current?.abort();\n abortControllerRef.current = undefined;\n };\n }, []);\n return useMemo(\n () => ({\n ...state,\n exchange,\n execute,\n }),\n [state, exchange, execute],\n );\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n useExecutePromise,\n useLatest,\n UseExecutePromiseReturn,\n UseExecutePromiseOptions,\n} from '../core';\nimport { useCallback, useMemo, useEffect } from 'react';\nimport { AttributesCapable, FetcherError } from '@ahoo-wang/fetcher';\nimport { AutoExecuteCapable } from './types';\n\n/**\n * Configuration options for the useQuery hook\n * @template Q - The type of the query parameters\n * @template R - The type of the result value\n * @template E - The type of the error value\n */\nexport interface UseQueryOptions<Q, R, E = FetcherError>\n extends UseExecutePromiseOptions<R, E>,\n AttributesCapable,\n AutoExecuteCapable {\n /** The initial query parameters */\n initialQuery: Q;\n\n /** Function to execute the query with given parameters and optional attributes */\n execute: (query: Q, attributes?: Record<string, any>) => Promise<R>;\n}\n\n/**\n * Return type of the useQuery hook\n * @template Q - The type of the query parameters\n * @template R - The type of the result value\n * @template E - The type of the error value\n */\nexport interface UseQueryReturn<Q, R, E = FetcherError>\n extends UseExecutePromiseReturn<R, E> {\n /** Function to execute the query with current parameters */\n execute: () => Promise<R | E>;\n /** Function to update the query parameters */\n setQuery: (query: Q) => void;\n}\n\n/**\n * A React hook for managing query-based asynchronous operations\n * @template Q - The type of the query parameters\n * @template R - The type of the result value\n * @template E - The type of the error value\n * @param options - Configuration options for the query\n * @returns An object containing the query state and control functions\n *\n * @example\n * ```typescript\n * import { useQuery } from '@ahoo-wang/fetcher-react';\n *\n * interface UserQuery {\n * id: string;\n * }\n *\n * interface User {\n * id: string;\n * name: string;\n * }\n *\n * function UserComponent() {\n * const { loading, result, error, execute, setQuery } = useQuery<UserQuery, User>({\n * initialQuery: { id: '1' },\n * execute: async (query) => {\n * const response = await fetch(`/api/users/${query.id}`);\n * return response.json();\n * },\n * autoExecute: true,\n * });\n *\n * const handleUserChange = (userId: string) => {\n * setQuery({ id: userId });\n * execute();\n * };\n *\n * if (loading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * return (\n * <div>\n * <button onClick={() => handleUserChange('2')}>Load User 2</button>\n * {result && <p>User: {result.name}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function useQuery<Q, R, E = FetcherError>(\n options: UseQueryOptions<Q, R, E>,\n): UseQueryReturn<Q, R, E> {\n const { initialQuery } = options;\n const promiseState = useExecutePromise<R, E>(options);\n const latestQuery = useLatest(initialQuery);\n const latestOptions = useLatest(options);\n const queryExecutor = useCallback(async (): Promise<R> => {\n return latestOptions.current.execute(\n latestQuery.current,\n latestOptions.current.attributes,\n );\n }, [latestQuery, latestOptions]);\n const setQuery = useCallback(\n (query: Q) => {\n latestQuery.current = query;\n },\n [latestQuery],\n );\n const { execute: promiseExecutor } = promiseState;\n const execute = useCallback(() => {\n return promiseExecutor(queryExecutor);\n }, [promiseExecutor, queryExecutor]);\n\n const { autoExecute } = options;\n\n useEffect(() => {\n if (autoExecute) {\n execute();\n }\n }, [autoExecute, execute]);\n\n return useMemo(\n () => ({\n ...promiseState,\n execute,\n setQuery,\n }),\n [promiseState, execute, setQuery],\n );\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { PagedList, PagedQuery } from '@ahoo-wang/fetcher-wow';\nimport { FetcherError } from '@ahoo-wang/fetcher';\nimport { useQuery, UseQueryOptions, UseQueryReturn } from './useQuery';\n\n/**\n * Options for the usePagedQuery hook.\n * Extends UseQueryOptions with PagedQuery as query key and PagedList as data type.\n *\n * @template R - The type of the result items in the paged list\n * @template FIELDS - The fields type for the paged query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UsePagedQueryOptions<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryOptions<PagedQuery<FIELDS>, PagedList<R>, E> {\n}\n\n/**\n * Return type for the usePagedQuery hook.\n * Extends UseQueryReturn with PagedQuery as query key and PagedList as data type.\n *\n * @template R - The type of the result items in the paged list\n * @template FIELDS - The fields type for the paged query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UsePagedQueryReturn<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryReturn<PagedQuery<FIELDS>, PagedList<R>, E> {\n}\n\n/**\n * Hook for querying paged data with conditions, projection, pagination, and sorting.\n * Wraps useQuery to provide type-safe paged queries.\n *\n * @template R - The type of the result items in the paged list\n * @template FIELDS - The fields type for the paged query\n * @template E - The error type, defaults to FetcherError\n * @param options - The query options including paged query configuration\n * @returns The query result with paged list data\n *\n * @example\n * ```typescript\n * const { data, isLoading } = usePagedQuery<{ id: number; name: string }, 'id' | 'name'>({\n * initialQuery: {\n * condition: all(),\n * pagination: { index: 1, size: 10 },\n * projection: { include: ['id', 'name'] },\n * sort: [{ field: 'id', direction: SortDirection.ASC }],\n * },\n * execute: async (query) => fetchPagedData(query),\n * });\n * ```\n */\nexport function usePagedQuery<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n>(\n options: UsePagedQueryOptions<R, FIELDS, E>,\n): UsePagedQueryReturn<R, FIELDS, E> {\n return useQuery<PagedQuery<FIELDS>, PagedList<R>, E>(options);\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { SingleQuery } from '@ahoo-wang/fetcher-wow';\nimport { FetcherError } from '@ahoo-wang/fetcher';\nimport { useQuery, UseQueryOptions, UseQueryReturn } from './useQuery';\n\n/**\n * Options for the useSingleQuery hook.\n * Extends UseQueryOptions with SingleQuery as query key and custom result type.\n *\n * @template R - The result type of the query\n * @template FIELDS - The fields type for the single query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseSingleQueryOptions<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryOptions<SingleQuery<FIELDS>, R, E> {\n}\n\n/**\n * Return type for the useSingleQuery hook.\n * Extends UseQueryReturn with SingleQuery as query key and custom result type.\n *\n * @template R - The result type of the query\n * @template FIELDS - The fields type for the single query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseSingleQueryReturn<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryReturn<SingleQuery<FIELDS>, R, E> {\n}\n\n/**\n * Hook for querying a single item with conditions, projection, and sorting.\n * Wraps useQuery to provide type-safe single item queries.\n *\n * @template R - The result type of the query\n * @template FIELDS - The fields type for the single query\n * @template E - The error type, defaults to FetcherError\n * @param options - The query options including single query configuration\n * @returns The query result with single item data\n *\n * @example\n * ```typescript\n * const { data, isLoading } = useSingleQuery<{ id: number; name: string }, 'id' | 'name'>({\n * initialQuery: {\n * condition: all(),\n * projection: { include: ['id', 'name'] },\n * sort: [{ field: 'id', direction: SortDirection.ASC }],\n * },\n * execute: async (query) => fetchSingleItem(query),\n * });\n * ```\n */\nexport function useSingleQuery<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n>(\n options: UseSingleQueryOptions<R, FIELDS, E>,\n): UseSingleQueryReturn<R, FIELDS, E> {\n return useQuery<SingleQuery<FIELDS>, R, E>(options);\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Condition } from '@ahoo-wang/fetcher-wow';\nimport { FetcherError } from '@ahoo-wang/fetcher';\nimport { useQuery, UseQueryOptions, UseQueryReturn } from './useQuery';\n\n/**\n * Options for the useCountQuery hook.\n * Extends UseQueryOptions with Condition as query key and number as data type.\n *\n * @template FIELDS - The fields type for the condition\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseCountQueryOptions<\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryOptions<Condition<FIELDS>, number, E> {\n}\n\n/**\n * Return type for the useCountQuery hook.\n * Extends UseQueryReturn with Condition as query key and number as data type.\n *\n * @template FIELDS - The fields type for the condition\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseCountQueryReturn<\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryReturn<Condition<FIELDS>, number, E> {\n}\n\n/**\n * Hook for querying count data with conditions.\n * Wraps useQuery to provide type-safe count queries.\n *\n * @template FIELDS - The fields type for the condition\n * @template E - The error type, defaults to FetcherError\n * @param options - The query options including condition and other settings\n * @returns The query result with count data\n *\n * @example\n * ```typescript\n * const { data, isLoading } = useCountQuery({\n * queryKey: [{ field: 'status', operator: 'eq', value: 'active' }],\n * queryFn: async (condition) => fetchCount(condition),\n * });\n * ```\n */\nexport function useCountQuery<FIELDS extends string = string, E = FetcherError>(\n options: UseCountQueryOptions<FIELDS, E>,\n): UseCountQueryReturn<FIELDS, E> {\n return useQuery(options);\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ListQuery } from '@ahoo-wang/fetcher-wow';\nimport { FetcherError } from '@ahoo-wang/fetcher';\nimport { useQuery, UseQueryOptions, UseQueryReturn } from './useQuery';\n\n/**\n * Options for the useListQuery hook.\n * Extends UseQueryOptions with ListQuery as query key and array of results as data type.\n *\n * @template R - The type of the result items in the list\n * @template FIELDS - The fields type for the list query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseListQueryOptions<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryOptions<ListQuery<FIELDS>, R[], E> {\n}\n\n/**\n * Return type for the useListQuery hook.\n * Extends UseQueryReturn with ListQuery as query key and array of results as data type.\n *\n * @template R - The type of the result items in the list\n * @template FIELDS - The fields type for the list query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseListQueryReturn<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryReturn<ListQuery<FIELDS>, R[], E> {\n}\n\n/**\n * Hook for querying list data with conditions, projection, and sorting.\n * Wraps useQuery to provide type-safe list queries.\n *\n * @template R - The type of the result items in the list\n * @template FIELDS - The fields type for the list query\n * @template E - The error type, defaults to FetcherError\n * @param options - The query options including list query configuration\n * @returns The query result with list data\n *\n * @example\n * ```typescript\n * const { data, isLoading } = useListQuery<{ id: number; name: string }, 'id' | 'name'>({\n * initialQuery: {\n * condition: all(),\n * projection: { include: ['id', 'name'] },\n * sort: [{ field: 'id', direction: SortDirection.ASC }],\n * },\n * execute: async (query) => fetchListData(query),\n * });\n * ```\n */\nexport function useListQuery<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n>(\n options: UseListQueryOptions<R, FIELDS, E>,\n): UseListQueryReturn<R, FIELDS, E> {\n return useQuery<ListQuery<FIELDS>, R[], E>(options);\n}","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ListQuery } from '@ahoo-wang/fetcher-wow';\nimport type { JsonServerSentEvent } from '@ahoo-wang/fetcher-eventstream';\nimport { FetcherError } from '@ahoo-wang/fetcher';\nimport { useQuery, UseQueryOptions, UseQueryReturn } from './useQuery';\n\n/**\n * Options for the useListStreamQuery hook.\n * Extends UseQueryOptions with ListQuery as query key and stream of events as data type.\n *\n * @template R - The type of the result items in the stream events\n * @template FIELDS - The fields type for the list stream query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseListStreamQueryOptions<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryOptions<\n ListQuery<FIELDS>,\n ReadableStream<JsonServerSentEvent<R>>,\n E\n> {\n}\n\n/**\n * Return type for the useListStreamQuery hook.\n * Extends UseQueryReturn with ListQuery as query key and stream of events as data type.\n *\n * @template R - The type of the result items in the stream events\n * @template FIELDS - The fields type for the list stream query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseListStreamQueryReturn<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryReturn<\n ListQuery<FIELDS>,\n ReadableStream<JsonServerSentEvent<R>>,\n E\n> {\n}\n\n/**\n * Hook for querying streaming list data with conditions, projection, and sorting.\n * Wraps useQuery to provide type-safe streaming list queries.\n *\n * @template R - The type of the result items in the stream events\n * @template FIELDS - The fields type for the list stream query\n * @template E - The error type, defaults to FetcherError\n * @param options - The query options including list stream query configuration\n * @returns The query result with streaming data\n *\n * @example\n * ```typescript\n * const { data, isLoading } = useListStreamQuery<{ id: number; name: string }, 'id' | 'name'>({\n * initialQuery: {\n * condition: all(),\n * projection: { include: ['id', 'name'] },\n * sort: [{ field: 'id', direction: SortDirection.ASC }],\n * },\n * execute: async (query) => fetchStreamData(query),\n * });\n * ```\n */\nexport function useListStreamQuery<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n>(\n options: UseListStreamQueryOptions<R, FIELDS, E>,\n): UseListStreamQueryReturn<R, FIELDS, E> {\n return useQuery<ListQuery<FIELDS>, ReadableStream<JsonServerSentEvent<R>>, E>(\n options,\n );\n}\n"],"names":["useMounted","isMountedRef","useRef","isMountedFn","useCallback","useEffect","useLatest","value","ref","PromiseStatus","usePromiseState","options","status","setStatus","useState","result","setResult","error","setErrorState","isMounted","latestOptions","setLoadingFn","setSuccessFn","callbackError","setErrorFn","setIdleFn","useMemo","useRequestId","requestIdRef","generate","current","isLatest","requestId","invalidate","reset","useExecutePromise","loading","setLoading","setSuccess","setError","setIdle","propagateError","execute","input","currentRequestId","data","err","useKeyStorage","keyStorage","subscribe","callback","getSnapshot","useSyncExternalStore","setValue","useFetcher","fetcher","fetcherRegistrar","state","exchange","setExchange","abortControllerRef","currentFetcher","getFetcher","request","useQuery","initialQuery","promiseState","latestQuery","queryExecutor","setQuery","query","promiseExecutor","autoExecute","usePagedQuery","useSingleQuery","useCountQuery","useListQuery","useListStreamQuery"],"mappings":"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"}
1
+ {"version":3,"file":"index.es.js","sources":["../src/core/useMounted.ts","../src/core/useLatest.ts","../src/core/usePromiseState.ts","../src/core/useRequestId.ts","../src/core/useExecutePromise.ts","../src/storage/useKeyStorage.ts","../src/fetcher/useFetcher.ts","../src/wow/useQuery.ts","../src/wow/usePagedQuery.ts","../src/wow/useSingleQuery.ts","../src/wow/useCountQuery.ts","../src/wow/useListQuery.ts","../src/wow/useListStreamQuery.ts"],"sourcesContent":["/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useRef, useEffect, useCallback } from 'react';\n\n/**\n * A React hook that returns a function to check if the component is mounted.\n *\n * @returns A function that returns true if the component is mounted, false otherwise\n *\n * @example\n * ```typescript\n * import { useMounted } from '@ahoo-wang/fetcher-react';\n *\n * const MyComponent = () => {\n * const isMounted = useMounted();\n *\n * useEffect(() => {\n * someAsyncOperation().then(() => {\n * if (isMounted()) {\n * setState(result);\n * }\n * });\n * }, []);\n *\n * return <div>My Component</div>;\n * };\n * ```\n */\nexport function useMounted() {\n const isMountedRef = useRef(false);\n const isMountedFn = useCallback(() => isMountedRef.current, []);\n useEffect(() => {\n isMountedRef.current = true;\n return () => {\n isMountedRef.current = false;\n };\n }, []);\n\n return isMountedFn;\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { MutableRefObject, useRef } from 'react';\n\n/**\n * A React hook that returns a ref containing the latest value, useful for accessing the current value in async callbacks.\n *\n * @template T - The type of the value\n * @param value - The value to track\n * @returns A ref object containing the latest value\n *\n * @example\n * ```typescript\n * import { useLatest } from '@ahoo-wang/fetcher-react';\n *\n * const MyComponent = () => {\n * const [count, setCount] = useState(0);\n * const latestCount = useLatest(count);\n *\n * const handleAsync = async () => {\n * await someAsyncOperation();\n * console.log('Latest count:', latestCount.current); // Always the latest\n * };\n *\n * return (\n * <div>\n * <p>Count: {count}</p>\n * <button onClick={() => setCount(c => c + 1)}>Increment</button>\n * <button onClick={handleAsync}>Async Log</button>\n * </div>\n * );\n * };\n * ```\n */\nexport function useLatest<T>(value: T): MutableRefObject<T> {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback, useMemo, useState } from 'react';\nimport { useMounted } from './useMounted';\nimport { useLatest } from './useLatest';\nimport { FetcherError } from '@ahoo-wang/fetcher';\n\n/**\n * Enumeration of possible promise execution states\n */\nexport enum PromiseStatus {\n IDLE = 'idle',\n LOADING = 'loading',\n SUCCESS = 'success',\n ERROR = 'error',\n}\n\nexport interface PromiseState<R, E = unknown> {\n /** Current status of the promise */\n status: PromiseStatus;\n /** Indicates if currently loading */\n loading: boolean;\n /** The result value */\n result: R | undefined;\n /** The error value */\n error: E | undefined;\n}\n\nexport interface PromiseStateCallbacks<R, E = unknown> {\n /** Callback invoked on success (can be async) */\n onSuccess?: (result: R) => void | Promise<void>;\n /** Callback invoked on error (can be async) */\n onError?: (error: E) => void | Promise<void>;\n}\n\n/**\n * Options for configuring usePromiseState behavior\n * @template R - The type of result\n *\n * @example\n * ```typescript\n * const options: UsePromiseStateOptions<string> = {\n * initialStatus: PromiseStatus.IDLE,\n * onSuccess: (result) => console.log('Success:', result),\n * onError: async (error) => {\n * await logErrorToServer(error);\n * console.error('Error:', error);\n * },\n * };\n * ```\n */\nexport interface UsePromiseStateOptions<R, E = FetcherError>\n extends PromiseStateCallbacks<R, E> {\n /** Initial status, defaults to IDLE */\n initialStatus?: PromiseStatus;\n}\n\n/**\n * Return type for usePromiseState hook\n * @template R - The type of result\n */\nexport interface UsePromiseStateReturn<R, E = FetcherError>\n extends PromiseState<R, E> {\n /** Set status to LOADING */\n setLoading: () => void;\n /** Set status to SUCCESS with result */\n setSuccess: (result: R) => Promise<void>;\n /** Set status to ERROR with error */\n setError: (error: E) => Promise<void>;\n /** Set status to IDLE */\n setIdle: () => void;\n}\n\n/**\n * A React hook for managing promise state without execution logic\n * @template R - The type of result\n * @param options - Configuration options\n * @returns State management object\n *\n * @example\n * ```typescript\n * import { usePromiseState, PromiseStatus } from '@ahoo-wang/fetcher-react';\n *\n * function MyComponent() {\n * const { status, loading, result, error, setSuccess, setError, setIdle } = usePromiseState<string>();\n *\n * const handleSuccess = () => setSuccess('Data loaded');\n * const handleError = () => setError(new Error('Failed to load'));\n *\n * return (\n * <div>\n * <button onClick={handleSuccess}>Set Success</button>\n * <button onClick={handleError}>Set Error</button>\n * <button onClick={setIdle}>Reset</button>\n * <p>Status: {status}</p>\n * {loading && <p>Loading...</p>}\n * {result && <p>Result: {result}</p>}\n * {error && <p>Error: {error.message}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function usePromiseState<R = unknown, E = FetcherError>(\n options?: UsePromiseStateOptions<R, E>,\n): UsePromiseStateReturn<R, E> {\n const [status, setStatus] = useState<PromiseStatus>(\n options?.initialStatus ?? PromiseStatus.IDLE,\n );\n const [result, setResult] = useState<R | undefined>(undefined);\n const [error, setErrorState] = useState<E | undefined>(undefined);\n const isMounted = useMounted();\n const latestOptions = useLatest(options);\n const setLoadingFn = useCallback(() => {\n if (isMounted()) {\n setStatus(PromiseStatus.LOADING);\n setErrorState(undefined);\n }\n }, [isMounted]);\n\n const setSuccessFn = useCallback(\n async (result: R) => {\n if (isMounted()) {\n setResult(result);\n setStatus(PromiseStatus.SUCCESS);\n setErrorState(undefined);\n try {\n await latestOptions.current?.onSuccess?.(result);\n } catch (callbackError) {\n // Log callback errors but don't affect state\n console.warn('PromiseState onSuccess callback error:', callbackError);\n }\n }\n },\n [isMounted, latestOptions],\n );\n\n const setErrorFn = useCallback(\n async (error: E) => {\n if (isMounted()) {\n setErrorState(error);\n setStatus(PromiseStatus.ERROR);\n setResult(undefined);\n try {\n await latestOptions.current?.onError?.(error);\n } catch (callbackError) {\n // Log callback errors but don't affect state\n console.warn('PromiseState onError callback error:', callbackError);\n }\n }\n },\n [isMounted, latestOptions],\n );\n\n const setIdleFn = useCallback(() => {\n if (isMounted()) {\n setStatus(PromiseStatus.IDLE);\n setErrorState(undefined);\n setResult(undefined);\n }\n }, [isMounted]);\n return useMemo(\n () => ({\n status,\n loading: status === PromiseStatus.LOADING,\n result,\n error,\n setLoading: setLoadingFn,\n setSuccess: setSuccessFn,\n setError: setErrorFn,\n setIdle: setIdleFn,\n }),\n [status, result, error, setLoadingFn, setSuccessFn, setErrorFn, setIdleFn],\n );\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useRef, useCallback, useMemo } from 'react';\n\n/**\n * Return type for useRequestId hook\n */\nexport interface UseRequestIdReturn {\n /** Generate a new request ID and get the current one */\n generate: () => number;\n /** Get the current request ID without generating a new one */\n current: () => number;\n /** Check if a given request ID is the latest */\n isLatest: (requestId: number) => boolean;\n /** Invalidate current request ID (mark as stale) */\n invalidate: () => void;\n /** Reset request ID counter */\n reset: () => void;\n}\n\n/**\n * A React hook for managing request IDs and race condition protection\n *\n * @example\n * ```typescript\n * // Basic usage\n * const requestId = useRequestId();\n *\n * const execute = async () => {\n * const id = requestId.generate();\n *\n * try {\n * const result = await someAsyncOperation();\n *\n * // Check if this is still the latest request\n * if (requestId.isLatest(id)) {\n * setState(result);\n * }\n * } catch (error) {\n * if (requestId.isLatest(id)) {\n * setError(error);\n * }\n * }\n * };\n *\n * // Manual cancellation\n * const handleCancel = () => {\n * requestId.invalidate(); // All ongoing requests will be ignored\n * };\n * ```\n *\n * @example\n * ```typescript\n * // With async operation wrapper\n * const { execute, cancel } = useAsyncOperation(async (data) => {\n * return await apiCall(data);\n * }, [requestId]);\n * ```\n */\nexport function useRequestId(): UseRequestIdReturn {\n const requestIdRef = useRef<number>(0);\n\n const generate = useCallback((): number => {\n return ++requestIdRef.current;\n }, []);\n\n const current = useCallback((): number => {\n return requestIdRef.current;\n }, []);\n\n const isLatest = useCallback((requestId: number): boolean => {\n return requestId === requestIdRef.current;\n }, []);\n\n const invalidate = useCallback((): void => {\n requestIdRef.current++;\n }, []);\n\n const reset = useCallback((): void => {\n requestIdRef.current = 0;\n }, []);\n return useMemo(() => {\n return {\n generate,\n current,\n isLatest,\n invalidate,\n reset,\n };\n }, [generate, current, isLatest, invalidate, reset]);\n}","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback, useMemo } from 'react';\nimport { useMounted } from './useMounted';\nimport {\n usePromiseState,\n PromiseState,\n UsePromiseStateOptions,\n} from './usePromiseState';\nimport { useRequestId } from './useRequestId';\nimport { FetcherError } from '@ahoo-wang/fetcher';\n\nexport interface UseExecutePromiseOptions<R, E = unknown>\n extends UsePromiseStateOptions<R, E> {\n /**\n * Whether to propagate errors thrown by the promise.\n * If true, the execute function will throw errors.\n * If false (default), the execute function will return the error as the result instead of throwing.\n */\n propagateError?: boolean;\n}\n\n/**\n * Type definition for a function that returns a Promise\n * @template R - The type of value the promise will resolve to\n */\nexport type PromiseSupplier<R> = () => Promise<R>;\n\n/**\n * Interface defining the return type of useExecutePromise hook\n * @template R - The type of the result value\n */\nexport interface UseExecutePromiseReturn<R, E = FetcherError>\n extends PromiseState<R, E> {\n /**\n * Function to execute a promise supplier or promise.\n * Returns a promise that resolves to the result on success, or the error if propagateError is false.\n */\n execute: (input: PromiseSupplier<R> | Promise<R>) => Promise<R | E>;\n /** Function to reset the state to initial values */\n reset: () => void;\n}\n\n/**\n * A React hook for managing asynchronous operations with proper state handling\n * @template R - The type of the result value\n * @template E - The type of the error value\n * @param options - Configuration options for the hook\n * @returns An object containing the current state and control functions\n *\n * @example\n * ```typescript\n * import { useExecutePromise } from '@ahoo-wang/fetcher-react';\n *\n * function MyComponent() {\n * const { loading, result, error, execute, reset } = useExecutePromise<string>();\n *\n * const fetchData = async () => {\n * const response = await fetch('/api/data');\n * return response.text();\n * };\n *\n * const handleFetch = () => {\n * execute(fetchData);\n * };\n *\n * const handleReset = () => {\n * reset();\n * };\n *\n * if (loading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * return (\n * <div>\n * <button onClick={handleFetch}>Fetch Data</button>\n * <button onClick={handleReset}>Reset</button>\n * {result && <p>{result}</p>}\n * </div>\n * );\n * }\n *\n * // Example with propagateError set to true\n * const { execute } = useExecutePromise<string>({ propagateError: true });\n * try {\n * await execute(fetchData);\n * } catch (err) {\n * console.error('Error occurred:', err);\n * }\n * ```\n */\nexport function useExecutePromise<R = unknown, E = FetcherError>(\n options?: UseExecutePromiseOptions<R, E>,\n): UseExecutePromiseReturn<R, E> {\n const { loading, result, error, status, setLoading, setSuccess, setError, setIdle } = usePromiseState<R, E>(options);\n const isMounted = useMounted();\n const requestId = useRequestId();\n const propagateError = options?.propagateError;\n /**\n * Execute a promise supplier or promise and manage its state\n * @param input - A function that returns a Promise or a Promise to be executed\n * @returns A Promise that resolves with the result on success, or the error if propagateError is false\n */\n const execute = useCallback(\n async (input: PromiseSupplier<R> | Promise<R>): Promise<R | E> => {\n if (!isMounted()) {\n throw new Error('Component is unmounted');\n }\n const currentRequestId = requestId.generate();\n setLoading();\n try {\n const promise = typeof input === 'function' ? input() : input;\n const data = await promise;\n\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n await setSuccess(data);\n }\n return data;\n } catch (err) {\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n await setError(err as E);\n }\n if (propagateError) {\n throw err;\n }\n return err as E;\n }\n },\n [setLoading, setSuccess, setError, isMounted, requestId, propagateError],\n );\n\n /**\n * Reset the state to initial values\n */\n const reset = useCallback(() => {\n if (isMounted()) {\n setIdle();\n }\n }, [setIdle, isMounted]);\n\n return useMemo(\n () => ({\n loading: loading,\n result: result,\n error: error,\n execute,\n reset,\n status: status,\n }),\n [loading, result, error, execute, reset, status],\n );\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback, useSyncExternalStore } from 'react';\nimport { KeyStorage } from '@ahoo-wang/fetcher-storage';\n\n/**\n * A React hook that provides state management for a KeyStorage instance.\n * Subscribes to storage changes and returns the current value along with a setter function.\n *\n * @template T - The type of value stored in the key storage\n * @param keyStorage - The KeyStorage instance to subscribe to and manage\n * @returns A tuple containing the current stored value and a function to update it\n */\nexport function useKeyStorage<T>(\n keyStorage: KeyStorage<T>,\n): [T | null, (value: T) => void] {\n const subscribe = useCallback(\n (callback: () => void) => keyStorage.addListener(callback),\n [keyStorage],\n );\n const getSnapshot = useCallback(() => keyStorage.get(), [keyStorage]);\n const value = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n const setValue = useCallback(\n (value: T) => keyStorage.set(value),\n [keyStorage],\n );\n return [value, setValue];\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n fetcherRegistrar,\n FetcherCapable,\n FetchExchange,\n FetchRequest,\n getFetcher,\n RequestOptions, FetcherError,\n} from '@ahoo-wang/fetcher';\nimport { useMounted } from '../core';\nimport { useRef, useCallback, useEffect, useState, useMemo } from 'react';\nimport {\n PromiseState,\n useLatest,\n usePromiseState,\n UsePromiseStateOptions,\n useRequestId,\n} from '../core';\n\n/**\n * Configuration options for the useFetcher hook.\n * Extends RequestOptions and FetcherCapable interfaces.\n */\nexport interface UseFetcherOptions<R, E = FetcherError>\n extends RequestOptions,\n FetcherCapable,\n UsePromiseStateOptions<R, E> {\n}\n\nexport interface UseFetcherReturn<R, E = FetcherError> extends PromiseState<R, E> {\n /** The FetchExchange object representing the ongoing fetch operation */\n exchange?: FetchExchange;\n execute: (request: FetchRequest) => Promise<void>;\n}\n\n/**\n * A React hook for managing asynchronous operations with proper state handling\n * @param options - Configuration options for the fetcher\n * @returns An object containing the current state and control functions\n *\n * @example\n * ```typescript\n * import { useFetcher } from '@ahoo-wang/fetcher-react';\n *\n * function MyComponent() {\n * const { loading, result, error, execute } = useFetcher<string>();\n *\n * const handleFetch = () => {\n * execute({ url: '/api/data', method: 'GET' });\n * };\n *\n * if (loading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * return (\n * <div>\n * <button onClick={handleFetch}>Fetch Data</button>\n * {result && <p>{result}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function useFetcher<R, E = FetcherError>(\n options?: UseFetcherOptions<R, E>,\n): UseFetcherReturn<R, E> {\n const { fetcher = fetcherRegistrar.default } = options || {};\n const state = usePromiseState<R, E>(options);\n const [exchange, setExchange] = useState<FetchExchange | undefined>(\n undefined,\n );\n const isMounted = useMounted();\n const abortControllerRef = useRef<AbortController | undefined>();\n const requestId = useRequestId();\n const latestOptions = useLatest(options);\n const currentFetcher = getFetcher(fetcher);\n /**\n * Execute the fetch operation.\n * Cancels any ongoing fetch before starting a new one.\n */\n const execute = useCallback(\n async (request: FetchRequest) => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n abortControllerRef.current =\n request.abortController ?? new AbortController();\n request.abortController = abortControllerRef.current;\n const currentRequestId = requestId.generate();\n state.setLoading();\n try {\n const exchange = await currentFetcher.exchange(\n request,\n latestOptions.current,\n );\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n setExchange(exchange);\n }\n const result = await exchange.extractResult<R>();\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n await state.setSuccess(result);\n }\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n if (isMounted()) {\n state.setIdle();\n }\n return;\n }\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n await state.setError(error as E);\n }\n } finally {\n if (abortControllerRef.current === request.abortController) {\n abortControllerRef.current = undefined;\n }\n }\n },\n [currentFetcher, isMounted, latestOptions, state, requestId],\n );\n\n useEffect(() => {\n return () => {\n abortControllerRef.current?.abort();\n abortControllerRef.current = undefined;\n };\n }, []);\n return useMemo(\n () => ({\n ...state,\n exchange,\n execute,\n }),\n [state, exchange, execute],\n );\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n useExecutePromise,\n useLatest,\n UseExecutePromiseReturn,\n UseExecutePromiseOptions,\n} from '../core';\nimport { useCallback, useMemo, useEffect } from 'react';\nimport { AttributesCapable, FetcherError } from '@ahoo-wang/fetcher';\nimport { AutoExecuteCapable } from './types';\n\n/**\n * Configuration options for the useQuery hook\n * @template Q - The type of the query parameters\n * @template R - The type of the result value\n * @template E - The type of the error value\n */\nexport interface UseQueryOptions<Q, R, E = FetcherError>\n extends UseExecutePromiseOptions<R, E>,\n AttributesCapable,\n AutoExecuteCapable {\n /** The initial query parameters */\n initialQuery: Q;\n\n /** Function to execute the query with given parameters and optional attributes */\n execute: (query: Q, attributes?: Record<string, any>) => Promise<R>;\n}\n\n/**\n * Return type of the useQuery hook\n * @template Q - The type of the query parameters\n * @template R - The type of the result value\n * @template E - The type of the error value\n */\nexport interface UseQueryReturn<Q, R, E = FetcherError>\n extends UseExecutePromiseReturn<R, E> {\n /**\n * Get the current query parameters\n */\n getQuery: () => Q;\n /** Function to update the query parameters */\n setQuery: (query: Q) => void;\n /** Function to execute the query with current parameters */\n execute: () => Promise<R | E>;\n}\n\n/**\n * A React hook for managing query-based asynchronous operations\n * @template Q - The type of the query parameters\n * @template R - The type of the result value\n * @template E - The type of the error value\n * @param options - Configuration options for the query\n * @returns An object containing the query state and control functions\n *\n * @example\n * ```typescript\n * import { useQuery } from '@ahoo-wang/fetcher-react';\n *\n * interface UserQuery {\n * id: string;\n * }\n *\n * interface User {\n * id: string;\n * name: string;\n * }\n *\n * function UserComponent() {\n * const { loading, result, error, execute, setQuery } = useQuery<UserQuery, User>({\n * initialQuery: { id: '1' },\n * execute: async (query) => {\n * const response = await fetch(`/api/users/${query.id}`);\n * return response.json();\n * },\n * autoExecute: true,\n * });\n *\n * const handleUserChange = (userId: string) => {\n * setQuery({ id: userId }); // Automatically executes if autoExecute is true\n * };\n *\n * if (loading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * return (\n * <div>\n * <button onClick={() => handleUserChange('2')}>Load User 2</button>\n * {result && <p>User: {result.name}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function useQuery<Q, R, E = FetcherError>(\n options: UseQueryOptions<Q, R, E>,\n): UseQueryReturn<Q, R, E> {\n const { initialQuery } = options;\n const latestOptions = useLatest(options);\n const promiseState = useExecutePromise<R, E>(latestOptions.current);\n const latestQuery = useLatest(initialQuery);\n\n const queryExecutor = useCallback(async (): Promise<R> => {\n return latestOptions.current.execute(\n latestQuery.current,\n latestOptions.current.attributes,\n );\n }, [latestQuery, latestOptions]);\n const { execute: promiseExecutor } = promiseState;\n const execute = useCallback(() => {\n return promiseExecutor(queryExecutor);\n }, [promiseExecutor, queryExecutor]);\n const getQuery = useCallback(() => {\n return latestQuery.current;\n }, [latestQuery]);\n const setQuery = useCallback(\n (query: Q) => {\n latestQuery.current = query;\n if (latestOptions.current.autoExecute) {\n execute();\n }\n },\n [latestQuery, latestOptions, execute],\n );\n\n useEffect(() => {\n if (latestOptions.current.autoExecute) {\n execute();\n }\n }, [latestOptions, execute]);\n\n return useMemo(\n () => ({\n ...promiseState,\n execute,\n getQuery,\n setQuery,\n }),\n [promiseState, execute, getQuery, setQuery],\n );\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { PagedList, PagedQuery } from '@ahoo-wang/fetcher-wow';\nimport { FetcherError } from '@ahoo-wang/fetcher';\nimport { useQuery, UseQueryOptions, UseQueryReturn } from './useQuery';\n\n/**\n * Options for the usePagedQuery hook.\n * Extends UseQueryOptions with PagedQuery as query key and PagedList as data type.\n *\n * @template R - The type of the result items in the paged list\n * @template FIELDS - The fields type for the paged query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UsePagedQueryOptions<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryOptions<PagedQuery<FIELDS>, PagedList<R>, E> {\n}\n\n/**\n * Return type for the usePagedQuery hook.\n * Extends UseQueryReturn with PagedQuery as query key and PagedList as data type.\n *\n * @template R - The type of the result items in the paged list\n * @template FIELDS - The fields type for the paged query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UsePagedQueryReturn<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryReturn<PagedQuery<FIELDS>, PagedList<R>, E> {\n}\n\n/**\n * Hook for querying paged data with conditions, projection, pagination, and sorting.\n * Wraps useQuery to provide type-safe paged queries.\n *\n * @template R - The type of the result items in the paged list\n * @template FIELDS - The fields type for the paged query\n * @template E - The error type, defaults to FetcherError\n * @param options - The query options including paged query configuration\n * @returns The query result with paged list data\n *\n * @example\n * ```typescript\n * const { data, isLoading } = usePagedQuery<{ id: number; name: string }, 'id' | 'name'>({\n * initialQuery: {\n * condition: all(),\n * pagination: { index: 1, size: 10 },\n * projection: { include: ['id', 'name'] },\n * sort: [{ field: 'id', direction: SortDirection.ASC }],\n * },\n * execute: async (query) => fetchPagedData(query),\n * });\n * ```\n */\nexport function usePagedQuery<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n>(\n options: UsePagedQueryOptions<R, FIELDS, E>,\n): UsePagedQueryReturn<R, FIELDS, E> {\n return useQuery<PagedQuery<FIELDS>, PagedList<R>, E>(options);\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { SingleQuery } from '@ahoo-wang/fetcher-wow';\nimport { FetcherError } from '@ahoo-wang/fetcher';\nimport { useQuery, UseQueryOptions, UseQueryReturn } from './useQuery';\n\n/**\n * Options for the useSingleQuery hook.\n * Extends UseQueryOptions with SingleQuery as query key and custom result type.\n *\n * @template R - The result type of the query\n * @template FIELDS - The fields type for the single query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseSingleQueryOptions<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryOptions<SingleQuery<FIELDS>, R, E> {\n}\n\n/**\n * Return type for the useSingleQuery hook.\n * Extends UseQueryReturn with SingleQuery as query key and custom result type.\n *\n * @template R - The result type of the query\n * @template FIELDS - The fields type for the single query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseSingleQueryReturn<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryReturn<SingleQuery<FIELDS>, R, E> {\n}\n\n/**\n * Hook for querying a single item with conditions, projection, and sorting.\n * Wraps useQuery to provide type-safe single item queries.\n *\n * @template R - The result type of the query\n * @template FIELDS - The fields type for the single query\n * @template E - The error type, defaults to FetcherError\n * @param options - The query options including single query configuration\n * @returns The query result with single item data\n *\n * @example\n * ```typescript\n * const { data, isLoading } = useSingleQuery<{ id: number; name: string }, 'id' | 'name'>({\n * initialQuery: {\n * condition: all(),\n * projection: { include: ['id', 'name'] },\n * sort: [{ field: 'id', direction: SortDirection.ASC }],\n * },\n * execute: async (query) => fetchSingleItem(query),\n * });\n * ```\n */\nexport function useSingleQuery<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n>(\n options: UseSingleQueryOptions<R, FIELDS, E>,\n): UseSingleQueryReturn<R, FIELDS, E> {\n return useQuery<SingleQuery<FIELDS>, R, E>(options);\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Condition } from '@ahoo-wang/fetcher-wow';\nimport { FetcherError } from '@ahoo-wang/fetcher';\nimport { useQuery, UseQueryOptions, UseQueryReturn } from './useQuery';\n\n/**\n * Options for the useCountQuery hook.\n * Extends UseQueryOptions with Condition as query key and number as data type.\n *\n * @template FIELDS - The fields type for the condition\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseCountQueryOptions<\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryOptions<Condition<FIELDS>, number, E> {\n}\n\n/**\n * Return type for the useCountQuery hook.\n * Extends UseQueryReturn with Condition as query key and number as data type.\n *\n * @template FIELDS - The fields type for the condition\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseCountQueryReturn<\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryReturn<Condition<FIELDS>, number, E> {\n}\n\n/**\n * Hook for querying count data with conditions.\n * Wraps useQuery to provide type-safe count queries.\n *\n * @template FIELDS - The fields type for the condition\n * @template E - The error type, defaults to FetcherError\n * @param options - The query options including condition and other settings\n * @returns The query result with count data\n *\n * @example\n * ```typescript\n * const { data, isLoading } = useCountQuery({\n * queryKey: [{ field: 'status', operator: 'eq', value: 'active' }],\n * queryFn: async (condition) => fetchCount(condition),\n * });\n * ```\n */\nexport function useCountQuery<FIELDS extends string = string, E = FetcherError>(\n options: UseCountQueryOptions<FIELDS, E>,\n): UseCountQueryReturn<FIELDS, E> {\n return useQuery(options);\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ListQuery } from '@ahoo-wang/fetcher-wow';\nimport { FetcherError } from '@ahoo-wang/fetcher';\nimport { useQuery, UseQueryOptions, UseQueryReturn } from './useQuery';\n\n/**\n * Options for the useListQuery hook.\n * Extends UseQueryOptions with ListQuery as query key and array of results as data type.\n *\n * @template R - The type of the result items in the list\n * @template FIELDS - The fields type for the list query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseListQueryOptions<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryOptions<ListQuery<FIELDS>, R[], E> {\n}\n\n/**\n * Return type for the useListQuery hook.\n * Extends UseQueryReturn with ListQuery as query key and array of results as data type.\n *\n * @template R - The type of the result items in the list\n * @template FIELDS - The fields type for the list query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseListQueryReturn<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryReturn<ListQuery<FIELDS>, R[], E> {\n}\n\n/**\n * Hook for querying list data with conditions, projection, and sorting.\n * Wraps useQuery to provide type-safe list queries.\n *\n * @template R - The type of the result items in the list\n * @template FIELDS - The fields type for the list query\n * @template E - The error type, defaults to FetcherError\n * @param options - The query options including list query configuration\n * @returns The query result with list data\n *\n * @example\n * ```typescript\n * const { data, isLoading } = useListQuery<{ id: number; name: string }, 'id' | 'name'>({\n * initialQuery: {\n * condition: all(),\n * projection: { include: ['id', 'name'] },\n * sort: [{ field: 'id', direction: SortDirection.ASC }],\n * },\n * execute: async (query) => fetchListData(query),\n * });\n * ```\n */\nexport function useListQuery<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n>(\n options: UseListQueryOptions<R, FIELDS, E>,\n): UseListQueryReturn<R, FIELDS, E> {\n return useQuery<ListQuery<FIELDS>, R[], E>(options);\n}","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ListQuery } from '@ahoo-wang/fetcher-wow';\nimport type { JsonServerSentEvent } from '@ahoo-wang/fetcher-eventstream';\nimport { FetcherError } from '@ahoo-wang/fetcher';\nimport { useQuery, UseQueryOptions, UseQueryReturn } from './useQuery';\n\n/**\n * Options for the useListStreamQuery hook.\n * Extends UseQueryOptions with ListQuery as query key and stream of events as data type.\n *\n * @template R - The type of the result items in the stream events\n * @template FIELDS - The fields type for the list stream query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseListStreamQueryOptions<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryOptions<\n ListQuery<FIELDS>,\n ReadableStream<JsonServerSentEvent<R>>,\n E\n> {\n}\n\n/**\n * Return type for the useListStreamQuery hook.\n * Extends UseQueryReturn with ListQuery as query key and stream of events as data type.\n *\n * @template R - The type of the result items in the stream events\n * @template FIELDS - The fields type for the list stream query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseListStreamQueryReturn<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryReturn<\n ListQuery<FIELDS>,\n ReadableStream<JsonServerSentEvent<R>>,\n E\n> {\n}\n\n/**\n * Hook for querying streaming list data with conditions, projection, and sorting.\n * Wraps useQuery to provide type-safe streaming list queries.\n *\n * @template R - The type of the result items in the stream events\n * @template FIELDS - The fields type for the list stream query\n * @template E - The error type, defaults to FetcherError\n * @param options - The query options including list stream query configuration\n * @returns The query result with streaming data\n *\n * @example\n * ```typescript\n * const { data, isLoading } = useListStreamQuery<{ id: number; name: string }, 'id' | 'name'>({\n * initialQuery: {\n * condition: all(),\n * projection: { include: ['id', 'name'] },\n * sort: [{ field: 'id', direction: SortDirection.ASC }],\n * },\n * execute: async (query) => fetchStreamData(query),\n * });\n * ```\n */\nexport function useListStreamQuery<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n>(\n options: UseListStreamQueryOptions<R, FIELDS, E>,\n): UseListStreamQueryReturn<R, FIELDS, E> {\n return useQuery<ListQuery<FIELDS>, ReadableStream<JsonServerSentEvent<R>>, E>(\n options,\n );\n}\n"],"names":["useMounted","isMountedRef","useRef","isMountedFn","useCallback","useEffect","useLatest","value","ref","PromiseStatus","usePromiseState","options","status","setStatus","useState","result","setResult","error","setErrorState","isMounted","latestOptions","setLoadingFn","setSuccessFn","callbackError","setErrorFn","setIdleFn","useMemo","useRequestId","requestIdRef","generate","current","isLatest","requestId","invalidate","reset","useExecutePromise","loading","setLoading","setSuccess","setError","setIdle","propagateError","execute","input","currentRequestId","data","err","useKeyStorage","keyStorage","subscribe","callback","getSnapshot","useSyncExternalStore","setValue","useFetcher","fetcher","fetcherRegistrar","state","exchange","setExchange","abortControllerRef","currentFetcher","getFetcher","request","useQuery","initialQuery","promiseState","latestQuery","queryExecutor","promiseExecutor","getQuery","setQuery","query","usePagedQuery","useSingleQuery","useCountQuery","useListQuery","useListStreamQuery"],"mappings":";;AAuCO,SAASA,IAAa;AAC3B,QAAMC,IAAeC,EAAO,EAAK,GAC3BC,IAAcC,EAAY,MAAMH,EAAa,SAAS,CAAA,CAAE;AAC9D,SAAAI,EAAU,OACRJ,EAAa,UAAU,IAChB,MAAM;AACX,IAAAA,EAAa,UAAU;AAAA,EACzB,IACC,CAAA,CAAE,GAEEE;AACT;ACLO,SAASG,EAAaC,GAA+B;AAC1D,QAAMC,IAAMN,EAAOK,CAAK;AACxB,SAAAC,EAAI,UAAUD,GACPC;AACT;AC5BO,IAAKC,sBAAAA,OACVA,EAAA,OAAO,QACPA,EAAA,UAAU,WACVA,EAAA,UAAU,WACVA,EAAA,QAAQ,SAJEA,IAAAA,KAAA,CAAA,CAAA;AA6FL,SAASC,EACdC,GAC6B;AAC7B,QAAM,CAACC,GAAQC,CAAS,IAAIC;AAAA,IAC1BH,GAAS,iBAAiB;AAAA;AAAA,EAAA,GAEtB,CAACI,GAAQC,CAAS,IAAIF,EAAwB,MAAS,GACvD,CAACG,GAAOC,CAAa,IAAIJ,EAAwB,MAAS,GAC1DK,IAAYnB,EAAA,GACZoB,IAAgBd,EAAUK,CAAO,GACjCU,IAAejB,EAAY,MAAM;AACrC,IAAIe,QACFN;AAAA,MAAU;AAAA;AAAA,IAAA,GACVK,EAAc,MAAS;AAAA,EAE3B,GAAG,CAACC,CAAS,CAAC,GAERG,IAAelB;AAAA,IACnB,OAAOW,MAAc;AACnB,UAAII,KAAa;AACf,QAAAH,EAAUD,CAAM,GAChBF;AAAA,UAAU;AAAA;AAAA,QAAA,GACVK,EAAc,MAAS;AACvB,YAAI;AACF,gBAAME,EAAc,SAAS,YAAYL,CAAM;AAAA,QACjD,SAASQ,GAAe;AAEtB,kBAAQ,KAAK,0CAA0CA,CAAa;AAAA,QACtE;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAACJ,GAAWC,CAAa;AAAA,EAAA,GAGrBI,IAAapB;AAAA,IACjB,OAAOa,MAAa;AAClB,UAAIE,KAAa;AACf,QAAAD,EAAcD,CAAK,GACnBJ;AAAA,UAAU;AAAA;AAAA,QAAA,GACVG,EAAU,MAAS;AACnB,YAAI;AACF,gBAAMI,EAAc,SAAS,UAAUH,CAAK;AAAA,QAC9C,SAASM,GAAe;AAEtB,kBAAQ,KAAK,wCAAwCA,CAAa;AAAA,QACpE;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAACJ,GAAWC,CAAa;AAAA,EAAA,GAGrBK,IAAYrB,EAAY,MAAM;AAClC,IAAIe,QACFN;AAAA,MAAU;AAAA;AAAA,IAAA,GACVK,EAAc,MAAS,GACvBF,EAAU,MAAS;AAAA,EAEvB,GAAG,CAACG,CAAS,CAAC;AACd,SAAOO;AAAA,IACL,OAAO;AAAA,MACL,QAAAd;AAAA,MACA,SAASA,MAAW;AAAA,MACpB,QAAAG;AAAA,MACA,OAAAE;AAAA,MACA,YAAYI;AAAA,MACZ,YAAYC;AAAA,MACZ,UAAUE;AAAA,MACV,SAASC;AAAA,IAAA;AAAA,IAEX,CAACb,GAAQG,GAAQE,GAAOI,GAAcC,GAAcE,GAAYC,CAAS;AAAA,EAAA;AAE7E;ACnHO,SAASE,IAAmC;AACjD,QAAMC,IAAe1B,EAAe,CAAC,GAE/B2B,IAAWzB,EAAY,MACpB,EAAEwB,EAAa,SACrB,CAAA,CAAE,GAECE,IAAU1B,EAAY,MACnBwB,EAAa,SACnB,CAAA,CAAE,GAECG,IAAW3B,EAAY,CAAC4B,MACrBA,MAAcJ,EAAa,SACjC,CAAA,CAAE,GAECK,IAAa7B,EAAY,MAAY;AACzC,IAAAwB,EAAa;AAAA,EACf,GAAG,CAAA,CAAE,GAECM,IAAQ9B,EAAY,MAAY;AACpC,IAAAwB,EAAa,UAAU;AAAA,EACzB,GAAG,CAAA,CAAE;AACL,SAAOF,EAAQ,OACN;AAAA,IACL,UAAAG;AAAA,IACA,SAAAC;AAAA,IACA,UAAAC;AAAA,IACA,YAAAE;AAAA,IACA,OAAAC;AAAA,EAAA,IAED,CAACL,GAAUC,GAASC,GAAUE,GAAYC,CAAK,CAAC;AACrD;ACAO,SAASC,EACdxB,GAC+B;AAC/B,QAAM,EAAE,SAAAyB,GAAS,QAAArB,GAAQ,OAAAE,GAAO,QAAAL,GAAQ,YAAAyB,GAAY,YAAAC,GAAY,UAAAC,GAAU,SAAAC,MAAY9B,EAAsBC,CAAO,GAC7GQ,IAAYnB,EAAA,GACZgC,IAAYL,EAAA,GACZc,IAAiB9B,GAAS,gBAM1B+B,IAAUtC;AAAA,IACd,OAAOuC,MAA2D;AAChE,UAAI,CAACxB;AACH,cAAM,IAAI,MAAM,wBAAwB;AAE1C,YAAMyB,IAAmBZ,EAAU,SAAA;AACnC,MAAAK,EAAA;AACA,UAAI;AAEF,cAAMQ,IAAO,OADG,OAAOF,KAAU,aAAaA,MAAUA;AAGxD,eAAIxB,EAAA,KAAea,EAAU,SAASY,CAAgB,KACpD,MAAMN,EAAWO,CAAI,GAEhBA;AAAA,MACT,SAASC,GAAK;AAIZ,YAHI3B,EAAA,KAAea,EAAU,SAASY,CAAgB,KACpD,MAAML,EAASO,CAAQ,GAErBL;AACF,gBAAMK;AAER,eAAOA;AAAA,MACT;AAAA,IACF;AAAA,IACA,CAACT,GAAYC,GAAYC,GAAUpB,GAAWa,GAAWS,CAAc;AAAA,EAAA,GAMnEP,IAAQ9B,EAAY,MAAM;AAC9B,IAAIe,OACFqB,EAAA;AAAA,EAEJ,GAAG,CAACA,GAASrB,CAAS,CAAC;AAEvB,SAAOO;AAAA,IACL,OAAO;AAAA,MACL,SAAAU;AAAA,MACA,QAAArB;AAAA,MACA,OAAAE;AAAA,MACA,SAAAyB;AAAA,MACA,OAAAR;AAAA,MACA,QAAAtB;AAAA,IAAA;AAAA,IAEF,CAACwB,GAASrB,GAAQE,GAAOyB,GAASR,GAAOtB,CAAM;AAAA,EAAA;AAEnD;ACzIO,SAASmC,EACdC,GACgC;AAChC,QAAMC,IAAY7C;AAAA,IAChB,CAAC8C,MAAyBF,EAAW,YAAYE,CAAQ;AAAA,IACzD,CAACF,CAAU;AAAA,EAAA,GAEPG,IAAc/C,EAAY,MAAM4C,EAAW,OAAO,CAACA,CAAU,CAAC,GAC9DzC,IAAQ6C,EAAqBH,GAAWE,GAAaA,CAAW,GAChEE,IAAWjD;AAAA,IACf,CAACG,MAAayC,EAAW,IAAIzC,CAAK;AAAA,IAClC,CAACyC,CAAU;AAAA,EAAA;AAEb,SAAO,CAACzC,GAAO8C,CAAQ;AACzB;ACoCO,SAASC,EACd3C,GACwB;AACxB,QAAM,EAAE,SAAA4C,IAAUC,EAAiB,QAAA,IAAY7C,KAAW,CAAA,GACpD8C,IAAQ/C,EAAsBC,CAAO,GACrC,CAAC+C,GAAUC,CAAW,IAAI7C;AAAA,IAC9B;AAAA,EAAA,GAEIK,IAAYnB,EAAA,GACZ4D,IAAqB1D,EAAA,GACrB8B,IAAYL,EAAA,GACZP,IAAgBd,EAAUK,CAAO,GACjCkD,IAAiBC,EAAWP,CAAO,GAKnCb,IAAUtC;AAAA,IACd,OAAO2D,MAA0B;AAC/B,MAAIH,EAAmB,WACrBA,EAAmB,QAAQ,MAAA,GAE7BA,EAAmB,UACjBG,EAAQ,mBAAmB,IAAI,gBAAA,GACjCA,EAAQ,kBAAkBH,EAAmB;AAC7C,YAAMhB,IAAmBZ,EAAU,SAAA;AACnC,MAAAyB,EAAM,WAAA;AACN,UAAI;AACF,cAAMC,IAAW,MAAMG,EAAe;AAAA,UACpCE;AAAA,UACA3C,EAAc;AAAA,QAAA;AAEhB,QAAID,EAAA,KAAea,EAAU,SAASY,CAAgB,KACpDe,EAAYD,CAAQ;AAEtB,cAAM3C,IAAS,MAAM2C,EAAS,cAAA;AAC9B,QAAIvC,EAAA,KAAea,EAAU,SAASY,CAAgB,KACpD,MAAMa,EAAM,WAAW1C,CAAM;AAAA,MAEjC,SAASE,GAAO;AACd,YAAIA,aAAiB,SAASA,EAAM,SAAS,cAAc;AACzD,UAAIE,OACFsC,EAAM,QAAA;AAER;AAAA,QACF;AACA,QAAItC,EAAA,KAAea,EAAU,SAASY,CAAgB,KACpD,MAAMa,EAAM,SAASxC,CAAU;AAAA,MAEnC,UAAA;AACE,QAAI2C,EAAmB,YAAYG,EAAQ,oBACzCH,EAAmB,UAAU;AAAA,MAEjC;AAAA,IACF;AAAA,IACA,CAACC,GAAgB1C,GAAWC,GAAeqC,GAAOzB,CAAS;AAAA,EAAA;AAG7D,SAAA3B,EAAU,MACD,MAAM;AACX,IAAAuD,EAAmB,SAAS,MAAA,GAC5BA,EAAmB,UAAU;AAAA,EAC/B,GACC,CAAA,CAAE,GACElC;AAAA,IACL,OAAO;AAAA,MACL,GAAG+B;AAAA,MACH,UAAAC;AAAA,MACA,SAAAhB;AAAA,IAAA;AAAA,IAEF,CAACe,GAAOC,GAAUhB,CAAO;AAAA,EAAA;AAE7B;AC1CO,SAASsB,EACdrD,GACyB;AACzB,QAAM,EAAE,cAAAsD,MAAiBtD,GACnBS,IAAgBd,EAAUK,CAAO,GACjCuD,IAAe/B,EAAwBf,EAAc,OAAO,GAC5D+C,IAAc7D,EAAU2D,CAAY,GAEpCG,IAAgBhE,EAAY,YACzBgB,EAAc,QAAQ;AAAA,IAC3B+C,EAAY;AAAA,IACZ/C,EAAc,QAAQ;AAAA,EAAA,GAEvB,CAAC+C,GAAa/C,CAAa,CAAC,GACzB,EAAE,SAASiD,EAAA,IAAoBH,GAC/BxB,IAAUtC,EAAY,MACnBiE,EAAgBD,CAAa,GACnC,CAACC,GAAiBD,CAAa,CAAC,GAC7BE,IAAWlE,EAAY,MACpB+D,EAAY,SAClB,CAACA,CAAW,CAAC,GACVI,IAAWnE;AAAA,IACf,CAACoE,MAAa;AACZ,MAAAL,EAAY,UAAUK,GAClBpD,EAAc,QAAQ,eACxBsB,EAAA;AAAA,IAEJ;AAAA,IACA,CAACyB,GAAa/C,GAAesB,CAAO;AAAA,EAAA;AAGtC,SAAArC,EAAU,MAAM;AACd,IAAIe,EAAc,QAAQ,eACxBsB,EAAA;AAAA,EAEJ,GAAG,CAACtB,GAAesB,CAAO,CAAC,GAEpBhB;AAAA,IACL,OAAO;AAAA,MACL,GAAGwC;AAAA,MACH,SAAAxB;AAAA,MACA,UAAA4B;AAAA,MACA,UAAAC;AAAA,IAAA;AAAA,IAEF,CAACL,GAAcxB,GAAS4B,GAAUC,CAAQ;AAAA,EAAA;AAE9C;AChFO,SAASE,EAKd9D,GACmC;AACnC,SAAOqD,EAA8CrD,CAAO;AAC9D;ACTO,SAAS+D,EAKd/D,GACoC;AACpC,SAAOqD,EAAoCrD,CAAO;AACpD;ACjBO,SAASgE,EACdhE,GACgC;AAChC,SAAOqD,EAASrD,CAAO;AACzB;ACKO,SAASiE,EAKdjE,GACkC;AAClC,SAAOqD,EAAoCrD,CAAO;AACpD;ACCO,SAASkE,EAKdlE,GACwC;AACxC,SAAOqD;AAAA,IACLrD;AAAA,EAAA;AAEJ;"}
package/dist/index.umd.js CHANGED
@@ -1,2 +1,2 @@
1
- (function(n,t){typeof exports=="object"&&typeof module<"u"?t(exports,require("react"),require("@ahoo-wang/fetcher")):typeof define=="function"&&define.amd?define(["exports","react","@ahoo-wang/fetcher"],t):(n=typeof globalThis<"u"?globalThis:n||self,t(n.FetcherReact={},n.React,n.Fetcher))})(this,(function(n,t,k){"use strict";function S(){const e=t.useRef(!1),c=t.useCallback(()=>e.current,[]);return t.useEffect(()=>(e.current=!0,()=>{e.current=!1}),[]),c}function g(e){const c=t.useRef(e);return c.current=e,c}var w=(e=>(e.IDLE="idle",e.LOADING="loading",e.SUCCESS="success",e.ERROR="error",e))(w||{});function L(e){const[c,s]=t.useState(e?.initialStatus??"idle"),[a,i]=t.useState(void 0),[r,u]=t.useState(void 0),o=S(),l=g(e),f=t.useCallback(()=>{o()&&(s("loading"),u(void 0))},[o]),b=t.useCallback(async d=>{if(o()){i(d),s("success"),u(void 0);try{await l.current?.onSuccess?.(d)}catch(E){console.warn("PromiseState onSuccess callback error:",E)}}},[o,l]),y=t.useCallback(async d=>{if(o()){u(d),s("error"),i(void 0);try{await l.current?.onError?.(d)}catch(E){console.warn("PromiseState onError callback error:",E)}}},[o,l]),C=t.useCallback(()=>{o()&&(s("idle"),u(void 0),i(void 0))},[o]);return t.useMemo(()=>({status:c,loading:c==="loading",result:a,error:r,setLoading:f,setSuccess:b,setError:y,setIdle:C}),[c,a,r,f,b,y,C])}function R(){const e=t.useRef(0),c=t.useCallback(()=>++e.current,[]),s=t.useCallback(()=>e.current,[]),a=t.useCallback(u=>u===e.current,[]),i=t.useCallback(()=>{e.current++},[]),r=t.useCallback(()=>{e.current=0},[]);return t.useMemo(()=>({generate:c,current:s,isLatest:a,invalidate:i,reset:r}),[c,s,a,i,r])}function Q(e){const{loading:c,result:s,error:a,status:i,setLoading:r,setSuccess:u,setError:o,setIdle:l}=L(e),f=S(),b=R(),y=e?.propagateError,C=t.useCallback(async E=>{if(!f())throw new Error("Component is unmounted");const v=b.generate();r();try{const I=await(typeof E=="function"?E():E);return f()&&b.isLatest(v)&&await u(I),I}catch(m){if(f()&&b.isLatest(v)&&await o(m),y)throw m;return m}},[r,u,o,f,b,y]),d=t.useCallback(()=>{f()&&l()},[l,f]);return t.useMemo(()=>({loading:c,result:s,error:a,execute:C,reset:d,status:i}),[c,s,a,C,d,i])}function M(e){const c=t.useCallback(r=>e.addListener(r),[e]),s=t.useCallback(()=>e.get(),[e]),a=t.useSyncExternalStore(c,s,s),i=t.useCallback(r=>e.set(r),[e]);return[a,i]}function F(e){const{fetcher:c=k.fetcherRegistrar.default}=e||{},s=L(e),[a,i]=t.useState(void 0),r=S(),u=t.useRef(),o=R(),l=g(e),f=k.getFetcher(c),b=t.useCallback(async y=>{u.current&&u.current.abort(),u.current=y.abortController??new AbortController,y.abortController=u.current;const C=o.generate();s.setLoading();try{const d=await f.exchange(y,l.current);r()&&o.isLatest(C)&&i(d);const E=await d.extractResult();r()&&o.isLatest(C)&&await s.setSuccess(E)}catch(d){if(d instanceof Error&&d.name==="AbortError"){r()&&s.setIdle();return}r()&&o.isLatest(C)&&await s.setError(d)}finally{u.current===y.abortController&&(u.current=void 0)}},[f,r,l,s,o]);return t.useEffect(()=>()=>{u.current?.abort(),u.current=void 0},[]),t.useMemo(()=>({...s,exchange:a,execute:b}),[s,a,b])}function h(e){const{initialQuery:c}=e,s=Q(e),a=g(c),i=g(e),r=t.useCallback(async()=>i.current.execute(a.current,i.current.attributes),[a,i]),u=t.useCallback(b=>{a.current=b},[a]),{execute:o}=s,l=t.useCallback(()=>o(r),[o,r]),{autoExecute:f}=e;return t.useEffect(()=>{f&&l()},[f,l]),t.useMemo(()=>({...s,execute:l,setQuery:u}),[s,l,u])}function q(e){return h(e)}function P(e){return h(e)}function O(e){return h(e)}function x(e){return h(e)}function A(e){return h(e)}n.PromiseStatus=w,n.useCountQuery=O,n.useExecutePromise=Q,n.useFetcher=F,n.useKeyStorage=M,n.useLatest=g,n.useListQuery=x,n.useListStreamQuery=A,n.useMounted=S,n.usePagedQuery=q,n.usePromiseState=L,n.useQuery=h,n.useRequestId=R,n.useSingleQuery=P,Object.defineProperty(n,Symbol.toStringTag,{value:"Module"})}));
1
+ (function(s,t){typeof exports=="object"&&typeof module<"u"?t(exports,require("react"),require("@ahoo-wang/fetcher")):typeof define=="function"&&define.amd?define(["exports","react","@ahoo-wang/fetcher"],t):(s=typeof globalThis<"u"?globalThis:s||self,t(s.FetcherReact={},s.React,s.Fetcher))})(this,(function(s,t,R){"use strict";function S(){const e=t.useRef(!1),o=t.useCallback(()=>e.current,[]);return t.useEffect(()=>(e.current=!0,()=>{e.current=!1}),[]),o}function h(e){const o=t.useRef(e);return o.current=e,o}var w=(e=>(e.IDLE="idle",e.LOADING="loading",e.SUCCESS="success",e.ERROR="error",e))(w||{});function k(e){const[o,r]=t.useState(e?.initialStatus??"idle"),[i,a]=t.useState(void 0),[u,c]=t.useState(void 0),n=S(),d=h(e),l=t.useCallback(()=>{n()&&(r("loading"),c(void 0))},[n]),b=t.useCallback(async f=>{if(n()){a(f),r("success"),c(void 0);try{await d.current?.onSuccess?.(f)}catch(E){console.warn("PromiseState onSuccess callback error:",E)}}},[n,d]),y=t.useCallback(async f=>{if(n()){c(f),r("error"),a(void 0);try{await d.current?.onError?.(f)}catch(E){console.warn("PromiseState onError callback error:",E)}}},[n,d]),C=t.useCallback(()=>{n()&&(r("idle"),c(void 0),a(void 0))},[n]);return t.useMemo(()=>({status:o,loading:o==="loading",result:i,error:u,setLoading:l,setSuccess:b,setError:y,setIdle:C}),[o,i,u,l,b,y,C])}function L(){const e=t.useRef(0),o=t.useCallback(()=>++e.current,[]),r=t.useCallback(()=>e.current,[]),i=t.useCallback(c=>c===e.current,[]),a=t.useCallback(()=>{e.current++},[]),u=t.useCallback(()=>{e.current=0},[]);return t.useMemo(()=>({generate:o,current:r,isLatest:i,invalidate:a,reset:u}),[o,r,i,a,u])}function Q(e){const{loading:o,result:r,error:i,status:a,setLoading:u,setSuccess:c,setError:n,setIdle:d}=k(e),l=S(),b=L(),y=e?.propagateError,C=t.useCallback(async E=>{if(!l())throw new Error("Component is unmounted");const v=b.generate();u();try{const I=await(typeof E=="function"?E():E);return l()&&b.isLatest(v)&&await c(I),I}catch(m){if(l()&&b.isLatest(v)&&await n(m),y)throw m;return m}},[u,c,n,l,b,y]),f=t.useCallback(()=>{l()&&d()},[d,l]);return t.useMemo(()=>({loading:o,result:r,error:i,execute:C,reset:f,status:a}),[o,r,i,C,f,a])}function M(e){const o=t.useCallback(u=>e.addListener(u),[e]),r=t.useCallback(()=>e.get(),[e]),i=t.useSyncExternalStore(o,r,r),a=t.useCallback(u=>e.set(u),[e]);return[i,a]}function F(e){const{fetcher:o=R.fetcherRegistrar.default}=e||{},r=k(e),[i,a]=t.useState(void 0),u=S(),c=t.useRef(),n=L(),d=h(e),l=R.getFetcher(o),b=t.useCallback(async y=>{c.current&&c.current.abort(),c.current=y.abortController??new AbortController,y.abortController=c.current;const C=n.generate();r.setLoading();try{const f=await l.exchange(y,d.current);u()&&n.isLatest(C)&&a(f);const E=await f.extractResult();u()&&n.isLatest(C)&&await r.setSuccess(E)}catch(f){if(f instanceof Error&&f.name==="AbortError"){u()&&r.setIdle();return}u()&&n.isLatest(C)&&await r.setError(f)}finally{c.current===y.abortController&&(c.current=void 0)}},[l,u,d,r,n]);return t.useEffect(()=>()=>{c.current?.abort(),c.current=void 0},[]),t.useMemo(()=>({...r,exchange:i,execute:b}),[r,i,b])}function g(e){const{initialQuery:o}=e,r=h(e),i=Q(r.current),a=h(o),u=t.useCallback(async()=>r.current.execute(a.current,r.current.attributes),[a,r]),{execute:c}=i,n=t.useCallback(()=>c(u),[c,u]),d=t.useCallback(()=>a.current,[a]),l=t.useCallback(b=>{a.current=b,r.current.autoExecute&&n()},[a,r,n]);return t.useEffect(()=>{r.current.autoExecute&&n()},[r,n]),t.useMemo(()=>({...i,execute:n,getQuery:d,setQuery:l}),[i,n,d,l])}function q(e){return g(e)}function P(e){return g(e)}function x(e){return g(e)}function O(e){return g(e)}function A(e){return g(e)}s.PromiseStatus=w,s.useCountQuery=x,s.useExecutePromise=Q,s.useFetcher=F,s.useKeyStorage=M,s.useLatest=h,s.useListQuery=O,s.useListStreamQuery=A,s.useMounted=S,s.usePagedQuery=q,s.usePromiseState=k,s.useQuery=g,s.useRequestId=L,s.useSingleQuery=P,Object.defineProperty(s,Symbol.toStringTag,{value:"Module"})}));
2
2
  //# sourceMappingURL=index.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","sources":["../src/core/useMounted.ts","../src/core/useLatest.ts","../src/core/usePromiseState.ts","../src/core/useRequestId.ts","../src/core/useExecutePromise.ts","../src/storage/useKeyStorage.ts","../src/fetcher/useFetcher.ts","../src/wow/useQuery.ts","../src/wow/usePagedQuery.ts","../src/wow/useSingleQuery.ts","../src/wow/useCountQuery.ts","../src/wow/useListQuery.ts","../src/wow/useListStreamQuery.ts"],"sourcesContent":["/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useRef, useEffect, useCallback } from 'react';\n\n/**\n * A React hook that returns a function to check if the component is mounted.\n *\n * @returns A function that returns true if the component is mounted, false otherwise\n *\n * @example\n * ```typescript\n * import { useMounted } from '@ahoo-wang/fetcher-react';\n *\n * const MyComponent = () => {\n * const isMounted = useMounted();\n *\n * useEffect(() => {\n * someAsyncOperation().then(() => {\n * if (isMounted()) {\n * setState(result);\n * }\n * });\n * }, []);\n *\n * return <div>My Component</div>;\n * };\n * ```\n */\nexport function useMounted() {\n const isMountedRef = useRef(false);\n const isMountedFn = useCallback(() => isMountedRef.current, []);\n useEffect(() => {\n isMountedRef.current = true;\n return () => {\n isMountedRef.current = false;\n };\n }, []);\n\n return isMountedFn;\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useRef } from 'react';\n\n/**\n * A React hook that returns a ref containing the latest value, useful for accessing the current value in async callbacks.\n *\n * @template T - The type of the value\n * @param value - The value to track\n * @returns A ref object containing the latest value\n *\n * @example\n * ```typescript\n * import { useLatest } from '@ahoo-wang/fetcher-react';\n *\n * const MyComponent = () => {\n * const [count, setCount] = useState(0);\n * const latestCount = useLatest(count);\n *\n * const handleAsync = async () => {\n * await someAsyncOperation();\n * console.log('Latest count:', latestCount.current); // Always the latest\n * };\n *\n * return (\n * <div>\n * <p>Count: {count}</p>\n * <button onClick={() => setCount(c => c + 1)}>Increment</button>\n * <button onClick={handleAsync}>Async Log</button>\n * </div>\n * );\n * };\n * ```\n */\nexport function useLatest<T>(value: T) {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback, useMemo, useState } from 'react';\nimport { useMounted } from './useMounted';\nimport { useLatest } from './useLatest';\nimport { FetcherError } from '@ahoo-wang/fetcher';\n\n/**\n * Enumeration of possible promise execution states\n */\nexport enum PromiseStatus {\n IDLE = 'idle',\n LOADING = 'loading',\n SUCCESS = 'success',\n ERROR = 'error',\n}\n\nexport interface PromiseState<R, E = unknown> {\n /** Current status of the promise */\n status: PromiseStatus;\n /** Indicates if currently loading */\n loading: boolean;\n /** The result value */\n result: R | undefined;\n /** The error value */\n error: E | undefined;\n}\n\nexport interface PromiseStateCallbacks<R, E = unknown> {\n /** Callback invoked on success (can be async) */\n onSuccess?: (result: R) => void | Promise<void>;\n /** Callback invoked on error (can be async) */\n onError?: (error: E) => void | Promise<void>;\n}\n\n/**\n * Options for configuring usePromiseState behavior\n * @template R - The type of result\n *\n * @example\n * ```typescript\n * const options: UsePromiseStateOptions<string> = {\n * initialStatus: PromiseStatus.IDLE,\n * onSuccess: (result) => console.log('Success:', result),\n * onError: async (error) => {\n * await logErrorToServer(error);\n * console.error('Error:', error);\n * },\n * };\n * ```\n */\nexport interface UsePromiseStateOptions<R, E = FetcherError>\n extends PromiseStateCallbacks<R, E> {\n /** Initial status, defaults to IDLE */\n initialStatus?: PromiseStatus;\n}\n\n/**\n * Return type for usePromiseState hook\n * @template R - The type of result\n */\nexport interface UsePromiseStateReturn<R, E = FetcherError>\n extends PromiseState<R, E> {\n /** Set status to LOADING */\n setLoading: () => void;\n /** Set status to SUCCESS with result */\n setSuccess: (result: R) => Promise<void>;\n /** Set status to ERROR with error */\n setError: (error: E) => Promise<void>;\n /** Set status to IDLE */\n setIdle: () => void;\n}\n\n/**\n * A React hook for managing promise state without execution logic\n * @template R - The type of result\n * @param options - Configuration options\n * @returns State management object\n *\n * @example\n * ```typescript\n * import { usePromiseState, PromiseStatus } from '@ahoo-wang/fetcher-react';\n *\n * function MyComponent() {\n * const { status, loading, result, error, setSuccess, setError, setIdle } = usePromiseState<string>();\n *\n * const handleSuccess = () => setSuccess('Data loaded');\n * const handleError = () => setError(new Error('Failed to load'));\n *\n * return (\n * <div>\n * <button onClick={handleSuccess}>Set Success</button>\n * <button onClick={handleError}>Set Error</button>\n * <button onClick={setIdle}>Reset</button>\n * <p>Status: {status}</p>\n * {loading && <p>Loading...</p>}\n * {result && <p>Result: {result}</p>}\n * {error && <p>Error: {error.message}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function usePromiseState<R = unknown, E = FetcherError>(\n options?: UsePromiseStateOptions<R, E>,\n): UsePromiseStateReturn<R, E> {\n const [status, setStatus] = useState<PromiseStatus>(\n options?.initialStatus ?? PromiseStatus.IDLE,\n );\n const [result, setResult] = useState<R | undefined>(undefined);\n const [error, setErrorState] = useState<E | undefined>(undefined);\n const isMounted = useMounted();\n const latestOptions = useLatest(options);\n const setLoadingFn = useCallback(() => {\n if (isMounted()) {\n setStatus(PromiseStatus.LOADING);\n setErrorState(undefined);\n }\n }, [isMounted]);\n\n const setSuccessFn = useCallback(\n async (result: R) => {\n if (isMounted()) {\n setResult(result);\n setStatus(PromiseStatus.SUCCESS);\n setErrorState(undefined);\n try {\n await latestOptions.current?.onSuccess?.(result);\n } catch (callbackError) {\n // Log callback errors but don't affect state\n console.warn('PromiseState onSuccess callback error:', callbackError);\n }\n }\n },\n [isMounted, latestOptions],\n );\n\n const setErrorFn = useCallback(\n async (error: E) => {\n if (isMounted()) {\n setErrorState(error);\n setStatus(PromiseStatus.ERROR);\n setResult(undefined);\n try {\n await latestOptions.current?.onError?.(error);\n } catch (callbackError) {\n // Log callback errors but don't affect state\n console.warn('PromiseState onError callback error:', callbackError);\n }\n }\n },\n [isMounted, latestOptions],\n );\n\n const setIdleFn = useCallback(() => {\n if (isMounted()) {\n setStatus(PromiseStatus.IDLE);\n setErrorState(undefined);\n setResult(undefined);\n }\n }, [isMounted]);\n return useMemo(\n () => ({\n status,\n loading: status === PromiseStatus.LOADING,\n result,\n error,\n setLoading: setLoadingFn,\n setSuccess: setSuccessFn,\n setError: setErrorFn,\n setIdle: setIdleFn,\n }),\n [status, result, error, setLoadingFn, setSuccessFn, setErrorFn, setIdleFn],\n );\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useRef, useCallback, useMemo } from 'react';\n\n/**\n * Return type for useRequestId hook\n */\nexport interface UseRequestIdReturn {\n /** Generate a new request ID and get the current one */\n generate: () => number;\n /** Get the current request ID without generating a new one */\n current: () => number;\n /** Check if a given request ID is the latest */\n isLatest: (requestId: number) => boolean;\n /** Invalidate current request ID (mark as stale) */\n invalidate: () => void;\n /** Reset request ID counter */\n reset: () => void;\n}\n\n/**\n * A React hook for managing request IDs and race condition protection\n *\n * @example\n * ```typescript\n * // Basic usage\n * const requestId = useRequestId();\n *\n * const execute = async () => {\n * const id = requestId.generate();\n *\n * try {\n * const result = await someAsyncOperation();\n *\n * // Check if this is still the latest request\n * if (requestId.isLatest(id)) {\n * setState(result);\n * }\n * } catch (error) {\n * if (requestId.isLatest(id)) {\n * setError(error);\n * }\n * }\n * };\n *\n * // Manual cancellation\n * const handleCancel = () => {\n * requestId.invalidate(); // All ongoing requests will be ignored\n * };\n * ```\n *\n * @example\n * ```typescript\n * // With async operation wrapper\n * const { execute, cancel } = useAsyncOperation(async (data) => {\n * return await apiCall(data);\n * }, [requestId]);\n * ```\n */\nexport function useRequestId(): UseRequestIdReturn {\n const requestIdRef = useRef<number>(0);\n\n const generate = useCallback((): number => {\n return ++requestIdRef.current;\n }, []);\n\n const current = useCallback((): number => {\n return requestIdRef.current;\n }, []);\n\n const isLatest = useCallback((requestId: number): boolean => {\n return requestId === requestIdRef.current;\n }, []);\n\n const invalidate = useCallback((): void => {\n requestIdRef.current++;\n }, []);\n\n const reset = useCallback((): void => {\n requestIdRef.current = 0;\n }, []);\n return useMemo(() => {\n return {\n generate,\n current,\n isLatest,\n invalidate,\n reset,\n };\n }, [generate, current, isLatest, invalidate, reset]);\n}","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback, useMemo } from 'react';\nimport { useMounted } from './useMounted';\nimport {\n usePromiseState,\n PromiseState,\n UsePromiseStateOptions,\n} from './usePromiseState';\nimport { useRequestId } from './useRequestId';\nimport { FetcherError } from '@ahoo-wang/fetcher';\n\nexport interface UseExecutePromiseOptions<R, E = unknown>\n extends UsePromiseStateOptions<R, E> {\n /**\n * Whether to propagate errors thrown by the promise.\n * If true, the execute function will throw errors.\n * If false (default), the execute function will return the error as the result instead of throwing.\n */\n propagateError?: boolean;\n}\n\n/**\n * Type definition for a function that returns a Promise\n * @template R - The type of value the promise will resolve to\n */\nexport type PromiseSupplier<R> = () => Promise<R>;\n\n/**\n * Interface defining the return type of useExecutePromise hook\n * @template R - The type of the result value\n */\nexport interface UseExecutePromiseReturn<R, E = FetcherError>\n extends PromiseState<R, E> {\n /**\n * Function to execute a promise supplier or promise.\n * Returns a promise that resolves to the result on success, or the error if propagateError is false.\n */\n execute: (input: PromiseSupplier<R> | Promise<R>) => Promise<R | E>;\n /** Function to reset the state to initial values */\n reset: () => void;\n}\n\n/**\n * A React hook for managing asynchronous operations with proper state handling\n * @template R - The type of the result value\n * @template E - The type of the error value\n * @param options - Configuration options for the hook\n * @returns An object containing the current state and control functions\n *\n * @example\n * ```typescript\n * import { useExecutePromise } from '@ahoo-wang/fetcher-react';\n *\n * function MyComponent() {\n * const { loading, result, error, execute, reset } = useExecutePromise<string>();\n *\n * const fetchData = async () => {\n * const response = await fetch('/api/data');\n * return response.text();\n * };\n *\n * const handleFetch = () => {\n * execute(fetchData);\n * };\n *\n * const handleReset = () => {\n * reset();\n * };\n *\n * if (loading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * return (\n * <div>\n * <button onClick={handleFetch}>Fetch Data</button>\n * <button onClick={handleReset}>Reset</button>\n * {result && <p>{result}</p>}\n * </div>\n * );\n * }\n *\n * // Example with propagateError set to true\n * const { execute } = useExecutePromise<string>({ propagateError: true });\n * try {\n * await execute(fetchData);\n * } catch (err) {\n * console.error('Error occurred:', err);\n * }\n * ```\n */\nexport function useExecutePromise<R = unknown, E = FetcherError>(\n options?: UseExecutePromiseOptions<R, E>,\n): UseExecutePromiseReturn<R, E> {\n const { loading, result, error, status, setLoading, setSuccess, setError, setIdle } = usePromiseState<R, E>(options);\n const isMounted = useMounted();\n const requestId = useRequestId();\n const propagateError = options?.propagateError;\n /**\n * Execute a promise supplier or promise and manage its state\n * @param input - A function that returns a Promise or a Promise to be executed\n * @returns A Promise that resolves with the result on success, or the error if propagateError is false\n */\n const execute = useCallback(\n async (input: PromiseSupplier<R> | Promise<R>): Promise<R | E> => {\n if (!isMounted()) {\n throw new Error('Component is unmounted');\n }\n const currentRequestId = requestId.generate();\n setLoading();\n try {\n const promise = typeof input === 'function' ? input() : input;\n const data = await promise;\n\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n await setSuccess(data);\n }\n return data;\n } catch (err) {\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n await setError(err as E);\n }\n if (propagateError) {\n throw err;\n }\n return err as E;\n }\n },\n [setLoading, setSuccess, setError, isMounted, requestId, propagateError],\n );\n\n /**\n * Reset the state to initial values\n */\n const reset = useCallback(() => {\n if (isMounted()) {\n setIdle();\n }\n }, [setIdle, isMounted]);\n\n return useMemo(\n () => ({\n loading: loading,\n result: result,\n error: error,\n execute,\n reset,\n status: status,\n }),\n [loading, result, error, execute, reset, status],\n );\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback, useSyncExternalStore } from 'react';\nimport { KeyStorage } from '@ahoo-wang/fetcher-storage';\n\n/**\n * A React hook that provides state management for a KeyStorage instance.\n * Subscribes to storage changes and returns the current value along with a setter function.\n *\n * @template T - The type of value stored in the key storage\n * @param keyStorage - The KeyStorage instance to subscribe to and manage\n * @returns A tuple containing the current stored value and a function to update it\n */\nexport function useKeyStorage<T>(\n keyStorage: KeyStorage<T>,\n): [T | null, (value: T) => void] {\n const subscribe = useCallback(\n (callback: () => void) => keyStorage.addListener(callback),\n [keyStorage],\n );\n const getSnapshot = useCallback(() => keyStorage.get(), [keyStorage]);\n const value = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n const setValue = useCallback(\n (value: T) => keyStorage.set(value),\n [keyStorage],\n );\n return [value, setValue];\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n fetcherRegistrar,\n FetcherCapable,\n FetchExchange,\n FetchRequest,\n getFetcher,\n RequestOptions, FetcherError,\n} from '@ahoo-wang/fetcher';\nimport { useMounted } from '../core';\nimport { useRef, useCallback, useEffect, useState, useMemo } from 'react';\nimport {\n PromiseState,\n useLatest,\n usePromiseState,\n UsePromiseStateOptions,\n useRequestId,\n} from '../core';\n\n/**\n * Configuration options for the useFetcher hook.\n * Extends RequestOptions and FetcherCapable interfaces.\n */\nexport interface UseFetcherOptions<R, E = FetcherError>\n extends RequestOptions,\n FetcherCapable,\n UsePromiseStateOptions<R, E> {\n}\n\nexport interface UseFetcherReturn<R, E = FetcherError> extends PromiseState<R, E> {\n /** The FetchExchange object representing the ongoing fetch operation */\n exchange?: FetchExchange;\n execute: (request: FetchRequest) => Promise<void>;\n}\n\n/**\n * A React hook for managing asynchronous operations with proper state handling\n * @param options - Configuration options for the fetcher\n * @returns An object containing the current state and control functions\n *\n * @example\n * ```typescript\n * import { useFetcher } from '@ahoo-wang/fetcher-react';\n *\n * function MyComponent() {\n * const { loading, result, error, execute } = useFetcher<string>();\n *\n * const handleFetch = () => {\n * execute({ url: '/api/data', method: 'GET' });\n * };\n *\n * if (loading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * return (\n * <div>\n * <button onClick={handleFetch}>Fetch Data</button>\n * {result && <p>{result}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function useFetcher<R, E = FetcherError>(\n options?: UseFetcherOptions<R, E>,\n): UseFetcherReturn<R, E> {\n const { fetcher = fetcherRegistrar.default } = options || {};\n const state = usePromiseState<R, E>(options);\n const [exchange, setExchange] = useState<FetchExchange | undefined>(\n undefined,\n );\n const isMounted = useMounted();\n const abortControllerRef = useRef<AbortController | undefined>();\n const requestId = useRequestId();\n const latestOptions = useLatest(options);\n const currentFetcher = getFetcher(fetcher);\n /**\n * Execute the fetch operation.\n * Cancels any ongoing fetch before starting a new one.\n */\n const execute = useCallback(\n async (request: FetchRequest) => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n abortControllerRef.current =\n request.abortController ?? new AbortController();\n request.abortController = abortControllerRef.current;\n const currentRequestId = requestId.generate();\n state.setLoading();\n try {\n const exchange = await currentFetcher.exchange(\n request,\n latestOptions.current,\n );\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n setExchange(exchange);\n }\n const result = await exchange.extractResult<R>();\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n await state.setSuccess(result);\n }\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n if (isMounted()) {\n state.setIdle();\n }\n return;\n }\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n await state.setError(error as E);\n }\n } finally {\n if (abortControllerRef.current === request.abortController) {\n abortControllerRef.current = undefined;\n }\n }\n },\n [currentFetcher, isMounted, latestOptions, state, requestId],\n );\n\n useEffect(() => {\n return () => {\n abortControllerRef.current?.abort();\n abortControllerRef.current = undefined;\n };\n }, []);\n return useMemo(\n () => ({\n ...state,\n exchange,\n execute,\n }),\n [state, exchange, execute],\n );\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n useExecutePromise,\n useLatest,\n UseExecutePromiseReturn,\n UseExecutePromiseOptions,\n} from '../core';\nimport { useCallback, useMemo, useEffect } from 'react';\nimport { AttributesCapable, FetcherError } from '@ahoo-wang/fetcher';\nimport { AutoExecuteCapable } from './types';\n\n/**\n * Configuration options for the useQuery hook\n * @template Q - The type of the query parameters\n * @template R - The type of the result value\n * @template E - The type of the error value\n */\nexport interface UseQueryOptions<Q, R, E = FetcherError>\n extends UseExecutePromiseOptions<R, E>,\n AttributesCapable,\n AutoExecuteCapable {\n /** The initial query parameters */\n initialQuery: Q;\n\n /** Function to execute the query with given parameters and optional attributes */\n execute: (query: Q, attributes?: Record<string, any>) => Promise<R>;\n}\n\n/**\n * Return type of the useQuery hook\n * @template Q - The type of the query parameters\n * @template R - The type of the result value\n * @template E - The type of the error value\n */\nexport interface UseQueryReturn<Q, R, E = FetcherError>\n extends UseExecutePromiseReturn<R, E> {\n /** Function to execute the query with current parameters */\n execute: () => Promise<R | E>;\n /** Function to update the query parameters */\n setQuery: (query: Q) => void;\n}\n\n/**\n * A React hook for managing query-based asynchronous operations\n * @template Q - The type of the query parameters\n * @template R - The type of the result value\n * @template E - The type of the error value\n * @param options - Configuration options for the query\n * @returns An object containing the query state and control functions\n *\n * @example\n * ```typescript\n * import { useQuery } from '@ahoo-wang/fetcher-react';\n *\n * interface UserQuery {\n * id: string;\n * }\n *\n * interface User {\n * id: string;\n * name: string;\n * }\n *\n * function UserComponent() {\n * const { loading, result, error, execute, setQuery } = useQuery<UserQuery, User>({\n * initialQuery: { id: '1' },\n * execute: async (query) => {\n * const response = await fetch(`/api/users/${query.id}`);\n * return response.json();\n * },\n * autoExecute: true,\n * });\n *\n * const handleUserChange = (userId: string) => {\n * setQuery({ id: userId });\n * execute();\n * };\n *\n * if (loading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * return (\n * <div>\n * <button onClick={() => handleUserChange('2')}>Load User 2</button>\n * {result && <p>User: {result.name}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function useQuery<Q, R, E = FetcherError>(\n options: UseQueryOptions<Q, R, E>,\n): UseQueryReturn<Q, R, E> {\n const { initialQuery } = options;\n const promiseState = useExecutePromise<R, E>(options);\n const latestQuery = useLatest(initialQuery);\n const latestOptions = useLatest(options);\n const queryExecutor = useCallback(async (): Promise<R> => {\n return latestOptions.current.execute(\n latestQuery.current,\n latestOptions.current.attributes,\n );\n }, [latestQuery, latestOptions]);\n const setQuery = useCallback(\n (query: Q) => {\n latestQuery.current = query;\n },\n [latestQuery],\n );\n const { execute: promiseExecutor } = promiseState;\n const execute = useCallback(() => {\n return promiseExecutor(queryExecutor);\n }, [promiseExecutor, queryExecutor]);\n\n const { autoExecute } = options;\n\n useEffect(() => {\n if (autoExecute) {\n execute();\n }\n }, [autoExecute, execute]);\n\n return useMemo(\n () => ({\n ...promiseState,\n execute,\n setQuery,\n }),\n [promiseState, execute, setQuery],\n );\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { PagedList, PagedQuery } from '@ahoo-wang/fetcher-wow';\nimport { FetcherError } from '@ahoo-wang/fetcher';\nimport { useQuery, UseQueryOptions, UseQueryReturn } from './useQuery';\n\n/**\n * Options for the usePagedQuery hook.\n * Extends UseQueryOptions with PagedQuery as query key and PagedList as data type.\n *\n * @template R - The type of the result items in the paged list\n * @template FIELDS - The fields type for the paged query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UsePagedQueryOptions<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryOptions<PagedQuery<FIELDS>, PagedList<R>, E> {\n}\n\n/**\n * Return type for the usePagedQuery hook.\n * Extends UseQueryReturn with PagedQuery as query key and PagedList as data type.\n *\n * @template R - The type of the result items in the paged list\n * @template FIELDS - The fields type for the paged query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UsePagedQueryReturn<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryReturn<PagedQuery<FIELDS>, PagedList<R>, E> {\n}\n\n/**\n * Hook for querying paged data with conditions, projection, pagination, and sorting.\n * Wraps useQuery to provide type-safe paged queries.\n *\n * @template R - The type of the result items in the paged list\n * @template FIELDS - The fields type for the paged query\n * @template E - The error type, defaults to FetcherError\n * @param options - The query options including paged query configuration\n * @returns The query result with paged list data\n *\n * @example\n * ```typescript\n * const { data, isLoading } = usePagedQuery<{ id: number; name: string }, 'id' | 'name'>({\n * initialQuery: {\n * condition: all(),\n * pagination: { index: 1, size: 10 },\n * projection: { include: ['id', 'name'] },\n * sort: [{ field: 'id', direction: SortDirection.ASC }],\n * },\n * execute: async (query) => fetchPagedData(query),\n * });\n * ```\n */\nexport function usePagedQuery<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n>(\n options: UsePagedQueryOptions<R, FIELDS, E>,\n): UsePagedQueryReturn<R, FIELDS, E> {\n return useQuery<PagedQuery<FIELDS>, PagedList<R>, E>(options);\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { SingleQuery } from '@ahoo-wang/fetcher-wow';\nimport { FetcherError } from '@ahoo-wang/fetcher';\nimport { useQuery, UseQueryOptions, UseQueryReturn } from './useQuery';\n\n/**\n * Options for the useSingleQuery hook.\n * Extends UseQueryOptions with SingleQuery as query key and custom result type.\n *\n * @template R - The result type of the query\n * @template FIELDS - The fields type for the single query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseSingleQueryOptions<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryOptions<SingleQuery<FIELDS>, R, E> {\n}\n\n/**\n * Return type for the useSingleQuery hook.\n * Extends UseQueryReturn with SingleQuery as query key and custom result type.\n *\n * @template R - The result type of the query\n * @template FIELDS - The fields type for the single query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseSingleQueryReturn<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryReturn<SingleQuery<FIELDS>, R, E> {\n}\n\n/**\n * Hook for querying a single item with conditions, projection, and sorting.\n * Wraps useQuery to provide type-safe single item queries.\n *\n * @template R - The result type of the query\n * @template FIELDS - The fields type for the single query\n * @template E - The error type, defaults to FetcherError\n * @param options - The query options including single query configuration\n * @returns The query result with single item data\n *\n * @example\n * ```typescript\n * const { data, isLoading } = useSingleQuery<{ id: number; name: string }, 'id' | 'name'>({\n * initialQuery: {\n * condition: all(),\n * projection: { include: ['id', 'name'] },\n * sort: [{ field: 'id', direction: SortDirection.ASC }],\n * },\n * execute: async (query) => fetchSingleItem(query),\n * });\n * ```\n */\nexport function useSingleQuery<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n>(\n options: UseSingleQueryOptions<R, FIELDS, E>,\n): UseSingleQueryReturn<R, FIELDS, E> {\n return useQuery<SingleQuery<FIELDS>, R, E>(options);\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Condition } from '@ahoo-wang/fetcher-wow';\nimport { FetcherError } from '@ahoo-wang/fetcher';\nimport { useQuery, UseQueryOptions, UseQueryReturn } from './useQuery';\n\n/**\n * Options for the useCountQuery hook.\n * Extends UseQueryOptions with Condition as query key and number as data type.\n *\n * @template FIELDS - The fields type for the condition\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseCountQueryOptions<\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryOptions<Condition<FIELDS>, number, E> {\n}\n\n/**\n * Return type for the useCountQuery hook.\n * Extends UseQueryReturn with Condition as query key and number as data type.\n *\n * @template FIELDS - The fields type for the condition\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseCountQueryReturn<\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryReturn<Condition<FIELDS>, number, E> {\n}\n\n/**\n * Hook for querying count data with conditions.\n * Wraps useQuery to provide type-safe count queries.\n *\n * @template FIELDS - The fields type for the condition\n * @template E - The error type, defaults to FetcherError\n * @param options - The query options including condition and other settings\n * @returns The query result with count data\n *\n * @example\n * ```typescript\n * const { data, isLoading } = useCountQuery({\n * queryKey: [{ field: 'status', operator: 'eq', value: 'active' }],\n * queryFn: async (condition) => fetchCount(condition),\n * });\n * ```\n */\nexport function useCountQuery<FIELDS extends string = string, E = FetcherError>(\n options: UseCountQueryOptions<FIELDS, E>,\n): UseCountQueryReturn<FIELDS, E> {\n return useQuery(options);\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ListQuery } from '@ahoo-wang/fetcher-wow';\nimport { FetcherError } from '@ahoo-wang/fetcher';\nimport { useQuery, UseQueryOptions, UseQueryReturn } from './useQuery';\n\n/**\n * Options for the useListQuery hook.\n * Extends UseQueryOptions with ListQuery as query key and array of results as data type.\n *\n * @template R - The type of the result items in the list\n * @template FIELDS - The fields type for the list query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseListQueryOptions<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryOptions<ListQuery<FIELDS>, R[], E> {\n}\n\n/**\n * Return type for the useListQuery hook.\n * Extends UseQueryReturn with ListQuery as query key and array of results as data type.\n *\n * @template R - The type of the result items in the list\n * @template FIELDS - The fields type for the list query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseListQueryReturn<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryReturn<ListQuery<FIELDS>, R[], E> {\n}\n\n/**\n * Hook for querying list data with conditions, projection, and sorting.\n * Wraps useQuery to provide type-safe list queries.\n *\n * @template R - The type of the result items in the list\n * @template FIELDS - The fields type for the list query\n * @template E - The error type, defaults to FetcherError\n * @param options - The query options including list query configuration\n * @returns The query result with list data\n *\n * @example\n * ```typescript\n * const { data, isLoading } = useListQuery<{ id: number; name: string }, 'id' | 'name'>({\n * initialQuery: {\n * condition: all(),\n * projection: { include: ['id', 'name'] },\n * sort: [{ field: 'id', direction: SortDirection.ASC }],\n * },\n * execute: async (query) => fetchListData(query),\n * });\n * ```\n */\nexport function useListQuery<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n>(\n options: UseListQueryOptions<R, FIELDS, E>,\n): UseListQueryReturn<R, FIELDS, E> {\n return useQuery<ListQuery<FIELDS>, R[], E>(options);\n}","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ListQuery } from '@ahoo-wang/fetcher-wow';\nimport type { JsonServerSentEvent } from '@ahoo-wang/fetcher-eventstream';\nimport { FetcherError } from '@ahoo-wang/fetcher';\nimport { useQuery, UseQueryOptions, UseQueryReturn } from './useQuery';\n\n/**\n * Options for the useListStreamQuery hook.\n * Extends UseQueryOptions with ListQuery as query key and stream of events as data type.\n *\n * @template R - The type of the result items in the stream events\n * @template FIELDS - The fields type for the list stream query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseListStreamQueryOptions<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryOptions<\n ListQuery<FIELDS>,\n ReadableStream<JsonServerSentEvent<R>>,\n E\n> {\n}\n\n/**\n * Return type for the useListStreamQuery hook.\n * Extends UseQueryReturn with ListQuery as query key and stream of events as data type.\n *\n * @template R - The type of the result items in the stream events\n * @template FIELDS - The fields type for the list stream query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseListStreamQueryReturn<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryReturn<\n ListQuery<FIELDS>,\n ReadableStream<JsonServerSentEvent<R>>,\n E\n> {\n}\n\n/**\n * Hook for querying streaming list data with conditions, projection, and sorting.\n * Wraps useQuery to provide type-safe streaming list queries.\n *\n * @template R - The type of the result items in the stream events\n * @template FIELDS - The fields type for the list stream query\n * @template E - The error type, defaults to FetcherError\n * @param options - The query options including list stream query configuration\n * @returns The query result with streaming data\n *\n * @example\n * ```typescript\n * const { data, isLoading } = useListStreamQuery<{ id: number; name: string }, 'id' | 'name'>({\n * initialQuery: {\n * condition: all(),\n * projection: { include: ['id', 'name'] },\n * sort: [{ field: 'id', direction: SortDirection.ASC }],\n * },\n * execute: async (query) => fetchStreamData(query),\n * });\n * ```\n */\nexport function useListStreamQuery<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n>(\n options: UseListStreamQueryOptions<R, FIELDS, E>,\n): UseListStreamQueryReturn<R, FIELDS, E> {\n return useQuery<ListQuery<FIELDS>, ReadableStream<JsonServerSentEvent<R>>, E>(\n options,\n );\n}\n"],"names":["useMounted","isMountedRef","useRef","isMountedFn","useCallback","useEffect","useLatest","value","ref","PromiseStatus","usePromiseState","options","status","setStatus","useState","result","setResult","error","setErrorState","isMounted","latestOptions","setLoadingFn","setSuccessFn","callbackError","setErrorFn","setIdleFn","useMemo","useRequestId","requestIdRef","generate","current","isLatest","requestId","invalidate","reset","useExecutePromise","loading","setLoading","setSuccess","setError","setIdle","propagateError","execute","input","currentRequestId","data","err","useKeyStorage","keyStorage","subscribe","callback","getSnapshot","useSyncExternalStore","setValue","useFetcher","fetcher","fetcherRegistrar","state","exchange","setExchange","abortControllerRef","currentFetcher","getFetcher","request","useQuery","initialQuery","promiseState","latestQuery","queryExecutor","setQuery","query","promiseExecutor","autoExecute","usePagedQuery","useSingleQuery","useCountQuery","useListQuery","useListStreamQuery"],"mappings":"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"}
1
+ {"version":3,"file":"index.umd.js","sources":["../src/core/useMounted.ts","../src/core/useLatest.ts","../src/core/usePromiseState.ts","../src/core/useRequestId.ts","../src/core/useExecutePromise.ts","../src/storage/useKeyStorage.ts","../src/fetcher/useFetcher.ts","../src/wow/useQuery.ts","../src/wow/usePagedQuery.ts","../src/wow/useSingleQuery.ts","../src/wow/useCountQuery.ts","../src/wow/useListQuery.ts","../src/wow/useListStreamQuery.ts"],"sourcesContent":["/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useRef, useEffect, useCallback } from 'react';\n\n/**\n * A React hook that returns a function to check if the component is mounted.\n *\n * @returns A function that returns true if the component is mounted, false otherwise\n *\n * @example\n * ```typescript\n * import { useMounted } from '@ahoo-wang/fetcher-react';\n *\n * const MyComponent = () => {\n * const isMounted = useMounted();\n *\n * useEffect(() => {\n * someAsyncOperation().then(() => {\n * if (isMounted()) {\n * setState(result);\n * }\n * });\n * }, []);\n *\n * return <div>My Component</div>;\n * };\n * ```\n */\nexport function useMounted() {\n const isMountedRef = useRef(false);\n const isMountedFn = useCallback(() => isMountedRef.current, []);\n useEffect(() => {\n isMountedRef.current = true;\n return () => {\n isMountedRef.current = false;\n };\n }, []);\n\n return isMountedFn;\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { MutableRefObject, useRef } from 'react';\n\n/**\n * A React hook that returns a ref containing the latest value, useful for accessing the current value in async callbacks.\n *\n * @template T - The type of the value\n * @param value - The value to track\n * @returns A ref object containing the latest value\n *\n * @example\n * ```typescript\n * import { useLatest } from '@ahoo-wang/fetcher-react';\n *\n * const MyComponent = () => {\n * const [count, setCount] = useState(0);\n * const latestCount = useLatest(count);\n *\n * const handleAsync = async () => {\n * await someAsyncOperation();\n * console.log('Latest count:', latestCount.current); // Always the latest\n * };\n *\n * return (\n * <div>\n * <p>Count: {count}</p>\n * <button onClick={() => setCount(c => c + 1)}>Increment</button>\n * <button onClick={handleAsync}>Async Log</button>\n * </div>\n * );\n * };\n * ```\n */\nexport function useLatest<T>(value: T): MutableRefObject<T> {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback, useMemo, useState } from 'react';\nimport { useMounted } from './useMounted';\nimport { useLatest } from './useLatest';\nimport { FetcherError } from '@ahoo-wang/fetcher';\n\n/**\n * Enumeration of possible promise execution states\n */\nexport enum PromiseStatus {\n IDLE = 'idle',\n LOADING = 'loading',\n SUCCESS = 'success',\n ERROR = 'error',\n}\n\nexport interface PromiseState<R, E = unknown> {\n /** Current status of the promise */\n status: PromiseStatus;\n /** Indicates if currently loading */\n loading: boolean;\n /** The result value */\n result: R | undefined;\n /** The error value */\n error: E | undefined;\n}\n\nexport interface PromiseStateCallbacks<R, E = unknown> {\n /** Callback invoked on success (can be async) */\n onSuccess?: (result: R) => void | Promise<void>;\n /** Callback invoked on error (can be async) */\n onError?: (error: E) => void | Promise<void>;\n}\n\n/**\n * Options for configuring usePromiseState behavior\n * @template R - The type of result\n *\n * @example\n * ```typescript\n * const options: UsePromiseStateOptions<string> = {\n * initialStatus: PromiseStatus.IDLE,\n * onSuccess: (result) => console.log('Success:', result),\n * onError: async (error) => {\n * await logErrorToServer(error);\n * console.error('Error:', error);\n * },\n * };\n * ```\n */\nexport interface UsePromiseStateOptions<R, E = FetcherError>\n extends PromiseStateCallbacks<R, E> {\n /** Initial status, defaults to IDLE */\n initialStatus?: PromiseStatus;\n}\n\n/**\n * Return type for usePromiseState hook\n * @template R - The type of result\n */\nexport interface UsePromiseStateReturn<R, E = FetcherError>\n extends PromiseState<R, E> {\n /** Set status to LOADING */\n setLoading: () => void;\n /** Set status to SUCCESS with result */\n setSuccess: (result: R) => Promise<void>;\n /** Set status to ERROR with error */\n setError: (error: E) => Promise<void>;\n /** Set status to IDLE */\n setIdle: () => void;\n}\n\n/**\n * A React hook for managing promise state without execution logic\n * @template R - The type of result\n * @param options - Configuration options\n * @returns State management object\n *\n * @example\n * ```typescript\n * import { usePromiseState, PromiseStatus } from '@ahoo-wang/fetcher-react';\n *\n * function MyComponent() {\n * const { status, loading, result, error, setSuccess, setError, setIdle } = usePromiseState<string>();\n *\n * const handleSuccess = () => setSuccess('Data loaded');\n * const handleError = () => setError(new Error('Failed to load'));\n *\n * return (\n * <div>\n * <button onClick={handleSuccess}>Set Success</button>\n * <button onClick={handleError}>Set Error</button>\n * <button onClick={setIdle}>Reset</button>\n * <p>Status: {status}</p>\n * {loading && <p>Loading...</p>}\n * {result && <p>Result: {result}</p>}\n * {error && <p>Error: {error.message}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function usePromiseState<R = unknown, E = FetcherError>(\n options?: UsePromiseStateOptions<R, E>,\n): UsePromiseStateReturn<R, E> {\n const [status, setStatus] = useState<PromiseStatus>(\n options?.initialStatus ?? PromiseStatus.IDLE,\n );\n const [result, setResult] = useState<R | undefined>(undefined);\n const [error, setErrorState] = useState<E | undefined>(undefined);\n const isMounted = useMounted();\n const latestOptions = useLatest(options);\n const setLoadingFn = useCallback(() => {\n if (isMounted()) {\n setStatus(PromiseStatus.LOADING);\n setErrorState(undefined);\n }\n }, [isMounted]);\n\n const setSuccessFn = useCallback(\n async (result: R) => {\n if (isMounted()) {\n setResult(result);\n setStatus(PromiseStatus.SUCCESS);\n setErrorState(undefined);\n try {\n await latestOptions.current?.onSuccess?.(result);\n } catch (callbackError) {\n // Log callback errors but don't affect state\n console.warn('PromiseState onSuccess callback error:', callbackError);\n }\n }\n },\n [isMounted, latestOptions],\n );\n\n const setErrorFn = useCallback(\n async (error: E) => {\n if (isMounted()) {\n setErrorState(error);\n setStatus(PromiseStatus.ERROR);\n setResult(undefined);\n try {\n await latestOptions.current?.onError?.(error);\n } catch (callbackError) {\n // Log callback errors but don't affect state\n console.warn('PromiseState onError callback error:', callbackError);\n }\n }\n },\n [isMounted, latestOptions],\n );\n\n const setIdleFn = useCallback(() => {\n if (isMounted()) {\n setStatus(PromiseStatus.IDLE);\n setErrorState(undefined);\n setResult(undefined);\n }\n }, [isMounted]);\n return useMemo(\n () => ({\n status,\n loading: status === PromiseStatus.LOADING,\n result,\n error,\n setLoading: setLoadingFn,\n setSuccess: setSuccessFn,\n setError: setErrorFn,\n setIdle: setIdleFn,\n }),\n [status, result, error, setLoadingFn, setSuccessFn, setErrorFn, setIdleFn],\n );\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useRef, useCallback, useMemo } from 'react';\n\n/**\n * Return type for useRequestId hook\n */\nexport interface UseRequestIdReturn {\n /** Generate a new request ID and get the current one */\n generate: () => number;\n /** Get the current request ID without generating a new one */\n current: () => number;\n /** Check if a given request ID is the latest */\n isLatest: (requestId: number) => boolean;\n /** Invalidate current request ID (mark as stale) */\n invalidate: () => void;\n /** Reset request ID counter */\n reset: () => void;\n}\n\n/**\n * A React hook for managing request IDs and race condition protection\n *\n * @example\n * ```typescript\n * // Basic usage\n * const requestId = useRequestId();\n *\n * const execute = async () => {\n * const id = requestId.generate();\n *\n * try {\n * const result = await someAsyncOperation();\n *\n * // Check if this is still the latest request\n * if (requestId.isLatest(id)) {\n * setState(result);\n * }\n * } catch (error) {\n * if (requestId.isLatest(id)) {\n * setError(error);\n * }\n * }\n * };\n *\n * // Manual cancellation\n * const handleCancel = () => {\n * requestId.invalidate(); // All ongoing requests will be ignored\n * };\n * ```\n *\n * @example\n * ```typescript\n * // With async operation wrapper\n * const { execute, cancel } = useAsyncOperation(async (data) => {\n * return await apiCall(data);\n * }, [requestId]);\n * ```\n */\nexport function useRequestId(): UseRequestIdReturn {\n const requestIdRef = useRef<number>(0);\n\n const generate = useCallback((): number => {\n return ++requestIdRef.current;\n }, []);\n\n const current = useCallback((): number => {\n return requestIdRef.current;\n }, []);\n\n const isLatest = useCallback((requestId: number): boolean => {\n return requestId === requestIdRef.current;\n }, []);\n\n const invalidate = useCallback((): void => {\n requestIdRef.current++;\n }, []);\n\n const reset = useCallback((): void => {\n requestIdRef.current = 0;\n }, []);\n return useMemo(() => {\n return {\n generate,\n current,\n isLatest,\n invalidate,\n reset,\n };\n }, [generate, current, isLatest, invalidate, reset]);\n}","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback, useMemo } from 'react';\nimport { useMounted } from './useMounted';\nimport {\n usePromiseState,\n PromiseState,\n UsePromiseStateOptions,\n} from './usePromiseState';\nimport { useRequestId } from './useRequestId';\nimport { FetcherError } from '@ahoo-wang/fetcher';\n\nexport interface UseExecutePromiseOptions<R, E = unknown>\n extends UsePromiseStateOptions<R, E> {\n /**\n * Whether to propagate errors thrown by the promise.\n * If true, the execute function will throw errors.\n * If false (default), the execute function will return the error as the result instead of throwing.\n */\n propagateError?: boolean;\n}\n\n/**\n * Type definition for a function that returns a Promise\n * @template R - The type of value the promise will resolve to\n */\nexport type PromiseSupplier<R> = () => Promise<R>;\n\n/**\n * Interface defining the return type of useExecutePromise hook\n * @template R - The type of the result value\n */\nexport interface UseExecutePromiseReturn<R, E = FetcherError>\n extends PromiseState<R, E> {\n /**\n * Function to execute a promise supplier or promise.\n * Returns a promise that resolves to the result on success, or the error if propagateError is false.\n */\n execute: (input: PromiseSupplier<R> | Promise<R>) => Promise<R | E>;\n /** Function to reset the state to initial values */\n reset: () => void;\n}\n\n/**\n * A React hook for managing asynchronous operations with proper state handling\n * @template R - The type of the result value\n * @template E - The type of the error value\n * @param options - Configuration options for the hook\n * @returns An object containing the current state and control functions\n *\n * @example\n * ```typescript\n * import { useExecutePromise } from '@ahoo-wang/fetcher-react';\n *\n * function MyComponent() {\n * const { loading, result, error, execute, reset } = useExecutePromise<string>();\n *\n * const fetchData = async () => {\n * const response = await fetch('/api/data');\n * return response.text();\n * };\n *\n * const handleFetch = () => {\n * execute(fetchData);\n * };\n *\n * const handleReset = () => {\n * reset();\n * };\n *\n * if (loading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * return (\n * <div>\n * <button onClick={handleFetch}>Fetch Data</button>\n * <button onClick={handleReset}>Reset</button>\n * {result && <p>{result}</p>}\n * </div>\n * );\n * }\n *\n * // Example with propagateError set to true\n * const { execute } = useExecutePromise<string>({ propagateError: true });\n * try {\n * await execute(fetchData);\n * } catch (err) {\n * console.error('Error occurred:', err);\n * }\n * ```\n */\nexport function useExecutePromise<R = unknown, E = FetcherError>(\n options?: UseExecutePromiseOptions<R, E>,\n): UseExecutePromiseReturn<R, E> {\n const { loading, result, error, status, setLoading, setSuccess, setError, setIdle } = usePromiseState<R, E>(options);\n const isMounted = useMounted();\n const requestId = useRequestId();\n const propagateError = options?.propagateError;\n /**\n * Execute a promise supplier or promise and manage its state\n * @param input - A function that returns a Promise or a Promise to be executed\n * @returns A Promise that resolves with the result on success, or the error if propagateError is false\n */\n const execute = useCallback(\n async (input: PromiseSupplier<R> | Promise<R>): Promise<R | E> => {\n if (!isMounted()) {\n throw new Error('Component is unmounted');\n }\n const currentRequestId = requestId.generate();\n setLoading();\n try {\n const promise = typeof input === 'function' ? input() : input;\n const data = await promise;\n\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n await setSuccess(data);\n }\n return data;\n } catch (err) {\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n await setError(err as E);\n }\n if (propagateError) {\n throw err;\n }\n return err as E;\n }\n },\n [setLoading, setSuccess, setError, isMounted, requestId, propagateError],\n );\n\n /**\n * Reset the state to initial values\n */\n const reset = useCallback(() => {\n if (isMounted()) {\n setIdle();\n }\n }, [setIdle, isMounted]);\n\n return useMemo(\n () => ({\n loading: loading,\n result: result,\n error: error,\n execute,\n reset,\n status: status,\n }),\n [loading, result, error, execute, reset, status],\n );\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback, useSyncExternalStore } from 'react';\nimport { KeyStorage } from '@ahoo-wang/fetcher-storage';\n\n/**\n * A React hook that provides state management for a KeyStorage instance.\n * Subscribes to storage changes and returns the current value along with a setter function.\n *\n * @template T - The type of value stored in the key storage\n * @param keyStorage - The KeyStorage instance to subscribe to and manage\n * @returns A tuple containing the current stored value and a function to update it\n */\nexport function useKeyStorage<T>(\n keyStorage: KeyStorage<T>,\n): [T | null, (value: T) => void] {\n const subscribe = useCallback(\n (callback: () => void) => keyStorage.addListener(callback),\n [keyStorage],\n );\n const getSnapshot = useCallback(() => keyStorage.get(), [keyStorage]);\n const value = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n const setValue = useCallback(\n (value: T) => keyStorage.set(value),\n [keyStorage],\n );\n return [value, setValue];\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n fetcherRegistrar,\n FetcherCapable,\n FetchExchange,\n FetchRequest,\n getFetcher,\n RequestOptions, FetcherError,\n} from '@ahoo-wang/fetcher';\nimport { useMounted } from '../core';\nimport { useRef, useCallback, useEffect, useState, useMemo } from 'react';\nimport {\n PromiseState,\n useLatest,\n usePromiseState,\n UsePromiseStateOptions,\n useRequestId,\n} from '../core';\n\n/**\n * Configuration options for the useFetcher hook.\n * Extends RequestOptions and FetcherCapable interfaces.\n */\nexport interface UseFetcherOptions<R, E = FetcherError>\n extends RequestOptions,\n FetcherCapable,\n UsePromiseStateOptions<R, E> {\n}\n\nexport interface UseFetcherReturn<R, E = FetcherError> extends PromiseState<R, E> {\n /** The FetchExchange object representing the ongoing fetch operation */\n exchange?: FetchExchange;\n execute: (request: FetchRequest) => Promise<void>;\n}\n\n/**\n * A React hook for managing asynchronous operations with proper state handling\n * @param options - Configuration options for the fetcher\n * @returns An object containing the current state and control functions\n *\n * @example\n * ```typescript\n * import { useFetcher } from '@ahoo-wang/fetcher-react';\n *\n * function MyComponent() {\n * const { loading, result, error, execute } = useFetcher<string>();\n *\n * const handleFetch = () => {\n * execute({ url: '/api/data', method: 'GET' });\n * };\n *\n * if (loading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * return (\n * <div>\n * <button onClick={handleFetch}>Fetch Data</button>\n * {result && <p>{result}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function useFetcher<R, E = FetcherError>(\n options?: UseFetcherOptions<R, E>,\n): UseFetcherReturn<R, E> {\n const { fetcher = fetcherRegistrar.default } = options || {};\n const state = usePromiseState<R, E>(options);\n const [exchange, setExchange] = useState<FetchExchange | undefined>(\n undefined,\n );\n const isMounted = useMounted();\n const abortControllerRef = useRef<AbortController | undefined>();\n const requestId = useRequestId();\n const latestOptions = useLatest(options);\n const currentFetcher = getFetcher(fetcher);\n /**\n * Execute the fetch operation.\n * Cancels any ongoing fetch before starting a new one.\n */\n const execute = useCallback(\n async (request: FetchRequest) => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n abortControllerRef.current =\n request.abortController ?? new AbortController();\n request.abortController = abortControllerRef.current;\n const currentRequestId = requestId.generate();\n state.setLoading();\n try {\n const exchange = await currentFetcher.exchange(\n request,\n latestOptions.current,\n );\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n setExchange(exchange);\n }\n const result = await exchange.extractResult<R>();\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n await state.setSuccess(result);\n }\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n if (isMounted()) {\n state.setIdle();\n }\n return;\n }\n if (isMounted() && requestId.isLatest(currentRequestId)) {\n await state.setError(error as E);\n }\n } finally {\n if (abortControllerRef.current === request.abortController) {\n abortControllerRef.current = undefined;\n }\n }\n },\n [currentFetcher, isMounted, latestOptions, state, requestId],\n );\n\n useEffect(() => {\n return () => {\n abortControllerRef.current?.abort();\n abortControllerRef.current = undefined;\n };\n }, []);\n return useMemo(\n () => ({\n ...state,\n exchange,\n execute,\n }),\n [state, exchange, execute],\n );\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n useExecutePromise,\n useLatest,\n UseExecutePromiseReturn,\n UseExecutePromiseOptions,\n} from '../core';\nimport { useCallback, useMemo, useEffect } from 'react';\nimport { AttributesCapable, FetcherError } from '@ahoo-wang/fetcher';\nimport { AutoExecuteCapable } from './types';\n\n/**\n * Configuration options for the useQuery hook\n * @template Q - The type of the query parameters\n * @template R - The type of the result value\n * @template E - The type of the error value\n */\nexport interface UseQueryOptions<Q, R, E = FetcherError>\n extends UseExecutePromiseOptions<R, E>,\n AttributesCapable,\n AutoExecuteCapable {\n /** The initial query parameters */\n initialQuery: Q;\n\n /** Function to execute the query with given parameters and optional attributes */\n execute: (query: Q, attributes?: Record<string, any>) => Promise<R>;\n}\n\n/**\n * Return type of the useQuery hook\n * @template Q - The type of the query parameters\n * @template R - The type of the result value\n * @template E - The type of the error value\n */\nexport interface UseQueryReturn<Q, R, E = FetcherError>\n extends UseExecutePromiseReturn<R, E> {\n /**\n * Get the current query parameters\n */\n getQuery: () => Q;\n /** Function to update the query parameters */\n setQuery: (query: Q) => void;\n /** Function to execute the query with current parameters */\n execute: () => Promise<R | E>;\n}\n\n/**\n * A React hook for managing query-based asynchronous operations\n * @template Q - The type of the query parameters\n * @template R - The type of the result value\n * @template E - The type of the error value\n * @param options - Configuration options for the query\n * @returns An object containing the query state and control functions\n *\n * @example\n * ```typescript\n * import { useQuery } from '@ahoo-wang/fetcher-react';\n *\n * interface UserQuery {\n * id: string;\n * }\n *\n * interface User {\n * id: string;\n * name: string;\n * }\n *\n * function UserComponent() {\n * const { loading, result, error, execute, setQuery } = useQuery<UserQuery, User>({\n * initialQuery: { id: '1' },\n * execute: async (query) => {\n * const response = await fetch(`/api/users/${query.id}`);\n * return response.json();\n * },\n * autoExecute: true,\n * });\n *\n * const handleUserChange = (userId: string) => {\n * setQuery({ id: userId }); // Automatically executes if autoExecute is true\n * };\n *\n * if (loading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * return (\n * <div>\n * <button onClick={() => handleUserChange('2')}>Load User 2</button>\n * {result && <p>User: {result.name}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function useQuery<Q, R, E = FetcherError>(\n options: UseQueryOptions<Q, R, E>,\n): UseQueryReturn<Q, R, E> {\n const { initialQuery } = options;\n const latestOptions = useLatest(options);\n const promiseState = useExecutePromise<R, E>(latestOptions.current);\n const latestQuery = useLatest(initialQuery);\n\n const queryExecutor = useCallback(async (): Promise<R> => {\n return latestOptions.current.execute(\n latestQuery.current,\n latestOptions.current.attributes,\n );\n }, [latestQuery, latestOptions]);\n const { execute: promiseExecutor } = promiseState;\n const execute = useCallback(() => {\n return promiseExecutor(queryExecutor);\n }, [promiseExecutor, queryExecutor]);\n const getQuery = useCallback(() => {\n return latestQuery.current;\n }, [latestQuery]);\n const setQuery = useCallback(\n (query: Q) => {\n latestQuery.current = query;\n if (latestOptions.current.autoExecute) {\n execute();\n }\n },\n [latestQuery, latestOptions, execute],\n );\n\n useEffect(() => {\n if (latestOptions.current.autoExecute) {\n execute();\n }\n }, [latestOptions, execute]);\n\n return useMemo(\n () => ({\n ...promiseState,\n execute,\n getQuery,\n setQuery,\n }),\n [promiseState, execute, getQuery, setQuery],\n );\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { PagedList, PagedQuery } from '@ahoo-wang/fetcher-wow';\nimport { FetcherError } from '@ahoo-wang/fetcher';\nimport { useQuery, UseQueryOptions, UseQueryReturn } from './useQuery';\n\n/**\n * Options for the usePagedQuery hook.\n * Extends UseQueryOptions with PagedQuery as query key and PagedList as data type.\n *\n * @template R - The type of the result items in the paged list\n * @template FIELDS - The fields type for the paged query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UsePagedQueryOptions<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryOptions<PagedQuery<FIELDS>, PagedList<R>, E> {\n}\n\n/**\n * Return type for the usePagedQuery hook.\n * Extends UseQueryReturn with PagedQuery as query key and PagedList as data type.\n *\n * @template R - The type of the result items in the paged list\n * @template FIELDS - The fields type for the paged query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UsePagedQueryReturn<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryReturn<PagedQuery<FIELDS>, PagedList<R>, E> {\n}\n\n/**\n * Hook for querying paged data with conditions, projection, pagination, and sorting.\n * Wraps useQuery to provide type-safe paged queries.\n *\n * @template R - The type of the result items in the paged list\n * @template FIELDS - The fields type for the paged query\n * @template E - The error type, defaults to FetcherError\n * @param options - The query options including paged query configuration\n * @returns The query result with paged list data\n *\n * @example\n * ```typescript\n * const { data, isLoading } = usePagedQuery<{ id: number; name: string }, 'id' | 'name'>({\n * initialQuery: {\n * condition: all(),\n * pagination: { index: 1, size: 10 },\n * projection: { include: ['id', 'name'] },\n * sort: [{ field: 'id', direction: SortDirection.ASC }],\n * },\n * execute: async (query) => fetchPagedData(query),\n * });\n * ```\n */\nexport function usePagedQuery<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n>(\n options: UsePagedQueryOptions<R, FIELDS, E>,\n): UsePagedQueryReturn<R, FIELDS, E> {\n return useQuery<PagedQuery<FIELDS>, PagedList<R>, E>(options);\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { SingleQuery } from '@ahoo-wang/fetcher-wow';\nimport { FetcherError } from '@ahoo-wang/fetcher';\nimport { useQuery, UseQueryOptions, UseQueryReturn } from './useQuery';\n\n/**\n * Options for the useSingleQuery hook.\n * Extends UseQueryOptions with SingleQuery as query key and custom result type.\n *\n * @template R - The result type of the query\n * @template FIELDS - The fields type for the single query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseSingleQueryOptions<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryOptions<SingleQuery<FIELDS>, R, E> {\n}\n\n/**\n * Return type for the useSingleQuery hook.\n * Extends UseQueryReturn with SingleQuery as query key and custom result type.\n *\n * @template R - The result type of the query\n * @template FIELDS - The fields type for the single query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseSingleQueryReturn<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryReturn<SingleQuery<FIELDS>, R, E> {\n}\n\n/**\n * Hook for querying a single item with conditions, projection, and sorting.\n * Wraps useQuery to provide type-safe single item queries.\n *\n * @template R - The result type of the query\n * @template FIELDS - The fields type for the single query\n * @template E - The error type, defaults to FetcherError\n * @param options - The query options including single query configuration\n * @returns The query result with single item data\n *\n * @example\n * ```typescript\n * const { data, isLoading } = useSingleQuery<{ id: number; name: string }, 'id' | 'name'>({\n * initialQuery: {\n * condition: all(),\n * projection: { include: ['id', 'name'] },\n * sort: [{ field: 'id', direction: SortDirection.ASC }],\n * },\n * execute: async (query) => fetchSingleItem(query),\n * });\n * ```\n */\nexport function useSingleQuery<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n>(\n options: UseSingleQueryOptions<R, FIELDS, E>,\n): UseSingleQueryReturn<R, FIELDS, E> {\n return useQuery<SingleQuery<FIELDS>, R, E>(options);\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Condition } from '@ahoo-wang/fetcher-wow';\nimport { FetcherError } from '@ahoo-wang/fetcher';\nimport { useQuery, UseQueryOptions, UseQueryReturn } from './useQuery';\n\n/**\n * Options for the useCountQuery hook.\n * Extends UseQueryOptions with Condition as query key and number as data type.\n *\n * @template FIELDS - The fields type for the condition\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseCountQueryOptions<\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryOptions<Condition<FIELDS>, number, E> {\n}\n\n/**\n * Return type for the useCountQuery hook.\n * Extends UseQueryReturn with Condition as query key and number as data type.\n *\n * @template FIELDS - The fields type for the condition\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseCountQueryReturn<\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryReturn<Condition<FIELDS>, number, E> {\n}\n\n/**\n * Hook for querying count data with conditions.\n * Wraps useQuery to provide type-safe count queries.\n *\n * @template FIELDS - The fields type for the condition\n * @template E - The error type, defaults to FetcherError\n * @param options - The query options including condition and other settings\n * @returns The query result with count data\n *\n * @example\n * ```typescript\n * const { data, isLoading } = useCountQuery({\n * queryKey: [{ field: 'status', operator: 'eq', value: 'active' }],\n * queryFn: async (condition) => fetchCount(condition),\n * });\n * ```\n */\nexport function useCountQuery<FIELDS extends string = string, E = FetcherError>(\n options: UseCountQueryOptions<FIELDS, E>,\n): UseCountQueryReturn<FIELDS, E> {\n return useQuery(options);\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ListQuery } from '@ahoo-wang/fetcher-wow';\nimport { FetcherError } from '@ahoo-wang/fetcher';\nimport { useQuery, UseQueryOptions, UseQueryReturn } from './useQuery';\n\n/**\n * Options for the useListQuery hook.\n * Extends UseQueryOptions with ListQuery as query key and array of results as data type.\n *\n * @template R - The type of the result items in the list\n * @template FIELDS - The fields type for the list query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseListQueryOptions<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryOptions<ListQuery<FIELDS>, R[], E> {\n}\n\n/**\n * Return type for the useListQuery hook.\n * Extends UseQueryReturn with ListQuery as query key and array of results as data type.\n *\n * @template R - The type of the result items in the list\n * @template FIELDS - The fields type for the list query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseListQueryReturn<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryReturn<ListQuery<FIELDS>, R[], E> {\n}\n\n/**\n * Hook for querying list data with conditions, projection, and sorting.\n * Wraps useQuery to provide type-safe list queries.\n *\n * @template R - The type of the result items in the list\n * @template FIELDS - The fields type for the list query\n * @template E - The error type, defaults to FetcherError\n * @param options - The query options including list query configuration\n * @returns The query result with list data\n *\n * @example\n * ```typescript\n * const { data, isLoading } = useListQuery<{ id: number; name: string }, 'id' | 'name'>({\n * initialQuery: {\n * condition: all(),\n * projection: { include: ['id', 'name'] },\n * sort: [{ field: 'id', direction: SortDirection.ASC }],\n * },\n * execute: async (query) => fetchListData(query),\n * });\n * ```\n */\nexport function useListQuery<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n>(\n options: UseListQueryOptions<R, FIELDS, E>,\n): UseListQueryReturn<R, FIELDS, E> {\n return useQuery<ListQuery<FIELDS>, R[], E>(options);\n}","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ListQuery } from '@ahoo-wang/fetcher-wow';\nimport type { JsonServerSentEvent } from '@ahoo-wang/fetcher-eventstream';\nimport { FetcherError } from '@ahoo-wang/fetcher';\nimport { useQuery, UseQueryOptions, UseQueryReturn } from './useQuery';\n\n/**\n * Options for the useListStreamQuery hook.\n * Extends UseQueryOptions with ListQuery as query key and stream of events as data type.\n *\n * @template R - The type of the result items in the stream events\n * @template FIELDS - The fields type for the list stream query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseListStreamQueryOptions<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryOptions<\n ListQuery<FIELDS>,\n ReadableStream<JsonServerSentEvent<R>>,\n E\n> {\n}\n\n/**\n * Return type for the useListStreamQuery hook.\n * Extends UseQueryReturn with ListQuery as query key and stream of events as data type.\n *\n * @template R - The type of the result items in the stream events\n * @template FIELDS - The fields type for the list stream query\n * @template E - The error type, defaults to FetcherError\n */\nexport interface UseListStreamQueryReturn<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n> extends UseQueryReturn<\n ListQuery<FIELDS>,\n ReadableStream<JsonServerSentEvent<R>>,\n E\n> {\n}\n\n/**\n * Hook for querying streaming list data with conditions, projection, and sorting.\n * Wraps useQuery to provide type-safe streaming list queries.\n *\n * @template R - The type of the result items in the stream events\n * @template FIELDS - The fields type for the list stream query\n * @template E - The error type, defaults to FetcherError\n * @param options - The query options including list stream query configuration\n * @returns The query result with streaming data\n *\n * @example\n * ```typescript\n * const { data, isLoading } = useListStreamQuery<{ id: number; name: string }, 'id' | 'name'>({\n * initialQuery: {\n * condition: all(),\n * projection: { include: ['id', 'name'] },\n * sort: [{ field: 'id', direction: SortDirection.ASC }],\n * },\n * execute: async (query) => fetchStreamData(query),\n * });\n * ```\n */\nexport function useListStreamQuery<\n R,\n FIELDS extends string = string,\n E = FetcherError,\n>(\n options: UseListStreamQueryOptions<R, FIELDS, E>,\n): UseListStreamQueryReturn<R, FIELDS, E> {\n return useQuery<ListQuery<FIELDS>, ReadableStream<JsonServerSentEvent<R>>, E>(\n options,\n );\n}\n"],"names":["useMounted","isMountedRef","useRef","isMountedFn","useCallback","useEffect","useLatest","value","ref","PromiseStatus","usePromiseState","options","status","setStatus","useState","result","setResult","error","setErrorState","isMounted","latestOptions","setLoadingFn","setSuccessFn","callbackError","setErrorFn","setIdleFn","useMemo","useRequestId","requestIdRef","generate","current","isLatest","requestId","invalidate","reset","useExecutePromise","loading","setLoading","setSuccess","setError","setIdle","propagateError","execute","input","currentRequestId","data","err","useKeyStorage","keyStorage","subscribe","callback","getSnapshot","useSyncExternalStore","setValue","useFetcher","fetcher","fetcherRegistrar","state","exchange","setExchange","abortControllerRef","currentFetcher","getFetcher","request","useQuery","initialQuery","promiseState","latestQuery","queryExecutor","promiseExecutor","getQuery","setQuery","query","usePagedQuery","useSingleQuery","useCountQuery","useListQuery","useListStreamQuery"],"mappings":"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"}
@@ -20,10 +20,14 @@ export interface UseQueryOptions<Q, R, E = FetcherError> extends UseExecutePromi
20
20
  * @template E - The type of the error value
21
21
  */
22
22
  export interface UseQueryReturn<Q, R, E = FetcherError> extends UseExecutePromiseReturn<R, E> {
23
- /** Function to execute the query with current parameters */
24
- execute: () => Promise<R | E>;
23
+ /**
24
+ * Get the current query parameters
25
+ */
26
+ getQuery: () => Q;
25
27
  /** Function to update the query parameters */
26
28
  setQuery: (query: Q) => void;
29
+ /** Function to execute the query with current parameters */
30
+ execute: () => Promise<R | E>;
27
31
  }
28
32
  /**
29
33
  * A React hook for managing query-based asynchronous operations
@@ -57,8 +61,7 @@ export interface UseQueryReturn<Q, R, E = FetcherError> extends UseExecutePromis
57
61
  * });
58
62
  *
59
63
  * const handleUserChange = (userId: string) => {
60
- * setQuery({ id: userId });
61
- * execute();
64
+ * setQuery({ id: userId }); // Automatically executes if autoExecute is true
62
65
  * };
63
66
  *
64
67
  * if (loading) return <div>Loading...</div>;
@@ -1 +1 @@
1
- {"version":3,"file":"useQuery.d.ts","sourceRoot":"","sources":["../../src/wow/useQuery.ts"],"names":[],"mappings":"AAaA,OAAO,EAGL,uBAAuB,EACvB,wBAAwB,EACzB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAE7C;;;;;GAKG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,YAAY,CACrD,SAAQ,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAAC,EACpC,iBAAiB,EACjB,kBAAkB;IACpB,mCAAmC;IACnC,YAAY,EAAE,CAAC,CAAC;IAEhB,kFAAkF;IAClF,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;CACrE;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,YAAY,CACpD,SAAQ,uBAAuB,CAAC,CAAC,EAAE,CAAC,CAAC;IACrC,4DAA4D;IAC5D,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,8CAA8C;IAC9C,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,YAAY,EAC7C,OAAO,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAChC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAsCzB"}
1
+ {"version":3,"file":"useQuery.d.ts","sourceRoot":"","sources":["../../src/wow/useQuery.ts"],"names":[],"mappings":"AAaA,OAAO,EAGL,uBAAuB,EACvB,wBAAwB,EACzB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAE7C;;;;;GAKG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,YAAY,CACrD,SAAQ,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAAC,EACpC,iBAAiB,EACjB,kBAAkB;IACpB,mCAAmC;IACnC,YAAY,EAAE,CAAC,CAAC;IAEhB,kFAAkF;IAClF,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;CACrE;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,YAAY,CACpD,SAAQ,uBAAuB,CAAC,CAAC,EAAE,CAAC,CAAC;IACrC;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC,CAAC;IAClB,8CAA8C;IAC9C,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC7B,4DAA4D;IAC5D,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,YAAY,EAC7C,OAAO,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAChC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CA4CzB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ahoo-wang/fetcher-react",
3
- "version": "2.6.16",
3
+ "version": "2.6.19",
4
4
  "description": "React integration for Fetcher HTTP client. Provides React Hooks and components for seamless data fetching with automatic re-rendering and loading states.",
5
5
  "keywords": [
6
6
  "fetch",