@cloudcome/utils-vue 1.13.3 → 1.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -9,15 +9,15 @@
9
9
 
10
10
  ## 包列表
11
11
 
12
- | 名称 | 版本 | 描述 |
13
- | --- | --- | --- |
14
- | [@cloudcome/utils-core](./packages/utils-core) | [![npm version](https://badge.fury.io/js/@cloudcome%2Futils-core.svg)](https://npmjs.com/package/@cloudcome/utils-core) | 核心工具库,与运行环境无关的通用工具 |
12
+ | 名称 | 版本 | 描述 |
13
+ | ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
14
+ | [@cloudcome/utils-core](./packages/utils-core) | [![npm version](https://badge.fury.io/js/@cloudcome%2Futils-core.svg)](https://npmjs.com/package/@cloudcome/utils-core) | 核心工具库,与运行环境无关的通用工具 |
15
15
  | [@cloudcome/utils-browser](./packages/utils-browser) | [![npm version](https://badge.fury.io/js/@cloudcome%2Futils-browser.svg)](https://npmjs.com/package/@cloudcome/utils-browser) | 浏览器端工具(DOM、Canvas、Cookie、剪贴板等) |
16
- | [@cloudcome/utils-node](./packages/utils-node) | [![npm version](https://badge.fury.io/js/@cloudcome%2Futils-node.svg)](https://npmjs.com/package/@cloudcome/utils-node) | Node.js 端工具(Base64、加密等) |
17
- | [@cloudcome/utils-vue](./packages/utils-vue) | [![npm version](https://badge.fury.io/js/@cloudcome%2Futils-vue.svg)](https://npmjs.com/package/@cloudcome/utils-vue) | Vue 3 工具库(组合式函数、组件、请求等) |
18
- | [@cloudcome/utils-react](./packages/utils-react) | [![npm version](https://badge.fury.io/js/@cloudcome%2Futils-react.svg)](https://npmjs.com/package/@cloudcome/utils-react) | React 工具库 |
19
- | [@cloudcome/utils-uni](./packages/utils-uni) | [![npm version](https://badge.fury.io/js/@cloudcome%2Futils-uni.svg)](https://npmjs.com/package/@cloudcome/utils-uni) | UniApp 工具库(云函数、数据库、页面等) |
20
- | [@cloudcome/docs](./packages/docs) | - | VitePress 文档站点 |
16
+ | [@cloudcome/utils-node](./packages/utils-node) | [![npm version](https://badge.fury.io/js/@cloudcome%2Futils-node.svg)](https://npmjs.com/package/@cloudcome/utils-node) | Node.js 端工具(Base64、加密、JSONL 等) |
17
+ | [@cloudcome/utils-vue](./packages/utils-vue) | [![npm version](https://badge.fury.io/js/@cloudcome%2Futils-vue.svg)](https://npmjs.com/package/@cloudcome/utils-vue) | Vue 3 工具库(组合式函数、组件、请求等) |
18
+ | [@cloudcome/utils-react](./packages/utils-react) | [![npm version](https://badge.fury.io/js/@cloudcome%2Futils-react.svg)](https://npmjs.com/package/@cloudcome/utils-react) | React 工具库 |
19
+ | [@cloudcome/utils-uni](./packages/utils-uni) | [![npm version](https://badge.fury.io/js/@cloudcome%2Futils-uni.svg)](https://npmjs.com/package/@cloudcome/utils-uni) | UniApp 工具库(云函数、数据库、页面等) |
20
+ | [@cloudcome/docs](./packages/docs) | - | VitePress 文档站点 |
21
21
 
22
22
  ## 功能概览
23
23
 
@@ -25,79 +25,80 @@
25
25
 
26
26
  核心工具库,提供以下子模块:
27
27
 
28
- | 子模块 | 导入路径 | 功能 |
29
- | --- | --- | --- |
30
- | array | `@cloudcome/utils-core/array` | 数组操作 |
31
- | async | `@cloudcome/utils-core/async` | 异步工具 |
32
- | base64 | `@cloudcome/utils-core/base64` | Base64 编解码 |
33
- | cache | `@cloudcome/utils-core/cache` | 缓存工具 |
34
- | color | `@cloudcome/utils-core/color` | 颜色转换(RGB/HSL/HSV/HWB/LAB/XYZ)、对比度、亮度、混合 |
35
- | crypto | `@cloudcome/utils-core/crypto` | 加密(MD5、SHA1、SHA256、SHA512) |
36
- | date | `@cloudcome/utils-core/date` | 日期解析、格式化、时区、相对时间、周/天计算 |
37
- | dict | `@cloudcome/utils-core/dict` | 字典/映射工具 |
38
- | easing | `@cloudcome/utils-core/easing` | 缓动函数 |
39
- | emitter | `@cloudcome/utils-core/emitter` | 事件发射器 |
40
- | env | `@cloudcome/utils-core/env` | 环境检测 |
41
- | error | `@cloudcome/utils-core/error` | 错误处理 |
42
- | exception | `@cloudcome/utils-core/exception` | 异常处理 |
43
- | function | `@cloudcome/utils-core/function` | 函数工具 |
44
- | number | `@cloudcome/utils-core/number` | 数字工具 |
45
- | object | `@cloudcome/utils-core/object` | 对象遍历、深层 get/set、合并、类型判断 |
46
- | path | `@cloudcome/utils-core/path` | 路径工具 |
47
- | promise | `@cloudcome/utils-core/promise` | Promise 工具 |
48
- | qs | `@cloudcome/utils-core/qs` | 查询字符串解析与序列化 |
49
- | regexp | `@cloudcome/utils-core/regexp` | 正则表达式工具 |
50
- | string | `@cloudcome/utils-core/string` | 字符串工具 |
51
- | time | `@cloudcome/utils-core/time` | 时间单位转换 |
52
- | timer | `@cloudcome/utils-core/timer` | 定时器工具 |
53
- | tree | `@cloudcome/utils-core/tree` | 树结构操作 |
54
- | try | `@cloudcome/utils-core/try` | 安全调用(try-catch 包装,支持同步/异步/柯里化) |
55
- | type | `@cloudcome/utils-core/type` | 类型判断 |
56
- | types | `@cloudcome/utils-core/types` | 公共类型定义 |
57
- | unique | `@cloudcome/utils-core/unique` | 唯一 ID 生成 |
58
- | url | `@cloudcome/utils-core/url` | URL 解析与构建 |
59
- | version | `@cloudcome/utils-core/version` | 版本号比较 |
28
+ | 子模块 | 导入路径 | 功能 |
29
+ | --------- | --------------------------------- | ------------------------------------------------------- |
30
+ | array | `@cloudcome/utils-core/array` | 数组操作 |
31
+ | async | `@cloudcome/utils-core/async` | 异步工具 |
32
+ | base64 | `@cloudcome/utils-core/base64` | Base64 编解码 |
33
+ | cache | `@cloudcome/utils-core/cache` | 缓存工具 |
34
+ | color | `@cloudcome/utils-core/color` | 颜色转换(RGB/HSL/HSV/HWB/LAB/XYZ)、对比度、亮度、混合 |
35
+ | crypto | `@cloudcome/utils-core/crypto` | 加密(MD5、SHA1、SHA256、SHA512) |
36
+ | date | `@cloudcome/utils-core/date` | 日期解析、格式化、时区、相对时间、周/天计算 |
37
+ | dict | `@cloudcome/utils-core/dict` | 字典/映射工具 |
38
+ | easing | `@cloudcome/utils-core/easing` | 缓动函数 |
39
+ | emitter | `@cloudcome/utils-core/emitter` | 事件发射器 |
40
+ | env | `@cloudcome/utils-core/env` | 环境检测 |
41
+ | error | `@cloudcome/utils-core/error` | 错误处理 |
42
+ | exception | `@cloudcome/utils-core/exception` | 异常处理 |
43
+ | function | `@cloudcome/utils-core/function` | 函数工具 |
44
+ | number | `@cloudcome/utils-core/number` | 数字工具 |
45
+ | object | `@cloudcome/utils-core/object` | 对象遍历、深层 get/set、合并、类型判断 |
46
+ | path | `@cloudcome/utils-core/path` | 路径工具 |
47
+ | promise | `@cloudcome/utils-core/promise` | Promise 工具 |
48
+ | qs | `@cloudcome/utils-core/qs` | 查询字符串解析与序列化 |
49
+ | regexp | `@cloudcome/utils-core/regexp` | 正则表达式工具 |
50
+ | string | `@cloudcome/utils-core/string` | 字符串工具 |
51
+ | time | `@cloudcome/utils-core/time` | 时间单位转换 |
52
+ | timer | `@cloudcome/utils-core/timer` | 定时器工具 |
53
+ | tree | `@cloudcome/utils-core/tree` | 树结构操作 |
54
+ | try | `@cloudcome/utils-core/try` | 安全调用(try-catch 包装,支持同步/异步/柯里化) |
55
+ | type | `@cloudcome/utils-core/type` | 类型判断 |
56
+ | types | `@cloudcome/utils-core/types` | 公共类型定义 |
57
+ | unique | `@cloudcome/utils-core/unique` | 唯一 ID 生成 |
58
+ | url | `@cloudcome/utils-core/url` | URL 解析与构建 |
59
+ | version | `@cloudcome/utils-core/version` | 版本号比较 |
60
60
 
61
61
  ### @cloudcome/utils-browser
62
62
 
63
63
  浏览器端工具库,依赖 `@cloudcome/utils-core`:
64
64
 
65
- | 子模块 | 导入路径 | 功能 |
66
- | --- | --- | --- |
67
- | base64 | `@cloudcome/utils-browser/base64` | 浏览器端 Base64 编解码 |
68
- | cache | `@cloudcome/utils-browser/cache` | 浏览器缓存(localStorage/sessionStorage) |
69
- | canvas | `@cloudcome/utils-browser/canvas` | Canvas 操作 |
70
- | clipboard | `@cloudcome/utils-browser/clipboard` | 剪贴板读写 |
71
- | cookie | `@cloudcome/utils-browser/cookie` | Cookie 读写 |
72
- | dom | `@cloudcome/utils-browser/dom` | DOM 操作 |
73
- | download | `@cloudcome/utils-browser/download` | 文件下载 |
74
- | image | `@cloudcome/utils-browser/image` | 图片处理 |
75
- | timer | `@cloudcome/utils-browser/timer` | 浏览器端定时器 |
76
- | video | `@cloudcome/utils-browser/video` | 视频处理 |
65
+ | 子模块 | 导入路径 | 功能 |
66
+ | --------- | ------------------------------------ | ----------------------------------------- |
67
+ | base64 | `@cloudcome/utils-browser/base64` | 浏览器端 Base64 编解码 |
68
+ | cache | `@cloudcome/utils-browser/cache` | 浏览器缓存(localStorage/sessionStorage) |
69
+ | canvas | `@cloudcome/utils-browser/canvas` | Canvas 操作 |
70
+ | clipboard | `@cloudcome/utils-browser/clipboard` | 剪贴板读写 |
71
+ | cookie | `@cloudcome/utils-browser/cookie` | Cookie 读写 |
72
+ | dom | `@cloudcome/utils-browser/dom` | DOM 操作 |
73
+ | download | `@cloudcome/utils-browser/download` | 文件下载 |
74
+ | image | `@cloudcome/utils-browser/image` | 图片处理 |
75
+ | timer | `@cloudcome/utils-browser/timer` | 浏览器端定时器 |
76
+ | video | `@cloudcome/utils-browser/video` | 视频处理 |
77
77
 
78
78
  ### @cloudcome/utils-node
79
79
 
80
80
  Node.js 端工具库:
81
81
 
82
- | 子模块 | 导入路径 | 功能 |
83
- | --- | --- | --- |
82
+ | 子模块 | 导入路径 | 功能 |
83
+ | ------ | ------------------------------ | ------------------------ |
84
84
  | base64 | `@cloudcome/utils-node/base64` | Node.js 端 Base64 编解码 |
85
- | crypto | `@cloudcome/utils-node/crypto` | Node.js 端加密工具 |
85
+ | crypto | `@cloudcome/utils-node/crypto` | Node.js 端加密工具 |
86
+ | jsonl | `@cloudcome/utils-node/jsonl` | JSONL 文件读写 |
86
87
 
87
88
  ### @cloudcome/utils-vue
88
89
 
89
90
  Vue 3 工具库,依赖 `@cloudcome/utils-core` 和 `vue`:
90
91
 
91
- | 子模块 | 导入路径 | 功能 |
92
- | --- | --- | --- |
93
- | async | `@cloudcome/utils-vue/async` | Vue 异步组合式函数 |
94
- | component | `@cloudcome/utils-vue/component` | 组件工具(生命周期等) |
95
- | event | `@cloudcome/utils-vue/event` | 事件工具 |
96
- | request | `@cloudcome/utils-vue/request` | 请求组合式函数(useRequest) |
97
- | shared | `@cloudcome/utils-vue/shared` | 共享工具 |
98
- | state | `@cloudcome/utils-vue/state` | 状态管理工具 |
99
- | time | `@cloudcome/utils-vue/time` | 时间相关组合式函数 |
100
- | types | `@cloudcome/utils-vue/types` | 类型定义 |
92
+ | 子模块 | 导入路径 | 功能 |
93
+ | --------- | -------------------------------- | ---------------------------- |
94
+ | async | `@cloudcome/utils-vue/async` | Vue 异步组合式函数 |
95
+ | component | `@cloudcome/utils-vue/component` | 组件工具(生命周期等) |
96
+ | event | `@cloudcome/utils-vue/event` | 事件工具 |
97
+ | request | `@cloudcome/utils-vue/request` | 请求组合式函数(useRequest) |
98
+ | shared | `@cloudcome/utils-vue/shared` | 共享工具 |
99
+ | state | `@cloudcome/utils-vue/state` | 状态管理工具 |
100
+ | time | `@cloudcome/utils-vue/time` | 时间相关组合式函数 |
101
+ | types | `@cloudcome/utils-vue/types` | 类型定义 |
101
102
 
102
103
  ### @cloudcome/utils-react
103
104
 
@@ -107,13 +108,11 @@ React 工具库。
107
108
 
108
109
  UniApp 工具库,依赖 `@cloudcome/utils-core`、`@cloudcome/utils-vue`:
109
110
 
110
- | 子模块 | 导入路径 | 功能 |
111
- | --- | --- | --- |
112
- | app | `@cloudcome/utils-uni/app` | App 相关工具 |
113
- | client | `@cloudcome/utils-uni/client` | 客户端工具 |
114
- | cloud | `@cloudcome/utils-uni/cloud` | 云函数工具(调用、错误处理、uni-id 等) |
115
- | database | `@cloudcome/utils-uni/database` | 数据库操作(CRUD、事务、分页、upsert 等) |
116
- | page | `@cloudcome/utils-uni/page` | 页面相关工具 |
111
+ | 子模块 | 导入路径 | 功能 |
112
+ | -------- | ------------------------------- | ---------------------------------------------------- |
113
+ | client | `@cloudcome/utils-uni/client` | 客户端工具(App/页面生命周期、消息提示、异步工具等) |
114
+ | cloud | `@cloudcome/utils-uni/cloud` | 云函数工具(调用、错误处理、uni-id 等) |
115
+ | database | `@cloudcome/utils-uni/database` | 数据库操作(CRUD、事务、分页、upsert 等) |
117
116
 
118
117
  ## 开发
119
118
 
package/dist/async.cjs CHANGED
@@ -26,7 +26,7 @@ function useAsync(fn, options) {
26
26
  error.value = err;
27
27
  try {
28
28
  options?.onError?.(err, ...inputs);
29
- } catch (_err) {}
29
+ } catch {}
30
30
  throw err;
31
31
  } finally {
32
32
  loading.value = false;
@@ -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 (_err) {\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;YAC3B,MAAM;GAGf,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 { 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"}
package/dist/async.mjs CHANGED
@@ -25,7 +25,7 @@ function useAsync(fn, options) {
25
25
  error.value = err;
26
26
  try {
27
27
  options?.onError?.(err, ...inputs);
28
- } catch (_err) {}
28
+ } catch {}
29
29
  throw err;
30
30
  } finally {
31
31
  loading.value = false;
@@ -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 (_err) {\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;YAC3B,MAAM;GAGf,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 { 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 +1 @@
1
- {"version":3,"file":"component.cjs","names":[],"sources":["../src/component/life.ts","../src/component/self.ts"],"sourcesContent":["import type { MaybePromise } from '@cloudcome/utils-core/types';\nimport {\n onActivated,\n onBeforeMount,\n onBeforeUnmount,\n onDeactivated,\n onMounted,\n onUnmounted,\n} from 'vue';\nimport { _runLifeHook } from '@/shared';\n\nexport type HookListener = () => MaybePromise<unknown>;\nexport type HookListenerWithDispose = () => MaybePromise<\n undefined | HookListener\n>;\n\n/**\n * 页面挂载前生命周期钩子\n *\n * @param beforeMount - 在组件挂载前执行的回调函数,可以返回一个清理函数\n *\n * @example\n * ```ts\n * useMount(() => {\n * console.log('组件即将挂载');\n * // 可以返回一个清理函数,在组件卸载前执行\n * return () => {\n * console.log('组件即将卸载');\n * };\n * });\n * ```\n */\nexport function useMount(beforeMount: HookListenerWithDispose) {\n _runLifeHook(onBeforeMount, onBeforeUnmount, beforeMount);\n}\n\n/**\n * 页面挂载后生命周期钩子\n *\n * @param mounted - 在组件挂载后执行的回调函数,可以返回一个清理函数\n *\n * @example\n * ```ts\n * useMounted(() => {\n * console.log('组件已挂载');\n * // 可以返回一个清理函数,在组件卸载前执行\n * return () => {\n * console.log('组件即将卸载');\n * };\n * });\n * ```\n */\nexport function useMounted(mounted: HookListenerWithDispose) {\n _runLifeHook(onMounted, onUnmounted, mounted);\n}\n\n/**\n * 页面激活时生命周期钩子\n *\n * @param activated - 在组件被激活时执行的回调函数,可以返回一个清理函数\n *\n * @example\n * ```ts\n * useActivated(() => {\n * console.log('组件已激活');\n * // 可以返回一个清理函数,在组件失活前执行\n * return () => {\n * console.log('组件即将失活');\n * };\n * });\n * ```\n */\nexport function useActivated(activated: HookListenerWithDispose) {\n _runLifeHook(onActivated, onDeactivated, activated);\n}\n","import { type Ref, ref } from 'vue';\nimport type {\n ComponentExposed,\n ComponentProps,\n} from 'vue-component-type-helpers';\n\n/**\n * 创建一个响应式引用,用于暴露组件实例\n * @template T 组件类型\n * @param {T} Comp 组件定义\n * @returns 返回一个可响应式访问的组件实例引用\n * @example\n * const compRef = useExpose(MyComponent)\n */\nexport function useExpose<T>(_Comp: T) {\n // 这里必须类型断言,否则构建会失败\n return ref<ComponentExposed<T> | null>(\n null,\n ) as Ref<ComponentExposed<T> | null>;\n}\n\n/**\n * 将字符串的首字母转换为小写\n * @template S 字符串类型\n * @typedef {S extends `${infer First}${infer Rest}` ? `${Lowercase<First>}${Rest}` : S} LowercaseFirst\n */\ntype LowercaseFirst<S extends string> = S extends `${infer First}${infer Rest}`\n ? `${Lowercase<First>}${Rest}`\n : S;\n\n/**\n * 从组件props中提取事件类型\n * @template T 组件props类型\n * @typedef {Object} PickEmits\n * @property {Object} [K in keyof T as K extends `on${infer Rest}`...] 转换后的emit事件名\n * - @property {Function} [...args: P] 事件回调函数\n */\ntype PickEmits<T> = {\n [K in keyof T as K extends `on${infer Rest}`\n ? // biome-ignore lint/suspicious/noExplicitAny: 必须使用 any\n T[K] extends (...args: any[]) => any\n ? LowercaseFirst<Rest>\n : never\n : // biome-ignore lint/suspicious/noExplicitAny: 必须使用 any\n never]: T[K] extends (...args: infer P) => any\n ? (...args: P) => unknown\n : never;\n};\n\n/**\n * 创建一个组件emit事件监听器\n * @template T 组件类型\n * @template E 从组件props中提取的事件类型\n * @template K 事件名\n * @param {T} Comp 组件定义\n * @param {K} event 事件名称\n * @param {E[K]} listener 事件监听函数\n * @returns {E[K]} 返回传入的事件监听函数\n * @example\n * const handleClick = useEmit(MyComponent, 'click', (payload) => {\n * console.log('click event', payload)\n * })\n */\nexport function useEmit<\n T,\n E extends PickEmits<Required<ComponentProps<T>>>,\n K extends keyof E,\n>(_Comp: T, _event: K, listener: E[K]) {\n return listener;\n}\n\ntype PickMethods<T> = {\n // biome-ignore lint/suspicious/noExplicitAny: 必须使用 any\n [K in keyof T]: T[K] extends (...args: unknown[]) => any ? T[K] : never;\n};\n\n/**\n * 从组件props中提取方法并返回指定方法\n * @template T 组件类型\n * @template M 从组件props中提取的方法类型\n * @template K 方法名类型\n * @param {T} Comp 组件定义\n * @param {K} name 方法名称\n * @param {M[K]} method 要返回的方法\n * @returns {M[K]} 返回传入的方法\n * @example\n * const handleUpdate = useMethod(MyComponent, 'update', (value) => {\n * console.log('update value', value)\n * })\n */\nexport function useMethod<\n T,\n M extends PickMethods<Required<ComponentProps<T>>>,\n K extends keyof M,\n>(_Comp: T, _name: K, method: M[K]) {\n return method;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAgCA,SAAgB,SAAS,aAAsC;CAC7D,eAAA,aAAa,IAAA,eAAe,IAAA,iBAAiB,YAAY;;;;;;;;;;;;;;;;;;AAmB3D,SAAgB,WAAW,SAAkC;CAC3D,eAAA,aAAa,IAAA,WAAW,IAAA,aAAa,QAAQ;;;;;;;;;;;;;;;;;;AAmB/C,SAAgB,aAAa,WAAoC;CAC/D,eAAA,aAAa,IAAA,aAAa,IAAA,eAAe,UAAU;;;;;;;;;;;;AC3DrD,SAAgB,UAAa,OAAU;CAErC,QAAA,GAAA,IAAA,KACE,KACD;;;;;;;;;;;;;;;;AA6CH,SAAgB,QAId,OAAU,QAAW,UAAgB;CACrC,OAAO;;;;;;;;;;;;;;;;AAsBT,SAAgB,UAId,OAAU,OAAU,QAAc;CAClC,OAAO"}
1
+ {"version":3,"file":"component.cjs","names":[],"sources":["../src/component/life.ts","../src/component/self.ts"],"sourcesContent":["import type { MaybePromise } from '@cloudcome/utils-core/types';\nimport { onActivated, onBeforeMount, onBeforeUnmount, onDeactivated, onMounted, onUnmounted } from 'vue';\nimport { _runLifeHook } from '@/shared';\n\nexport type HookListener = () => MaybePromise<unknown>;\nexport type HookListenerWithDispose = () => MaybePromise<undefined | HookListener>;\n\n/**\n * 页面挂载前生命周期钩子\n *\n * @param beforeMount - 在组件挂载前执行的回调函数,可以返回一个清理函数\n *\n * @example\n * ```ts\n * useMount(() => {\n * console.log('组件即将挂载');\n * // 可以返回一个清理函数,在组件卸载前执行\n * return () => {\n * console.log('组件即将卸载');\n * };\n * });\n * ```\n */\nexport function useMount(beforeMount: HookListenerWithDispose) {\n _runLifeHook(onBeforeMount, onBeforeUnmount, beforeMount);\n}\n\n/**\n * 页面挂载后生命周期钩子\n *\n * @param mounted - 在组件挂载后执行的回调函数,可以返回一个清理函数\n *\n * @example\n * ```ts\n * useMounted(() => {\n * console.log('组件已挂载');\n * // 可以返回一个清理函数,在组件卸载前执行\n * return () => {\n * console.log('组件即将卸载');\n * };\n * });\n * ```\n */\nexport function useMounted(mounted: HookListenerWithDispose) {\n _runLifeHook(onMounted, onUnmounted, mounted);\n}\n\n/**\n * 页面激活时生命周期钩子\n *\n * @param activated - 在组件被激活时执行的回调函数,可以返回一个清理函数\n *\n * @example\n * ```ts\n * useActivated(() => {\n * console.log('组件已激活');\n * // 可以返回一个清理函数,在组件失活前执行\n * return () => {\n * console.log('组件即将失活');\n * };\n * });\n * ```\n */\nexport function useActivated(activated: HookListenerWithDispose) {\n _runLifeHook(onActivated, onDeactivated, activated);\n}\n","import { type Ref, ref } from 'vue';\nimport type { ComponentExposed, ComponentProps } from 'vue-component-type-helpers';\n\n/**\n * 创建一个响应式引用,用于暴露组件实例\n * @template T 组件类型\n * @param {T} Comp 组件定义\n * @returns 返回一个可响应式访问的组件实例引用\n * @example\n * const compRef = useExpose(MyComponent)\n */\nexport function useExpose<T>(_Comp: T) {\n // 这里必须类型断言,否则构建会失败\n return ref<ComponentExposed<T> | null>(null) as Ref<ComponentExposed<T> | null>;\n}\n\n/**\n * 将字符串的首字母转换为小写\n * @template S 字符串类型\n * @typedef {S extends `${infer First}${infer Rest}` ? `${Lowercase<First>}${Rest}` : S} LowercaseFirst\n */\ntype LowercaseFirst<S extends string> = S extends `${infer First}${infer Rest}` ? `${Lowercase<First>}${Rest}` : S;\n\n/**\n * 从组件props中提取事件类型\n * @template T 组件props类型\n * @typedef {Object} PickEmits\n * @property {Object} [K in keyof T as K extends `on${infer Rest}`...] 转换后的emit事件名\n * - @property {Function} [...args: P] 事件回调函数\n */\ntype PickEmits<T> = {\n [K in keyof T as K extends `on${infer Rest}`\n ? // biome-ignore lint/suspicious/noExplicitAny: 必须使用 any\n T[K] extends (...args: any[]) => any\n ? LowercaseFirst<Rest>\n : never\n : // biome-ignore lint/suspicious/noExplicitAny: 必须使用 any\n never]: T[K] extends (...args: infer P) => any ? (...args: P) => unknown : never;\n};\n\n/**\n * 创建一个组件emit事件监听器\n * @template T 组件类型\n * @template E 从组件props中提取的事件类型\n * @template K 事件名\n * @param {T} Comp 组件定义\n * @param {K} event 事件名称\n * @param {E[K]} listener 事件监听函数\n * @returns {E[K]} 返回传入的事件监听函数\n * @example\n * const handleClick = useEmit(MyComponent, 'click', (payload) => {\n * console.log('click event', payload)\n * })\n */\nexport function useEmit<T, E extends PickEmits<Required<ComponentProps<T>>>, K extends keyof E>(\n _Comp: T,\n _event: K,\n listener: E[K],\n) {\n return listener;\n}\n\ntype PickMethods<T> = {\n // biome-ignore lint/suspicious/noExplicitAny: 必须使用 any\n [K in keyof T]: T[K] extends (...args: unknown[]) => any ? T[K] : never;\n};\n\n/**\n * 从组件props中提取方法并返回指定方法\n * @template T 组件类型\n * @template M 从组件props中提取的方法类型\n * @template K 方法名类型\n * @param {T} Comp 组件定义\n * @param {K} name 方法名称\n * @param {M[K]} method 要返回的方法\n * @returns {M[K]} 返回传入的方法\n * @example\n * const handleUpdate = useMethod(MyComponent, 'update', (value) => {\n * console.log('update value', value)\n * })\n */\nexport function useMethod<T, M extends PickMethods<Required<ComponentProps<T>>>, K extends keyof M>(\n _Comp: T,\n _name: K,\n method: M[K],\n) {\n return method;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,SAAS,aAAsC;CAC7D,eAAA,aAAa,IAAA,eAAe,IAAA,iBAAiB,YAAY;;;;;;;;;;;;;;;;;;AAmB3D,SAAgB,WAAW,SAAkC;CAC3D,eAAA,aAAa,IAAA,WAAW,IAAA,aAAa,QAAQ;;;;;;;;;;;;;;;;;;AAmB/C,SAAgB,aAAa,WAAoC;CAC/D,eAAA,aAAa,IAAA,aAAa,IAAA,eAAe,UAAU;;;;;;;;;;;;ACrDrD,SAAgB,UAAa,OAAU;CAErC,QAAA,GAAA,IAAA,KAAuC,KAAK;;;;;;;;;;;;;;;;AAyC9C,SAAgB,QACd,OACA,QACA,UACA;CACA,OAAO;;;;;;;;;;;;;;;;AAsBT,SAAgB,UACd,OACA,OACA,QACA;CACA,OAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"component.mjs","names":[],"sources":["../src/component/life.ts","../src/component/self.ts"],"sourcesContent":["import type { MaybePromise } from '@cloudcome/utils-core/types';\nimport {\n onActivated,\n onBeforeMount,\n onBeforeUnmount,\n onDeactivated,\n onMounted,\n onUnmounted,\n} from 'vue';\nimport { _runLifeHook } from '@/shared';\n\nexport type HookListener = () => MaybePromise<unknown>;\nexport type HookListenerWithDispose = () => MaybePromise<\n undefined | HookListener\n>;\n\n/**\n * 页面挂载前生命周期钩子\n *\n * @param beforeMount - 在组件挂载前执行的回调函数,可以返回一个清理函数\n *\n * @example\n * ```ts\n * useMount(() => {\n * console.log('组件即将挂载');\n * // 可以返回一个清理函数,在组件卸载前执行\n * return () => {\n * console.log('组件即将卸载');\n * };\n * });\n * ```\n */\nexport function useMount(beforeMount: HookListenerWithDispose) {\n _runLifeHook(onBeforeMount, onBeforeUnmount, beforeMount);\n}\n\n/**\n * 页面挂载后生命周期钩子\n *\n * @param mounted - 在组件挂载后执行的回调函数,可以返回一个清理函数\n *\n * @example\n * ```ts\n * useMounted(() => {\n * console.log('组件已挂载');\n * // 可以返回一个清理函数,在组件卸载前执行\n * return () => {\n * console.log('组件即将卸载');\n * };\n * });\n * ```\n */\nexport function useMounted(mounted: HookListenerWithDispose) {\n _runLifeHook(onMounted, onUnmounted, mounted);\n}\n\n/**\n * 页面激活时生命周期钩子\n *\n * @param activated - 在组件被激活时执行的回调函数,可以返回一个清理函数\n *\n * @example\n * ```ts\n * useActivated(() => {\n * console.log('组件已激活');\n * // 可以返回一个清理函数,在组件失活前执行\n * return () => {\n * console.log('组件即将失活');\n * };\n * });\n * ```\n */\nexport function useActivated(activated: HookListenerWithDispose) {\n _runLifeHook(onActivated, onDeactivated, activated);\n}\n","import { type Ref, ref } from 'vue';\nimport type {\n ComponentExposed,\n ComponentProps,\n} from 'vue-component-type-helpers';\n\n/**\n * 创建一个响应式引用,用于暴露组件实例\n * @template T 组件类型\n * @param {T} Comp 组件定义\n * @returns 返回一个可响应式访问的组件实例引用\n * @example\n * const compRef = useExpose(MyComponent)\n */\nexport function useExpose<T>(_Comp: T) {\n // 这里必须类型断言,否则构建会失败\n return ref<ComponentExposed<T> | null>(\n null,\n ) as Ref<ComponentExposed<T> | null>;\n}\n\n/**\n * 将字符串的首字母转换为小写\n * @template S 字符串类型\n * @typedef {S extends `${infer First}${infer Rest}` ? `${Lowercase<First>}${Rest}` : S} LowercaseFirst\n */\ntype LowercaseFirst<S extends string> = S extends `${infer First}${infer Rest}`\n ? `${Lowercase<First>}${Rest}`\n : S;\n\n/**\n * 从组件props中提取事件类型\n * @template T 组件props类型\n * @typedef {Object} PickEmits\n * @property {Object} [K in keyof T as K extends `on${infer Rest}`...] 转换后的emit事件名\n * - @property {Function} [...args: P] 事件回调函数\n */\ntype PickEmits<T> = {\n [K in keyof T as K extends `on${infer Rest}`\n ? // biome-ignore lint/suspicious/noExplicitAny: 必须使用 any\n T[K] extends (...args: any[]) => any\n ? LowercaseFirst<Rest>\n : never\n : // biome-ignore lint/suspicious/noExplicitAny: 必须使用 any\n never]: T[K] extends (...args: infer P) => any\n ? (...args: P) => unknown\n : never;\n};\n\n/**\n * 创建一个组件emit事件监听器\n * @template T 组件类型\n * @template E 从组件props中提取的事件类型\n * @template K 事件名\n * @param {T} Comp 组件定义\n * @param {K} event 事件名称\n * @param {E[K]} listener 事件监听函数\n * @returns {E[K]} 返回传入的事件监听函数\n * @example\n * const handleClick = useEmit(MyComponent, 'click', (payload) => {\n * console.log('click event', payload)\n * })\n */\nexport function useEmit<\n T,\n E extends PickEmits<Required<ComponentProps<T>>>,\n K extends keyof E,\n>(_Comp: T, _event: K, listener: E[K]) {\n return listener;\n}\n\ntype PickMethods<T> = {\n // biome-ignore lint/suspicious/noExplicitAny: 必须使用 any\n [K in keyof T]: T[K] extends (...args: unknown[]) => any ? T[K] : never;\n};\n\n/**\n * 从组件props中提取方法并返回指定方法\n * @template T 组件类型\n * @template M 从组件props中提取的方法类型\n * @template K 方法名类型\n * @param {T} Comp 组件定义\n * @param {K} name 方法名称\n * @param {M[K]} method 要返回的方法\n * @returns {M[K]} 返回传入的方法\n * @example\n * const handleUpdate = useMethod(MyComponent, 'update', (value) => {\n * console.log('update value', value)\n * })\n */\nexport function useMethod<\n T,\n M extends PickMethods<Required<ComponentProps<T>>>,\n K extends keyof M,\n>(_Comp: T, _name: K, method: M[K]) {\n return method;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAgCA,SAAgB,SAAS,aAAsC;CAC7D,aAAa,eAAe,iBAAiB,YAAY;;;;;;;;;;;;;;;;;;AAmB3D,SAAgB,WAAW,SAAkC;CAC3D,aAAa,WAAW,aAAa,QAAQ;;;;;;;;;;;;;;;;;;AAmB/C,SAAgB,aAAa,WAAoC;CAC/D,aAAa,aAAa,eAAe,UAAU;;;;;;;;;;;;AC3DrD,SAAgB,UAAa,OAAU;CAErC,OAAO,IACL,KACD;;;;;;;;;;;;;;;;AA6CH,SAAgB,QAId,OAAU,QAAW,UAAgB;CACrC,OAAO;;;;;;;;;;;;;;;;AAsBT,SAAgB,UAId,OAAU,OAAU,QAAc;CAClC,OAAO"}
1
+ {"version":3,"file":"component.mjs","names":[],"sources":["../src/component/life.ts","../src/component/self.ts"],"sourcesContent":["import type { MaybePromise } from '@cloudcome/utils-core/types';\nimport { onActivated, onBeforeMount, onBeforeUnmount, onDeactivated, onMounted, onUnmounted } from 'vue';\nimport { _runLifeHook } from '@/shared';\n\nexport type HookListener = () => MaybePromise<unknown>;\nexport type HookListenerWithDispose = () => MaybePromise<undefined | HookListener>;\n\n/**\n * 页面挂载前生命周期钩子\n *\n * @param beforeMount - 在组件挂载前执行的回调函数,可以返回一个清理函数\n *\n * @example\n * ```ts\n * useMount(() => {\n * console.log('组件即将挂载');\n * // 可以返回一个清理函数,在组件卸载前执行\n * return () => {\n * console.log('组件即将卸载');\n * };\n * });\n * ```\n */\nexport function useMount(beforeMount: HookListenerWithDispose) {\n _runLifeHook(onBeforeMount, onBeforeUnmount, beforeMount);\n}\n\n/**\n * 页面挂载后生命周期钩子\n *\n * @param mounted - 在组件挂载后执行的回调函数,可以返回一个清理函数\n *\n * @example\n * ```ts\n * useMounted(() => {\n * console.log('组件已挂载');\n * // 可以返回一个清理函数,在组件卸载前执行\n * return () => {\n * console.log('组件即将卸载');\n * };\n * });\n * ```\n */\nexport function useMounted(mounted: HookListenerWithDispose) {\n _runLifeHook(onMounted, onUnmounted, mounted);\n}\n\n/**\n * 页面激活时生命周期钩子\n *\n * @param activated - 在组件被激活时执行的回调函数,可以返回一个清理函数\n *\n * @example\n * ```ts\n * useActivated(() => {\n * console.log('组件已激活');\n * // 可以返回一个清理函数,在组件失活前执行\n * return () => {\n * console.log('组件即将失活');\n * };\n * });\n * ```\n */\nexport function useActivated(activated: HookListenerWithDispose) {\n _runLifeHook(onActivated, onDeactivated, activated);\n}\n","import { type Ref, ref } from 'vue';\nimport type { ComponentExposed, ComponentProps } from 'vue-component-type-helpers';\n\n/**\n * 创建一个响应式引用,用于暴露组件实例\n * @template T 组件类型\n * @param {T} Comp 组件定义\n * @returns 返回一个可响应式访问的组件实例引用\n * @example\n * const compRef = useExpose(MyComponent)\n */\nexport function useExpose<T>(_Comp: T) {\n // 这里必须类型断言,否则构建会失败\n return ref<ComponentExposed<T> | null>(null) as Ref<ComponentExposed<T> | null>;\n}\n\n/**\n * 将字符串的首字母转换为小写\n * @template S 字符串类型\n * @typedef {S extends `${infer First}${infer Rest}` ? `${Lowercase<First>}${Rest}` : S} LowercaseFirst\n */\ntype LowercaseFirst<S extends string> = S extends `${infer First}${infer Rest}` ? `${Lowercase<First>}${Rest}` : S;\n\n/**\n * 从组件props中提取事件类型\n * @template T 组件props类型\n * @typedef {Object} PickEmits\n * @property {Object} [K in keyof T as K extends `on${infer Rest}`...] 转换后的emit事件名\n * - @property {Function} [...args: P] 事件回调函数\n */\ntype PickEmits<T> = {\n [K in keyof T as K extends `on${infer Rest}`\n ? // biome-ignore lint/suspicious/noExplicitAny: 必须使用 any\n T[K] extends (...args: any[]) => any\n ? LowercaseFirst<Rest>\n : never\n : // biome-ignore lint/suspicious/noExplicitAny: 必须使用 any\n never]: T[K] extends (...args: infer P) => any ? (...args: P) => unknown : never;\n};\n\n/**\n * 创建一个组件emit事件监听器\n * @template T 组件类型\n * @template E 从组件props中提取的事件类型\n * @template K 事件名\n * @param {T} Comp 组件定义\n * @param {K} event 事件名称\n * @param {E[K]} listener 事件监听函数\n * @returns {E[K]} 返回传入的事件监听函数\n * @example\n * const handleClick = useEmit(MyComponent, 'click', (payload) => {\n * console.log('click event', payload)\n * })\n */\nexport function useEmit<T, E extends PickEmits<Required<ComponentProps<T>>>, K extends keyof E>(\n _Comp: T,\n _event: K,\n listener: E[K],\n) {\n return listener;\n}\n\ntype PickMethods<T> = {\n // biome-ignore lint/suspicious/noExplicitAny: 必须使用 any\n [K in keyof T]: T[K] extends (...args: unknown[]) => any ? T[K] : never;\n};\n\n/**\n * 从组件props中提取方法并返回指定方法\n * @template T 组件类型\n * @template M 从组件props中提取的方法类型\n * @template K 方法名类型\n * @param {T} Comp 组件定义\n * @param {K} name 方法名称\n * @param {M[K]} method 要返回的方法\n * @returns {M[K]} 返回传入的方法\n * @example\n * const handleUpdate = useMethod(MyComponent, 'update', (value) => {\n * console.log('update value', value)\n * })\n */\nexport function useMethod<T, M extends PickMethods<Required<ComponentProps<T>>>, K extends keyof M>(\n _Comp: T,\n _name: K,\n method: M[K],\n) {\n return method;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,SAAS,aAAsC;CAC7D,aAAa,eAAe,iBAAiB,YAAY;;;;;;;;;;;;;;;;;;AAmB3D,SAAgB,WAAW,SAAkC;CAC3D,aAAa,WAAW,aAAa,QAAQ;;;;;;;;;;;;;;;;;;AAmB/C,SAAgB,aAAa,WAAoC;CAC/D,aAAa,aAAa,eAAe,UAAU;;;;;;;;;;;;ACrDrD,SAAgB,UAAa,OAAU;CAErC,OAAO,IAAgC,KAAK;;;;;;;;;;;;;;;;AAyC9C,SAAgB,QACd,OACA,QACA,UACA;CACA,OAAO;;;;;;;;;;;;;;;;AAsBT,SAAgB,UACd,OACA,OACA,QACA;CACA,OAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"event.cjs","names":[],"sources":["../src/event.ts"],"sourcesContent":["import {\n Emitter,\n type EmitterListener,\n type EmitterMap,\n} from '@cloudcome/utils-core/emitter';\nimport { onBeforeMount, onBeforeUnmount, onMounted, onUnmounted } from 'vue';\n\nexport type EventEmitter = {\n on: (event: string, listener: (...payloads: unknown[]) => unknown) => unknown;\n off: (\n event: string,\n listener: (...payloads: unknown[]) => unknown,\n ) => unknown;\n emit: (event: string, ...payloads: unknown[]) => unknown;\n};\n\nexport type CreateEventCenterOptions = {\n emitter?: EventEmitter;\n stage?: 'mount' | 'mounted';\n};\n\nexport function createEventHook<E extends EmitterMap>(\n options: CreateEventCenterOptions = {},\n) {\n const emitter = options.emitter || new Emitter();\n\n const on = <K extends keyof E>(event: K, listener: EmitterListener<E, K>) => {\n // @ts-expect-error\n emitter.on(event as string, listener);\n };\n\n const off = <K extends keyof E>(\n event: K,\n listener: EmitterListener<E, K>,\n ) => {\n // @ts-expect-error\n emitter.off(event as string, listener);\n };\n\n const emit = <K extends keyof E>(event: K, ...payloads: E[K]) => {\n emitter.emit(event as string, ...payloads);\n };\n\n const useEvent = <K extends keyof E>(\n event: K,\n fn: (...payloads: E[K]) => unknown,\n ) => {\n if (options.stage === 'mounted') {\n onMounted(() => {\n on(event, fn);\n });\n onUnmounted(() => {\n off(event, fn);\n });\n } else {\n onBeforeMount(() => {\n on(event, fn);\n });\n onBeforeUnmount(() => {\n off(event, fn);\n });\n }\n };\n\n return { on, off, emit, useEvent };\n}\n"],"mappings":";;;;AAqBA,SAAgB,gBACd,UAAoC,EAAE,EACtC;CACA,MAAM,UAAU,QAAQ,WAAW,IAAI,8BAAA,SAAS;CAEhD,MAAM,MAAyB,OAAU,aAAoC;EAE3E,QAAQ,GAAG,OAAiB,SAAS;;CAGvC,MAAM,OACJ,OACA,aACG;EAEH,QAAQ,IAAI,OAAiB,SAAS;;CAGxC,MAAM,QAA2B,OAAU,GAAG,aAAmB;EAC/D,QAAQ,KAAK,OAAiB,GAAG,SAAS;;CAG5C,MAAM,YACJ,OACA,OACG;EACH,IAAI,QAAQ,UAAU,WAAW;GAC/B,CAAA,GAAA,IAAA,iBAAgB;IACd,GAAG,OAAO,GAAG;KACb;GACF,CAAA,GAAA,IAAA,mBAAkB;IAChB,IAAI,OAAO,GAAG;KACd;SACG;GACL,CAAA,GAAA,IAAA,qBAAoB;IAClB,GAAG,OAAO,GAAG;KACb;GACF,CAAA,GAAA,IAAA,uBAAsB;IACpB,IAAI,OAAO,GAAG;KACd;;;CAIN,OAAO;EAAE;EAAI;EAAK;EAAM;EAAU"}
1
+ {"version":3,"file":"event.cjs","names":[],"sources":["../src/event.ts"],"sourcesContent":["import { Emitter, type EmitterListener, type EmitterMap } from '@cloudcome/utils-core/emitter';\nimport { onBeforeMount, onBeforeUnmount, onMounted, onUnmounted } from 'vue';\n\nexport type EventEmitter = {\n on: (event: string, listener: (...payloads: unknown[]) => unknown) => unknown;\n off: (event: string, listener: (...payloads: unknown[]) => unknown) => unknown;\n emit: (event: string, ...payloads: unknown[]) => unknown;\n};\n\nexport type CreateEventCenterOptions = {\n emitter?: EventEmitter;\n stage?: 'mount' | 'mounted';\n};\n\nexport function createEventHook<E extends EmitterMap>(options: CreateEventCenterOptions = {}) {\n const emitter = options.emitter || new Emitter();\n\n const on = <K extends keyof E>(event: K, listener: EmitterListener<E, K>) => {\n // @ts-expect-error\n emitter.on(event as string, listener);\n };\n\n const off = <K extends keyof E>(event: K, listener: EmitterListener<E, K>) => {\n // @ts-expect-error\n emitter.off(event as string, listener);\n };\n\n const emit = <K extends keyof E>(event: K, ...payloads: E[K]) => {\n emitter.emit(event as string, ...payloads);\n };\n\n const useEvent = <K extends keyof E>(event: K, fn: (...payloads: E[K]) => unknown) => {\n if (options.stage === 'mounted') {\n onMounted(() => {\n on(event, fn);\n });\n onUnmounted(() => {\n off(event, fn);\n });\n } else {\n onBeforeMount(() => {\n on(event, fn);\n });\n onBeforeUnmount(() => {\n off(event, fn);\n });\n }\n };\n\n return { on, off, emit, useEvent };\n}\n"],"mappings":";;;;AAcA,SAAgB,gBAAsC,UAAoC,EAAE,EAAE;CAC5F,MAAM,UAAU,QAAQ,WAAW,IAAI,8BAAA,SAAS;CAEhD,MAAM,MAAyB,OAAU,aAAoC;EAE3E,QAAQ,GAAG,OAAiB,SAAS;;CAGvC,MAAM,OAA0B,OAAU,aAAoC;EAE5E,QAAQ,IAAI,OAAiB,SAAS;;CAGxC,MAAM,QAA2B,OAAU,GAAG,aAAmB;EAC/D,QAAQ,KAAK,OAAiB,GAAG,SAAS;;CAG5C,MAAM,YAA+B,OAAU,OAAuC;EACpF,IAAI,QAAQ,UAAU,WAAW;GAC/B,CAAA,GAAA,IAAA,iBAAgB;IACd,GAAG,OAAO,GAAG;KACb;GACF,CAAA,GAAA,IAAA,mBAAkB;IAChB,IAAI,OAAO,GAAG;KACd;SACG;GACL,CAAA,GAAA,IAAA,qBAAoB;IAClB,GAAG,OAAO,GAAG;KACb;GACF,CAAA,GAAA,IAAA,uBAAsB;IACpB,IAAI,OAAO,GAAG;KACd;;;CAIN,OAAO;EAAE;EAAI;EAAK;EAAM;EAAU"}
@@ -1 +1 @@
1
- {"version":3,"file":"event.mjs","names":[],"sources":["../src/event.ts"],"sourcesContent":["import {\n Emitter,\n type EmitterListener,\n type EmitterMap,\n} from '@cloudcome/utils-core/emitter';\nimport { onBeforeMount, onBeforeUnmount, onMounted, onUnmounted } from 'vue';\n\nexport type EventEmitter = {\n on: (event: string, listener: (...payloads: unknown[]) => unknown) => unknown;\n off: (\n event: string,\n listener: (...payloads: unknown[]) => unknown,\n ) => unknown;\n emit: (event: string, ...payloads: unknown[]) => unknown;\n};\n\nexport type CreateEventCenterOptions = {\n emitter?: EventEmitter;\n stage?: 'mount' | 'mounted';\n};\n\nexport function createEventHook<E extends EmitterMap>(\n options: CreateEventCenterOptions = {},\n) {\n const emitter = options.emitter || new Emitter();\n\n const on = <K extends keyof E>(event: K, listener: EmitterListener<E, K>) => {\n // @ts-expect-error\n emitter.on(event as string, listener);\n };\n\n const off = <K extends keyof E>(\n event: K,\n listener: EmitterListener<E, K>,\n ) => {\n // @ts-expect-error\n emitter.off(event as string, listener);\n };\n\n const emit = <K extends keyof E>(event: K, ...payloads: E[K]) => {\n emitter.emit(event as string, ...payloads);\n };\n\n const useEvent = <K extends keyof E>(\n event: K,\n fn: (...payloads: E[K]) => unknown,\n ) => {\n if (options.stage === 'mounted') {\n onMounted(() => {\n on(event, fn);\n });\n onUnmounted(() => {\n off(event, fn);\n });\n } else {\n onBeforeMount(() => {\n on(event, fn);\n });\n onBeforeUnmount(() => {\n off(event, fn);\n });\n }\n };\n\n return { on, off, emit, useEvent };\n}\n"],"mappings":";;;AAqBA,SAAgB,gBACd,UAAoC,EAAE,EACtC;CACA,MAAM,UAAU,QAAQ,WAAW,IAAI,SAAS;CAEhD,MAAM,MAAyB,OAAU,aAAoC;EAE3E,QAAQ,GAAG,OAAiB,SAAS;;CAGvC,MAAM,OACJ,OACA,aACG;EAEH,QAAQ,IAAI,OAAiB,SAAS;;CAGxC,MAAM,QAA2B,OAAU,GAAG,aAAmB;EAC/D,QAAQ,KAAK,OAAiB,GAAG,SAAS;;CAG5C,MAAM,YACJ,OACA,OACG;EACH,IAAI,QAAQ,UAAU,WAAW;GAC/B,gBAAgB;IACd,GAAG,OAAO,GAAG;KACb;GACF,kBAAkB;IAChB,IAAI,OAAO,GAAG;KACd;SACG;GACL,oBAAoB;IAClB,GAAG,OAAO,GAAG;KACb;GACF,sBAAsB;IACpB,IAAI,OAAO,GAAG;KACd;;;CAIN,OAAO;EAAE;EAAI;EAAK;EAAM;EAAU"}
1
+ {"version":3,"file":"event.mjs","names":[],"sources":["../src/event.ts"],"sourcesContent":["import { Emitter, type EmitterListener, type EmitterMap } from '@cloudcome/utils-core/emitter';\nimport { onBeforeMount, onBeforeUnmount, onMounted, onUnmounted } from 'vue';\n\nexport type EventEmitter = {\n on: (event: string, listener: (...payloads: unknown[]) => unknown) => unknown;\n off: (event: string, listener: (...payloads: unknown[]) => unknown) => unknown;\n emit: (event: string, ...payloads: unknown[]) => unknown;\n};\n\nexport type CreateEventCenterOptions = {\n emitter?: EventEmitter;\n stage?: 'mount' | 'mounted';\n};\n\nexport function createEventHook<E extends EmitterMap>(options: CreateEventCenterOptions = {}) {\n const emitter = options.emitter || new Emitter();\n\n const on = <K extends keyof E>(event: K, listener: EmitterListener<E, K>) => {\n // @ts-expect-error\n emitter.on(event as string, listener);\n };\n\n const off = <K extends keyof E>(event: K, listener: EmitterListener<E, K>) => {\n // @ts-expect-error\n emitter.off(event as string, listener);\n };\n\n const emit = <K extends keyof E>(event: K, ...payloads: E[K]) => {\n emitter.emit(event as string, ...payloads);\n };\n\n const useEvent = <K extends keyof E>(event: K, fn: (...payloads: E[K]) => unknown) => {\n if (options.stage === 'mounted') {\n onMounted(() => {\n on(event, fn);\n });\n onUnmounted(() => {\n off(event, fn);\n });\n } else {\n onBeforeMount(() => {\n on(event, fn);\n });\n onBeforeUnmount(() => {\n off(event, fn);\n });\n }\n };\n\n return { on, off, emit, useEvent };\n}\n"],"mappings":";;;AAcA,SAAgB,gBAAsC,UAAoC,EAAE,EAAE;CAC5F,MAAM,UAAU,QAAQ,WAAW,IAAI,SAAS;CAEhD,MAAM,MAAyB,OAAU,aAAoC;EAE3E,QAAQ,GAAG,OAAiB,SAAS;;CAGvC,MAAM,OAA0B,OAAU,aAAoC;EAE5E,QAAQ,IAAI,OAAiB,SAAS;;CAGxC,MAAM,QAA2B,OAAU,GAAG,aAAmB;EAC/D,QAAQ,KAAK,OAAiB,GAAG,SAAS;;CAG5C,MAAM,YAA+B,OAAU,OAAuC;EACpF,IAAI,QAAQ,UAAU,WAAW;GAC/B,gBAAgB;IACd,GAAG,OAAO,GAAG;KACb;GACF,kBAAkB;IAChB,IAAI,OAAO,GAAG;KACd;SACG;GACL,oBAAoB;IAClB,GAAG,OAAO,GAAG;KACb;GACF,sBAAsB;IACpB,IAAI,OAAO,GAAG;KACd;;;CAIN,OAAO;EAAE;EAAI;EAAK;EAAM;EAAU"}
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.13.3";
6
+ var VERSION = "1.14.1";
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.13.3";
5
+ var VERSION = "1.14.1";
6
6
  //#endregion
7
7
  export { VERSION };
8
8
 
package/dist/request.cjs CHANGED
@@ -45,7 +45,7 @@ function useRequest(fn, options) {
45
45
  await onCacheHit?.(cached);
46
46
  return promise;
47
47
  }
48
- }
48
+ } else if (cacheAble) console.warn("[useRequest] 缓存功能启用但未提供 requestId,无法使用缓存");
49
49
  const [err, data] = await (0, _cloudcome_utils_core_try.tryFlatten)(fn(...inputs));
50
50
  if (err) {
51
51
  reject(err);
@@ -1 +1 @@
1
- {"version":3,"file":"request.cjs","names":[],"sources":["../src/request.ts"],"sourcesContent":["import {\n type Cache,\n type Cached,\n type CacheOptions,\n MemoryCache,\n} 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<\n UseAsyncOutput<I, O>,\n 'run' | 'runAsync' | 'state'\n> & {\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 }\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 {\n state: asyncState,\n run: send,\n runAsync: sendAsync,\n ...async\n } = 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":";;;;;;;AAyJA,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;;;EAIX,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,EACJ,OAAO,YACP,KAAK,MACL,UAAU,WACV,GAAG,UACD,cAAA,SAAS,aAAa,QAAQ;CAElC,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 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"}
package/dist/request.mjs CHANGED
@@ -44,7 +44,7 @@ function useRequest(fn, options) {
44
44
  await onCacheHit?.(cached);
45
45
  return promise;
46
46
  }
47
- }
47
+ } else if (cacheAble) console.warn("[useRequest] 缓存功能启用但未提供 requestId,无法使用缓存");
48
48
  const [err, data] = await tryFlatten(fn(...inputs));
49
49
  if (err) {
50
50
  reject(err);
@@ -1 +1 @@
1
- {"version":3,"file":"request.mjs","names":[],"sources":["../src/request.ts"],"sourcesContent":["import {\n type Cache,\n type Cached,\n type CacheOptions,\n MemoryCache,\n} 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<\n UseAsyncOutput<I, O>,\n 'run' | 'runAsync' | 'state'\n> & {\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 }\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 {\n state: asyncState,\n run: send,\n runAsync: sendAsync,\n ...async\n } = 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":";;;;;;AAyJA,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;;;EAIX,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,EACJ,OAAO,YACP,KAAK,MACL,UAAU,WACV,GAAG,UACD,SAAS,aAAa,QAAQ;CAElC,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 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 +1 @@
1
- {"version":3,"file":"shared.cjs","names":[],"sources":["../src/shared.ts"],"sourcesContent":["import { isFunction } from '@cloudcome/utils-core/type';\nimport type { AnyFunction, MaybePromise } from '@cloudcome/utils-core/types';\nimport { effectScope, onScopeDispose } from 'vue';\n\nexport type HookListener = () => MaybePromise<unknown>;\nexport type HookListenerWithDispose = () => MaybePromise<\n unknown | HookListener\n>;\n\n/**\n * 运行生命周期钩子函数的工具函数\n *\n * @protected 内部方法\n * @template T - 泛型参数(未在函数中使用)\n * @param enterHook - 进入时执行的钩子函数,接收一个回调函数作为参数\n * @param leaveHook - 离开时执行的钩子函数,接收一个回调函数作为参数\n * @param onEnter - 进入时的监听器,可以返回一个清理函数\n *\n * @example\n * _runLifeHook(\n * (hook) => onMounted(hook), // 在组件挂载时执行进入逻辑\n * (hook) => onUnmounted(hook), // 在组件卸载时执行离开逻辑\n * () => {\n * // 执行进入时的逻辑\n * console.log('组件已挂载');\n *\n * // 返回一个清理函数,在离开时执行\n * return () => {\n * console.log('组件将要卸载');\n * };\n * }\n * );\n */\nexport function _runLifeHook<_T>(\n enterHook: (hook: AnyFunction) => unknown,\n leaveHook: (hook: AnyFunction) => unknown,\n onEnter: HookListenerWithDispose,\n) {\n // 存储离开时需要执行的清理函数\n let onLeave: HookListener | undefined;\n\n // 注册进入钩子,在 enterHook 触发时执行\n enterHook(async () => {\n // 执行进入时的监听器逻辑\n const enterResult = await onEnter();\n\n // 如果返回结果是一个函数,则将其作为离开时的清理函数保存\n if (isFunction(enterResult)) {\n onLeave = enterResult;\n }\n });\n\n // 注册离开钩子,在 leaveHook 触发时执行\n leaveHook(() => {\n // 如果存在清理函数,则执行它\n onLeave?.();\n });\n}\n\n/**\n * 运行作用域钩子函数的工具函数\n *\n * 该函数创建一个独立的响应式作用域,在该作用域内执行传入的回调函数,\n * 并在适当的时机自动清理资源。这确保了响应式副作用的隔离和自动回收。\n *\n * @protected 内部方法\n * @param runner - 需要在作用域内执行的回调函数,可以返回一个清理函数\n *\n * @example\n * // 基本用法\n * _runScope(() => {\n * // 在这里创建的响应式副作用会被限制在当前作用域内\n * const stop = watch(someRef, (val) => {\n * console.log(val);\n * });\n *\n * // 返回一个清理函数,在作用域销毁时执行\n * return () => {\n * stop();\n * };\n * });\n *\n * @example\n * // 异步用法\n * _runScope(async () => {\n * const data = await fetchData();\n *\n * // 根据获取的数据创建响应式监听\n * const stop = watch(() => data.value, (val) => {\n * console.log(val);\n * });\n *\n * // 返回清理函数\n * return () => {\n * stop();\n * };\n * });\n */\nexport function _runScope(runner: HookListenerWithDispose) {\n // 创建一个独立的响应式作用域,用于收集和管理响应式副作用\n const scope = effectScope();\n // 存储用户提供的清理函数\n let dispose: HookListener | undefined;\n\n // 在创建的作用域内执行回调函数\n scope.run(async () => {\n // 执行传入的回调函数并等待其完成(支持异步操作)\n const result = await runner();\n\n // 如果回调函数返回了一个函数,则将其作为清理函数保存\n if (isFunction(result)) {\n dispose = result;\n }\n });\n\n // 注册作用域销毁时的回调函数\n onScopeDispose(() => {\n // 如果存在用户提供的清理函数,则执行它\n dispose?.();\n // 停止并清理整个作用域内的所有响应式副作用\n scope.stop();\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,SAAgB,aACd,WACA,WACA,SACA;CAEA,IAAI;CAGJ,UAAU,YAAY;EAEpB,MAAM,cAAc,MAAM,SAAS;EAGnC,KAAA,GAAA,2BAAA,YAAe,YAAY,EACzB,UAAU;GAEZ;CAGF,gBAAgB;EAEd,WAAW;GACX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CJ,SAAgB,UAAU,QAAiC;CAEzD,MAAM,SAAA,GAAA,IAAA,cAAqB;CAE3B,IAAI;CAGJ,MAAM,IAAI,YAAY;EAEpB,MAAM,SAAS,MAAM,QAAQ;EAG7B,KAAA,GAAA,2BAAA,YAAe,OAAO,EACpB,UAAU;GAEZ;CAGF,CAAA,GAAA,IAAA,sBAAqB;EAEnB,WAAW;EAEX,MAAM,MAAM;GACZ"}
1
+ {"version":3,"file":"shared.cjs","names":[],"sources":["../src/shared.ts"],"sourcesContent":["import { isFunction } from '@cloudcome/utils-core/type';\nimport type { AnyFunction, MaybePromise } from '@cloudcome/utils-core/types';\nimport { effectScope, onScopeDispose } from 'vue';\n\nexport type HookListener = () => MaybePromise<unknown>;\nexport type HookListenerWithDispose = () => MaybePromise<unknown | HookListener>;\n\n/**\n * 运行生命周期钩子函数的工具函数\n *\n * @protected 内部方法\n * @template T - 泛型参数(未在函数中使用)\n * @param enterHook - 进入时执行的钩子函数,接收一个回调函数作为参数\n * @param leaveHook - 离开时执行的钩子函数,接收一个回调函数作为参数\n * @param onEnter - 进入时的监听器,可以返回一个清理函数\n *\n * @example\n * _runLifeHook(\n * (hook) => onMounted(hook), // 在组件挂载时执行进入逻辑\n * (hook) => onUnmounted(hook), // 在组件卸载时执行离开逻辑\n * () => {\n * // 执行进入时的逻辑\n * console.log('组件已挂载');\n *\n * // 返回一个清理函数,在离开时执行\n * return () => {\n * console.log('组件将要卸载');\n * };\n * }\n * );\n */\nexport function _runLifeHook<_T>(\n enterHook: (hook: AnyFunction) => unknown,\n leaveHook: (hook: AnyFunction) => unknown,\n onEnter: HookListenerWithDispose,\n) {\n // 存储离开时需要执行的清理函数\n let onLeave: HookListener | undefined;\n\n // 注册进入钩子,在 enterHook 触发时执行\n enterHook(async () => {\n // 执行进入时的监听器逻辑\n const enterResult = await onEnter();\n\n // 如果返回结果是一个函数,则将其作为离开时的清理函数保存\n if (isFunction(enterResult)) {\n onLeave = enterResult;\n }\n });\n\n // 注册离开钩子,在 leaveHook 触发时执行\n leaveHook(() => {\n // 如果存在清理函数,则执行它\n onLeave?.();\n });\n}\n\n/**\n * 运行作用域钩子函数的工具函数\n *\n * 该函数创建一个独立的响应式作用域,在该作用域内执行传入的回调函数,\n * 并在适当的时机自动清理资源。这确保了响应式副作用的隔离和自动回收。\n *\n * @protected 内部方法\n * @param runner - 需要在作用域内执行的回调函数,可以返回一个清理函数\n *\n * @example\n * // 基本用法\n * _runScope(() => {\n * // 在这里创建的响应式副作用会被限制在当前作用域内\n * const stop = watch(someRef, (val) => {\n * console.log(val);\n * });\n *\n * // 返回一个清理函数,在作用域销毁时执行\n * return () => {\n * stop();\n * };\n * });\n *\n * @example\n * // 异步用法\n * _runScope(async () => {\n * const data = await fetchData();\n *\n * // 根据获取的数据创建响应式监听\n * const stop = watch(() => data.value, (val) => {\n * console.log(val);\n * });\n *\n * // 返回清理函数\n * return () => {\n * stop();\n * };\n * });\n */\nexport function _runScope(runner: HookListenerWithDispose) {\n // 创建一个独立的响应式作用域,用于收集和管理响应式副作用\n const scope = effectScope();\n // 存储用户提供的清理函数\n let dispose: HookListener | undefined;\n\n // 在创建的作用域内执行回调函数\n scope.run(async () => {\n // 执行传入的回调函数并等待其完成(支持异步操作)\n const result = await runner();\n\n // 如果回调函数返回了一个函数,则将其作为清理函数保存\n if (isFunction(result)) {\n dispose = result;\n }\n });\n\n // 注册作用域销毁时的回调函数\n onScopeDispose(() => {\n // 如果存在用户提供的清理函数,则执行它\n dispose?.();\n // 停止并清理整个作用域内的所有响应式副作用\n scope.stop();\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BA,SAAgB,aACd,WACA,WACA,SACA;CAEA,IAAI;CAGJ,UAAU,YAAY;EAEpB,MAAM,cAAc,MAAM,SAAS;EAGnC,KAAA,GAAA,2BAAA,YAAe,YAAY,EACzB,UAAU;GAEZ;CAGF,gBAAgB;EAEd,WAAW;GACX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CJ,SAAgB,UAAU,QAAiC;CAEzD,MAAM,SAAA,GAAA,IAAA,cAAqB;CAE3B,IAAI;CAGJ,MAAM,IAAI,YAAY;EAEpB,MAAM,SAAS,MAAM,QAAQ;EAG7B,KAAA,GAAA,2BAAA,YAAe,OAAO,EACpB,UAAU;GAEZ;CAGF,CAAA,GAAA,IAAA,sBAAqB;EAEnB,WAAW;EAEX,MAAM,MAAM;GACZ"}
@@ -1 +1 @@
1
- {"version":3,"file":"shared.mjs","names":[],"sources":["../src/shared.ts"],"sourcesContent":["import { isFunction } from '@cloudcome/utils-core/type';\nimport type { AnyFunction, MaybePromise } from '@cloudcome/utils-core/types';\nimport { effectScope, onScopeDispose } from 'vue';\n\nexport type HookListener = () => MaybePromise<unknown>;\nexport type HookListenerWithDispose = () => MaybePromise<\n unknown | HookListener\n>;\n\n/**\n * 运行生命周期钩子函数的工具函数\n *\n * @protected 内部方法\n * @template T - 泛型参数(未在函数中使用)\n * @param enterHook - 进入时执行的钩子函数,接收一个回调函数作为参数\n * @param leaveHook - 离开时执行的钩子函数,接收一个回调函数作为参数\n * @param onEnter - 进入时的监听器,可以返回一个清理函数\n *\n * @example\n * _runLifeHook(\n * (hook) => onMounted(hook), // 在组件挂载时执行进入逻辑\n * (hook) => onUnmounted(hook), // 在组件卸载时执行离开逻辑\n * () => {\n * // 执行进入时的逻辑\n * console.log('组件已挂载');\n *\n * // 返回一个清理函数,在离开时执行\n * return () => {\n * console.log('组件将要卸载');\n * };\n * }\n * );\n */\nexport function _runLifeHook<_T>(\n enterHook: (hook: AnyFunction) => unknown,\n leaveHook: (hook: AnyFunction) => unknown,\n onEnter: HookListenerWithDispose,\n) {\n // 存储离开时需要执行的清理函数\n let onLeave: HookListener | undefined;\n\n // 注册进入钩子,在 enterHook 触发时执行\n enterHook(async () => {\n // 执行进入时的监听器逻辑\n const enterResult = await onEnter();\n\n // 如果返回结果是一个函数,则将其作为离开时的清理函数保存\n if (isFunction(enterResult)) {\n onLeave = enterResult;\n }\n });\n\n // 注册离开钩子,在 leaveHook 触发时执行\n leaveHook(() => {\n // 如果存在清理函数,则执行它\n onLeave?.();\n });\n}\n\n/**\n * 运行作用域钩子函数的工具函数\n *\n * 该函数创建一个独立的响应式作用域,在该作用域内执行传入的回调函数,\n * 并在适当的时机自动清理资源。这确保了响应式副作用的隔离和自动回收。\n *\n * @protected 内部方法\n * @param runner - 需要在作用域内执行的回调函数,可以返回一个清理函数\n *\n * @example\n * // 基本用法\n * _runScope(() => {\n * // 在这里创建的响应式副作用会被限制在当前作用域内\n * const stop = watch(someRef, (val) => {\n * console.log(val);\n * });\n *\n * // 返回一个清理函数,在作用域销毁时执行\n * return () => {\n * stop();\n * };\n * });\n *\n * @example\n * // 异步用法\n * _runScope(async () => {\n * const data = await fetchData();\n *\n * // 根据获取的数据创建响应式监听\n * const stop = watch(() => data.value, (val) => {\n * console.log(val);\n * });\n *\n * // 返回清理函数\n * return () => {\n * stop();\n * };\n * });\n */\nexport function _runScope(runner: HookListenerWithDispose) {\n // 创建一个独立的响应式作用域,用于收集和管理响应式副作用\n const scope = effectScope();\n // 存储用户提供的清理函数\n let dispose: HookListener | undefined;\n\n // 在创建的作用域内执行回调函数\n scope.run(async () => {\n // 执行传入的回调函数并等待其完成(支持异步操作)\n const result = await runner();\n\n // 如果回调函数返回了一个函数,则将其作为清理函数保存\n if (isFunction(result)) {\n dispose = result;\n }\n });\n\n // 注册作用域销毁时的回调函数\n onScopeDispose(() => {\n // 如果存在用户提供的清理函数,则执行它\n dispose?.();\n // 停止并清理整个作用域内的所有响应式副作用\n scope.stop();\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,SAAgB,aACd,WACA,WACA,SACA;CAEA,IAAI;CAGJ,UAAU,YAAY;EAEpB,MAAM,cAAc,MAAM,SAAS;EAGnC,IAAI,WAAW,YAAY,EACzB,UAAU;GAEZ;CAGF,gBAAgB;EAEd,WAAW;GACX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CJ,SAAgB,UAAU,QAAiC;CAEzD,MAAM,QAAQ,aAAa;CAE3B,IAAI;CAGJ,MAAM,IAAI,YAAY;EAEpB,MAAM,SAAS,MAAM,QAAQ;EAG7B,IAAI,WAAW,OAAO,EACpB,UAAU;GAEZ;CAGF,qBAAqB;EAEnB,WAAW;EAEX,MAAM,MAAM;GACZ"}
1
+ {"version":3,"file":"shared.mjs","names":[],"sources":["../src/shared.ts"],"sourcesContent":["import { isFunction } from '@cloudcome/utils-core/type';\nimport type { AnyFunction, MaybePromise } from '@cloudcome/utils-core/types';\nimport { effectScope, onScopeDispose } from 'vue';\n\nexport type HookListener = () => MaybePromise<unknown>;\nexport type HookListenerWithDispose = () => MaybePromise<unknown | HookListener>;\n\n/**\n * 运行生命周期钩子函数的工具函数\n *\n * @protected 内部方法\n * @template T - 泛型参数(未在函数中使用)\n * @param enterHook - 进入时执行的钩子函数,接收一个回调函数作为参数\n * @param leaveHook - 离开时执行的钩子函数,接收一个回调函数作为参数\n * @param onEnter - 进入时的监听器,可以返回一个清理函数\n *\n * @example\n * _runLifeHook(\n * (hook) => onMounted(hook), // 在组件挂载时执行进入逻辑\n * (hook) => onUnmounted(hook), // 在组件卸载时执行离开逻辑\n * () => {\n * // 执行进入时的逻辑\n * console.log('组件已挂载');\n *\n * // 返回一个清理函数,在离开时执行\n * return () => {\n * console.log('组件将要卸载');\n * };\n * }\n * );\n */\nexport function _runLifeHook<_T>(\n enterHook: (hook: AnyFunction) => unknown,\n leaveHook: (hook: AnyFunction) => unknown,\n onEnter: HookListenerWithDispose,\n) {\n // 存储离开时需要执行的清理函数\n let onLeave: HookListener | undefined;\n\n // 注册进入钩子,在 enterHook 触发时执行\n enterHook(async () => {\n // 执行进入时的监听器逻辑\n const enterResult = await onEnter();\n\n // 如果返回结果是一个函数,则将其作为离开时的清理函数保存\n if (isFunction(enterResult)) {\n onLeave = enterResult;\n }\n });\n\n // 注册离开钩子,在 leaveHook 触发时执行\n leaveHook(() => {\n // 如果存在清理函数,则执行它\n onLeave?.();\n });\n}\n\n/**\n * 运行作用域钩子函数的工具函数\n *\n * 该函数创建一个独立的响应式作用域,在该作用域内执行传入的回调函数,\n * 并在适当的时机自动清理资源。这确保了响应式副作用的隔离和自动回收。\n *\n * @protected 内部方法\n * @param runner - 需要在作用域内执行的回调函数,可以返回一个清理函数\n *\n * @example\n * // 基本用法\n * _runScope(() => {\n * // 在这里创建的响应式副作用会被限制在当前作用域内\n * const stop = watch(someRef, (val) => {\n * console.log(val);\n * });\n *\n * // 返回一个清理函数,在作用域销毁时执行\n * return () => {\n * stop();\n * };\n * });\n *\n * @example\n * // 异步用法\n * _runScope(async () => {\n * const data = await fetchData();\n *\n * // 根据获取的数据创建响应式监听\n * const stop = watch(() => data.value, (val) => {\n * console.log(val);\n * });\n *\n * // 返回清理函数\n * return () => {\n * stop();\n * };\n * });\n */\nexport function _runScope(runner: HookListenerWithDispose) {\n // 创建一个独立的响应式作用域,用于收集和管理响应式副作用\n const scope = effectScope();\n // 存储用户提供的清理函数\n let dispose: HookListener | undefined;\n\n // 在创建的作用域内执行回调函数\n scope.run(async () => {\n // 执行传入的回调函数并等待其完成(支持异步操作)\n const result = await runner();\n\n // 如果回调函数返回了一个函数,则将其作为清理函数保存\n if (isFunction(result)) {\n dispose = result;\n }\n });\n\n // 注册作用域销毁时的回调函数\n onScopeDispose(() => {\n // 如果存在用户提供的清理函数,则执行它\n dispose?.();\n // 停止并清理整个作用域内的所有响应式副作用\n scope.stop();\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BA,SAAgB,aACd,WACA,WACA,SACA;CAEA,IAAI;CAGJ,UAAU,YAAY;EAEpB,MAAM,cAAc,MAAM,SAAS;EAGnC,IAAI,WAAW,YAAY,EACzB,UAAU;GAEZ;CAGF,gBAAgB;EAEd,WAAW;GACX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CJ,SAAgB,UAAU,QAAiC;CAEzD,MAAM,QAAQ,aAAa;CAE3B,IAAI;CAGJ,MAAM,IAAI,YAAY;EAEpB,MAAM,SAAS,MAAM,QAAQ;EAG7B,IAAI,WAAW,OAAO,EACpB,UAAU;GAEZ;CAGF,qBAAqB;EAEnB,WAAW;EAEX,MAAM,MAAM;GACZ"}
package/dist/time.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"time.cjs","names":[],"sources":["../src/time.ts"],"sourcesContent":["import { computed, type Ref, ref, toValue, watch } from 'vue';\nimport { useMount } from './component';\nimport { _runScope } from './shared';\n\n/**\n * 创建一个延迟更新的响应式值\n *\n * 该函数创建一个基于原始响应式值的延迟更新值,当原始值发生变化时,\n * 延迟值会在指定的延迟时间后更新。如果在延迟期间原始值再次变化,\n * 则会重新计算延迟时间。\n *\n * @param initialValue 原始响应式值,类型为Ref<T>\n * @param delay 延迟时间,可以是数字或响应式数字,默认为100毫秒\n * @returns 返回一个计算属性,其值会在延迟后更新为原始值\n */\nexport function useLazyValue<T>(\n initialValue: Ref<T>,\n delay?: number | Ref<number>,\n) {\n const lazyValue = ref(initialValue.value);\n let changedAt = 0;\n\n _runScope(() => {\n // biome-ignore lint/suspicious/noExplicitAny: 内部使用 any\n let t: any;\n\n watch(initialValue, (value) => {\n const delayValue = toValue(delay) || 100;\n clearTimeout(t);\n\n if (changedAt > 0 && Date.now() - changedAt > delayValue) {\n lazyValue.value = value;\n } else {\n t = setTimeout(() => {\n lazyValue.value = value;\n }, delayValue);\n }\n\n changedAt = Date.now();\n });\n\n return () => {\n clearTimeout(t);\n };\n });\n\n return computed<T>(() => {\n return lazyValue.value;\n });\n}\n\nexport function useInterval(\n callback: () => void,\n delay?: number | Ref<number>,\n) {\n useMount(() => {\n const delayValue = toValue(delay) || 100;\n const t = setInterval(callback, delayValue);\n\n return () => {\n clearInterval(t);\n };\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,SAAgB,aACd,cACA,OACA;CACA,MAAM,aAAA,GAAA,IAAA,KAAgB,aAAa,MAAM;CACzC,IAAI,YAAY;CAEhB,eAAA,gBAAgB;EAEd,IAAI;EAEJ,CAAA,GAAA,IAAA,OAAM,eAAe,UAAU;GAC7B,MAAM,cAAA,GAAA,IAAA,SAAqB,MAAM,IAAI;GACrC,aAAa,EAAE;GAEf,IAAI,YAAY,KAAK,KAAK,KAAK,GAAG,YAAY,YAC5C,UAAU,QAAQ;QAElB,IAAI,iBAAiB;IACnB,UAAU,QAAQ;MACjB,WAAW;GAGhB,YAAY,KAAK,KAAK;IACtB;EAEF,aAAa;GACX,aAAa,EAAE;;GAEjB;CAEF,QAAA,GAAA,IAAA,gBAAyB;EACvB,OAAO,UAAU;GACjB;;AAGJ,SAAgB,YACd,UACA,OACA;CACA,kBAAA,eAAe;EACb,MAAM,cAAA,GAAA,IAAA,SAAqB,MAAM,IAAI;EACrC,MAAM,IAAI,YAAY,UAAU,WAAW;EAE3C,aAAa;GACX,cAAc,EAAE;;GAElB"}
1
+ {"version":3,"file":"time.cjs","names":[],"sources":["../src/time.ts"],"sourcesContent":["import { computed, type Ref, ref, toValue, watch } from 'vue';\nimport { useMount } from './component';\nimport { _runScope } from './shared';\n\n/**\n * 创建一个延迟更新的响应式值\n *\n * 该函数创建一个基于原始响应式值的延迟更新值,当原始值发生变化时,\n * 延迟值会在指定的延迟时间后更新。如果在延迟期间原始值再次变化,\n * 则会重新计算延迟时间。\n *\n * @param initialValue 原始响应式值,类型为Ref<T>\n * @param delay 延迟时间,可以是数字或响应式数字,默认为100毫秒\n * @returns 返回一个计算属性,其值会在延迟后更新为原始值\n */\nexport function useLazyValue<T>(initialValue: Ref<T>, delay?: number | Ref<number>) {\n const lazyValue = ref(initialValue.value);\n let changedAt = 0;\n\n _runScope(() => {\n // biome-ignore lint/suspicious/noExplicitAny: 内部使用 any\n let t: any;\n\n watch(initialValue, (value) => {\n const delayValue = toValue(delay) || 100;\n clearTimeout(t);\n\n if (changedAt > 0 && Date.now() - changedAt > delayValue) {\n lazyValue.value = value;\n } else {\n t = setTimeout(() => {\n lazyValue.value = value;\n }, delayValue);\n }\n\n changedAt = Date.now();\n });\n\n return () => {\n clearTimeout(t);\n };\n });\n\n return computed<T>(() => {\n return lazyValue.value;\n });\n}\n\nexport function useInterval(callback: () => void, delay?: number | Ref<number>) {\n useMount(() => {\n const delayValue = toValue(delay) || 100;\n const t = setInterval(callback, delayValue);\n\n return () => {\n clearInterval(t);\n };\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,SAAgB,aAAgB,cAAsB,OAA8B;CAClF,MAAM,aAAA,GAAA,IAAA,KAAgB,aAAa,MAAM;CACzC,IAAI,YAAY;CAEhB,eAAA,gBAAgB;EAEd,IAAI;EAEJ,CAAA,GAAA,IAAA,OAAM,eAAe,UAAU;GAC7B,MAAM,cAAA,GAAA,IAAA,SAAqB,MAAM,IAAI;GACrC,aAAa,EAAE;GAEf,IAAI,YAAY,KAAK,KAAK,KAAK,GAAG,YAAY,YAC5C,UAAU,QAAQ;QAElB,IAAI,iBAAiB;IACnB,UAAU,QAAQ;MACjB,WAAW;GAGhB,YAAY,KAAK,KAAK;IACtB;EAEF,aAAa;GACX,aAAa,EAAE;;GAEjB;CAEF,QAAA,GAAA,IAAA,gBAAyB;EACvB,OAAO,UAAU;GACjB;;AAGJ,SAAgB,YAAY,UAAsB,OAA8B;CAC9E,kBAAA,eAAe;EACb,MAAM,cAAA,GAAA,IAAA,SAAqB,MAAM,IAAI;EACrC,MAAM,IAAI,YAAY,UAAU,WAAW;EAE3C,aAAa;GACX,cAAc,EAAE;;GAElB"}
package/dist/time.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"time.mjs","names":[],"sources":["../src/time.ts"],"sourcesContent":["import { computed, type Ref, ref, toValue, watch } from 'vue';\nimport { useMount } from './component';\nimport { _runScope } from './shared';\n\n/**\n * 创建一个延迟更新的响应式值\n *\n * 该函数创建一个基于原始响应式值的延迟更新值,当原始值发生变化时,\n * 延迟值会在指定的延迟时间后更新。如果在延迟期间原始值再次变化,\n * 则会重新计算延迟时间。\n *\n * @param initialValue 原始响应式值,类型为Ref<T>\n * @param delay 延迟时间,可以是数字或响应式数字,默认为100毫秒\n * @returns 返回一个计算属性,其值会在延迟后更新为原始值\n */\nexport function useLazyValue<T>(\n initialValue: Ref<T>,\n delay?: number | Ref<number>,\n) {\n const lazyValue = ref(initialValue.value);\n let changedAt = 0;\n\n _runScope(() => {\n // biome-ignore lint/suspicious/noExplicitAny: 内部使用 any\n let t: any;\n\n watch(initialValue, (value) => {\n const delayValue = toValue(delay) || 100;\n clearTimeout(t);\n\n if (changedAt > 0 && Date.now() - changedAt > delayValue) {\n lazyValue.value = value;\n } else {\n t = setTimeout(() => {\n lazyValue.value = value;\n }, delayValue);\n }\n\n changedAt = Date.now();\n });\n\n return () => {\n clearTimeout(t);\n };\n });\n\n return computed<T>(() => {\n return lazyValue.value;\n });\n}\n\nexport function useInterval(\n callback: () => void,\n delay?: number | Ref<number>,\n) {\n useMount(() => {\n const delayValue = toValue(delay) || 100;\n const t = setInterval(callback, delayValue);\n\n return () => {\n clearInterval(t);\n };\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;AAeA,SAAgB,aACd,cACA,OACA;CACA,MAAM,YAAY,IAAI,aAAa,MAAM;CACzC,IAAI,YAAY;CAEhB,gBAAgB;EAEd,IAAI;EAEJ,MAAM,eAAe,UAAU;GAC7B,MAAM,aAAa,QAAQ,MAAM,IAAI;GACrC,aAAa,EAAE;GAEf,IAAI,YAAY,KAAK,KAAK,KAAK,GAAG,YAAY,YAC5C,UAAU,QAAQ;QAElB,IAAI,iBAAiB;IACnB,UAAU,QAAQ;MACjB,WAAW;GAGhB,YAAY,KAAK,KAAK;IACtB;EAEF,aAAa;GACX,aAAa,EAAE;;GAEjB;CAEF,OAAO,eAAkB;EACvB,OAAO,UAAU;GACjB;;AAGJ,SAAgB,YACd,UACA,OACA;CACA,eAAe;EACb,MAAM,aAAa,QAAQ,MAAM,IAAI;EACrC,MAAM,IAAI,YAAY,UAAU,WAAW;EAE3C,aAAa;GACX,cAAc,EAAE;;GAElB"}
1
+ {"version":3,"file":"time.mjs","names":[],"sources":["../src/time.ts"],"sourcesContent":["import { computed, type Ref, ref, toValue, watch } from 'vue';\nimport { useMount } from './component';\nimport { _runScope } from './shared';\n\n/**\n * 创建一个延迟更新的响应式值\n *\n * 该函数创建一个基于原始响应式值的延迟更新值,当原始值发生变化时,\n * 延迟值会在指定的延迟时间后更新。如果在延迟期间原始值再次变化,\n * 则会重新计算延迟时间。\n *\n * @param initialValue 原始响应式值,类型为Ref<T>\n * @param delay 延迟时间,可以是数字或响应式数字,默认为100毫秒\n * @returns 返回一个计算属性,其值会在延迟后更新为原始值\n */\nexport function useLazyValue<T>(initialValue: Ref<T>, delay?: number | Ref<number>) {\n const lazyValue = ref(initialValue.value);\n let changedAt = 0;\n\n _runScope(() => {\n // biome-ignore lint/suspicious/noExplicitAny: 内部使用 any\n let t: any;\n\n watch(initialValue, (value) => {\n const delayValue = toValue(delay) || 100;\n clearTimeout(t);\n\n if (changedAt > 0 && Date.now() - changedAt > delayValue) {\n lazyValue.value = value;\n } else {\n t = setTimeout(() => {\n lazyValue.value = value;\n }, delayValue);\n }\n\n changedAt = Date.now();\n });\n\n return () => {\n clearTimeout(t);\n };\n });\n\n return computed<T>(() => {\n return lazyValue.value;\n });\n}\n\nexport function useInterval(callback: () => void, delay?: number | Ref<number>) {\n useMount(() => {\n const delayValue = toValue(delay) || 100;\n const t = setInterval(callback, delayValue);\n\n return () => {\n clearInterval(t);\n };\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;AAeA,SAAgB,aAAgB,cAAsB,OAA8B;CAClF,MAAM,YAAY,IAAI,aAAa,MAAM;CACzC,IAAI,YAAY;CAEhB,gBAAgB;EAEd,IAAI;EAEJ,MAAM,eAAe,UAAU;GAC7B,MAAM,aAAa,QAAQ,MAAM,IAAI;GACrC,aAAa,EAAE;GAEf,IAAI,YAAY,KAAK,KAAK,KAAK,GAAG,YAAY,YAC5C,UAAU,QAAQ;QAElB,IAAI,iBAAiB;IACnB,UAAU,QAAQ;MACjB,WAAW;GAGhB,YAAY,KAAK,KAAK;IACtB;EAEF,aAAa;GACX,aAAa,EAAE;;GAEjB;CAEF,OAAO,eAAkB;EACvB,OAAO,UAAU;GACjB;;AAGJ,SAAgB,YAAY,UAAsB,OAA8B;CAC9E,eAAe;EACb,MAAM,aAAa,QAAQ,MAAM,IAAI;EACrC,MAAM,IAAI,YAAY,UAAU,WAAW;EAE3C,aAAa;GACX,cAAc,EAAE;;GAElB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudcome/utils-vue",
3
- "version": "1.13.3",
3
+ "version": "1.14.1",
4
4
  "description": "cloudcome utils for vue",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -89,21 +89,21 @@
89
89
  "node": ">=22"
90
90
  },
91
91
  "dependencies": {
92
- "@cloudcome/utils-core": "~1.20.0",
92
+ "@cloudcome/utils-core": "~1.21.0",
93
93
  "vue": "^3.5.34",
94
94
  "vue-component-type-helpers": "^3.2.8"
95
95
  },
96
96
  "keywords": [
97
- "utils",
98
97
  "cloudcome",
98
+ "utils",
99
+ "utils-browser",
99
100
  "utils-core",
100
- "utils-vue",
101
+ "utils-node",
101
102
  "utils-react",
102
103
  "utils-uni",
103
- "utils-node",
104
- "utils-browser"
104
+ "utils-vue"
105
105
  ],
106
- "homepage": "https://github.com/cloudcome/utils",
106
+ "homepage": "https://cloudcome.github.io/utils/",
107
107
  "license": "MIT",
108
108
  "author": "云淡然 <hi@ydr.me> (https://ydr.me/)",
109
109
  "repository": {