@ahoo-wang/fetcher-react 1.8.6 → 1.8.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -26,6 +26,88 @@ npm install @ahoo-wang/fetcher-react
26
26
 
27
27
  ## Usage
28
28
 
29
+ ### useFetcher Hook
30
+
31
+ The `useFetcher` hook provides a convenient way to fetch data in React components with automatic state management for
32
+ loading, error, and result states.
33
+
34
+ ```typescript jsx
35
+ import { useFetcher } from '@ahoo-wang/fetcher-react';
36
+
37
+ const MyComponent = () => {
38
+ const { loading, error, result, execute, cancel } = useFetcher({
39
+ url: '/api/users',
40
+ method: 'GET'
41
+ });
42
+
43
+ if (loading) return <div>Loading...</div>;
44
+ if (error) return <div>Error: {error.message}</div>;
45
+
46
+ return (
47
+ <div>
48
+ <pre>{JSON.stringify(result, null, 2)}</pre>
49
+ <button onClick={execute}>Refresh</button>
50
+ <button onClick={cancel}>Cancel</button>
51
+ </div>
52
+ );
53
+ };
54
+ ```
55
+
56
+ ### Manual Execution
57
+
58
+ To manually control when the fetch occurs, set the `immediate` option to `false`:
59
+
60
+ ```typescript jsx
61
+ import { useFetcher } from '@ahoo-wang/fetcher-react';
62
+
63
+ const MyComponent = () => {
64
+ const { loading, error, result, execute } = useFetcher({
65
+ url: '/api/users',
66
+ method: 'POST',
67
+ body: JSON.stringify({ name: 'John' })
68
+ }, { immediate: false });
69
+
70
+ const handleSubmit = async () => {
71
+ await execute();
72
+ };
73
+
74
+ if (loading) return <div>Submitting...</div>;
75
+ if (error) return <div>Error: {error.message}</div>;
76
+
77
+ return (
78
+ <div>
79
+ {result && <pre>{JSON.stringify(result, null, 2)}</pre>}
80
+ <button onClick={handleSubmit}>Submit</button>
81
+ </div>
82
+ );
83
+ };
84
+ ```
85
+
86
+ ### Custom Dependencies
87
+
88
+ You can specify dependencies that will trigger a refetch when they change:
89
+
90
+ ```typescript jsx
91
+ import { useFetcher } from '@ahoo-wang/fetcher-react';
92
+
93
+ const UserProfile = ({ userId }: { userId: string }) => {
94
+ const { loading, error, result } = useFetcher({
95
+ url: `/api/users/${userId}`,
96
+ method: 'GET'
97
+ }, { deps: [userId] });
98
+
99
+ if (loading) return <div>Loading...</div>;
100
+ if (error) return <div>Error: {error.message}</div>;
101
+
102
+ return (
103
+ <div>
104
+ <h1>{result?.name}</h1>
105
+ <p>{result?.email}</p>
106
+ </div>
107
+ );
108
+ };
109
+ ```
110
+
29
111
  ### useKeyStorage Hook
30
112
 
31
113
  The `useKeyStorage` hook provides state management for a KeyStorage instance. It subscribes to storage changes and
@@ -77,6 +159,37 @@ const [user, setUser] = useKeyStorage(userStorage);
77
159
 
78
160
  ## API Reference
79
161
 
162
+ ### useFetcher
163
+
164
+ ```typescript
165
+ function useFetcher<R>(
166
+ request: FetchRequest,
167
+ options?: UseFetcherOptions
168
+ ): UseFetcherResult<R>
169
+ ```
170
+
171
+ A React hook that provides data fetching capabilities with automatic state management.
172
+
173
+ **Parameters:**
174
+
175
+ - `request`: The fetch request configuration
176
+ - `options`: Configuration options for the fetch operation
177
+ - `deps`: Dependencies list for the fetch operation. When provided, the hook will re-fetch when any of these values
178
+ change.
179
+ - `immediate`: Whether the fetch operation should execute immediately upon component mount. Defaults to `true`.
180
+ - `fetcher`: Custom fetcher instance to use. Defaults to the default fetcher.
181
+
182
+ **Returns:**
183
+
184
+ An object containing:
185
+
186
+ - `loading`: Indicates if the fetch operation is currently in progress
187
+ - `exchange`: The FetchExchange object representing the ongoing fetch operation
188
+ - `result`: The data returned by the fetch operation
189
+ - `error`: Any error that occurred during the fetch operation
190
+ - `execute`: Function to manually trigger the fetch operation
191
+ - `cancel`: Function to cancel the ongoing fetch operation
192
+
80
193
  ### useKeyStorage
81
194
 
82
195
  ```typescript jsx
package/README.zh-CN.md CHANGED
@@ -25,6 +25,87 @@ npm install @ahoo-wang/fetcher-react
25
25
 
26
26
  ## 使用方法
27
27
 
28
+ ### useFetcher Hook
29
+
30
+ `useFetcher` hook 提供了一种在 React 组件中获取数据的便捷方式,具有自动管理加载、错误和结果状态的功能。
31
+
32
+ ```typescript jsx
33
+ import { useFetcher } from '@ahoo-wang/fetcher-react';
34
+
35
+ const MyComponent = () => {
36
+ const { loading, error, result, execute, cancel } = useFetcher({
37
+ url: '/api/users',
38
+ method: 'GET'
39
+ });
40
+
41
+ if (loading) return <div>加载中...</div>;
42
+ if (error) return <div>错误: {error.message}</div>;
43
+
44
+ return (
45
+ <div>
46
+ <pre>{JSON.stringify(result, null, 2)}</pre>
47
+ <button onClick={execute}>刷新</button>
48
+ <button onClick={cancel}>取消</button>
49
+ </div>
50
+ );
51
+ };
52
+ ```
53
+
54
+ ### 手动执行
55
+
56
+ 要手动控制获取数据的时机,请将 `immediate` 选项设置为 `false`:
57
+
58
+ ```typescript jsx
59
+ import { useFetcher } from '@ahoo-wang/fetcher-react';
60
+
61
+ const MyComponent = () => {
62
+ const { loading, error, result, execute } = useFetcher({
63
+ url: '/api/users',
64
+ method: 'POST',
65
+ body: JSON.stringify({ name: 'John' })
66
+ }, { immediate: false });
67
+
68
+ const handleSubmit = async () => {
69
+ await execute();
70
+ };
71
+
72
+ if (loading) return <div>提交中...</div>;
73
+ if (error) return <div>错误: {error.message}</div>;
74
+
75
+ return (
76
+ <div>
77
+ {result && <pre>{JSON.stringify(result, null, 2)}</pre>}
78
+ <button onClick={handleSubmit}>提交</button>
79
+ </div>
80
+ );
81
+ };
82
+ ```
83
+
84
+ ### 自定义依赖项
85
+
86
+ 您可以指定依赖项,当它们发生变化时会触发重新获取:
87
+
88
+ ```typescript jsx
89
+ import { useFetcher } from '@ahoo-wang/fetcher-react';
90
+
91
+ const UserProfile = ({ userId }: { userId: string }) => {
92
+ const { loading, error, result } = useFetcher({
93
+ url: `/api/users/${userId}`,
94
+ method: 'GET'
95
+ }, { deps: [userId] });
96
+
97
+ if (loading) return <div>加载中...</div>;
98
+ if (error) return <div>错误: {error.message}</div>;
99
+
100
+ return (
101
+ <div>
102
+ <h1>{result?.name}</h1>
103
+ <p>{result?.email}</p>
104
+ </div>
105
+ );
106
+ };
107
+ ```
108
+
28
109
  ### useKeyStorage Hook
29
110
 
30
111
  `useKeyStorage` hook 为 KeyStorage 实例提供状态管理。它订阅存储变化并返回当前值以及设置值的函数。
@@ -72,6 +153,36 @@ const [user, setUser] = useKeyStorage(userStorage);
72
153
 
73
154
  ## API 参考
74
155
 
156
+ ### useFetcher
157
+
158
+ ```typescript
159
+ function useFetcher<R>(
160
+ request: FetchRequest,
161
+ options?: UseFetcherOptions
162
+ ): UseFetcherResult<R>
163
+ ```
164
+
165
+ 提供数据获取功能并自动管理状态的 React hook。
166
+
167
+ **参数:**
168
+
169
+ - `request`: 获取数据的请求配置
170
+ - `options`: 获取数据操作的配置选项
171
+ - `deps`: 获取数据操作的依赖项列表。提供时,当这些值中的任何一个发生变化时,hook 将重新获取数据。
172
+ - `immediate`: 获取数据操作是否应在组件挂载时立即执行。默认为 `true`。
173
+ - `fetcher`: 要使用的自定义获取器实例。默认为默认获取器。
174
+
175
+ **返回值:**
176
+
177
+ 包含以下属性的对象:
178
+
179
+ - `loading`: 指示获取数据操作当前是否正在进行中
180
+ - `exchange`: 代表正在进行的获取数据操作的 FetchExchange 对象
181
+ - `result`: 获取数据操作返回的数据
182
+ - `error`: 获取数据操作期间发生的任何错误
183
+ - `execute`: 手动触发获取数据操作的函数
184
+ - `cancel`: 取消正在进行的获取数据操作的函数
185
+
75
186
  ### useKeyStorage
76
187
 
77
188
  ```typescript jsx
