@cloudcome/utils-vue 1.14.1 → 1.15.0

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/dist/async.cjs CHANGED
@@ -2,34 +2,37 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  let vue = require("vue");
3
3
  //#region src/async.ts
4
4
  function useAsync(fn, options) {
5
- const times = (0, vue.ref)(0);
6
- const loading = (0, vue.ref)(false);
5
+ const _times = (0, vue.ref)(0);
6
+ const _loading = (0, vue.ref)(false);
7
7
  const placeholder = options?.placeholder;
8
- const data = (0, vue.ref)(placeholder ? placeholder() : null);
9
- const error = (0, vue.ref)(null);
8
+ const _data = (0, vue.shallowRef)(placeholder ? placeholder() : null);
9
+ const _error = (0, vue.ref)(null);
10
+ const times = (0, vue.computed)(() => _times.value);
11
+ const loading = (0, vue.computed)(() => _loading.value);
12
+ const data = (0, vue.computed)(() => _data.value);
13
+ const error = (0, vue.computed)(() => _error.value);
10
14
  const state = (0, vue.computed)(() => ({
11
15
  times: times.value,
12
16
  loading: loading.value,
13
- data: data.value,
14
17
  error: error.value
15
18
  }));
16
19
  const runAsync = async (...inputs) => {
17
- loading.value = true;
18
- error.value = null;
20
+ _loading.value = true;
21
+ _error.value = null;
19
22
  try {
20
23
  await options?.onBefore?.(...inputs);
21
- times.value++;
22
- data.value = await fn(...inputs);
23
- await options?.onSuccess?.(data.value, ...inputs);
24
- return data.value;
24
+ _times.value++;
25
+ _data.value = await fn(...inputs);
26
+ await options?.onSuccess?.(_data.value, ...inputs);
27
+ return _data.value;
25
28
  } catch (err) {
26
- error.value = err;
29
+ _error.value = err;
27
30
  try {
28
31
  options?.onError?.(err, ...inputs);
29
32
  } catch {}
30
33
  throw err;
31
34
  } finally {
32
- loading.value = false;
35
+ _loading.value = false;
33
36
  await options?.onAfter?.(...inputs);
34
37
  }
35
38
  };
@@ -1 +1 @@
1
- {"version":3,"file":"async.cjs","names":[],"sources":["../src/async.ts"],"sourcesContent":["import type { AnyArray } from '@cloudcome/utils-core/types';\nimport { type ComputedRef, computed, type Ref, ref } from 'vue';\n\n/**\n * 异步操作的配置选项\n * @template T 异步操作返回的数据类型\n * @template P 异步操作的参数类型\n */\nexport type UseAsyncOptions<I extends AnyArray, O> = {\n placeholder?: () => O;\n\n /**\n * 异步操作开始前的回调函数,可用于执行初始化逻辑或显示加载状态,抛出错误则中断操作\n */\n onBefore?: (...inputs: I) => unknown;\n\n /**\n * 异步操作成功后的回调函数,可用于处理成功后的数据更新或通知。\n * @param data 异步操作返回的数据。\n */\n onSuccess?: (data: O, ...inputs: I) => unknown;\n\n /**\n * 异步操作失败后的回调函数,可用于记录错误日志或显示错误提示。\n * @param err 异步操作抛出的错误。\n */\n onError?: (err: unknown, ...inputs: I) => unknown;\n\n /**\n * 异步操作结束后的回调函数(无论成功或失败),可用于清理操作或触发后续逻辑。\n */\n onAfter?: (...inputs: I) => unknown;\n};\n\nexport type UseAsyncState<O> = {\n times: number;\n loading: boolean;\n error: unknown;\n data: O | null;\n};\n\nexport type UseAsyncStateFilled<O> = {\n times: number;\n loading: boolean;\n error: unknown;\n data: O;\n};\n\nexport type UseAsyncOutput<I extends AnyArray, O> = {\n state: ComputedRef<UseAsyncState<O>>;\n loading: Ref<boolean>;\n data: Ref<O | null>;\n error: Ref<unknown>;\n run: (...inputs: I) => void;\n runAsync: (...inputs: I) => Promise<O>;\n};\n\nexport type UseAsyncOutputFilled<I extends AnyArray, O> = {\n state: ComputedRef<UseAsyncStateFilled<O>>;\n loading: Ref<boolean>;\n data: Ref<O>;\n error: Ref<unknown>;\n run: (...inputs: I) => void;\n runAsync: (...inputs: I) => Promise<O>;\n};\n\n/**\n * 用于处理异步操作的组合式函数。\n * 提供加载状态、数据、错误信息以及执行方法。\n * @template O 异步函数返回的数据类型\n * @template I 异步函数的入参类型\n * @param fn 异步函数,接收参数并返回 Promise。\n * @param options 异步操作的配置选项。\n * @returns 包含状态和操作方法的对象:\n * - loading: 是否正在加载。\n * - data: 异步操作返回的数据。\n * - error: 异步操作抛出的错误。\n * - runAsync: 执行异步操作并返回 Promise。\n * - run: 执行异步操作但不返回 Promise。\n * @example\n * const { loading, data, error, runAsync, run } = useAsync(async (id: number) => {\n * const response = await fetch(`/api/user/${id}`);\n * return response.json();\n * }, {\n * onBefore: () => console.log('Fetching user data...'),\n * onSuccess: (data) => console.log('User data fetched:', data),\n * onError: (err) => console.error('Failed to fetch user data:', err),\n * onFinally: () => console.log('Fetch operation completed.'),\n * });\n */\nexport function useAsync<I extends AnyArray, O>(\n fn: (...inputs: I) => Promise<O>,\n options: Omit<UseAsyncOptions<I, O>, 'placeholder'> & {\n placeholder: () => O;\n },\n): UseAsyncOutputFilled<I, O>;\nexport function useAsync<I extends AnyArray, O>(\n fn: (...inputs: I) => Promise<O>,\n options?: UseAsyncOptions<I, O>,\n): UseAsyncOutput<I, O>;\nexport function useAsync<I extends AnyArray, O>(\n fn: (...inputs: I) => Promise<O>,\n options?: UseAsyncOptions<I, O>,\n): UseAsyncOutput<I, O> {\n const times = ref(0);\n const loading = ref(false);\n const placeholder = options?.placeholder;\n const data = ref(placeholder ? placeholder() : null) as Ref<O | null>;\n const error = ref<unknown>(null);\n const state = computed(() => ({\n times: times.value,\n loading: loading.value,\n data: data.value,\n error: error.value,\n }));\n\n const runAsync = async (...inputs: I): Promise<O> => {\n loading.value = true;\n error.value = null;\n\n try {\n await options?.onBefore?.(...inputs);\n times.value++;\n data.value = await fn(...inputs);\n await options?.onSuccess?.(data.value, ...inputs);\n return data.value;\n } catch (err) {\n error.value = err;\n try {\n options?.onError?.(err, ...inputs);\n } catch {\n //\n }\n throw err;\n } finally {\n loading.value = false;\n await options?.onAfter?.(...inputs);\n }\n };\n\n const run = (...inputs: I) => {\n runAsync(...inputs).then();\n };\n\n return {\n state,\n /**\n * 是否正在加载。\n */\n loading,\n\n /**\n * 异步操作返回的数据。\n */\n data,\n\n /**\n * 异步操作抛出的错误。\n */\n error,\n\n /**\n * 执行异步操作并返回 Promise。\n * @param inputs 异步函数的参数。\n * @returns 异步操作的结果。\n */\n runAsync,\n\n /**\n * 执行异步操作但不返回 Promise。\n * @param inputs 异步函数的参数。\n */\n run,\n };\n}\n\n// const { run: run1 } = useAsync(() => Promise.resolve(1));\n// run1();\n\n// const { run: run2 } = useAsync((a: number) => Promise.resolve(1));\n// run2(2);\n\n// const { run: run3 } = useAsync((a: number, b: string) => Promise.resolve(1));\n// run3(2, '2');\n"],"mappings":";;;AAoGA,SAAgB,SACd,IACA,SACsB;CACtB,MAAM,SAAA,GAAA,IAAA,KAAY,EAAE;CACpB,MAAM,WAAA,GAAA,IAAA,KAAc,MAAM;CAC1B,MAAM,cAAc,SAAS;CAC7B,MAAM,QAAA,GAAA,IAAA,KAAW,cAAc,aAAa,GAAG,KAAK;CACpD,MAAM,SAAA,GAAA,IAAA,KAAqB,KAAK;CAChC,MAAM,SAAA,GAAA,IAAA,iBAAwB;EAC5B,OAAO,MAAM;EACb,SAAS,QAAQ;EACjB,MAAM,KAAK;EACX,OAAO,MAAM;EACd,EAAE;CAEH,MAAM,WAAW,OAAO,GAAG,WAA0B;EACnD,QAAQ,QAAQ;EAChB,MAAM,QAAQ;EAEd,IAAI;GACF,MAAM,SAAS,WAAW,GAAG,OAAO;GACpC,MAAM;GACN,KAAK,QAAQ,MAAM,GAAG,GAAG,OAAO;GAChC,MAAM,SAAS,YAAY,KAAK,OAAO,GAAG,OAAO;GACjD,OAAO,KAAK;WACL,KAAK;GACZ,MAAM,QAAQ;GACd,IAAI;IACF,SAAS,UAAU,KAAK,GAAG,OAAO;WAC5B;GAGR,MAAM;YACE;GACR,QAAQ,QAAQ;GAChB,MAAM,SAAS,UAAU,GAAG,OAAO;;;CAIvC,MAAM,OAAO,GAAG,WAAc;EAC5B,SAAS,GAAG,OAAO,CAAC,MAAM;;CAG5B,OAAO;EACL;;;;EAIA;;;;EAKA;;;;EAKA;;;;;;EAOA;;;;;EAMA;EACD"}
1
+ {"version":3,"file":"async.cjs","names":[],"sources":["../src/async.ts"],"sourcesContent":["import type { AnyArray } from '@cloudcome/utils-core/types';\nimport { computed, type ComputedRef, ref, type ShallowRef, shallowRef } from 'vue';\n\n/**\n * 异步操作的配置选项\n * @template T 异步操作返回的数据类型\n * @template P 异步操作的参数类型\n */\nexport type UseAsyncOptions<I extends AnyArray, O> = {\n placeholder?: () => O;\n\n /**\n * 异步操作开始前的回调函数,可用于执行初始化逻辑或显示加载状态,抛出错误则中断操作\n */\n onBefore?: (...inputs: I) => unknown;\n\n /**\n * 异步操作成功后的回调函数,可用于处理成功后的数据更新或通知。\n * @param data 异步操作返回的数据。\n */\n onSuccess?: (data: O, ...inputs: I) => unknown;\n\n /**\n * 异步操作失败后的回调函数,可用于记录错误日志或显示错误提示。\n * @param err 异步操作抛出的错误。\n */\n onError?: (err: unknown, ...inputs: I) => unknown;\n\n /**\n * 异步操作结束后的回调函数(无论成功或失败),可用于清理操作或触发后续逻辑。\n */\n onAfter?: (...inputs: I) => unknown;\n};\n\nexport type UseAsyncState = {\n times: number;\n loading: boolean;\n error: unknown;\n};\n\nexport type UseAsyncOutput<I extends AnyArray, O> = {\n state: ComputedRef<UseAsyncState>;\n loading: ComputedRef<boolean>;\n data: ComputedRef<O | null>;\n error: ComputedRef<unknown>;\n run: (...inputs: I) => void;\n runAsync: (...inputs: I) => Promise<O>;\n};\n\nexport type UseAsyncOutputFilled<I extends AnyArray, O> = {\n state: ComputedRef<UseAsyncState>;\n loading: ComputedRef<boolean>;\n data: ComputedRef<O>;\n error: ComputedRef<unknown>;\n run: (...inputs: I) => void;\n runAsync: (...inputs: I) => Promise<O>;\n};\n\n/**\n * 用于处理异步操作的组合式函数。\n * 提供加载状态、数据、错误信息以及执行方法。\n * @template O 异步函数返回的数据类型\n * @template I 异步函数的入参类型\n * @param fn 异步函数,接收参数并返回 Promise。\n * @param options 异步操作的配置选项。\n * @returns 包含状态和操作方法的对象:\n * - loading: 是否正在加载。\n * - data: 异步操作返回的数据。\n * - error: 异步操作抛出的错误。\n * - runAsync: 执行异步操作并返回 Promise。\n * - run: 执行异步操作但不返回 Promise。\n * @example\n * const { loading, data, error, runAsync, run } = useAsync(async (id: number) => {\n * const response = await fetch(`/api/user/${id}`);\n * return response.json();\n * }, {\n * onBefore: () => console.log('Fetching user data...'),\n * onSuccess: (data) => console.log('User data fetched:', data),\n * onError: (err) => console.error('Failed to fetch user data:', err),\n * onFinally: () => console.log('Fetch operation completed.'),\n * });\n */\nexport function useAsync<I extends AnyArray, O>(\n fn: (...inputs: I) => Promise<O>,\n options: Omit<UseAsyncOptions<I, O>, 'placeholder'> & {\n placeholder: () => O;\n },\n): UseAsyncOutputFilled<I, O>;\nexport function useAsync<I extends AnyArray, O>(\n fn: (...inputs: I) => Promise<O>,\n options?: UseAsyncOptions<I, O>,\n): UseAsyncOutput<I, O>;\nexport function useAsync<I extends AnyArray, O>(\n fn: (...inputs: I) => Promise<O>,\n options?: UseAsyncOptions<I, O>,\n): UseAsyncOutput<I, O> {\n const _times = ref(0);\n const _loading = ref(false);\n const placeholder = options?.placeholder;\n const _data = shallowRef(placeholder ? placeholder() : null) as ShallowRef<O | null>;\n const _error = ref<unknown>(null);\n const times = computed(() => _times.value);\n const loading = computed(() => _loading.value);\n const data = computed(() => _data.value);\n const error = computed(() => _error.value);\n const state = computed(() => ({\n times: times.value,\n loading: loading.value,\n error: error.value,\n }));\n\n const runAsync = async (...inputs: I): Promise<O> => {\n _loading.value = true;\n _error.value = null;\n\n try {\n await options?.onBefore?.(...inputs);\n _times.value++;\n _data.value = await fn(...inputs);\n await options?.onSuccess?.(_data.value, ...inputs);\n return _data.value;\n } catch (err) {\n _error.value = err;\n try {\n options?.onError?.(err, ...inputs);\n } catch {\n //\n }\n throw err;\n } finally {\n _loading.value = false;\n await options?.onAfter?.(...inputs);\n }\n };\n\n const run = (...inputs: I) => {\n runAsync(...inputs).then();\n };\n\n return {\n state,\n\n /**\n * 是否正在加载。\n */\n loading,\n\n /**\n * 异步操作返回的数据。\n */\n data,\n\n /**\n * 异步操作抛出的错误。\n */\n error,\n\n /**\n * 执行异步操作并返回 Promise。\n * @param inputs 异步函数的参数。\n * @returns 异步操作的结果。\n */\n runAsync,\n\n /**\n * 执行异步操作但不返回 Promise。\n * @param inputs 异步函数的参数。\n */\n run,\n };\n}\n\n// const { run: run1 } = useAsync(() => Promise.resolve(1));\n// run1();\n\n// const { run: run2 } = useAsync((a: number) => Promise.resolve(1));\n// run2(2);\n\n// const { run: run3 } = useAsync((a: number, b: string) => Promise.resolve(1));\n// run3(2, '2');\n"],"mappings":";;;AA4FA,SAAgB,SACd,IACA,SACsB;CACtB,MAAM,UAAA,GAAA,IAAA,KAAa,EAAE;CACrB,MAAM,YAAA,GAAA,IAAA,KAAe,MAAM;CAC3B,MAAM,cAAc,SAAS;CAC7B,MAAM,SAAA,GAAA,IAAA,YAAmB,cAAc,aAAa,GAAG,KAAK;CAC5D,MAAM,UAAA,GAAA,IAAA,KAAsB,KAAK;CACjC,MAAM,SAAA,GAAA,IAAA,gBAAuB,OAAO,MAAM;CAC1C,MAAM,WAAA,GAAA,IAAA,gBAAyB,SAAS,MAAM;CAC9C,MAAM,QAAA,GAAA,IAAA,gBAAsB,MAAM,MAAM;CACxC,MAAM,SAAA,GAAA,IAAA,gBAAuB,OAAO,MAAM;CAC1C,MAAM,SAAA,GAAA,IAAA,iBAAwB;EAC5B,OAAO,MAAM;EACb,SAAS,QAAQ;EACjB,OAAO,MAAM;EACd,EAAE;CAEH,MAAM,WAAW,OAAO,GAAG,WAA0B;EACnD,SAAS,QAAQ;EACjB,OAAO,QAAQ;EAEf,IAAI;GACF,MAAM,SAAS,WAAW,GAAG,OAAO;GACpC,OAAO;GACP,MAAM,QAAQ,MAAM,GAAG,GAAG,OAAO;GACjC,MAAM,SAAS,YAAY,MAAM,OAAO,GAAG,OAAO;GAClD,OAAO,MAAM;WACN,KAAK;GACZ,OAAO,QAAQ;GACf,IAAI;IACF,SAAS,UAAU,KAAK,GAAG,OAAO;WAC5B;GAGR,MAAM;YACE;GACR,SAAS,QAAQ;GACjB,MAAM,SAAS,UAAU,GAAG,OAAO;;;CAIvC,MAAM,OAAO,GAAG,WAAc;EAC5B,SAAS,GAAG,OAAO,CAAC,MAAM;;CAG5B,OAAO;EACL;;;;EAKA;;;;EAKA;;;;EAKA;;;;;;EAOA;;;;;EAMA;EACD"}
package/dist/async.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { AnyArray } from '@cloudcome/utils-core/types';
2
- import { ComputedRef, Ref } from 'vue';
2
+ import { ComputedRef } from 'vue';
3
3
  /**
4
4
  * 异步操作的配置选项
5
5
  * @template T 异步操作返回的数据类型
@@ -26,31 +26,24 @@ export type UseAsyncOptions<I extends AnyArray, O> = {
26
26
  */
27
27
  onAfter?: (...inputs: I) => unknown;
28
28
  };