@@ -1,15 +1,9 @@
1
1
  import { FetcherCapable, FetchExchange, FetchRequest, RequestOptions } from '@ahoo-wang/fetcher';
2
- import { DependencyList } from 'react';
3
2
  /**
4
3
  * Configuration options for the useFetcher hook.
5
4
  * Extends RequestOptions and FetcherCapable interfaces.
6
5
  */
7
6
  export interface UseFetcherOptions extends RequestOptions, FetcherCapable {
8
- /**
9
- * Dependencies list for the fetch operation.
10
- * When provided, the hook will re-fetch when any of these values change.
11
- */
12
- readonly deps?: DependencyList;
13
7
  /**
14
8
  * Whether the fetch operation should execute immediately upon component mount.
15
9
  * Defaults to true.
@@ -1 +1 @@
1
- {"version":3,"file":"useFetcher.d.ts","sourceRoot":"","sources":["../../src/fetcher/useFetcher.ts"],"names":[],"mappings":"AAaA,OAAO,EAEL,cAAc,EACd,aAAa,EACb,YAAY,EACZ,cAAc,EACf,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,cAAc,EAA4C,MAAM,OAAO,CAAC;AAGjF;;;GAGG;AACH,MAAM,WAAW,iBAAkB,SAAQ,cAAc,EAAE,cAAc;IACvE;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,cAAc,CAAC;IAE/B;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,gEAAgE;IAChE,OAAO,EAAE,OAAO,CAAC;IAEjB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,aAAa,CAAC;IAEzB,oGAAoG;IACpG,MAAM,CAAC,EAAE,CAAC,CAAC;IAEX,mFAAmF;IACnF,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;OAGG;IACH,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7B,qDAAqD;IACrD,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAmErG"}
1
+ {"version":3,"file":"useFetcher.d.ts","sourceRoot":"","sources":["../../src/fetcher/useFetcher.ts"],"names":[],"mappings":"AAaA,OAAO,EAEL,cAAc,EACd,aAAa,EACb,YAAY,EACZ,cAAc,EACf,MAAM,oBAAoB,CAAC;AAI5B;;;GAGG;AACH,MAAM,WAAW,iBAAkB,SAAQ,cAAc,EAAE,cAAc;IACvE;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,gEAAgE;IAChE,OAAO,EAAE,OAAO,CAAC;IAEjB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,aAAa,CAAC;IAEzB,oGAAoG;IACpG,MAAM,CAAC,EAAE,CAAC,CAAC;IAEX,mFAAmF;IACnF,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;OAGG;IACH,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7B,qDAAqD;IACrD,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAmErG"}
package/dist/index.es.js CHANGED
@@ -1,63 +1,63 @@
1
- import { useCallback as o, useSyncExternalStore as F, useRef as v, useEffect as m, useState as i } from "react";
2
- import { fetcher as A, getFetcher as L } from "@ahoo-wang/fetcher";
3
- function V(t) {
4
- const e = o(
5
- (s) => t.addListener(s),
1
+ import { useCallback as u, useSyncExternalStore as F, useRef as h, useEffect as v, useState as i } from "react";
2
+ import { fetcher as p, getFetcher as A } from "@ahoo-wang/fetcher";
3
+ function S(t) {
4
+ const e = u(
5
+ (n) => t.addListener(n),
6
6
  [t]
7
- ), u = o(
7
+ ), s = u(
8
8
  () => t.get(),
9
9
  [t]
10
- ), f = F(
10
+ ), a = F(
11
11
  e,
12
- u,
13
- u
14
- ), a = o(
15
- (s) => t.set(s),
12
+ s,
13
+ s
14
+ ), f = u(
15
+ (n) => t.set(n),
16
16
  [t]
17
17
  );
18
- return [f, a];
18
+ return [a, f];
19
19
  }
20
- function M() {
21
- var t = v(!1), e = o(function() {
20
+ function L() {
21
+ var t = h(!1), e = u(function() {
22
22
  return t.current;
23
23
  }, []);
24
- return m(function() {
24
+ return v(function() {
25
25
  return t.current = !0, function() {
26
26
  t.current = !1;
27
27
  };
28
28
  }, []), e;
29
29
  }
30
- function $(t, e) {
31
- const { deps: u = [], fetcher: f = A, immediate: a = !0 } = e || {}, [s, d] = i(!1), [x, b] = i(void 0), [g, C] = i(void 0), [E, R] = i(void 0), n = M(), r = v(), h = L(f), l = o(async () => {
32
- r.current && r.current.abort(), r.current = t.abortController ?? new AbortController(), t.abortController = r.current, n() && (d(!0), b(void 0));
30
+ function V(t, e) {
31
+ const { fetcher: s = p, immediate: a = !0 } = e || {}, [f, n] = i(!1), [m, d] = i(void 0), [x, g] = i(void 0), [C, E] = i(void 0), c = L(), r = h(), b = A(s), l = u(async () => {
32
+ r.current && r.current.abort(), r.current = t.abortController ?? new AbortController(), t.abortController = r.current, c() && (n(!0), d(void 0));
33
33
  try {
34
- const c = await h.exchange(t, e);
35
- n() && C(c);
36
- const w = await c.extractResult();
37
- n() && R(w);
38
- } catch (c) {
39
- if (c instanceof Error && c.name === "AbortError")
34
+ const o = await b.exchange(t, e);
35
+ c() && g(o);
36
+ const w = await o.extractResult();
37
+ c() && E(w);
38
+ } catch (o) {
39
+ if (o instanceof Error && o.name === "AbortError")
40
40
  return;
41
- n() && b(c);
41
+ c() && d(o);
42
42
  } finally {
43
- n() && d(!1), r.current === t.abortController && (r.current = void 0);
43
+ c() && n(!1), r.current === t.abortController && (r.current = void 0);
44
44
  }
45
- }, [h, n, e, ...u]), p = o(() => {
45
+ }, [b, t, c, e]), R = u(() => {
46
46
  r.current?.abort();
47
47
  }, []);
48
- return m(() => (a && l(), () => {
48
+ return v(() => (a && l(), () => {
49
49
  r.current?.abort(), r.current = void 0;
50
- }), [l, a, ...u]), {
51
- loading: s,
52
- exchange: g,
53
- result: E,
54
- error: x,
50
+ }), [l, t, a]), {
51
+ loading: f,
52
+ exchange: x,
53
+ result: C,
54
+ error: m,
55
55
  execute: l,
56
- cancel: p
56
+ cancel: R
57
57
  };
58
58
  }
59
59
  export {
60
- $ as useFetcher,
61
- V as useKeyStorage
60
+ V as useFetcher,
61
+ S as useKeyStorage
62
62
  };
63
63
  //# sourceMappingURL=index.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../src/storage/useKeyStorage.ts","../../../node_modules/.pnpm/react-use@17.6.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/react-use/esm/useMountedState.js","../src/fetcher/useFetcher.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 { 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(\n () => keyStorage.get(),\n [keyStorage],\n );\n const value = useSyncExternalStore(\n subscribe,\n getSnapshot,\n getSnapshot,\n );\n const setValue = useCallback(\n (value: T) => keyStorage.set(value),\n [keyStorage],\n );\n return [value, setValue];\n}","import { useCallback, useEffect, useRef } from 'react';\nexport default function useMountedState() {\n var mountedRef = useRef(false);\n var get = useCallback(function () { return mountedRef.current; }, []);\n useEffect(function () {\n mountedRef.current = true;\n return function () {\n mountedRef.current = false;\n };\n }, []);\n return get;\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 fetcher as defaultFetcher,\n FetcherCapable,\n FetchExchange,\n FetchRequest, getFetcher,\n RequestOptions,\n} from '@ahoo-wang/fetcher';\nimport { DependencyList, useRef, useCallback, useEffect, useState } from 'react';\nimport { useMountedState } from 'react-use';\n\n/**\n * Configuration options for the useFetcher hook.\n * Extends RequestOptions and FetcherCapable interfaces.\n */\nexport interface UseFetcherOptions extends RequestOptions, FetcherCapable {\n /**\n * Dependencies list for the fetch operation.\n * When provided, the hook will re-fetch when any of these values change.\n */\n readonly deps?: DependencyList;\n\n /**\n * Whether the fetch operation should execute immediately upon component mount.\n * Defaults to true.\n */\n readonly immediate?: boolean;\n}\n\n/**\n * The result object returned by the useFetcher hook.\n * @template R - The type of the data returned by the fetch operation\n */\nexport interface UseFetcherResult<R> {\n /** Indicates if the fetch operation is currently in progress */\n loading: boolean;\n\n /** The FetchExchange object representing the ongoing fetch operation */\n exchange?: FetchExchange;\n\n /** The data returned by the fetch operation, or undefined if not yet loaded or an error occurred */\n result?: R;\n\n /** Any error that occurred during the fetch operation, or undefined if no error */\n error?: unknown;\n\n /**\n * Function to manually trigger the fetch operation.\n * Useful for fetching data on demand rather than automatically.\n */\n execute: () => Promise<void>;\n\n /** Function to cancel the ongoing fetch operation */\n cancel: () => void;\n}\n\nexport function useFetcher<R>(request: FetchRequest, options?: UseFetcherOptions): UseFetcherResult<R> {\n const { deps = [], fetcher = defaultFetcher, immediate = true } = options || {};\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<unknown>(undefined);\n const [exchange, setExchange] = useState<FetchExchange | undefined>(undefined);\n const [result, setResult] = useState<R | undefined>(undefined);\n const isMounted = useMountedState();\n const abortControllerRef = useRef<AbortController | undefined>();\n\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(async () => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n abortControllerRef.current = request.abortController ?? new AbortController();\n request.abortController = abortControllerRef.current;\n if (isMounted()) {\n setLoading(true);\n setError(undefined);\n }\n try {\n const exchange = await currentFetcher.exchange(request, options);\n if (isMounted()) {\n setExchange(exchange);\n }\n const result = await exchange.extractResult<R>();\n if (isMounted()) {\n setResult(result);\n }\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n return;\n }\n if (isMounted()) {\n setError(error);\n }\n } finally {\n if (isMounted()) {\n setLoading(false);\n }\n if (abortControllerRef.current === request.abortController) {\n abortControllerRef.current = undefined;\n }\n }\n }, [currentFetcher, isMounted, options, ...deps]);\n /**\n * Cancel the ongoing fetch operation if one is in progress.\n */\n const cancel = useCallback(() => {\n abortControllerRef.current?.abort();\n }, []);\n useEffect(() => {\n if (immediate) {\n execute();\n }\n return () => {\n abortControllerRef.current?.abort();\n abortControllerRef.current = undefined;\n };\n }, [execute, immediate, ...deps]);\n return {\n loading, exchange, result, error, execute, cancel,\n };\n}"],"names":["useKeyStorage","keyStorage","subscribe","useCallback","callback","getSnapshot","value","useSyncExternalStore","setValue","useMountedState","mountedRef","useRef","get","useEffect","useFetcher","request","options","deps","fetcher","defaultFetcher","immediate","loading","setLoading","useState","error","setError","exchange","setExchange","result","setResult","isMounted","abortControllerRef","currentFetcher","getFetcher","execute","cancel"],"mappings":";;AAwBO,SAASA,EACdC,GACgC;AAChC,QAAMC,IAAYC;AAAA,IAChB,CAACC,MAAyBH,EAAW,YAAYG,CAAQ;AAAA,IACzD,CAACH,CAAU;AAAA,EAAA,GAEPI,IAAcF;AAAA,IAClB,MAAMF,EAAW,IAAA;AAAA,IACjB,CAACA,CAAU;AAAA,EAAA,GAEPK,IAAQC;AAAA,IACZL;AAAA,IACAG;AAAA,IACAA;AAAA,EAAA,GAEIG,IAAWL;AAAA,IACf,CAACG,MAAaL,EAAW,IAAIK,CAAK;AAAA,IAClC,CAACL,CAAU;AAAA,EAAA;AAEb,SAAO,CAACK,GAAOE,CAAQ;AACzB;AC5Ce,SAASC,IAAkB;AACtC,MAAIC,IAAaC,EAAO,EAAK,GACzBC,IAAMT,EAAY,WAAY;AAAE,WAAOO,EAAW;AAAA,EAAS,GAAG,EAAE;AACpE,SAAAG,EAAU,WAAY;AAClB,WAAAH,EAAW,UAAU,IACd,WAAY;AACf,MAAAA,EAAW,UAAU;AAAA,IACzB;AAAA,EACJ,GAAG,CAAA,CAAE,GACEE;AACX;ACyDO,SAASE,EAAcC,GAAuBC,GAAkD;AACrG,QAAM,EAAE,MAAAC,IAAO,CAAA,YAAIC,IAAUC,GAAgB,WAAAC,IAAY,OAASJ,KAAW,CAAA,GACvE,CAACK,GAASC,CAAU,IAAIC,EAAS,EAAK,GACtC,CAACC,GAAOC,CAAQ,IAAIF,EAAkB,MAAS,GAC/C,CAACG,GAAUC,CAAW,IAAIJ,EAAoC,MAAS,GACvE,CAACK,GAAQC,CAAS,IAAIN,EAAwB,MAAS,GACvDO,IAAYrB,EAAA,GACZsB,IAAqBpB,EAAA,GAErBqB,IAAiBC,EAAWf,CAAO,GAKnCgB,IAAU/B,EAAY,YAAY;AACtC,IAAI4B,EAAmB,WACrBA,EAAmB,QAAQ,MAAA,GAE7BA,EAAmB,UAAUhB,EAAQ,mBAAmB,IAAI,gBAAA,GAC5DA,EAAQ,kBAAkBgB,EAAmB,SACzCD,QACFR,EAAW,EAAI,GACfG,EAAS,MAAS;AAEpB,QAAI;AACF,YAAMC,IAAW,MAAMM,EAAe,SAASjB,GAASC,CAAO;AAC/D,MAAIc,OACFH,EAAYD,CAAQ;AAEtB,YAAME,IAAS,MAAMF,EAAS,cAAA;AAC9B,MAAII,OACFD,EAAUD,CAAM;AAAA,IAEpB,SAASJ,GAAO;AACd,UAAIA,aAAiB,SAASA,EAAM,SAAS;AAC3C;AAEF,MAAIM,OACFL,EAASD,CAAK;AAAA,IAElB,UAAA;AACE,MAAIM,OACFR,EAAW,EAAK,GAEdS,EAAmB,YAAYhB,EAAQ,oBACzCgB,EAAmB,UAAU;AAAA,IAEjC;AAAA,EACF,GAAG,CAACC,GAAgBF,GAAWd,GAAS,GAAGC,CAAI,CAAC,GAI1CkB,IAAShC,EAAY,MAAM;AAC/B,IAAA4B,EAAmB,SAAS,MAAA;AAAA,EAC9B,GAAG,CAAA,CAAE;AACL,SAAAlB,EAAU,OACJO,KACFc,EAAA,GAEK,MAAM;AACX,IAAAH,EAAmB,SAAS,MAAA,GAC5BA,EAAmB,UAAU;AAAA,EAC/B,IACC,CAACG,GAASd,GAAW,GAAGH,CAAI,CAAC,GACzB;AAAA,IACL,SAAAI;AAAA,IAAS,UAAAK;AAAA,IAAU,QAAAE;AAAA,IAAQ,OAAAJ;AAAA,IAAO,SAAAU;AAAA,IAAS,QAAAC;AAAA,EAAA;AAE/C;","x_google_ignoreList":[1]}