29
- export type UseAsyncState<O> = {
29
+ export type UseAsyncState = {
30
30
  times: number;
31
31
  loading: boolean;
32
32
  error: unknown;
33
- data: O | null;
34
- };
35
- export type UseAsyncStateFilled<O> = {
36
- times: number;
37
- loading: boolean;
38
- error: unknown;
39
- data: O;
40
33
  };
41
34
  export type UseAsyncOutput<I extends AnyArray, O> = {
42
- state: ComputedRef<UseAsyncState<O>>;
43
- loading: Ref<boolean>;
44
- data: Ref<O | null>;
45
- error: Ref<unknown>;
35
+ state: ComputedRef<UseAsyncState>;
36
+ loading: ComputedRef<boolean>;
37
+ data: ComputedRef<O | null>;
38
+ error: ComputedRef<unknown>;
46
39
  run: (...inputs: I) => void;
47
40
  runAsync: (...inputs: I) => Promise<O>;
48
41
  };
49
42
  export type UseAsyncOutputFilled<I extends AnyArray, O> = {
50
- state: ComputedRef<UseAsyncStateFilled<O>>;
51
- loading: Ref<boolean>;
52
- data: Ref<O>;
53
- error: Ref<unknown>;
43
+ state: ComputedRef<UseAsyncState>;
44
+ loading: ComputedRef<boolean>;
45
+ data: ComputedRef<O>;
46
+ error: ComputedRef<unknown>;
54
47
  run: (...inputs: I) => void;
55
48
  runAsync: (...inputs: I) => Promise<O>;
56
49
  };
package/dist/async.mjs CHANGED
@@ -1,34 +1,37 @@
1
- import { computed, ref } from "vue";
1
+ import { computed, ref, shallowRef } from "vue";
2
2
  //#region src/async.ts
3
3
  function useAsync(fn, options) {
4
- const times = ref(0);
5
- const loading = ref(false);
4
+ const _times = ref(0);
5
+ const _loading = ref(false);
6
6
  const placeholder = options?.placeholder;
7
- const data = ref(placeholder ? placeholder() : null);
8
- const error = ref(null);
7
+ const _data = shallowRef(placeholder ? placeholder() : null);
8
+ const _error = ref(null);
9
+ const times = computed(() => _times.value);
10
+ const loading = computed(() => _loading.value);
11
+ const data = computed(() => _data.value);
12
+ const error = computed(() => _error.value);
9
13
  const state = computed(() => ({
10
14
  times: times.value,
11
15
  loading: loading.value,
12
- data: data.value,
13
16
  error: error.value
14
17
  }));
15
18
  const runAsync = async (...inputs) => {
16
- loading.value = true;
17
- error.value = null;
19
+ _loading.value = true;
20
+ _error.value = null;
18
21
  try {
19
22
  await options?.onBefore?.(...inputs);
20
- times.value++;
21
- data.value = await fn(...inputs);
22
- await options?.onSuccess?.(data.value, ...inputs);
23
- return data.value;
23
+ _times.value++;
24
+ _data.value = await fn(...inputs);
25
+ await options?.onSuccess?.(_data.value, ...inputs);
26
+ return _data.value;
24
27
  } catch (err) {
25
- error.value = err;
28
+ _error.value = err;
26
29
  try {
27
30
  options?.onError?.(err, ...inputs);
28
31
  } catch {}
29
32
  throw err;
30
33
  } finally {
31
- loading.value = false;
34
+ _loading.value = false;
32
35
  await options?.onAfter?.(...inputs);
33
36
  }
34
37
  };
@@ -1 +1 @@
1
- {"version":3,"file":"async.mjs","names":[],"sources":["../src/async.ts"],"sourcesContent":["import type { AnyArray } from '@cloudcome/utils-core/types';\nimport { type ComputedRef, computed, type Ref, ref } from 'vue';\n\n/**\n * 异步操作的配置选项\n * @template T 异步操作返回的数据类型\n * @template P 异步操作的参数类型\n */\nexport type UseAsyncOptions<I extends AnyArray, O> = {\n placeholder?: () => O;\n\n /**\n * 异步操作开始前的回调函数,可用于执行初始化逻辑或显示加载状态,抛出错误则中断操作\n */\n onBefore?: (...inputs: I) => unknown;\n\n /**\n * 异步操作成功后的回调函数,可用于处理成功后的数据更新或通知。\n * @param data 异步操作返回的数据。\n */\n onSuccess?: (data: O, ...inputs: I) => unknown;\n\n /**\n * 异步操作失败后的回调函数,可用于记录错误日志或显示错误提示。\n * @param err 异步操作抛出的错误。\n */\n onError?: (err: unknown, ...inputs: I) => unknown;\n\n /**\n * 异步操作结束后的回调函数(无论成功或失败),可用于清理操作或触发后续逻辑。\n */\n onAfter?: (...inputs: I) => unknown;\n};\n\nexport type UseAsyncState<O> = {\n times: number;\n loading: boolean;\n error: unknown;\n data: O | null;\n};\n\nexport type UseAsyncStateFilled<O> = {\n times: number;\n loading: boolean;\n error: unknown;\n data: O;\n};\n\nexport type UseAsyncOutput<I extends AnyArray, O> = {\n state: ComputedRef<UseAsyncState<O>>;\n loading: Ref<boolean>;\n data: Ref<O | null>;\n error: Ref<unknown>;\n run: (...inputs: I) => void;\n runAsync: (...inputs: I) => Promise<O>;\n};\n\nexport type UseAsyncOutputFilled<I extends AnyArray, O> = {\n state: ComputedRef<UseAsyncStateFilled<O>>;\n loading: Ref<boolean>;\n data: Ref<O>;\n error: Ref<unknown>;\n run: (...inputs: I) => void;\n runAsync: (...inputs: I) => Promise<O>;\n};\n\n/**\n * 用于处理异步操作的组合式函数。\n * 提供加载状态、数据、错误信息以及执行方法。\n * @template O 异步函数返回的数据类型\n * @template I 异步函数的入参类型\n * @param fn 异步函数,接收参数并返回 Promise。\n * @param options 异步操作的配置选项。\n * @returns 包含状态和操作方法的对象:\n * - loading: 是否正在加载。\n * - data: 异步操作返回的数据。\n * - error: 异步操作抛出的错误。\n * - runAsync: 执行异步操作并返回 Promise。\n * - run: 执行异步操作但不返回 Promise。\n * @example\n * const { loading, data, error, runAsync, run } = useAsync(async (id: number) => {\n * const response = await fetch(`/api/user/${id}`);\n * return response.json();\n * }, {\n * onBefore: () => console.log('Fetching user data...'),\n * onSuccess: (data) => console.log('User data fetched:', data),\n * onError: (err) => console.error('Failed to fetch user data:', err),\n * onFinally: () => console.log('Fetch operation completed.'),\n * });\n */\nexport function useAsync<I extends AnyArray, O>(\n fn: (...inputs: I) => Promise<O>,\n options: Omit<UseAsyncOptions<I, O>, 'placeholder'> & {\n placeholder: () => O;\n },\n): UseAsyncOutputFilled<I, O>;\nexport function useAsync<I extends AnyArray, O>(\n fn: (...inputs: I) => Promise<O>,\n options?: UseAsyncOptions<I, O>,\n): UseAsyncOutput<I, O>;\nexport function useAsync<I extends AnyArray, O>(\n fn: (...inputs: I) => Promise<O>,\n options?: UseAsyncOptions<I, O>,\n): UseAsyncOutput<I, O> {\n const times = ref(0);\n const loading = ref(false);\n const placeholder = options?.placeholder;\n const data = ref(placeholder ? placeholder() : null) as Ref<O | null>;\n const error = ref<unknown>(null);\n const state = computed(() => ({\n times: times.value,\n loading: loading.value,\n data: data.value,\n error: error.value,\n }));\n\n const runAsync = async (...inputs: I): Promise<O> => {\n loading.value = true;\n error.value = null;\n\n try {\n await options?.onBefore?.(...inputs);\n times.value++;\n data.value = await fn(...inputs);\n await options?.onSuccess?.(data.value, ...inputs);\n return data.value;\n } catch (err) {\n error.value = err;\n try {\n options?.onError?.(err, ...inputs);\n } catch {\n //\n }\n throw err;\n } finally {\n loading.value = false;\n await options?.onAfter?.(...inputs);\n }\n };\n\n const run = (...inputs: I) => {\n runAsync(...inputs).then();\n };\n\n return {\n state,\n /**\n * 是否正在加载。\n */\n loading,\n\n /**\n * 异步操作返回的数据。\n */\n data,\n\n /**\n * 异步操作抛出的错误。\n */\n error,\n\n /**\n * 执行异步操作并返回 Promise。\n * @param inputs 异步函数的参数。\n * @returns 异步操作的结果。\n */\n runAsync,\n\n /**\n * 执行异步操作但不返回 Promise。\n * @param inputs 异步函数的参数。\n */\n run,\n };\n}\n\n// const { run: run1 } = useAsync(() => Promise.resolve(1));\n// run1();\n\n// const { run: run2 } = useAsync((a: number) => Promise.resolve(1));\n// run2(2);\n\n// const { run: run3 } = useAsync((a: number, b: string) => Promise.resolve(1));\n// run3(2, '2');\n"],"mappings":";;AAoGA,SAAgB,SACd,IACA,SACsB;CACtB,MAAM,QAAQ,IAAI,EAAE;CACpB,MAAM,UAAU,IAAI,MAAM;CAC1B,MAAM,cAAc,SAAS;CAC7B,MAAM,OAAO,IAAI,cAAc,aAAa,GAAG,KAAK;CACpD,MAAM,QAAQ,IAAa,KAAK;CAChC,MAAM,QAAQ,gBAAgB;EAC5B,OAAO,MAAM;EACb,SAAS,QAAQ;EACjB,MAAM,KAAK;EACX,OAAO,MAAM;EACd,EAAE;CAEH,MAAM,WAAW,OAAO,GAAG,WAA0B;EACnD,QAAQ,QAAQ;EAChB,MAAM,QAAQ;EAEd,IAAI;GACF,MAAM,SAAS,WAAW,GAAG,OAAO;GACpC,MAAM;GACN,KAAK,QAAQ,MAAM,GAAG,GAAG,OAAO;GAChC,MAAM,SAAS,YAAY,KAAK,OAAO,GAAG,OAAO;GACjD,OAAO,KAAK;WACL,KAAK;GACZ,MAAM,QAAQ;GACd,IAAI;IACF,SAAS,UAAU,KAAK,GAAG,OAAO;WAC5B;GAGR,MAAM;YACE;GACR,QAAQ,QAAQ;GAChB,MAAM,SAAS,UAAU,GAAG,OAAO;;;CAIvC,MAAM,OAAO,GAAG,WAAc;EAC5B,SAAS,GAAG,OAAO,CAAC,MAAM;;CAG5B,OAAO;EACL;;;;EAIA;;;;EAKA;;;;EAKA;;;;;;EAOA;;;;;EAMA;EACD"}
1
+ {"version":3,"file":"async.mjs","names":[],"sources":["../src/async.ts"],"sourcesContent":["import type { AnyArray } from '@cloudcome/utils-core/types';\nimport { computed, type ComputedRef, ref, type ShallowRef, shallowRef } from 'vue';\n\n/**\n * 异步操作的配置选项\n * @template T 异步操作返回的数据类型\n * @template P 异步操作的参数类型\n */\nexport type UseAsyncOptions<I extends AnyArray, O> = {\n placeholder?: () => O;\n\n /**\n * 异步操作开始前的回调函数,可用于执行初始化逻辑或显示加载状态,抛出错误则中断操作\n */\n onBefore?: (...inputs: I) => unknown;\n\n /**\n * 异步操作成功后的回调函数,可用于处理成功后的数据更新或通知。\n * @param data 异步操作返回的数据。\n */\n onSuccess?: (data: O, ...inputs: I) => unknown;\n\n /**\n * 异步操作失败后的回调函数,可用于记录错误日志或显示错误提示。\n * @param err 异步操作抛出的错误。\n */\n onError?: (err: unknown, ...inputs: I) => unknown;\n\n /**\n * 异步操作结束后的回调函数(无论成功或失败),可用于清理操作或触发后续逻辑。\n */\n onAfter?: (...inputs: I) => unknown;\n};\n\nexport type UseAsyncState = {\n times: number;\n loading: boolean;\n error: unknown;\n};\n\nexport type UseAsyncOutput<I extends AnyArray, O> = {\n state: ComputedRef<UseAsyncState>;\n loading: ComputedRef<boolean>;\n data: ComputedRef<O | null>;\n error: ComputedRef<unknown>;\n run: (...inputs: I) => void;\n runAsync: (...inputs: I) => Promise<O>;\n};\n\nexport type UseAsyncOutputFilled<I extends AnyArray, O> = {\n state: ComputedRef<UseAsyncState>;\n loading: ComputedRef<boolean>;\n data: ComputedRef<O>;\n error: ComputedRef<unknown>;\n run: (...inputs: I) => void;\n runAsync: (...inputs: I) => Promise<O>;\n};\n\n/**\n * 用于处理异步操作的组合式函数。\n * 提供加载状态、数据、错误信息以及执行方法。\n * @template O 异步函数返回的数据类型\n * @template I 异步函数的入参类型\n * @param fn 异步函数,接收参数并返回 Promise。\n * @param options 异步操作的配置选项。\n * @returns 包含状态和操作方法的对象:\n * - loading: 是否正在加载。\n * - data: 异步操作返回的数据。\n * - error: 异步操作抛出的错误。\n * - runAsync: 执行异步操作并返回 Promise。\n * - run: 执行异步操作但不返回 Promise。\n * @example\n * const { loading, data, error, runAsync, run } = useAsync(async (id: number) => {\n * const response = await fetch(`/api/user/${id}`);\n * return response.json();\n * }, {\n * onBefore: () => console.log('Fetching user data...'),\n * onSuccess: (data) => console.log('User data fetched:', data),\n * onError: (err) => console.error('Failed to fetch user data:', err),\n * onFinally: () => console.log('Fetch operation completed.'),\n * });\n */\nexport function useAsync<I extends AnyArray, O>(\n fn: (...inputs: I) => Promise<O>,\n options: Omit<UseAsyncOptions<I, O>, 'placeholder'> & {\n placeholder: () => O;\n },\n): UseAsyncOutputFilled<I, O>;\nexport function useAsync<I extends AnyArray, O>(\n fn: (...inputs: I) => Promise<O>,\n options?: UseAsyncOptions<I, O>,\n): UseAsyncOutput<I, O>;\nexport function useAsync<I extends AnyArray, O>(\n fn: (...inputs: I) => Promise<O>,\n options?: UseAsyncOptions<I, O>,\n): UseAsyncOutput<I, O> {\n const _times = ref(0);\n const _loading = ref(false);\n const placeholder = options?.placeholder;\n const _data = shallowRef(placeholder ? placeholder() : null) as ShallowRef<O | null>;\n const _error = ref<unknown>(null);\n const times = computed(() => _times.value);\n const loading = computed(() => _loading.value);\n const data = computed(() => _data.value);\n const error = computed(() => _error.value);\n const state = computed(() => ({\n times: times.value,\n loading: loading.value,\n error: error.value,\n }));\n\n const runAsync = async (...inputs: I): Promise<O> => {\n _loading.value = true;\n _error.value = null;\n\n try {\n await options?.onBefore?.(...inputs);\n _times.value++;\n _data.value = await fn(...inputs);\n await options?.onSuccess?.(_data.value, ...inputs);\n return _data.value;\n } catch (err) {\n _error.value = err;\n try {\n options?.onError?.(err, ...inputs);\n } catch {\n //\n }\n throw err;\n } finally {\n _loading.value = false;\n await options?.onAfter?.(...inputs);\n }\n };\n\n const run = (...inputs: I) => {\n runAsync(...inputs).then();\n };\n\n return {\n state,\n\n /**\n * 是否正在加载。\n */\n loading,\n\n /**\n * 异步操作返回的数据。\n */\n data,\n\n /**\n * 异步操作抛出的错误。\n */\n error,\n\n /**\n * 执行异步操作并返回 Promise。\n * @param inputs 异步函数的参数。\n * @returns 异步操作的结果。\n */\n runAsync,\n\n /**\n * 执行异步操作但不返回 Promise。\n * @param inputs 异步函数的参数。\n */\n run,\n };\n}\n\n// const { run: run1 } = useAsync(() => Promise.resolve(1));\n// run1();\n\n// const { run: run2 } = useAsync((a: number) => Promise.resolve(1));\n// run2(2);\n\n// const { run: run3 } = useAsync((a: number, b: string) => Promise.resolve(1));\n// run3(2, '2');\n"],"mappings":";;AA4FA,SAAgB,SACd,IACA,SACsB;CACtB,MAAM,SAAS,IAAI,EAAE;CACrB,MAAM,WAAW,IAAI,MAAM;CAC3B,MAAM,cAAc,SAAS;CAC7B,MAAM,QAAQ,WAAW,cAAc,aAAa,GAAG,KAAK;CAC5D,MAAM,SAAS,IAAa,KAAK;CACjC,MAAM,QAAQ,eAAe,OAAO,MAAM;CAC1C,MAAM,UAAU,eAAe,SAAS,MAAM;CAC9C,MAAM,OAAO,eAAe,MAAM,MAAM;CACxC,MAAM,QAAQ,eAAe,OAAO,MAAM;CAC1C,MAAM,QAAQ,gBAAgB;EAC5B,OAAO,MAAM;EACb,SAAS,QAAQ;EACjB,OAAO,MAAM;EACd,EAAE;CAEH,MAAM,WAAW,OAAO,GAAG,WAA0B;EACnD,SAAS,QAAQ;EACjB,OAAO,QAAQ;EAEf,IAAI;GACF,MAAM,SAAS,WAAW,GAAG,OAAO;GACpC,OAAO;GACP,MAAM,QAAQ,MAAM,GAAG,GAAG,OAAO;GACjC,MAAM,SAAS,YAAY,MAAM,OAAO,GAAG,OAAO;GAClD,OAAO,MAAM;WACN,KAAK;GACZ,OAAO,QAAQ;GACf,IAAI;IACF,SAAS,UAAU,KAAK,GAAG,OAAO;WAC5B;GAGR,MAAM;YACE;GACR,SAAS,QAAQ;GACjB,MAAM,SAAS,UAAU,GAAG,OAAO;;;CAIvC,MAAM,OAAO,GAAG,WAAc;EAC5B,SAAS,GAAG,OAAO,CAAC,MAAM;;CAG5B,OAAO;EACL;;;;EAKA;;;;EAKA;;;;EAKA;;;;;;EAOA;;;;;EAMA;EACD"}
package/dist/index.cjs CHANGED
@@ -3,7 +3,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  /**
4
4
  * `@cloudcome/utils-vue` 版本号
5
5
  */
6
- var VERSION = "1.14.1";
6
+ var VERSION = "1.15.0";
7
7
  //#endregion
8
8
  exports.VERSION = VERSION;
9
9
 
package/dist/index.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * `@cloudcome/utils-vue` 版本号
4
4
  */
5
- var VERSION = "1.14.1";
5
+ var VERSION = "1.15.0";
6
6
  //#endregion
7
7
  export { VERSION };
8
8
 
@@ -1 +1 @@
1
- {"version":3,"file":"request.cjs","names":[],"sources":["../src/request.ts"],"sourcesContent":["import { type Cache, type Cached, type CacheOptions, MemoryCache } from '@cloudcome/utils-core/cache';\nimport type { DateValue } from '@cloudcome/utils-core/date';\nimport { tryFlatten } from '@cloudcome/utils-core/try';\nimport { isFunction, isObject } from '@cloudcome/utils-core/type';\nimport type { AnyArray, MaybeCallable } from '@cloudcome/utils-core/types';\nimport type { ComputedRef, Ref } from 'vue';\nimport { computed, ref } from 'vue';\nimport {\n type UseAsyncOptions,\n type UseAsyncOutput,\n type UseAsyncOutputFilled,\n type UseAsyncState,\n type UseAsyncStateFilled,\n useAsync,\n} from './async';\n\n/**\n * 请求缓存配置选项。\n * @template T 缓存数据的类型。\n */\nexport type RequestCacheOptions<T> = CacheOptions & {\n /**\n * 是否禁用缓存,默认为 false。\n * 如果设置为 true,则不会使用缓存。\n */\n disabled?: boolean;\n\n /**\n * 自定义缓存存储实现。\n * 可以传入自定义的缓存类来替代默认的内存缓存。\n */\n storage?: Cache<T>;\n};\n\nexport type RequestShareOptions = {\n /**\n * 是否禁用共享请求,默认为 false。\n * 如果设置为 true,则不会共享请求结果。\n */\n disabled?: boolean;\n\n /**\n * 共享的最大时长(毫秒),为 0 时表示永久共享。\n * 超过该时长后,共享的请求结果将被清除。\n */\n maxAge?: number;\n\n /**\n * 共享的过期时间(时间戳、日期字符串、日期对象等)。\n * 优先级比 maxAge 更高,指定具体的过期时间。\n */\n expiredAt?: DateValue;\n};\n\nexport type RetryOptions = {\n /**\n * 是否禁用重试,默认为 false。\n * 如果设置为 true,则不会重试。\n */\n disabled?: boolean;\n};\n\n/**\n * 请求选项,扩展了异步操作的选项。\n * @template T 请求返回的数据类型。\n * @template I 请求参数的类型。\n */\nexport type UseRequestOptions<I extends AnyArray, O> = UseAsyncOptions<I, O> & {\n /**\n * 请求的唯一标识符,可以是字符串或函数返回的字符串。\n * 用于缓存和共享的键值。\n */\n id?: MaybeCallable<string>;\n\n /**\n * 缓存配置,可以是布尔值或完整的缓存选项。\n * 如果为 true,则启用默认缓存;如果为对象,则可以自定义缓存行为。\n */\n cache?: boolean | RequestCacheOptions<O>;\n\n /**\n * 共享配置,可以是布尔值或完整的共享选项。\n * 共享时,相同的请求 ID 会复用第一次发出且没有响应完成的请求。\n *\n * 例如,10 组件同时或先后发起 10 次请求用于获取用户信息,\n * 那么这 10 个组件会共同等待第一次发起的请求,直到完成。\n *\n * 共享与缓存是不同的概念,共享是进行时,缓存是过去时,即:\n * - 共享是共享**正在发送**的请求\n * - 缓存是缓存**已经发送**的请求\n *\n * 如果为 true,则启用默认共享;如果为对象,则可以自定义共享行为。\n */\n share?: boolean | RequestShareOptions;\n\n /**\n * 当命中缓存时的回调函数。\n * 在缓存命中时触发,接收缓存的数据作为参数。\n */\n onCacheHit?: (cached: Cached<O>) => unknown;\n};\n\nexport type UseRequestState<O> = UseAsyncState<O> & {\n /**\n * 是否命中共享数据\n */\n hitShare: boolean;\n\n /**\n * 是否命中缓存\n */\n hitCache: boolean;\n};\n\nexport type UseRequestStateFilled<O> = UseAsyncStateFilled<O> & {\n /**\n * 是否命中共享数据\n */\n hitShare: boolean;\n\n /**\n * 是否命中缓存\n */\n hitCache: boolean;\n};\n\nexport type UseRequestOutput<I extends AnyArray, O> = Omit<UseAsyncOutput<I, O>, 'run' | 'runAsync' | 'state'> & {\n state: ComputedRef<UseRequestState<O>>;\n send: (...inputs: I) => void;\n sendAsync: (...inputs: I) => Promise<O>;\n hitShare: Ref<boolean>;\n hitCache: Ref<boolean>;\n};\n\nexport type UseRequestOutputFilled<I extends AnyArray, O> = Omit<\n UseAsyncOutputFilled<I, O>,\n 'run' | 'runAsync' | 'state'\n> & {\n state: ComputedRef<UseRequestStateFilled<O>>;\n send: (...inputs: I) => void;\n sendAsync: (...inputs: I) => Promise<O>;\n hitShare: Ref<boolean>;\n hitCache: Ref<boolean>;\n};\n\nconst defaultCacheStorage = new MemoryCache();\nconst defaultShareStorage = new MemoryCache();\n\n/**\n * 使用请求功能的组合式函数。\n * 支持缓存和异步操作的封装。\n *\n * @template O 请求返回的数据类型。\n * @template I 请求参数的类型。\n * @param {() => Promise<O>} fn 实际的请求函数,返回一个 Promise。\n * @param {UseRequestOptions<I, O>} [options] 请求选项,包括缓存和回调配置。\n * @returns 返回一个对象,包含以下内容:\n * - 异步操作的状态(如 loading、error 等)。\n * - 是否命中缓存(hitCache)。\n * - 是否命中共享请求(hitShare)。\n */\nexport function useRequest<I extends AnyArray, O>(\n fn: (...inputs: I) => Promise<O>,\n options: Omit<UseRequestOptions<I, O>, 'placeholder'> & {\n placeholder: () => O;\n },\n): UseRequestOutputFilled<I, O>;\nexport function useRequest<I extends AnyArray, O>(\n fn: (...inputs: I) => Promise<O>,\n options?: UseRequestOptions<I, O>,\n): UseRequestOutput<I, O>;\nexport function useRequest<I extends AnyArray, O>(\n fn: (...inputs: I) => Promise<O>,\n options?: UseRequestOptions<I, O>,\n): UseRequestOutput<I, O> {\n const { id, cache, share, onCacheHit } = options || {};\n\n const shareStorage = defaultShareStorage as MemoryCache<Promise<O>>;\n const shareAble = isObject(share) ? !share.disabled : share;\n const shareOptions = isObject(share) ? share : {};\n const hitShare = ref(false);\n\n const _cached = defaultCacheStorage as Cache<O>;\n const cacheStorage = isObject(cache) ? cache.storage || _cached : _cached;\n const cacheAble = isObject(cache) ? !cache.disabled : cache;\n const cacheOptions = isObject(cache) ? cache : {};\n const hitCache = ref(false);\n\n const cacheableFn = async (...inputs: I) => {\n const requestId = isFunction(id) ? id() : id;\n\n hitShare.value = false;\n hitCache.value = false;\n\n if (requestId && shareAble) {\n const shared = shareStorage.get(requestId);\n if (shared) {\n hitShare.value = true;\n const [err, data] = await tryFlatten(shared.data);\n if (err) {\n shareStorage.del(requestId);\n throw err;\n }\n\n return data;\n }\n }\n\n // 这里不能先执行,因为如果要缓存的话,必须用缓存结果\n const { promise, resolve, reject } = Promise.withResolvers<O>();\n\n if (requestId && shareAble) {\n shareStorage.set(requestId, promise, shareOptions);\n }\n\n if (requestId && cacheAble) {\n const cached = await cacheStorage.get(requestId);\n\n if (cached) {\n const data = cached.data;\n resolve(data);\n hitCache.value = true;\n await onCacheHit?.(cached);\n return promise;\n }\n } else if (cacheAble) {\n console.warn('[useRequest] 缓存功能启用但未提供 requestId,无法使用缓存');\n }\n\n const [err, data] = await tryFlatten(fn(...inputs));\n\n if (err) {\n reject(err);\n return promise;\n }\n\n if (requestId && cacheAble) {\n cacheStorage.set(requestId, data, cacheOptions);\n }\n\n resolve(data);\n return promise;\n };\n const { state: asyncState, run: send, runAsync: sendAsync, ...async } = useAsync(cacheableFn, options);\n\n const state = computed(() => ({\n ...asyncState.value,\n hitShare: hitShare.value,\n hitCache: hitCache.value,\n }));\n\n return {\n ...async,\n state,\n send,\n sendAsync,\n hitShare,\n hitCache,\n };\n}\n"],"mappings":";;;;;;;AAiJA,IAAM,sBAAsB,IAAI,4BAAA,aAAa;AAC7C,IAAM,sBAAsB,IAAI,4BAAA,aAAa;AAyB7C,SAAgB,WACd,IACA,SACwB;CACxB,MAAM,EAAE,IAAI,OAAO,OAAO,eAAe,WAAW,EAAE;CAEtD,MAAM,eAAe;CACrB,MAAM,aAAA,GAAA,2BAAA,UAAqB,MAAM,GAAG,CAAC,MAAM,WAAW;CACtD,MAAM,gBAAA,GAAA,2BAAA,UAAwB,MAAM,GAAG,QAAQ,EAAE;CACjD,MAAM,YAAA,GAAA,IAAA,KAAe,MAAM;CAE3B,MAAM,UAAU;CAChB,MAAM,gBAAA,GAAA,2BAAA,UAAwB,MAAM,GAAG,MAAM,WAAW,UAAU;CAClE,MAAM,aAAA,GAAA,2BAAA,UAAqB,MAAM,GAAG,CAAC,MAAM,WAAW;CACtD,MAAM,gBAAA,GAAA,2BAAA,UAAwB,MAAM,GAAG,QAAQ,EAAE;CACjD,MAAM,YAAA,GAAA,IAAA,KAAe,MAAM;CAE3B,MAAM,cAAc,OAAO,GAAG,WAAc;EAC1C,MAAM,aAAA,GAAA,2BAAA,YAAuB,GAAG,GAAG,IAAI,GAAG;EAE1C,SAAS,QAAQ;EACjB,SAAS,QAAQ;EAEjB,IAAI,aAAa,WAAW;GAC1B,MAAM,SAAS,aAAa,IAAI,UAAU;GAC1C,IAAI,QAAQ;IACV,SAAS,QAAQ;IACjB,MAAM,CAAC,KAAK,QAAQ,OAAA,GAAA,0BAAA,YAAiB,OAAO,KAAK;IACjD,IAAI,KAAK;KACP,aAAa,IAAI,UAAU;KAC3B,MAAM;;IAGR,OAAO;;;EAKX,MAAM,EAAE,SAAS,SAAS,WAAW,QAAQ,eAAkB;EAE/D,IAAI,aAAa,WACf,aAAa,IAAI,WAAW,SAAS,aAAa;EAGpD,IAAI,aAAa,WAAW;GAC1B,MAAM,SAAS,MAAM,aAAa,IAAI,UAAU;GAEhD,IAAI,QAAQ;IACV,MAAM,OAAO,OAAO;IACpB,QAAQ,KAAK;IACb,SAAS,QAAQ;IACjB,MAAM,aAAa,OAAO;IAC1B,OAAO;;SAEJ,IAAI,WACT,QAAQ,KAAK,2CAA2C;EAG1D,MAAM,CAAC,KAAK,QAAQ,OAAA,GAAA,0BAAA,YAAiB,GAAG,GAAG,OAAO,CAAC;EAEnD,IAAI,KAAK;GACP,OAAO,IAAI;GACX,OAAO;;EAGT,IAAI,aAAa,WACf,aAAa,IAAI,WAAW,MAAM,aAAa;EAGjD,QAAQ,KAAK;EACb,OAAO;;CAET,MAAM,EAAE,OAAO,YAAY,KAAK,MAAM,UAAU,WAAW,GAAG,UAAU,cAAA,SAAS,aAAa,QAAQ;CAEtG,MAAM,SAAA,GAAA,IAAA,iBAAwB;EAC5B,GAAG,WAAW;EACd,UAAU,SAAS;EACnB,UAAU,SAAS;EACpB,EAAE;CAEH,OAAO;EACL,GAAG;EACH;EACA;EACA;EACA;EACA;EACD"}
1
+ {"version":3,"file":"request.cjs","names":[],"sources":["../src/request.ts"],"sourcesContent":["import { type Cache, type Cached, type CacheOptions, MemoryCache } from '@cloudcome/utils-core/cache';\nimport type { DateValue } from '@cloudcome/utils-core/date';\nimport { tryFlatten } from '@cloudcome/utils-core/try';\nimport { isFunction, isObject } from '@cloudcome/utils-core/type';\nimport type { AnyArray, MaybeCallable } from '@cloudcome/utils-core/types';\nimport type { ComputedRef, Ref } from 'vue';\nimport { computed, ref } from 'vue';\nimport {\n type UseAsyncOptions,\n type UseAsyncOutput,\n type UseAsyncOutputFilled,\n type UseAsyncState,\n useAsync,\n} from './async';\n\n/**\n * 请求缓存配置选项。\n * @template T 缓存数据的类型。\n */\nexport type RequestCacheOptions<T> = CacheOptions & {\n /**\n * 是否禁用缓存,默认为 false。\n * 如果设置为 true,则不会使用缓存。\n */\n disabled?: boolean;\n\n /**\n * 自定义缓存存储实现。\n * 可以传入自定义的缓存类来替代默认的内存缓存。\n */\n storage?: Cache<T>;\n};\n\nexport type RequestShareOptions = {\n /**\n * 是否禁用共享请求,默认为 false。\n * 如果设置为 true,则不会共享请求结果。\n */\n disabled?: boolean;\n\n /**\n * 共享的最大时长(毫秒),为 0 时表示永久共享。\n * 超过该时长后,共享的请求结果将被清除。\n */\n maxAge?: number;\n\n /**\n * 共享的过期时间(时间戳、日期字符串、日期对象等)。\n * 优先级比 maxAge 更高,指定具体的过期时间。\n */\n expiredAt?: DateValue;\n};\n\nexport type RetryOptions = {\n /**\n * 是否禁用重试,默认为 false。\n * 如果设置为 true,则不会重试。\n */\n disabled?: boolean;\n};\n\n/**\n * 请求选项,扩展了异步操作的选项。\n * @template T 请求返回的数据类型。\n * @template I 请求参数的类型。\n */\nexport type UseRequestOptions<I extends AnyArray, O> = UseAsyncOptions<I, O> & {\n /**\n * 请求的唯一标识符,可以是字符串或函数返回的字符串。\n * 用于缓存和共享的键值。\n */\n id?: MaybeCallable<string>;\n\n /**\n * 缓存配置,可以是布尔值或完整的缓存选项。\n * 如果为 true,则启用默认缓存;如果为对象,则可以自定义缓存行为。\n */\n cache?: boolean | RequestCacheOptions<O>;\n\n /**\n * 共享配置,可以是布尔值或完整的共享选项。\n * 共享时,相同的请求 ID 会复用第一次发出且没有响应完成的请求。\n *\n * 例如,10 组件同时或先后发起 10 次请求用于获取用户信息,\n * 那么这 10 个组件会共同等待第一次发起的请求,直到完成。\n *\n * 共享与缓存是不同的概念,共享是进行时,缓存是过去时,即:\n * - 共享是共享**正在发送**的请求\n * - 缓存是缓存**已经发送**的请求\n *\n * 如果为 true,则启用默认共享;如果为对象,则可以自定义共享行为。\n */\n share?: boolean | RequestShareOptions;\n\n /**\n * 当命中缓存时的回调函数。\n * 在缓存命中时触发,接收缓存的数据作为参数。\n */\n onCacheHit?: (cached: Cached<O>) => unknown;\n};\n\nexport type UseRequestState = UseAsyncState & {\n /**\n * 是否命中共享数据\n */\n hitShare: boolean;\n\n /**\n * 是否命中缓存\n */\n hitCache: boolean;\n};\n\nexport type UseRequestStateFilled = UseRequestState;\n\nexport type UseRequestOutput<I extends AnyArray, O> = Omit<UseAsyncOutput<I, O>, 'run' | 'runAsync' | 'state'> & {\n state: ComputedRef<UseRequestState>;\n send: (...inputs: I) => void;\n sendAsync: (...inputs: I) => Promise<O>;\n hitShare: Ref<boolean>;\n hitCache: Ref<boolean>;\n};\n\nexport type UseRequestOutputFilled<I extends AnyArray, O> = Omit<\n UseAsyncOutputFilled<I, O>,\n 'run' | 'runAsync' | 'state'\n> & {\n state: ComputedRef<UseRequestStateFilled>;\n send: (...inputs: I) => void;\n sendAsync: (...inputs: I) => Promise<O>;\n hitShare: Ref<boolean>;\n hitCache: Ref<boolean>;\n};\n\nconst defaultCacheStorage = new MemoryCache();\nconst defaultShareStorage = new MemoryCache();\n\n/**\n * 使用请求功能的组合式函数。\n * 支持缓存和异步操作的封装。\n *\n * @template O 请求返回的数据类型。\n * @template I 请求参数的类型。\n * @param {() => Promise<O>} fn 实际的请求函数,返回一个 Promise。\n * @param {UseRequestOptions<I, O>} [options] 请求选项,包括缓存和回调配置。\n * @returns 返回一个对象,包含以下内容:\n * - 异步操作的状态(如 loading、error 等)。\n * - 是否命中缓存(hitCache)。\n * - 是否命中共享请求(hitShare)。\n */\nexport function useRequest<I extends AnyArray, O>(\n fn: (...inputs: I) => Promise<O>,\n options: Omit<UseRequestOptions<I, O>, 'placeholder'> & {\n placeholder: () => O;\n },\n): UseRequestOutputFilled<I, O>;\nexport function useRequest<I extends AnyArray, O>(\n fn: (...inputs: I) => Promise<O>,\n options?: UseRequestOptions<I, O>,\n): UseRequestOutput<I, O>;\nexport function useRequest<I extends AnyArray, O>(\n fn: (...inputs: I) => Promise<O>,\n options?: UseRequestOptions<I, O>,\n): UseRequestOutput<I, O> {\n const { id, cache, share, onCacheHit } = options || {};\n\n const shareStorage = defaultShareStorage as MemoryCache<Promise<O>>;\n const shareAble = isObject(share) ? !share.disabled : share;\n const shareOptions = isObject(share) ? share : {};\n const hitShare = ref(false);\n\n const _cached = defaultCacheStorage as Cache<O>;\n const cacheStorage = isObject(cache) ? cache.storage || _cached : _cached;\n const cacheAble = isObject(cache) ? !cache.disabled : cache;\n const cacheOptions = isObject(cache) ? cache : {};\n const hitCache = ref(false);\n\n const cacheableFn = async (...inputs: I) => {\n const requestId = isFunction(id) ? id() : id;\n\n hitShare.value = false;\n hitCache.value = false;\n\n if (requestId && shareAble) {\n const shared = shareStorage.get(requestId);\n if (shared) {\n hitShare.value = true;\n const [err, data] = await tryFlatten(shared.data);\n if (err) {\n shareStorage.del(requestId);\n throw err;\n }\n\n return data;\n }\n }\n\n // 这里不能先执行,因为如果要缓存的话,必须用缓存结果\n const { promise, resolve, reject } = Promise.withResolvers<O>();\n\n if (requestId && shareAble) {\n shareStorage.set(requestId, promise, shareOptions);\n }\n\n if (requestId && cacheAble) {\n const cached = await cacheStorage.get(requestId);\n\n if (cached) {\n const data = cached.data;\n resolve(data);\n hitCache.value = true;\n await onCacheHit?.(cached);\n return promise;\n }\n } else if (cacheAble) {\n console.warn('[useRequest] 缓存功能启用但未提供 requestId,无法使用缓存');\n }\n\n const [err, data] = await tryFlatten(fn(...inputs));\n\n if (err) {\n reject(err);\n return promise;\n }\n\n if (requestId && cacheAble) {\n cacheStorage.set(requestId, data, cacheOptions);\n }\n\n resolve(data);\n return promise;\n };\n const { state: asyncState, run: send, runAsync: sendAsync, ...async } = useAsync(cacheableFn, options);\n\n const state = computed(() => ({\n ...asyncState.value,\n hitShare: hitShare.value,\n hitCache: hitCache.value,\n }));\n\n return {\n ...async,\n state,\n send,\n sendAsync,\n hitShare,\n hitCache,\n };\n}\n"],"mappings":";;;;;;;AAsIA,IAAM,sBAAsB,IAAI,4BAAA,aAAa;AAC7C,IAAM,sBAAsB,IAAI,4BAAA,aAAa;AAyB7C,SAAgB,WACd,IACA,SACwB;CACxB,MAAM,EAAE,IAAI,OAAO,OAAO,eAAe,WAAW,EAAE;CAEtD,MAAM,eAAe;CACrB,MAAM,aAAA,GAAA,2BAAA,UAAqB,MAAM,GAAG,CAAC,MAAM,WAAW;CACtD,MAAM,gBAAA,GAAA,2BAAA,UAAwB,MAAM,GAAG,QAAQ,EAAE;CACjD,MAAM,YAAA,GAAA,IAAA,KAAe,MAAM;CAE3B,MAAM,UAAU;CAChB,MAAM,gBAAA,GAAA,2BAAA,UAAwB,MAAM,GAAG,MAAM,WAAW,UAAU;CAClE,MAAM,aAAA,GAAA,2BAAA,UAAqB,MAAM,GAAG,CAAC,MAAM,WAAW;CACtD,MAAM,gBAAA,GAAA,2BAAA,UAAwB,MAAM,GAAG,QAAQ,EAAE;CACjD,MAAM,YAAA,GAAA,IAAA,KAAe,MAAM;CAE3B,MAAM,cAAc,OAAO,GAAG,WAAc;EAC1C,MAAM,aAAA,GAAA,2BAAA,YAAuB,GAAG,GAAG,IAAI,GAAG;EAE1C,SAAS,QAAQ;EACjB,SAAS,QAAQ;EAEjB,IAAI,aAAa,WAAW;GAC1B,MAAM,SAAS,aAAa,IAAI,UAAU;GAC1C,IAAI,QAAQ;IACV,SAAS,QAAQ;IACjB,MAAM,CAAC,KAAK,QAAQ,OAAA,GAAA,0BAAA,YAAiB,OAAO,KAAK;IACjD,IAAI,KAAK;KACP,aAAa,IAAI,UAAU;KAC3B,MAAM;;IAGR,OAAO;;;EAKX,MAAM,EAAE,SAAS,SAAS,WAAW,QAAQ,eAAkB;EAE/D,IAAI,aAAa,WACf,aAAa,IAAI,WAAW,SAAS,aAAa;EAGpD,IAAI,aAAa,WAAW;GAC1B,MAAM,SAAS,MAAM,aAAa,IAAI,UAAU;GAEhD,IAAI,QAAQ;IACV,MAAM,OAAO,OAAO;IACpB,QAAQ,KAAK;IACb,SAAS,QAAQ;IACjB,MAAM,aAAa,OAAO;IAC1B,OAAO;;SAEJ,IAAI,WACT,QAAQ,KAAK,2CAA2C;EAG1D,MAAM,CAAC,KAAK,QAAQ,OAAA,GAAA,0BAAA,YAAiB,GAAG,GAAG,OAAO,CAAC;EAEnD,IAAI,KAAK;GACP,OAAO,IAAI;GACX,OAAO;;EAGT,IAAI,aAAa,WACf,aAAa,IAAI,WAAW,MAAM,aAAa;EAGjD,QAAQ,KAAK;EACb,OAAO;;CAET,MAAM,EAAE,OAAO,YAAY,KAAK,MAAM,UAAU,WAAW,GAAG,UAAU,cAAA,SAAS,aAAa,QAAQ;CAEtG,MAAM,SAAA,GAAA,IAAA,iBAAwB;EAC5B,GAAG,WAAW;EACd,UAAU,SAAS;EACnB,UAAU,SAAS;EACpB,EAAE;CAEH,OAAO;EACL,GAAG;EACH;EACA;EACA;EACA;EACA;EACD"}
package/dist/request.d.ts CHANGED
@@ -2,7 +2,7 @@ import { Cache, Cached, CacheOptions } from '@cloudcome/utils-core/cache';
2
2
  import { DateValue } from '@cloudcome/utils-core/date';
3
3
  import { AnyArray, MaybeCallable } from '@cloudcome/utils-core/types';
4
4
  import { ComputedRef, Ref } from 'vue';
5
- import { UseAsyncOptions, UseAsyncOutput, UseAsyncOutputFilled, UseAsyncState, UseAsyncStateFilled } from './async';
5
+ import { UseAsyncOptions, UseAsyncOutput, UseAsyncOutputFilled, UseAsyncState } from './async';
6
6
  /**
7
7
  * 请求缓存配置选项。
8
8
  * @template T 缓存数据的类型。
@@ -79,17 +79,7 @@ export type UseRequestOptions<I extends AnyArray, O> = UseAsyncOptions<I, O> & {
79
79
  */
80
80
  onCacheHit?: (cached: Cached<O>) => unknown;
81
81
  };
82
- export type UseRequestState<O> = UseAsyncState<O> & {
83
- /**
84
- * 是否命中共享数据
85
- */
86
- hitShare: boolean;
87
- /**
88
- * 是否命中缓存
89
- */
90
- hitCache: boolean;
91
- };
92
- export type UseRequestStateFilled<O> = UseAsyncStateFilled<O> & {
82
+ export type UseRequestState = UseAsyncState & {
93
83
  /**
94
84
  * 是否命中共享数据
95
85
  */
@@ -99,15 +89,16 @@ export type UseRequestStateFilled<O> = UseAsyncStateFilled<O> & {
99
89
  */
100
90
  hitCache: boolean;
101
91
  };
92
+ export type UseRequestStateFilled = UseRequestState;
102
93
  export type UseRequestOutput<I extends AnyArray, O> = Omit<UseAsyncOutput<I, O>, 'run' | 'runAsync' | 'state'> & {
103
- state: ComputedRef<UseRequestState<O>>;
94
+ state: ComputedRef<UseRequestState>;
104
95
  send: (...inputs: I) => void;
105
96
  sendAsync: (...inputs: I) => Promise<O>;
106
97
  hitShare: Ref<boolean>;
107
98
  hitCache: Ref<boolean>;
108
99
  };
109
100
  export type UseRequestOutputFilled<I extends AnyArray, O> = Omit<UseAsyncOutputFilled<I, O>, 'run' | 'runAsync' | 'state'> & {
110
- state: ComputedRef<UseRequestStateFilled<O>>;
101
+ state: ComputedRef<UseRequestStateFilled>;
111
102
  send: (...inputs: I) => void;
112
103
  sendAsync: (...inputs: I) => Promise<O>;
113
104
  hitShare: Ref<boolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"request.mjs","names":[],"sources":["../src/request.ts"],"sourcesContent":["import { type Cache, type Cached, type CacheOptions, MemoryCache } from '@cloudcome/utils-core/cache';\nimport type { DateValue } from '@cloudcome/utils-core/date';\nimport { tryFlatten } from '@cloudcome/utils-core/try';\nimport { isFunction, isObject } from '@cloudcome/utils-core/type';\nimport type { AnyArray, MaybeCallable } from '@cloudcome/utils-core/types';\nimport type { ComputedRef, Ref } from 'vue';\nimport { computed, ref } from 'vue';\nimport {\n type UseAsyncOptions,\n type UseAsyncOutput,\n type UseAsyncOutputFilled,\n type UseAsyncState,\n type UseAsyncStateFilled,\n useAsync,\n} from './async';\n\n/**\n * 请求缓存配置选项。\n * @template T 缓存数据的类型。\n */\nexport type RequestCacheOptions<T> = CacheOptions & {\n /**\n * 是否禁用缓存,默认为 false。\n * 如果设置为 true,则不会使用缓存。\n */\n disabled?: boolean;\n\n /**\n * 自定义缓存存储实现。\n * 可以传入自定义的缓存类来替代默认的内存缓存。\n */\n storage?: Cache<T>;\n};\n\nexport type RequestShareOptions = {\n /**\n * 是否禁用共享请求,默认为 false。\n * 如果设置为 true,则不会共享请求结果。\n */\n disabled?: boolean;\n\n /**\n * 共享的最大时长(毫秒),为 0 时表示永久共享。\n * 超过该时长后,共享的请求结果将被清除。\n */\n maxAge?: number;\n\n /**\n * 共享的过期时间(时间戳、日期字符串、日期对象等)。\n * 优先级比 maxAge 更高,指定具体的过期时间。\n */\n expiredAt?: DateValue;\n};\n\nexport type RetryOptions = {\n /**\n * 是否禁用重试,默认为 false。\n * 如果设置为 true,则不会重试。\n */\n disabled?: boolean;\n};\n\n/**\n * 请求选项,扩展了异步操作的选项。\n * @template T 请求返回的数据类型。\n * @template I 请求参数的类型。\n */\nexport type UseRequestOptions<I extends AnyArray, O> = UseAsyncOptions<I, O> & {\n /**\n * 请求的唯一标识符,可以是字符串或函数返回的字符串。\n * 用于缓存和共享的键值。\n */\n id?: MaybeCallable<string>;\n\n /**\n * 缓存配置,可以是布尔值或完整的缓存选项。\n * 如果为 true,则启用默认缓存;如果为对象,则可以自定义缓存行为。\n */\n cache?: boolean | RequestCacheOptions<O>;\n\n /**\n * 共享配置,可以是布尔值或完整的共享选项。\n * 共享时,相同的请求 ID 会复用第一次发出且没有响应完成的请求。\n *\n * 例如,10 组件同时或先后发起 10 次请求用于获取用户信息,\n * 那么这 10 个组件会共同等待第一次发起的请求,直到完成。\n *\n * 共享与缓存是不同的概念,共享是进行时,缓存是过去时,即:\n * - 共享是共享**正在发送**的请求\n * - 缓存是缓存**已经发送**的请求\n *\n * 如果为 true,则启用默认共享;如果为对象,则可以自定义共享行为。\n */\n share?: boolean | RequestShareOptions;\n\n /**\n * 当命中缓存时的回调函数。\n * 在缓存命中时触发,接收缓存的数据作为参数。\n */\n onCacheHit?: (cached: Cached<O>) => unknown;\n};\n\nexport type UseRequestState<O> = UseAsyncState<O> & {\n /**\n * 是否命中共享数据\n */\n hitShare: boolean;\n\n /**\n * 是否命中缓存\n */\n hitCache: boolean;\n};\n\nexport type UseRequestStateFilled<O> = UseAsyncStateFilled<O> & {\n /**\n * 是否命中共享数据\n */\n hitShare: boolean;\n\n /**\n * 是否命中缓存\n */\n hitCache: boolean;\n};\n\nexport type UseRequestOutput<I extends AnyArray, O> = Omit<UseAsyncOutput<I, O>, 'run' | 'runAsync' | 'state'> & {\n state: ComputedRef<UseRequestState<O>>;\n send: (...inputs: I) => void;\n sendAsync: (...inputs: I) => Promise<O>;\n hitShare: Ref<boolean>;\n hitCache: Ref<boolean>;\n};\n\nexport type UseRequestOutputFilled<I extends AnyArray, O> = Omit<\n UseAsyncOutputFilled<I, O>,\n 'run' | 'runAsync' | 'state'\n> & {\n state: ComputedRef<UseRequestStateFilled<O>>;\n send: (...inputs: I) => void;\n sendAsync: (...inputs: I) => Promise<O>;\n hitShare: Ref<boolean>;\n hitCache: Ref<boolean>;\n};\n\nconst defaultCacheStorage = new MemoryCache();\nconst defaultShareStorage = new MemoryCache();\n\n/**\n * 使用请求功能的组合式函数。\n * 支持缓存和异步操作的封装。\n *\n * @template O 请求返回的数据类型。\n * @template I 请求参数的类型。\n * @param {() => Promise<O>} fn 实际的请求函数,返回一个 Promise。\n * @param {UseRequestOptions<I, O>} [options] 请求选项,包括缓存和回调配置。\n * @returns 返回一个对象,包含以下内容:\n * - 异步操作的状态(如 loading、error 等)。\n * - 是否命中缓存(hitCache)。\n * - 是否命中共享请求(hitShare)。\n */\nexport function useRequest<I extends AnyArray, O>(\n fn: (...inputs: I) => Promise<O>,\n options: Omit<UseRequestOptions<I, O>, 'placeholder'> & {\n placeholder: () => O;\n },\n): UseRequestOutputFilled<I, O>;\nexport function useRequest<I extends AnyArray, O>(\n fn: (...inputs: I) => Promise<O>,\n options?: UseRequestOptions<I, O>,\n): UseRequestOutput<I, O>;\nexport function useRequest<I extends AnyArray, O>(\n fn: (...inputs: I) => Promise<O>,\n options?: UseRequestOptions<I, O>,\n): UseRequestOutput<I, O> {\n const { id, cache, share, onCacheHit } = options || {};\n\n const shareStorage = defaultShareStorage as MemoryCache<Promise<O>>;\n const shareAble = isObject(share) ? !share.disabled : share;\n const shareOptions = isObject(share) ? share : {};\n const hitShare = ref(false);\n\n const _cached = defaultCacheStorage as Cache<O>;\n const cacheStorage = isObject(cache) ? cache.storage || _cached : _cached;\n const cacheAble = isObject(cache) ? !cache.disabled : cache;\n const cacheOptions = isObject(cache) ? cache : {};\n const hitCache = ref(false);\n\n const cacheableFn = async (...inputs: I) => {\n const requestId = isFunction(id) ? id() : id;\n\n hitShare.value = false;\n hitCache.value = false;\n\n if (requestId && shareAble) {\n const shared = shareStorage.get(requestId);\n if (shared) {\n hitShare.value = true;\n const [err, data] = await tryFlatten(shared.data);\n if (err) {\n shareStorage.del(requestId);\n throw err;\n }\n\n return data;\n }\n }\n\n // 这里不能先执行,因为如果要缓存的话,必须用缓存结果\n const { promise, resolve, reject } = Promise.withResolvers<O>();\n\n if (requestId && shareAble) {\n shareStorage.set(requestId, promise, shareOptions);\n }\n\n if (requestId && cacheAble) {\n const cached = await cacheStorage.get(requestId);\n\n if (cached) {\n const data = cached.data;\n resolve(data);\n hitCache.value = true;\n await onCacheHit?.(cached);\n return promise;\n }\n } else if (cacheAble) {\n console.warn('[useRequest] 缓存功能启用但未提供 requestId,无法使用缓存');\n }\n\n const [err, data] = await tryFlatten(fn(...inputs));\n\n if (err) {\n reject(err);\n return promise;\n }\n\n if (requestId && cacheAble) {\n cacheStorage.set(requestId, data, cacheOptions);\n }\n\n resolve(data);\n return promise;\n };\n const { state: asyncState, run: send, runAsync: sendAsync, ...async } = useAsync(cacheableFn, options);\n\n const state = computed(() => ({\n ...asyncState.value,\n hitShare: hitShare.value,\n hitCache: hitCache.value,\n }));\n\n return {\n ...async,\n state,\n send,\n sendAsync,\n hitShare,\n hitCache,\n };\n}\n"],"mappings":";;;;;;AAiJA,IAAM,sBAAsB,IAAI,aAAa;AAC7C,IAAM,sBAAsB,IAAI,aAAa;AAyB7C,SAAgB,WACd,IACA,SACwB;CACxB,MAAM,EAAE,IAAI,OAAO,OAAO,eAAe,WAAW,EAAE;CAEtD,MAAM,eAAe;CACrB,MAAM,YAAY,SAAS,MAAM,GAAG,CAAC,MAAM,WAAW;CACtD,MAAM,eAAe,SAAS,MAAM,GAAG,QAAQ,EAAE;CACjD,MAAM,WAAW,IAAI,MAAM;CAE3B,MAAM,UAAU;CAChB,MAAM,eAAe,SAAS,MAAM,GAAG,MAAM,WAAW,UAAU;CAClE,MAAM,YAAY,SAAS,MAAM,GAAG,CAAC,MAAM,WAAW;CACtD,MAAM,eAAe,SAAS,MAAM,GAAG,QAAQ,EAAE;CACjD,MAAM,WAAW,IAAI,MAAM;CAE3B,MAAM,cAAc,OAAO,GAAG,WAAc;EAC1C,MAAM,YAAY,WAAW,GAAG,GAAG,IAAI,GAAG;EAE1C,SAAS,QAAQ;EACjB,SAAS,QAAQ;EAEjB,IAAI,aAAa,WAAW;GAC1B,MAAM,SAAS,aAAa,IAAI,UAAU;GAC1C,IAAI,QAAQ;IACV,SAAS,QAAQ;IACjB,MAAM,CAAC,KAAK,QAAQ,MAAM,WAAW,OAAO,KAAK;IACjD,IAAI,KAAK;KACP,aAAa,IAAI,UAAU;KAC3B,MAAM;;IAGR,OAAO;;;EAKX,MAAM,EAAE,SAAS,SAAS,WAAW,QAAQ,eAAkB;EAE/D,IAAI,aAAa,WACf,aAAa,IAAI,WAAW,SAAS,aAAa;EAGpD,IAAI,aAAa,WAAW;GAC1B,MAAM,SAAS,MAAM,aAAa,IAAI,UAAU;GAEhD,IAAI,QAAQ;IACV,MAAM,OAAO,OAAO;IACpB,QAAQ,KAAK;IACb,SAAS,QAAQ;IACjB,MAAM,aAAa,OAAO;IAC1B,OAAO;;SAEJ,IAAI,WACT,QAAQ,KAAK,2CAA2C;EAG1D,MAAM,CAAC,KAAK,QAAQ,MAAM,WAAW,GAAG,GAAG,OAAO,CAAC;EAEnD,IAAI,KAAK;GACP,OAAO,IAAI;GACX,OAAO;;EAGT,IAAI,aAAa,WACf,aAAa,IAAI,WAAW,MAAM,aAAa;EAGjD,QAAQ,KAAK;EACb,OAAO;;CAET,MAAM,EAAE,OAAO,YAAY,KAAK,MAAM,UAAU,WAAW,GAAG,UAAU,SAAS,aAAa,QAAQ;CAEtG,MAAM,QAAQ,gBAAgB;EAC5B,GAAG,WAAW;EACd,UAAU,SAAS;EACnB,UAAU,SAAS;EACpB,EAAE;CAEH,OAAO;EACL,GAAG;EACH;EACA;EACA;EACA;EACA;EACD"}
1
+ {"version":3,"file":"request.mjs","names":[],"sources":["../src/request.ts"],"sourcesContent":["import { type Cache, type Cached, type CacheOptions, MemoryCache } from '@cloudcome/utils-core/cache';\nimport type { DateValue } from '@cloudcome/utils-core/date';\nimport { tryFlatten } from '@cloudcome/utils-core/try';\nimport { isFunction, isObject } from '@cloudcome/utils-core/type';\nimport type { AnyArray, MaybeCallable } from '@cloudcome/utils-core/types';\nimport type { ComputedRef, Ref } from 'vue';\nimport { computed, ref } from 'vue';\nimport {\n type UseAsyncOptions,\n type UseAsyncOutput,\n type UseAsyncOutputFilled,\n type UseAsyncState,\n useAsync,\n} from './async';\n\n/**\n * 请求缓存配置选项。\n * @template T 缓存数据的类型。\n */\nexport type RequestCacheOptions<T> = CacheOptions & {\n /**\n * 是否禁用缓存,默认为 false。\n * 如果设置为 true,则不会使用缓存。\n */\n disabled?: boolean;\n\n /**\n * 自定义缓存存储实现。\n * 可以传入自定义的缓存类来替代默认的内存缓存。\n */\n storage?: Cache<T>;\n};\n\nexport type RequestShareOptions = {\n /**\n * 是否禁用共享请求,默认为 false。\n * 如果设置为 true,则不会共享请求结果。\n */\n disabled?: boolean;\n\n /**\n * 共享的最大时长(毫秒),为 0 时表示永久共享。\n * 超过该时长后,共享的请求结果将被清除。\n */\n maxAge?: number;\n\n /**\n * 共享的过期时间(时间戳、日期字符串、日期对象等)。\n * 优先级比 maxAge 更高,指定具体的过期时间。\n */\n expiredAt?: DateValue;\n};\n\nexport type RetryOptions = {\n /**\n * 是否禁用重试,默认为 false。\n * 如果设置为 true,则不会重试。\n */\n disabled?: boolean;\n};\n\n/**\n * 请求选项,扩展了异步操作的选项。\n * @template T 请求返回的数据类型。\n * @template I 请求参数的类型。\n */\nexport type UseRequestOptions<I extends AnyArray, O> = UseAsyncOptions<I, O> & {\n /**\n * 请求的唯一标识符,可以是字符串或函数返回的字符串。\n * 用于缓存和共享的键值。\n */\n id?: MaybeCallable<string>;\n\n /**\n * 缓存配置,可以是布尔值或完整的缓存选项。\n * 如果为 true,则启用默认缓存;如果为对象,则可以自定义缓存行为。\n */\n cache?: boolean | RequestCacheOptions<O>;\n\n /**\n * 共享配置,可以是布尔值或完整的共享选项。\n * 共享时,相同的请求 ID 会复用第一次发出且没有响应完成的请求。\n *\n * 例如,10 组件同时或先后发起 10 次请求用于获取用户信息,\n * 那么这 10 个组件会共同等待第一次发起的请求,直到完成。\n *\n * 共享与缓存是不同的概念,共享是进行时,缓存是过去时,即:\n * - 共享是共享**正在发送**的请求\n * - 缓存是缓存**已经发送**的请求\n *\n * 如果为 true,则启用默认共享;如果为对象,则可以自定义共享行为。\n */\n share?: boolean | RequestShareOptions;\n\n /**\n * 当命中缓存时的回调函数。\n * 在缓存命中时触发,接收缓存的数据作为参数。\n */\n onCacheHit?: (cached: Cached<O>) => unknown;\n};\n\nexport type UseRequestState = UseAsyncState & {\n /**\n * 是否命中共享数据\n */\n hitShare: boolean;\n\n /**\n * 是否命中缓存\n */\n hitCache: boolean;\n};\n\nexport type UseRequestStateFilled = UseRequestState;\n\nexport type UseRequestOutput<I extends AnyArray, O> = Omit<UseAsyncOutput<I, O>, 'run' | 'runAsync' | 'state'> & {\n state: ComputedRef<UseRequestState>;\n send: (...inputs: I) => void;\n sendAsync: (...inputs: I) => Promise<O>;\n hitShare: Ref<boolean>;\n hitCache: Ref<boolean>;\n};\n\nexport type UseRequestOutputFilled<I extends AnyArray, O> = Omit<\n UseAsyncOutputFilled<I, O>,\n 'run' | 'runAsync' | 'state'\n> & {\n state: ComputedRef<UseRequestStateFilled>;\n send: (...inputs: I) => void;\n sendAsync: (...inputs: I) => Promise<O>;\n hitShare: Ref<boolean>;\n hitCache: Ref<boolean>;\n};\n\nconst defaultCacheStorage = new MemoryCache();\nconst defaultShareStorage = new MemoryCache();\n\n/**\n * 使用请求功能的组合式函数。\n * 支持缓存和异步操作的封装。\n *\n * @template O 请求返回的数据类型。\n * @template I 请求参数的类型。\n * @param {() => Promise<O>} fn 实际的请求函数,返回一个 Promise。\n * @param {UseRequestOptions<I, O>} [options] 请求选项,包括缓存和回调配置。\n * @returns 返回一个对象,包含以下内容:\n * - 异步操作的状态(如 loading、error 等)。\n * - 是否命中缓存(hitCache)。\n * - 是否命中共享请求(hitShare)。\n */\nexport function useRequest<I extends AnyArray, O>(\n fn: (...inputs: I) => Promise<O>,\n options: Omit<UseRequestOptions<I, O>, 'placeholder'> & {\n placeholder: () => O;\n },\n): UseRequestOutputFilled<I, O>;\nexport function useRequest<I extends AnyArray, O>(\n fn: (...inputs: I) => Promise<O>,\n options?: UseRequestOptions<I, O>,\n): UseRequestOutput<I, O>;\nexport function useRequest<I extends AnyArray, O>(\n fn: (...inputs: I) => Promise<O>,\n options?: UseRequestOptions<I, O>,\n): UseRequestOutput<I, O> {\n const { id, cache, share, onCacheHit } = options || {};\n\n const shareStorage = defaultShareStorage as MemoryCache<Promise<O>>;\n const shareAble = isObject(share) ? !share.disabled : share;\n const shareOptions = isObject(share) ? share : {};\n const hitShare = ref(false);\n\n const _cached = defaultCacheStorage as Cache<O>;\n const cacheStorage = isObject(cache) ? cache.storage || _cached : _cached;\n const cacheAble = isObject(cache) ? !cache.disabled : cache;\n const cacheOptions = isObject(cache) ? cache : {};\n const hitCache = ref(false);\n\n const cacheableFn = async (...inputs: I) => {\n const requestId = isFunction(id) ? id() : id;\n\n hitShare.value = false;\n hitCache.value = false;\n\n if (requestId && shareAble) {\n const shared = shareStorage.get(requestId);\n if (shared) {\n hitShare.value = true;\n const [err, data] = await tryFlatten(shared.data);\n if (err) {\n shareStorage.del(requestId);\n throw err;\n }\n\n return data;\n }\n }\n\n // 这里不能先执行,因为如果要缓存的话,必须用缓存结果\n const { promise, resolve, reject } = Promise.withResolvers<O>();\n\n if (requestId && shareAble) {\n shareStorage.set(requestId, promise, shareOptions);\n }\n\n if (requestId && cacheAble) {\n const cached = await cacheStorage.get(requestId);\n\n if (cached) {\n const data = cached.data;\n resolve(data);\n hitCache.value = true;\n await onCacheHit?.(cached);\n return promise;\n }\n } else if (cacheAble) {\n console.warn('[useRequest] 缓存功能启用但未提供 requestId,无法使用缓存');\n }\n\n const [err, data] = await tryFlatten(fn(...inputs));\n\n if (err) {\n reject(err);\n return promise;\n }\n\n if (requestId && cacheAble) {\n cacheStorage.set(requestId, data, cacheOptions);\n }\n\n resolve(data);\n return promise;\n };\n const { state: asyncState, run: send, runAsync: sendAsync, ...async } = useAsync(cacheableFn, options);\n\n const state = computed(() => ({\n ...asyncState.value,\n hitShare: hitShare.value,\n hitCache: hitCache.value,\n }));\n\n return {\n ...async,\n state,\n send,\n sendAsync,\n hitShare,\n hitCache,\n };\n}\n"],"mappings":";;;;;;AAsIA,IAAM,sBAAsB,IAAI,aAAa;AAC7C,IAAM,sBAAsB,IAAI,aAAa;AAyB7C,SAAgB,WACd,IACA,SACwB;CACxB,MAAM,EAAE,IAAI,OAAO,OAAO,eAAe,WAAW,EAAE;CAEtD,MAAM,eAAe;CACrB,MAAM,YAAY,SAAS,MAAM,GAAG,CAAC,MAAM,WAAW;CACtD,MAAM,eAAe,SAAS,MAAM,GAAG,QAAQ,EAAE;CACjD,MAAM,WAAW,IAAI,MAAM;CAE3B,MAAM,UAAU;CAChB,MAAM,eAAe,SAAS,MAAM,GAAG,MAAM,WAAW,UAAU;CAClE,MAAM,YAAY,SAAS,MAAM,GAAG,CAAC,MAAM,WAAW;CACtD,MAAM,eAAe,SAAS,MAAM,GAAG,QAAQ,EAAE;CACjD,MAAM,WAAW,IAAI,MAAM;CAE3B,MAAM,cAAc,OAAO,GAAG,WAAc;EAC1C,MAAM,YAAY,WAAW,GAAG,GAAG,IAAI,GAAG;EAE1C,SAAS,QAAQ;EACjB,SAAS,QAAQ;EAEjB,IAAI,aAAa,WAAW;GAC1B,MAAM,SAAS,aAAa,IAAI,UAAU;GAC1C,IAAI,QAAQ;IACV,SAAS,QAAQ;IACjB,MAAM,CAAC,KAAK,QAAQ,MAAM,WAAW,OAAO,KAAK;IACjD,IAAI,KAAK;KACP,aAAa,IAAI,UAAU;KAC3B,MAAM;;IAGR,OAAO;;;EAKX,MAAM,EAAE,SAAS,SAAS,WAAW,QAAQ,eAAkB;EAE/D,IAAI,aAAa,WACf,aAAa,IAAI,WAAW,SAAS,aAAa;EAGpD,IAAI,aAAa,WAAW;GAC1B,MAAM,SAAS,MAAM,aAAa,IAAI,UAAU;GAEhD,IAAI,QAAQ;IACV,MAAM,OAAO,OAAO;IACpB,QAAQ,KAAK;IACb,SAAS,QAAQ;IACjB,MAAM,aAAa,OAAO;IAC1B,OAAO;;SAEJ,IAAI,WACT,QAAQ,KAAK,2CAA2C;EAG1D,MAAM,CAAC,KAAK,QAAQ,MAAM,WAAW,GAAG,GAAG,OAAO,CAAC;EAEnD,IAAI,KAAK;GACP,OAAO,IAAI;GACX,OAAO;;EAGT,IAAI,aAAa,WACf,aAAa,IAAI,WAAW,MAAM,aAAa;EAGjD,QAAQ,KAAK;EACb,OAAO;;CAET,MAAM,EAAE,OAAO,YAAY,KAAK,MAAM,UAAU,WAAW,GAAG,UAAU,SAAS,aAAa,QAAQ;CAEtG,MAAM,QAAQ,gBAAgB;EAC5B,GAAG,WAAW;EACd,UAAU,SAAS;EACnB,UAAU,SAAS;EACpB,EAAE;CAEH,OAAO;EACL,GAAG;EACH;EACA;EACA;EACA;EACA;EACD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudcome/utils-vue",
3
- "version": "1.14.1",
3
+ "version": "1.15.0",
4
4
  "description": "cloudcome utils for vue",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -89,7 +89,7 @@
89
89
  "node": ">=22"
90
90
  },
91
91
  "dependencies": {
92
- "@cloudcome/utils-core": "~1.21.0",
92
+ "@cloudcome/utils-core": "~1.22.0",
93
93
  "vue": "^3.5.34",
94
94
  "vue-component-type-helpers": "^3.2.8"
95
95
  },