1
+ {"version":3,"file":"index.es.js","sources":["../src/storage/useKeyStorage.ts","../../../node_modules/.pnpm/react-use@17.6.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/react-use/esm/useMountedState.js","../src/fetcher/useFetcher.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 { 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(\n () => keyStorage.get(),\n [keyStorage],\n );\n const value = useSyncExternalStore(\n subscribe,\n getSnapshot,\n getSnapshot,\n );\n const setValue = useCallback(\n (value: T) => keyStorage.set(value),\n [keyStorage],\n );\n return [value, setValue];\n}","import { useCallback, useEffect, useRef } from 'react';\nexport default function useMountedState() {\n var mountedRef = useRef(false);\n var get = useCallback(function () { return mountedRef.current; }, []);\n useEffect(function () {\n mountedRef.current = true;\n return function () {\n mountedRef.current = false;\n };\n }, []);\n return get;\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 fetcher as defaultFetcher,\n FetcherCapable,\n FetchExchange,\n FetchRequest, getFetcher,\n RequestOptions,\n} from '@ahoo-wang/fetcher';\nimport { useRef, useCallback, useEffect, useState } from 'react';\nimport { useMountedState } from 'react-use';\n\n/**\n * Configuration options for the useFetcher hook.\n * Extends RequestOptions and FetcherCapable interfaces.\n */\nexport interface UseFetcherOptions extends RequestOptions, FetcherCapable {\n /**\n * Whether the fetch operation should execute immediately upon component mount.\n * Defaults to true.\n */\n readonly immediate?: boolean;\n}\n\n/**\n * The result object returned by the useFetcher hook.\n * @template R - The type of the data returned by the fetch operation\n */\nexport interface UseFetcherResult<R> {\n /** Indicates if the fetch operation is currently in progress */\n loading: boolean;\n\n /** The FetchExchange object representing the ongoing fetch operation */\n exchange?: FetchExchange;\n\n /** The data returned by the fetch operation, or undefined if not yet loaded or an error occurred */\n result?: R;\n\n /** Any error that occurred during the fetch operation, or undefined if no error */\n error?: unknown;\n\n /**\n * Function to manually trigger the fetch operation.\n * Useful for fetching data on demand rather than automatically.\n */\n execute: () => Promise<void>;\n\n /** Function to cancel the ongoing fetch operation */\n cancel: () => void;\n}\n\nexport function useFetcher<R>(request: FetchRequest, options?: UseFetcherOptions): UseFetcherResult<R> {\n const { fetcher = defaultFetcher, immediate = true } = options || {};\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<unknown>(undefined);\n const [exchange, setExchange] = useState<FetchExchange | undefined>(undefined);\n const [result, setResult] = useState<R | undefined>(undefined);\n const isMounted = useMountedState();\n const abortControllerRef = useRef<AbortController | undefined>();\n\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(async () => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n abortControllerRef.current = request.abortController ?? new AbortController();\n request.abortController = abortControllerRef.current;\n if (isMounted()) {\n setLoading(true);\n setError(undefined);\n }\n try {\n const exchange = await currentFetcher.exchange(request, options);\n if (isMounted()) {\n setExchange(exchange);\n }\n const result = await exchange.extractResult<R>();\n if (isMounted()) {\n setResult(result);\n }\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n return;\n }\n if (isMounted()) {\n setError(error);\n }\n } finally {\n if (isMounted()) {\n setLoading(false);\n }\n if (abortControllerRef.current === request.abortController) {\n abortControllerRef.current = undefined;\n }\n }\n }, [currentFetcher, request, isMounted, options]);\n /**\n * Cancel the ongoing fetch operation if one is in progress.\n */\n const cancel = useCallback(() => {\n abortControllerRef.current?.abort();\n }, []);\n useEffect(() => {\n if (immediate) {\n execute();\n }\n return () => {\n abortControllerRef.current?.abort();\n abortControllerRef.current = undefined;\n };\n }, [execute, request, immediate]);\n return {\n loading, exchange, result, error, execute, cancel,\n };\n}"],"names":["useKeyStorage","keyStorage","subscribe","useCallback","callback","getSnapshot","value","useSyncExternalStore","setValue","useMountedState","mountedRef","useRef","get","useEffect","useFetcher","request","options","fetcher","defaultFetcher","immediate","loading","setLoading","useState","error","setError","exchange","setExchange","result","setResult","isMounted","abortControllerRef","currentFetcher","getFetcher","execute","cancel"],"mappings":";;AAwBO,SAASA,EACdC,GACgC;AAChC,QAAMC,IAAYC;AAAA,IAChB,CAACC,MAAyBH,EAAW,YAAYG,CAAQ;AAAA,IACzD,CAACH,CAAU;AAAA,EAAA,GAEPI,IAAcF;AAAA,IAClB,MAAMF,EAAW,IAAA;AAAA,IACjB,CAACA,CAAU;AAAA,EAAA,GAEPK,IAAQC;AAAA,IACZL;AAAA,IACAG;AAAA,IACAA;AAAA,EAAA,GAEIG,IAAWL;AAAA,IACf,CAACG,MAAaL,EAAW,IAAIK,CAAK;AAAA,IAClC,CAACL,CAAU;AAAA,EAAA;AAEb,SAAO,CAACK,GAAOE,CAAQ;AACzB;AC5Ce,SAASC,IAAkB;AACtC,MAAIC,IAAaC,EAAO,EAAK,GACzBC,IAAMT,EAAY,WAAY;AAAE,WAAOO,EAAW;AAAA,EAAS,GAAG,EAAE;AACpE,SAAAG,EAAU,WAAY;AAClB,WAAAH,EAAW,UAAU,IACd,WAAY;AACf,MAAAA,EAAW,UAAU;AAAA,IACzB;AAAA,EACJ,GAAG,CAAA,CAAE,GACEE;AACX;ACmDO,SAASE,EAAcC,GAAuBC,GAAkD;AACrG,QAAM,EAAA,SAAEC,IAAUC,GAAgB,WAAAC,IAAY,GAAA,IAASH,KAAW,CAAA,GAC5D,CAACI,GAASC,CAAU,IAAIC,EAAS,EAAK,GACtC,CAACC,GAAOC,CAAQ,IAAIF,EAAkB,MAAS,GAC/C,CAACG,GAAUC,CAAW,IAAIJ,EAAoC,MAAS,GACvE,CAACK,GAAQC,CAAS,IAAIN,EAAwB,MAAS,GACvDO,IAAYpB,EAAA,GACZqB,IAAqBnB,EAAA,GAErBoB,IAAiBC,EAAWf,CAAO,GAKnCgB,IAAU9B,EAAY,YAAY;AACtC,IAAI2B,EAAmB,WACrBA,EAAmB,QAAQ,MAAA,GAE7BA,EAAmB,UAAUf,EAAQ,mBAAmB,IAAI,gBAAA,GAC5DA,EAAQ,kBAAkBe,EAAmB,SACzCD,QACFR,EAAW,EAAI,GACfG,EAAS,MAAS;AAEpB,QAAI;AACF,YAAMC,IAAW,MAAMM,EAAe,SAAShB,GAASC,CAAO;AAC/D,MAAIa,OACFH,EAAYD,CAAQ;AAEtB,YAAME,IAAS,MAAMF,EAAS,cAAA;AAC9B,MAAII,OACFD,EAAUD,CAAM;AAAA,IAEpB,SAASJ,GAAO;AACd,UAAIA,aAAiB,SAASA,EAAM,SAAS;AAC3C;AAEF,MAAIM,OACFL,EAASD,CAAK;AAAA,IAElB,UAAA;AACE,MAAIM,OACFR,EAAW,EAAK,GAEdS,EAAmB,YAAYf,EAAQ,oBACzCe,EAAmB,UAAU;AAAA,IAEjC;AAAA,EACF,GAAG,CAACC,GAAgBhB,GAASc,GAAWb,CAAO,CAAC,GAI1CkB,IAAS/B,EAAY,MAAM;AAC/B,IAAA2B,EAAmB,SAAS,MAAA;AAAA,EAC9B,GAAG,CAAA,CAAE;AACL,SAAAjB,EAAU,OACJM,KACFc,EAAA,GAEK,MAAM;AACX,IAAAH,EAAmB,SAAS,MAAA,GAC5BA,EAAmB,UAAU;AAAA,EAC/B,IACC,CAACG,GAASlB,GAASI,CAAS,CAAC,GACzB;AAAA,IACL,SAAAC;AAAA,IAAS,UAAAK;AAAA,IAAU,QAAAE;AAAA,IAAQ,OAAAJ;AAAA,IAAO,SAAAU;AAAA,IAAS,QAAAC;AAAA,EAAA;AAE/C;","x_google_ignoreList":[1]}
package/dist/index.umd.js CHANGED
@@ -1,2 +1,2 @@
1
- (function(r,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("react"),require("@ahoo-wang/fetcher")):typeof define=="function"&&define.amd?define(["exports","react","@ahoo-wang/fetcher"],e):(r=typeof globalThis<"u"?globalThis:r||self,e(r.FetcherReact={},r.React,r.Fetcher))})(this,(function(r,e,d){"use strict";function v(t){const u=e.useCallback(i=>t.addListener(i),[t]),s=e.useCallback(()=>t.get(),[t]),a=e.useSyncExternalStore(u,s,s),f=e.useCallback(i=>t.set(i),[t]);return[a,f]}function g(){var t=e.useRef(!1),u=e.useCallback(function(){return t.current},[]);return e.useEffect(function(){return t.current=!0,function(){t.current=!1}},[]),u}function x(t,u){const{deps:s=[],fetcher:a=d.fetcher,immediate:f=!0}=u||{},[i,h]=e.useState(!1),[m,b]=e.useState(void 0),[E,S]=e.useState(void 0),[p,F]=e.useState(void 0),o=g(),n=e.useRef(),C=d.getFetcher(a),l=e.useCallback(async()=>{n.current&&n.current.abort(),n.current=t.abortController??new AbortController,t.abortController=n.current,o()&&(h(!0),b(void 0));try{const c=await C.exchange(t,u);o()&&S(c);const y=await c.extractResult();o()&&F(y)}catch(c){if(c instanceof Error&&c.name==="AbortError")return;o()&&b(c)}finally{o()&&h(!1),n.current===t.abortController&&(n.current=void 0)}},[C,o,u,...s]),w=e.useCallback(()=>{n.current?.abort()},[]);return e.useEffect(()=>(f&&l(),()=>{n.current?.abort(),n.current=void 0}),[l,f,...s]),{loading:i,exchange:E,result:p,error:m,execute:l,cancel:w}}r.useFetcher=x,r.useKeyStorage=v,Object.defineProperty(r,Symbol.toStringTag,{value:"Module"})}));
1
+ (function(r,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("react"),require("@ahoo-wang/fetcher")):typeof define=="function"&&define.amd?define(["exports","react","@ahoo-wang/fetcher"],e):(r=typeof globalThis<"u"?globalThis:r||self,e(r.FetcherReact={},r.React,r.Fetcher))})(this,(function(r,e,d){"use strict";function C(t){const o=e.useCallback(u=>t.addListener(u),[t]),i=e.useCallback(()=>t.get(),[t]),f=e.useSyncExternalStore(o,i,i),a=e.useCallback(u=>t.set(u),[t]);return[f,a]}function v(){var t=e.useRef(!1),o=e.useCallback(function(){return t.current},[]);return e.useEffect(function(){return t.current=!0,function(){t.current=!1}},[]),o}function g(t,o){const{fetcher:i=d.fetcher,immediate:f=!0}=o||{},[a,u]=e.useState(!1),[x,h]=e.useState(void 0),[m,E]=e.useState(void 0),[S,F]=e.useState(void 0),c=v(),n=e.useRef(),b=d.getFetcher(i),l=e.useCallback(async()=>{n.current&&n.current.abort(),n.current=t.abortController??new AbortController,t.abortController=n.current,c()&&(u(!0),h(void 0));try{const s=await b.exchange(t,o);c()&&E(s);const w=await s.extractResult();c()&&F(w)}catch(s){if(s instanceof Error&&s.name==="AbortError")return;c()&&h(s)}finally{c()&&u(!1),n.current===t.abortController&&(n.current=void 0)}},[b,t,c,o]),p=e.useCallback(()=>{n.current?.abort()},[]);return e.useEffect(()=>(f&&l(),()=>{n.current?.abort(),n.current=void 0}),[l,t,f]),{loading:a,exchange:m,result:S,error:x,execute:l,cancel:p}}r.useFetcher=g,r.useKeyStorage=C,Object.defineProperty(r,Symbol.toStringTag,{value:"Module"})}));
2
2
  //# sourceMappingURL=index.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","sources":["../src/storage/useKeyStorage.ts","../../../node_modules/.pnpm/react-use@17.6.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/react-use/esm/useMountedState.js","../src/fetcher/useFetcher.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 { 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(\n () => keyStorage.get(),\n [keyStorage],\n );\n const value = useSyncExternalStore(\n subscribe,\n getSnapshot,\n getSnapshot,\n );\n const setValue = useCallback(\n (value: T) => keyStorage.set(value),\n [keyStorage],\n );\n return [value, setValue];\n}","import { useCallback, useEffect, useRef } from 'react';\nexport default function useMountedState() {\n var mountedRef = useRef(false);\n var get = useCallback(function () { return mountedRef.current; }, []);\n useEffect(function () {\n mountedRef.current = true;\n return function () {\n mountedRef.current = false;\n };\n }, []);\n return get;\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 fetcher as defaultFetcher,\n FetcherCapable,\n FetchExchange,\n FetchRequest, getFetcher,\n RequestOptions,\n} from '@ahoo-wang/fetcher';\nimport { DependencyList, useRef, useCallback, useEffect, useState } from 'react';\nimport { useMountedState } from 'react-use';\n\n/**\n * Configuration options for the useFetcher hook.\n * Extends RequestOptions and FetcherCapable interfaces.\n */\nexport interface UseFetcherOptions extends RequestOptions, FetcherCapable {\n /**\n * Dependencies list for the fetch operation.\n * When provided, the hook will re-fetch when any of these values change.\n */\n readonly deps?: DependencyList;\n\n /**\n * Whether the fetch operation should execute immediately upon component mount.\n * Defaults to true.\n */\n readonly immediate?: boolean;\n}\n\n/**\n * The result object returned by the useFetcher hook.\n * @template R - The type of the data returned by the fetch operation\n */\nexport interface UseFetcherResult<R> {\n /** Indicates if the fetch operation is currently in progress */\n loading: boolean;\n\n /** The FetchExchange object representing the ongoing fetch operation */\n exchange?: FetchExchange;\n\n /** The data returned by the fetch operation, or undefined if not yet loaded or an error occurred */\n result?: R;\n\n /** Any error that occurred during the fetch operation, or undefined if no error */\n error?: unknown;\n\n /**\n * Function to manually trigger the fetch operation.\n * Useful for fetching data on demand rather than automatically.\n */\n execute: () => Promise<void>;\n\n /** Function to cancel the ongoing fetch operation */\n cancel: () => void;\n}\n\nexport function useFetcher<R>(request: FetchRequest, options?: UseFetcherOptions): UseFetcherResult<R> {\n const { deps = [], fetcher = defaultFetcher, immediate = true } = options || {};\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<unknown>(undefined);\n const [exchange, setExchange] = useState<FetchExchange | undefined>(undefined);\n const [result, setResult] = useState<R | undefined>(undefined);\n const isMounted = useMountedState();\n const abortControllerRef = useRef<AbortController | undefined>();\n\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(async () => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n abortControllerRef.current = request.abortController ?? new AbortController();\n request.abortController = abortControllerRef.current;\n if (isMounted()) {\n setLoading(true);\n setError(undefined);\n }\n try {\n const exchange = await currentFetcher.exchange(request, options);\n if (isMounted()) {\n setExchange(exchange);\n }\n const result = await exchange.extractResult<R>();\n if (isMounted()) {\n setResult(result);\n }\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n return;\n }\n if (isMounted()) {\n setError(error);\n }\n } finally {\n if (isMounted()) {\n setLoading(false);\n }\n if (abortControllerRef.current === request.abortController) {\n abortControllerRef.current = undefined;\n }\n }\n }, [currentFetcher, isMounted, options, ...deps]);\n /**\n * Cancel the ongoing fetch operation if one is in progress.\n */\n const cancel = useCallback(() => {\n abortControllerRef.current?.abort();\n }, []);\n useEffect(() => {\n if (immediate) {\n execute();\n }\n return () => {\n abortControllerRef.current?.abort();\n abortControllerRef.current = undefined;\n };\n }, [execute, immediate, ...deps]);\n return {\n loading, exchange, result, error, execute, cancel,\n };\n}"],"names":["useKeyStorage","keyStorage","subscribe","useCallback","callback","getSnapshot","value","useSyncExternalStore","setValue","useMountedState","mountedRef","useRef","get","useEffect","useFetcher","request","options","deps","fetcher","defaultFetcher","immediate","loading","setLoading","useState","error","setError","exchange","setExchange","result","setResult","isMounted","abortControllerRef","currentFetcher","getFetcher","execute","cancel"],"mappings":"uUAwBO,SAASA,EACdC,EACgC,CAChC,MAAMC,EAAYC,EAAAA,YACfC,GAAyBH,EAAW,YAAYG,CAAQ,EACzD,CAACH,CAAU,CAAA,EAEPI,EAAcF,EAAAA,YAClB,IAAMF,EAAW,IAAA,EACjB,CAACA,CAAU,CAAA,EAEPK,EAAQC,EAAAA,qBACZL,EACAG,EACAA,CAAA,EAEIG,EAAWL,EAAAA,YACdG,GAAaL,EAAW,IAAIK,CAAK,EAClC,CAACL,CAAU,CAAA,EAEb,MAAO,CAACK,EAAOE,CAAQ,CACzB,CC5Ce,SAASC,GAAkB,CACtC,IAAIC,EAAaC,EAAAA,OAAO,EAAK,EACzBC,EAAMT,EAAAA,YAAY,UAAY,CAAE,OAAOO,EAAW,OAAS,EAAG,EAAE,EACpEG,OAAAA,EAAAA,UAAU,UAAY,CAClB,OAAAH,EAAW,QAAU,GACd,UAAY,CACfA,EAAW,QAAU,EACzB,CACJ,EAAG,CAAA,CAAE,EACEE,CACX,CCyDO,SAASE,EAAcC,EAAuBC,EAAkD,CACrG,KAAM,CAAE,KAAAC,EAAO,CAAA,UAAIC,EAAUC,EAAAA,QAAgB,UAAAC,EAAY,IAASJ,GAAW,CAAA,EACvE,CAACK,EAASC,CAAU,EAAIC,EAAAA,SAAS,EAAK,EACtC,CAACC,EAAOC,CAAQ,EAAIF,EAAAA,SAAkB,MAAS,EAC/C,CAACG,EAAUC,CAAW,EAAIJ,EAAAA,SAAoC,MAAS,EACvE,CAACK,EAAQC,CAAS,EAAIN,EAAAA,SAAwB,MAAS,EACvDO,EAAYrB,EAAA,EACZsB,EAAqBpB,EAAAA,OAAA,EAErBqB,EAAiBC,EAAAA,WAAWf,CAAO,EAKnCgB,EAAU/B,EAAAA,YAAY,SAAY,CAClC4B,EAAmB,SACrBA,EAAmB,QAAQ,MAAA,EAE7BA,EAAmB,QAAUhB,EAAQ,iBAAmB,IAAI,gBAC5DA,EAAQ,gBAAkBgB,EAAmB,QACzCD,MACFR,EAAW,EAAI,EACfG,EAAS,MAAS,GAEpB,GAAI,CACF,MAAMC,EAAW,MAAMM,EAAe,SAASjB,EAASC,CAAO,EAC3Dc,KACFH,EAAYD,CAAQ,EAEtB,MAAME,EAAS,MAAMF,EAAS,cAAA,EAC1BI,KACFD,EAAUD,CAAM,CAEpB,OAASJ,EAAO,CACd,GAAIA,aAAiB,OAASA,EAAM,OAAS,aAC3C,OAEEM,KACFL,EAASD,CAAK,CAElB,QAAA,CACMM,KACFR,EAAW,EAAK,EAEdS,EAAmB,UAAYhB,EAAQ,kBACzCgB,EAAmB,QAAU,OAEjC,CACF,EAAG,CAACC,EAAgBF,EAAWd,EAAS,GAAGC,CAAI,CAAC,EAI1CkB,EAAShC,EAAAA,YAAY,IAAM,CAC/B4B,EAAmB,SAAS,MAAA,CAC9B,EAAG,CAAA,CAAE,EACLlB,OAAAA,EAAAA,UAAU,KACJO,GACFc,EAAA,EAEK,IAAM,CACXH,EAAmB,SAAS,MAAA,EAC5BA,EAAmB,QAAU,MAC/B,GACC,CAACG,EAASd,EAAW,GAAGH,CAAI,CAAC,EACzB,CACL,QAAAI,EAAS,SAAAK,EAAU,OAAAE,EAAQ,MAAAJ,EAAO,QAAAU,EAAS,OAAAC,CAAA,CAE/C","x_google_ignoreList":[1]}
1
+ {"version":3,"file":"index.umd.js","sources":["../src/storage/useKeyStorage.ts","../../../node_modules/.pnpm/react-use@17.6.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/react-use/esm/useMountedState.js","../src/fetcher/useFetcher.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 { 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(\n () => keyStorage.get(),\n [keyStorage],\n );\n const value = useSyncExternalStore(\n subscribe,\n getSnapshot,\n getSnapshot,\n );\n const setValue = useCallback(\n (value: T) => keyStorage.set(value),\n [keyStorage],\n );\n return [value, setValue];\n}","import { useCallback, useEffect, useRef } from 'react';\nexport default function useMountedState() {\n var mountedRef = useRef(false);\n var get = useCallback(function () { return mountedRef.current; }, []);\n useEffect(function () {\n mountedRef.current = true;\n return function () {\n mountedRef.current = false;\n };\n }, []);\n return get;\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 fetcher as defaultFetcher,\n FetcherCapable,\n FetchExchange,\n FetchRequest, getFetcher,\n RequestOptions,\n} from '@ahoo-wang/fetcher';\nimport { useRef, useCallback, useEffect, useState } from 'react';\nimport { useMountedState } from 'react-use';\n\n/**\n * Configuration options for the useFetcher hook.\n * Extends RequestOptions and FetcherCapable interfaces.\n */\nexport interface UseFetcherOptions extends RequestOptions, FetcherCapable {\n /**\n * Whether the fetch operation should execute immediately upon component mount.\n * Defaults to true.\n */\n readonly immediate?: boolean;\n}\n\n/**\n * The result object returned by the useFetcher hook.\n * @template R - The type of the data returned by the fetch operation\n */\nexport interface UseFetcherResult<R> {\n /** Indicates if the fetch operation is currently in progress */\n loading: boolean;\n\n /** The FetchExchange object representing the ongoing fetch operation */\n exchange?: FetchExchange;\n\n /** The data returned by the fetch operation, or undefined if not yet loaded or an error occurred */\n result?: R;\n\n /** Any error that occurred during the fetch operation, or undefined if no error */\n error?: unknown;\n\n /**\n * Function to manually trigger the fetch operation.\n * Useful for fetching data on demand rather than automatically.\n */\n execute: () => Promise<void>;\n\n /** Function to cancel the ongoing fetch operation */\n cancel: () => void;\n}\n\nexport function useFetcher<R>(request: FetchRequest, options?: UseFetcherOptions): UseFetcherResult<R> {\n const { fetcher = defaultFetcher, immediate = true } = options || {};\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<unknown>(undefined);\n const [exchange, setExchange] = useState<FetchExchange | undefined>(undefined);\n const [result, setResult] = useState<R | undefined>(undefined);\n const isMounted = useMountedState();\n const abortControllerRef = useRef<AbortController | undefined>();\n\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(async () => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n abortControllerRef.current = request.abortController ?? new AbortController();\n request.abortController = abortControllerRef.current;\n if (isMounted()) {\n setLoading(true);\n setError(undefined);\n }\n try {\n const exchange = await currentFetcher.exchange(request, options);\n if (isMounted()) {\n setExchange(exchange);\n }\n const result = await exchange.extractResult<R>();\n if (isMounted()) {\n setResult(result);\n }\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n return;\n }\n if (isMounted()) {\n setError(error);\n }\n } finally {\n if (isMounted()) {\n setLoading(false);\n }\n if (abortControllerRef.current === request.abortController) {\n abortControllerRef.current = undefined;\n }\n }\n }, [currentFetcher, request, isMounted, options]);\n /**\n * Cancel the ongoing fetch operation if one is in progress.\n */\n const cancel = useCallback(() => {\n abortControllerRef.current?.abort();\n }, []);\n useEffect(() => {\n if (immediate) {\n execute();\n }\n return () => {\n abortControllerRef.current?.abort();\n abortControllerRef.current = undefined;\n };\n }, [execute, request, immediate]);\n return {\n loading, exchange, result, error, execute, cancel,\n };\n}"],"names":["useKeyStorage","keyStorage","subscribe","useCallback","callback","getSnapshot","value","useSyncExternalStore","setValue","useMountedState","mountedRef","useRef","get","useEffect","useFetcher","request","options","fetcher","defaultFetcher","immediate","loading","setLoading","useState","error","setError","exchange","setExchange","result","setResult","isMounted","abortControllerRef","currentFetcher","getFetcher","execute","cancel"],"mappings":"uUAwBO,SAASA,EACdC,EACgC,CAChC,MAAMC,EAAYC,EAAAA,YACfC,GAAyBH,EAAW,YAAYG,CAAQ,EACzD,CAACH,CAAU,CAAA,EAEPI,EAAcF,EAAAA,YAClB,IAAMF,EAAW,IAAA,EACjB,CAACA,CAAU,CAAA,EAEPK,EAAQC,EAAAA,qBACZL,EACAG,EACAA,CAAA,EAEIG,EAAWL,EAAAA,YACdG,GAAaL,EAAW,IAAIK,CAAK,EAClC,CAACL,CAAU,CAAA,EAEb,MAAO,CAACK,EAAOE,CAAQ,CACzB,CC5Ce,SAASC,GAAkB,CACtC,IAAIC,EAAaC,EAAAA,OAAO,EAAK,EACzBC,EAAMT,EAAAA,YAAY,UAAY,CAAE,OAAOO,EAAW,OAAS,EAAG,EAAE,EACpEG,OAAAA,EAAAA,UAAU,UAAY,CAClB,OAAAH,EAAW,QAAU,GACd,UAAY,CACfA,EAAW,QAAU,EACzB,CACJ,EAAG,CAAA,CAAE,EACEE,CACX,CCmDO,SAASE,EAAcC,EAAuBC,EAAkD,CACrG,KAAM,CAAA,QAAEC,EAAUC,EAAAA,QAAgB,UAAAC,EAAY,EAAA,EAASH,GAAW,CAAA,EAC5D,CAACI,EAASC,CAAU,EAAIC,EAAAA,SAAS,EAAK,EACtC,CAACC,EAAOC,CAAQ,EAAIF,EAAAA,SAAkB,MAAS,EAC/C,CAACG,EAAUC,CAAW,EAAIJ,EAAAA,SAAoC,MAAS,EACvE,CAACK,EAAQC,CAAS,EAAIN,EAAAA,SAAwB,MAAS,EACvDO,EAAYpB,EAAA,EACZqB,EAAqBnB,EAAAA,OAAA,EAErBoB,EAAiBC,EAAAA,WAAWf,CAAO,EAKnCgB,EAAU9B,EAAAA,YAAY,SAAY,CAClC2B,EAAmB,SACrBA,EAAmB,QAAQ,MAAA,EAE7BA,EAAmB,QAAUf,EAAQ,iBAAmB,IAAI,gBAC5DA,EAAQ,gBAAkBe,EAAmB,QACzCD,MACFR,EAAW,EAAI,EACfG,EAAS,MAAS,GAEpB,GAAI,CACF,MAAMC,EAAW,MAAMM,EAAe,SAAShB,EAASC,CAAO,EAC3Da,KACFH,EAAYD,CAAQ,EAEtB,MAAME,EAAS,MAAMF,EAAS,cAAA,EAC1BI,KACFD,EAAUD,CAAM,CAEpB,OAASJ,EAAO,CACd,GAAIA,aAAiB,OAASA,EAAM,OAAS,aAC3C,OAEEM,KACFL,EAASD,CAAK,CAElB,QAAA,CACMM,KACFR,EAAW,EAAK,EAEdS,EAAmB,UAAYf,EAAQ,kBACzCe,EAAmB,QAAU,OAEjC,CACF,EAAG,CAACC,EAAgBhB,EAASc,EAAWb,CAAO,CAAC,EAI1CkB,EAAS/B,EAAAA,YAAY,IAAM,CAC/B2B,EAAmB,SAAS,MAAA,CAC9B,EAAG,CAAA,CAAE,EACLjB,OAAAA,EAAAA,UAAU,KACJM,GACFc,EAAA,EAEK,IAAM,CACXH,EAAmB,SAAS,MAAA,EAC5BA,EAAmB,QAAU,MAC/B,GACC,CAACG,EAASlB,EAASI,CAAS,CAAC,EACzB,CACL,QAAAC,EAAS,SAAAK,EAAU,OAAAE,EAAQ,MAAAJ,EAAO,QAAAU,EAAS,OAAAC,CAAA,CAE/C","x_google_ignoreList":[1]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ahoo-wang/fetcher-react",
3
- "version": "1.8.6",
3
+ "version": "1.8.9",
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",
@@ -38,24 +38,37 @@
38
38
  ],
39
39
  "dependencies": {
40
40
  "react-use": "^17.6.0",
41
- "@ahoo-wang/fetcher": "1.8.6",
42
- "@ahoo-wang/fetcher-storage": "1.8.6"
41
+ "@ahoo-wang/fetcher": "1.8.9",
42
+ "@ahoo-wang/fetcher-storage": "1.8.9"
43
43
  },
44
44
  "peerDependencies": {
45
45
  "react": ">=16.8.0",
46
46
  "react-dom": ">=16.8.0"
47
47
  },
48
48
  "devDependencies": {
49
+ "@eslint/js": "^9.35.0",
50
+ "@vitest/coverage-v8": "^3.2.4",
51
+ "@vitest/ui": "^3.2.4",
52
+ "eslint": "^9.35.0",
53
+ "globals": "^16.4.0",
54
+ "prettier": "^3.6.2",
55
+ "typescript": "^5.9.2",
56
+ "typescript-eslint": "^8.43.0",
57
+ "eslint-plugin-react-hooks": "^5.2.0",
58
+ "unplugin-dts": "1.0.0-beta.6",
59
+ "vite": "^7.1.5",
60
+ "vite-bundle-analyzer": "^1.2.3",
61
+ "vitest": "^3.2.4",
49
62
  "@testing-library/react": "^16.0.0",
50
63
  "@types/react": "^18.0.0",
51
64
  "@types/react-dom": "^18.0.0",
52
- "@vitest/coverage-v8": "^3.2.4",
53
65
  "jsdom": "^27.0.0",
54
66
  "react": "^18.0.0",
55
67
  "react-dom": "^18.0.0"
56
68
  },
57
69
  "scripts": {
58
70
  "build": "vite build",
71
+ "test:ui": "vitest --ui",
59
72
  "test": "vitest run --coverage",
60
73
  "lint": "eslint . --fix",
61
74
  "clean": "rm -rf dist",