@cloudcome/utils-vue 1.13.1 → 1.13.3

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.
Files changed (46) hide show
  1. package/README.md +1 -1
  2. package/dist/async.cjs +65 -65
  3. package/dist/async.cjs.map +1 -1
  4. package/dist/async.mjs +66 -67
  5. package/dist/async.mjs.map +1 -1
  6. package/dist/component/self.d.ts +4 -4
  7. package/dist/component.cjs +110 -13
  8. package/dist/component.cjs.map +1 -1
  9. package/dist/component.d.ts +1 -1
  10. package/dist/component.mjs +108 -17
  11. package/dist/component.mjs.map +1 -1
  12. package/dist/event.cjs +39 -32
  13. package/dist/event.cjs.map +1 -1
  14. package/dist/event.mjs +39 -33
  15. package/dist/event.mjs.map +1 -1
  16. package/dist/index.cjs +8 -3
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.mjs +9 -5
  19. package/dist/index.mjs.map +1 -1
  20. package/dist/request.cjs +72 -74
  21. package/dist/request.cjs.map +1 -1
  22. package/dist/request.d.ts +1 -1
  23. package/dist/request.mjs +71 -74
  24. package/dist/request.mjs.map +1 -1
  25. package/dist/shared.cjs +87 -26
  26. package/dist/shared.cjs.map +1 -1
  27. package/dist/shared.d.ts +1 -1
  28. package/dist/shared.mjs +87 -28
  29. package/dist/shared.mjs.map +1 -1
  30. package/dist/state.cjs +26 -25
  31. package/dist/state.cjs.map +1 -1
  32. package/dist/state.mjs +27 -27
  33. package/dist/state.mjs.map +1 -1
  34. package/dist/time.cjs +45 -35
  35. package/dist/time.cjs.map +1 -1
  36. package/dist/time.mjs +45 -37
  37. package/dist/time.mjs.map +1 -1
  38. package/dist/types.cjs +0 -2
  39. package/dist/types.mjs +0 -2
  40. package/package.json +42 -43
  41. package/dist/life.cjs +0 -16
  42. package/dist/life.cjs.map +0 -1
  43. package/dist/life.mjs +0 -17
  44. package/dist/life.mjs.map +0 -1
  45. package/dist/types.cjs.map +0 -1
  46. package/dist/types.mjs.map +0 -1
package/dist/request.mjs CHANGED
@@ -1,78 +1,75 @@
1
+ import { useAsync } from "./async.mjs";
2
+ import { computed, ref } from "vue";
3
+ import { isFunction, isObject } from "@cloudcome/utils-core/type";
1
4
  import { MemoryCache } from "@cloudcome/utils-core/cache";
2
5
  import { tryFlatten } from "@cloudcome/utils-core/try";
3
- import { isObject, isFunction } from "@cloudcome/utils-core/type";
4
- import { ref, computed } from "vue";
5
- import { useAsync } from "./async.mjs";
6
- const defaultCacheStorage = new MemoryCache();
7
- const defaultShareStorage = new MemoryCache();
6
+ //#region src/request.ts
7
+ var defaultCacheStorage = new MemoryCache();
8
+ var defaultShareStorage = new MemoryCache();
8
9
  function useRequest(fn, options) {
9
- const { id, cache, share, onCacheHit, onSuccess } = options || {};
10
- const shareStorage = defaultShareStorage;
11
- const shareAble = isObject(share) ? !share.disabled : share;
12
- const shareOptions = isObject(share) ? share : {};
13
- const hitShare = ref(false);
14
- const _cached = defaultCacheStorage;
15
- const cacheStorage = isObject(cache) ? cache.storage || _cached : _cached;
16
- const cacheAble = isObject(cache) ? !cache.disabled : cache;
17
- const cacheOptions = isObject(cache) ? cache : {};
18
- const hitCache = ref(false);
19
- const cacheableFn = async (...inputs) => {
20
- const requestId = isFunction(id) ? id() : id;
21
- hitShare.value = false;
22
- hitCache.value = false;
23
- if (requestId && shareAble) {
24
- const shared = shareStorage.get(requestId);
25
- if (shared) {
26
- hitShare.value = true;
27
- const [err2, data2] = await tryFlatten(shared.data);
28
- if (err2) {
29
- shareStorage.del(requestId);
30
- throw err2;
31
- }
32
- return data2;
33
- }
34
- }
35
- const { promise, resolve, reject } = Promise.withResolvers();
36
- if (requestId && shareAble) {
37
- shareStorage.set(requestId, promise, shareOptions);
38
- }
39
- if (requestId && cacheAble) {
40
- const cached = await cacheStorage.get(requestId);
41
- if (cached) {
42
- const data2 = cached.data;
43
- resolve(data2);
44
- hitCache.value = true;
45
- await onCacheHit?.(cached);
46
- return promise;
47
- }
48
- }
49
- const [err, data] = await tryFlatten(fn(...inputs));
50
- if (err) {
51
- reject(err);
52
- return promise;
53
- }
54
- if (requestId && cacheAble) {
55
- cacheStorage.set(requestId, data, cacheOptions);
56
- }
57
- resolve(data);
58
- return promise;
59
- };
60
- const { state: asyncState, run: send, runAsync: sendAsync, ...async } = useAsync(cacheableFn, options);
61
- const state = computed(() => ({
62
- ...asyncState.value,
63
- hitShare: hitShare.value,
64
- hitCache: hitCache.value
65
- }));
66
- return {
67
- ...async,
68
- state,
69
- send,
70
- sendAsync,
71
- hitShare,
72
- hitCache
73
- };
10
+ const { id, cache, share, onCacheHit } = options || {};
11
+ const shareStorage = defaultShareStorage;
12
+ const shareAble = isObject(share) ? !share.disabled : share;
13
+ const shareOptions = isObject(share) ? share : {};
14
+ const hitShare = ref(false);
15
+ const _cached = defaultCacheStorage;
16
+ const cacheStorage = isObject(cache) ? cache.storage || _cached : _cached;
17
+ const cacheAble = isObject(cache) ? !cache.disabled : cache;
18
+ const cacheOptions = isObject(cache) ? cache : {};
19
+ const hitCache = ref(false);
20
+ const cacheableFn = async (...inputs) => {
21
+ const requestId = isFunction(id) ? id() : id;
22
+ hitShare.value = false;
23
+ hitCache.value = false;
24
+ if (requestId && shareAble) {
25
+ const shared = shareStorage.get(requestId);
26
+ if (shared) {
27
+ hitShare.value = true;
28
+ const [err, data] = await tryFlatten(shared.data);
29
+ if (err) {
30
+ shareStorage.del(requestId);
31
+ throw err;
32
+ }
33
+ return data;
34
+ }
35
+ }
36
+ const { promise, resolve, reject } = Promise.withResolvers();
37
+ if (requestId && shareAble) shareStorage.set(requestId, promise, shareOptions);
38
+ if (requestId && cacheAble) {
39
+ const cached = await cacheStorage.get(requestId);
40
+ if (cached) {
41
+ const data = cached.data;
42
+ resolve(data);
43
+ hitCache.value = true;
44
+ await onCacheHit?.(cached);
45
+ return promise;
46
+ }
47
+ }
48
+ const [err, data] = await tryFlatten(fn(...inputs));
49
+ if (err) {
50
+ reject(err);
51
+ return promise;
52
+ }
53
+ if (requestId && cacheAble) cacheStorage.set(requestId, data, cacheOptions);
54
+ resolve(data);
55
+ return promise;
56
+ };
57
+ const { state: asyncState, run: send, runAsync: sendAsync, ...async } = useAsync(cacheableFn, options);
58
+ const state = computed(() => ({
59
+ ...asyncState.value,
60
+ hitShare: hitShare.value,
61
+ hitCache: hitCache.value
62
+ }));
63
+ return {
64
+ ...async,
65
+ state,
66
+ send,
67
+ sendAsync,
68
+ hitShare,
69
+ hitCache
70
+ };
74
71
  }
75
- export {
76
- useRequest
77
- };
78
- //# sourceMappingURL=request.mjs.map
72
+ //#endregion
73
+ export { useRequest };
74
+
75
+ //# sourceMappingURL=request.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"request.mjs","sources":["../src/request.ts"],"sourcesContent":["import { type Cache, type CacheOptions, type Cached, 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'> & { placeholder: () => O },\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, onSuccess } = 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 { 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"],"names":["err","data"],"mappings":";;;;;AAiJA,MAAM,sBAAsB,IAAI,YAAY;AAC5C,MAAM,sBAAsB,IAAI,YAAY;AAuB5B,SAAA,WACd,IACA,SACwB;AAClB,QAAA,EAAE,IAAI,OAAO,OAAO,YAAY,UAAU,IAAI,WAAW,CAAC;AAEhE,QAAM,eAAe;AACrB,QAAM,YAAY,SAAS,KAAK,IAAI,CAAC,MAAM,WAAW;AACtD,QAAM,eAAe,SAAS,KAAK,IAAI,QAAQ,CAAC;AAC1C,QAAA,WAAW,IAAI,KAAK;AAE1B,QAAM,UAAU;AAChB,QAAM,eAAe,SAAS,KAAK,IAAI,MAAM,WAAW,UAAU;AAClE,QAAM,YAAY,SAAS,KAAK,IAAI,CAAC,MAAM,WAAW;AACtD,QAAM,eAAe,SAAS,KAAK,IAAI,QAAQ,CAAC;AAC1C,QAAA,WAAW,IAAI,KAAK;AAEpB,QAAA,cAAc,UAAU,WAAc;AAC1C,UAAM,YAAY,WAAW,EAAE,IAAI,GAAO,IAAA;AAE1C,aAAS,QAAQ;AACjB,aAAS,QAAQ;AAEjB,QAAI,aAAa,WAAW;AACpB,YAAA,SAAS,aAAa,IAAI,SAAS;AACzC,UAAI,QAAQ;AACV,iBAAS,QAAQ;AACjB,cAAM,CAACA,MAAKC,KAAI,IAAI,MAAM,WAAW,OAAO,IAAI;AAChD,YAAID,MAAK;AACP,uBAAa,IAAI,SAAS;AACpBA,gBAAAA;AAAAA,QAAA;AAGDC,eAAAA;AAAAA,MAAA;AAAA,IACT;AAIF,UAAM,EAAE,SAAS,SAAS,OAAO,IAAI,QAAQ,cAAiB;AAE9D,QAAI,aAAa,WAAW;AACb,mBAAA,IAAI,WAAW,SAAS,YAAY;AAAA,IAAA;AAGnD,QAAI,aAAa,WAAW;AAC1B,YAAM,SAAS,MAAM,aAAa,IAAI,SAAS;AAE/C,UAAI,QAAQ;AACV,cAAMA,QAAO,OAAO;AACpB,gBAAQA,KAAI;AACZ,iBAAS,QAAQ;AACjB,cAAM,aAAa,MAAM;AAClB,eAAA;AAAA,MAAA;AAAA,IACT;AAGI,UAAA,CAAC,KAAK,IAAI,IAAI,MAAM,WAAW,GAAG,GAAG,MAAM,CAAC;AAElD,QAAI,KAAK;AACP,aAAO,GAAG;AACH,aAAA;AAAA,IAAA;AAGT,QAAI,aAAa,WAAW;AACb,mBAAA,IAAI,WAAW,MAAM,YAAY;AAAA,IAAA;AAGhD,YAAQ,IAAI;AACL,WAAA;AAAA,EACT;AACA,QAAM,EAAE,OAAO,YAAY,KAAK,MAAM,UAAU,WAAW,GAAG,MAAM,IAAI,SAAS,aAAa,OAAO;AAE/F,QAAA,QAAQ,SAAS,OAAO;AAAA,IAC5B,GAAG,WAAW;AAAA,IACd,UAAU,SAAS;AAAA,IACnB,UAAU,SAAS;AAAA,EAAA,EACnB;AAEK,SAAA;AAAA,IACL,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;"}
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"}
package/dist/shared.cjs CHANGED
@@ -1,33 +1,94 @@
1
- "use strict";
2
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const type = require("@cloudcome/utils-core/type");
4
- const vue = require("vue");
2
+ let vue = require("vue");
3
+ let _cloudcome_utils_core_type = require("@cloudcome/utils-core/type");
4
+ //#region src/shared.ts
5
+ /**
6
+ * 运行生命周期钩子函数的工具函数
7
+ *
8
+ * @protected 内部方法
9
+ * @template T - 泛型参数(未在函数中使用)
10
+ * @param enterHook - 进入时执行的钩子函数,接收一个回调函数作为参数
11
+ * @param leaveHook - 离开时执行的钩子函数,接收一个回调函数作为参数
12
+ * @param onEnter - 进入时的监听器,可以返回一个清理函数
13
+ *
14
+ * @example
15
+ * _runLifeHook(
16
+ * (hook) => onMounted(hook), // 在组件挂载时执行进入逻辑
17
+ * (hook) => onUnmounted(hook), // 在组件卸载时执行离开逻辑
18
+ * () => {
19
+ * // 执行进入时的逻辑
20
+ * console.log('组件已挂载');
21
+ *
22
+ * // 返回一个清理函数,在离开时执行
23
+ * return () => {
24
+ * console.log('组件将要卸载');
25
+ * };
26
+ * }
27
+ * );
28
+ */
5
29
  function _runLifeHook(enterHook, leaveHook, onEnter) {
6
- let onLeave;
7
- enterHook(async () => {
8
- const enterResult = await onEnter();
9
- if (type.isFunction(enterResult)) {
10
- onLeave = enterResult;
11
- }
12
- });
13
- leaveHook(() => {
14
- onLeave?.();
15
- });
30
+ let onLeave;
31
+ enterHook(async () => {
32
+ const enterResult = await onEnter();
33
+ if ((0, _cloudcome_utils_core_type.isFunction)(enterResult)) onLeave = enterResult;
34
+ });
35
+ leaveHook(() => {
36
+ onLeave?.();
37
+ });
16
38
  }
39
+ /**
40
+ * 运行作用域钩子函数的工具函数
41
+ *
42
+ * 该函数创建一个独立的响应式作用域,在该作用域内执行传入的回调函数,
43
+ * 并在适当的时机自动清理资源。这确保了响应式副作用的隔离和自动回收。
44
+ *
45
+ * @protected 内部方法
46
+ * @param runner - 需要在作用域内执行的回调函数,可以返回一个清理函数
47
+ *
48
+ * @example
49
+ * // 基本用法
50
+ * _runScope(() => {
51
+ * // 在这里创建的响应式副作用会被限制在当前作用域内
52
+ * const stop = watch(someRef, (val) => {
53
+ * console.log(val);
54
+ * });
55
+ *
56
+ * // 返回一个清理函数,在作用域销毁时执行
57
+ * return () => {
58
+ * stop();
59
+ * };
60
+ * });
61
+ *
62
+ * @example
63
+ * // 异步用法
64
+ * _runScope(async () => {
65
+ * const data = await fetchData();
66
+ *
67
+ * // 根据获取的数据创建响应式监听
68
+ * const stop = watch(() => data.value, (val) => {
69
+ * console.log(val);
70
+ * });
71
+ *
72
+ * // 返回清理函数
73
+ * return () => {
74
+ * stop();
75
+ * };
76
+ * });
77
+ */
17
78
  function _runScope(runner) {
18
- const scope = vue.effectScope();
19
- let dispose;
20
- scope.run(async () => {
21
- const result = await runner();
22
- if (type.isFunction(result)) {
23
- dispose = result;
24
- }
25
- });
26
- vue.onScopeDispose(() => {
27
- dispose?.();
28
- scope.stop();
29
- });
79
+ const scope = (0, vue.effectScope)();
80
+ let dispose;
81
+ scope.run(async () => {
82
+ const result = await runner();
83
+ if ((0, _cloudcome_utils_core_type.isFunction)(result)) dispose = result;
84
+ });
85
+ (0, vue.onScopeDispose)(() => {
86
+ dispose?.();
87
+ scope.stop();
88
+ });
30
89
  }
90
+ //#endregion
31
91
  exports._runLifeHook = _runLifeHook;
32
92
  exports._runScope = _runScope;
33
- //# sourceMappingURL=shared.cjs.map
93
+
94
+ //# sourceMappingURL=shared.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared.cjs","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"],"names":["isFunction","effectScope","onScopeDispose"],"mappings":";;;;AA+BgB,SAAA,aACd,WACA,WACA,SACA;AAEI,MAAA;AAGJ,YAAU,YAAY;AAEd,UAAA,cAAc,MAAM,QAAQ;AAG9B,QAAAA,KAAAA,WAAW,WAAW,GAAG;AACjB,gBAAA;AAAA,IAAA;AAAA,EACZ,CACD;AAGD,YAAU,MAAM;AAEJ,cAAA;AAAA,EAAA,CACX;AACH;AAyCO,SAAS,UAAU,QAAiC;AAEzD,QAAM,QAAQC,IAAAA,YAAY;AAEtB,MAAA;AAGJ,QAAM,IAAI,YAAY;AAEd,UAAA,SAAS,MAAM,OAAO;AAGxB,QAAAD,KAAAA,WAAW,MAAM,GAAG;AACZ,gBAAA;AAAA,IAAA;AAAA,EACZ,CACD;AAGDE,MAAAA,eAAe,MAAM;AAET,cAAA;AAEV,UAAM,KAAK;AAAA,EAAA,CACZ;AACH;;;"}
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"}
package/dist/shared.d.ts CHANGED
@@ -25,7 +25,7 @@ export type HookListenerWithDispose = () => MaybePromise<unknown | HookListener>
25
25
  * }
26
26
  * );
27
27
  */
28
- export declare function _runLifeHook<T>(enterHook: (hook: AnyFunction) => unknown, leaveHook: (hook: AnyFunction) => unknown, onEnter: HookListenerWithDispose): void;
28
+ export declare function _runLifeHook<_T>(enterHook: (hook: AnyFunction) => unknown, leaveHook: (hook: AnyFunction) => unknown, onEnter: HookListenerWithDispose): void;
29
29
  /**
30
30
  * 运行作用域钩子函数的工具函数
31
31
  *
package/dist/shared.mjs CHANGED
@@ -1,33 +1,92 @@
1
- import { isFunction } from "@cloudcome/utils-core/type";
2
1
  import { effectScope, onScopeDispose } from "vue";
2
+ import { isFunction } from "@cloudcome/utils-core/type";
3
+ //#region src/shared.ts
4
+ /**
5
+ * 运行生命周期钩子函数的工具函数
6
+ *
7
+ * @protected 内部方法
8
+ * @template T - 泛型参数(未在函数中使用)
9
+ * @param enterHook - 进入时执行的钩子函数,接收一个回调函数作为参数
10
+ * @param leaveHook - 离开时执行的钩子函数,接收一个回调函数作为参数
11
+ * @param onEnter - 进入时的监听器,可以返回一个清理函数
12
+ *
13
+ * @example
14
+ * _runLifeHook(
15
+ * (hook) => onMounted(hook), // 在组件挂载时执行进入逻辑
16
+ * (hook) => onUnmounted(hook), // 在组件卸载时执行离开逻辑
17
+ * () => {
18
+ * // 执行进入时的逻辑
19
+ * console.log('组件已挂载');
20
+ *
21
+ * // 返回一个清理函数,在离开时执行
22
+ * return () => {
23
+ * console.log('组件将要卸载');
24
+ * };
25
+ * }
26
+ * );
27
+ */
3
28
  function _runLifeHook(enterHook, leaveHook, onEnter) {
4
- let onLeave;
5
- enterHook(async () => {
6
- const enterResult = await onEnter();
7
- if (isFunction(enterResult)) {
8
- onLeave = enterResult;
9
- }
10
- });
11
- leaveHook(() => {
12
- onLeave?.();
13
- });
29
+ let onLeave;
30
+ enterHook(async () => {
31
+ const enterResult = await onEnter();
32
+ if (isFunction(enterResult)) onLeave = enterResult;
33
+ });
34
+ leaveHook(() => {
35
+ onLeave?.();
36
+ });
14
37
  }
38
+ /**
39
+ * 运行作用域钩子函数的工具函数
40
+ *
41
+ * 该函数创建一个独立的响应式作用域,在该作用域内执行传入的回调函数,
42
+ * 并在适当的时机自动清理资源。这确保了响应式副作用的隔离和自动回收。
43
+ *
44
+ * @protected 内部方法
45
+ * @param runner - 需要在作用域内执行的回调函数,可以返回一个清理函数
46
+ *
47
+ * @example
48
+ * // 基本用法
49
+ * _runScope(() => {
50
+ * // 在这里创建的响应式副作用会被限制在当前作用域内
51
+ * const stop = watch(someRef, (val) => {
52
+ * console.log(val);
53
+ * });
54
+ *
55
+ * // 返回一个清理函数,在作用域销毁时执行
56
+ * return () => {
57
+ * stop();
58
+ * };
59
+ * });
60
+ *
61
+ * @example
62
+ * // 异步用法
63
+ * _runScope(async () => {
64
+ * const data = await fetchData();
65
+ *
66
+ * // 根据获取的数据创建响应式监听
67
+ * const stop = watch(() => data.value, (val) => {
68
+ * console.log(val);
69
+ * });
70
+ *
71
+ * // 返回清理函数
72
+ * return () => {
73
+ * stop();
74
+ * };
75
+ * });
76
+ */
15
77
  function _runScope(runner) {
16
- const scope = effectScope();
17
- let dispose;
18
- scope.run(async () => {
19
- const result = await runner();
20
- if (isFunction(result)) {
21
- dispose = result;
22
- }
23
- });
24
- onScopeDispose(() => {
25
- dispose?.();
26
- scope.stop();
27
- });
78
+ const scope = effectScope();
79
+ let dispose;
80
+ scope.run(async () => {
81
+ const result = await runner();
82
+ if (isFunction(result)) dispose = result;
83
+ });
84
+ onScopeDispose(() => {
85
+ dispose?.();
86
+ scope.stop();
87
+ });
28
88
  }
29
- export {
30
- _runLifeHook,
31
- _runScope
32
- };
33
- //# sourceMappingURL=shared.mjs.map
89
+ //#endregion
90
+ export { _runLifeHook, _runScope };
91
+
92
+ //# sourceMappingURL=shared.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared.mjs","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"],"names":[],"mappings":";;AA+BgB,SAAA,aACd,WACA,WACA,SACA;AAEI,MAAA;AAGJ,YAAU,YAAY;AAEd,UAAA,cAAc,MAAM,QAAQ;AAG9B,QAAA,WAAW,WAAW,GAAG;AACjB,gBAAA;AAAA,IAAA;AAAA,EACZ,CACD;AAGD,YAAU,MAAM;AAEJ,cAAA;AAAA,EAAA,CACX;AACH;AAyCO,SAAS,UAAU,QAAiC;AAEzD,QAAM,QAAQ,YAAY;AAEtB,MAAA;AAGJ,QAAM,IAAI,YAAY;AAEd,UAAA,SAAS,MAAM,OAAO;AAGxB,QAAA,WAAW,MAAM,GAAG;AACZ,gBAAA;AAAA,IAAA;AAAA,EACZ,CACD;AAGD,iBAAe,MAAM;AAET,cAAA;AAEV,UAAM,KAAK;AAAA,EAAA,CACZ;AACH;"}
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"}
package/dist/state.cjs CHANGED
@@ -1,29 +1,30 @@
1
- "use strict";
2
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const vue = require("vue");
2
+ let vue = require("vue");
3
+ //#region src/state.ts
4
+ /**
5
+ * 只改变一次的值
6
+ * @param value 初始值
7
+ * @param options 选项
8
+ * @returns 包含 change 方法和 value 响应式值的对象
9
+ */
4
10
  function useOnceState(value, options) {
5
- let lastValue = value;
6
- const changed = vue.ref(false);
7
- const { equal = Object.is } = options || {};
8
- return {
9
- change(newValue) {
10
- if (equal(newValue, lastValue)) {
11
- return;
12
- }
13
- if (changed.value) {
14
- return;
15
- }
16
- changed.value = true;
17
- lastValue = newValue;
18
- },
19
- // 这里需要使用 computed 确保返回的是原始值,而不是 reactive 包装后的对象
20
- state: vue.computed(() => {
21
- if (!changed.value) {
22
- return value;
23
- }
24
- return lastValue;
25
- })
26
- };
11
+ let lastValue = value;
12
+ const changed = (0, vue.ref)(false);
13
+ const { equal = Object.is } = options || {};
14
+ return {
15
+ change(newValue) {
16
+ if (equal(newValue, lastValue)) return;
17
+ if (changed.value) return;
18
+ changed.value = true;
19
+ lastValue = newValue;
20
+ },
21
+ state: (0, vue.computed)(() => {
22
+ if (!changed.value) return value;
23
+ return lastValue;
24
+ })
25
+ };
27
26
  }
27
+ //#endregion
28
28
  exports.useOnceState = useOnceState;
29
- //# sourceMappingURL=state.cjs.map
29
+
30
+ //# sourceMappingURL=state.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"state.cjs","sources":["../src/state.ts"],"sourcesContent":["import { computed, ref } from 'vue';\n\nexport type UseOnceValueOptions<T> = {\n equal?: (a: T, b: T) => boolean;\n};\n\n/**\n * 只改变一次的值\n * @param value 初始值\n * @param options 选项\n * @returns 包含 change 方法和 value 响应式值的对象\n */\nexport function useOnceState<T>(value: T, options?: UseOnceValueOptions<T>) {\n let lastValue = value;\n const changed = ref(false);\n const { equal = Object.is } = options || {};\n\n return {\n change(newValue: T) {\n if (equal(newValue, lastValue)) {\n return;\n }\n\n if (changed.value) {\n return;\n }\n\n changed.value = true;\n lastValue = newValue;\n },\n // 这里需要使用 computed 确保返回的是原始值,而不是 reactive 包装后的对象\n state: computed(() => {\n // changed 使用响应式是为确保 computed 能够响应式更新\n if (!changed.value) {\n return value;\n }\n\n return lastValue;\n }),\n };\n}\n"],"names":["ref","computed"],"mappings":";;;AAYgB,SAAA,aAAgB,OAAU,SAAkC;AAC1E,MAAI,YAAY;AACV,QAAA,UAAUA,QAAI,KAAK;AACzB,QAAM,EAAE,QAAQ,OAAO,GAAG,IAAI,WAAW,CAAC;AAEnC,SAAA;AAAA,IACL,OAAO,UAAa;AACd,UAAA,MAAM,UAAU,SAAS,GAAG;AAC9B;AAAA,MAAA;AAGF,UAAI,QAAQ,OAAO;AACjB;AAAA,MAAA;AAGF,cAAQ,QAAQ;AACJ,kBAAA;AAAA,IACd;AAAA;AAAA,IAEA,OAAOC,aAAS,MAAM;AAEhB,UAAA,CAAC,QAAQ,OAAO;AACX,eAAA;AAAA,MAAA;AAGF,aAAA;AAAA,IACR,CAAA;AAAA,EACH;AACF;;"}
1
+ {"version":3,"file":"state.cjs","names":[],"sources":["../src/state.ts"],"sourcesContent":["import { computed, ref } from 'vue';\n\nexport type UseOnceValueOptions<T> = {\n equal?: (a: T, b: T) => boolean;\n};\n\n/**\n * 只改变一次的值\n * @param value 初始值\n * @param options 选项\n * @returns 包含 change 方法和 value 响应式值的对象\n */\nexport function useOnceState<T>(value: T, options?: UseOnceValueOptions<T>) {\n let lastValue = value;\n const changed = ref(false);\n const { equal = Object.is } = options || {};\n\n return {\n change(newValue: T) {\n if (equal(newValue, lastValue)) {\n return;\n }\n\n if (changed.value) {\n return;\n }\n\n changed.value = true;\n lastValue = newValue;\n },\n // 这里需要使用 computed 确保返回的是原始值,而不是 reactive 包装后的对象\n state: computed(() => {\n // changed 使用响应式是为确保 computed 能够响应式更新\n if (!changed.value) {\n return value;\n }\n\n return lastValue;\n }),\n };\n}\n"],"mappings":";;;;;;;;;AAYA,SAAgB,aAAgB,OAAU,SAAkC;CAC1E,IAAI,YAAY;CAChB,MAAM,WAAA,GAAA,IAAA,KAAc,MAAM;CAC1B,MAAM,EAAE,QAAQ,OAAO,OAAO,WAAW,EAAE;CAE3C,OAAO;EACL,OAAO,UAAa;GAClB,IAAI,MAAM,UAAU,UAAU,EAC5B;GAGF,IAAI,QAAQ,OACV;GAGF,QAAQ,QAAQ;GAChB,YAAY;;EAGd,QAAA,GAAA,IAAA,gBAAsB;GAEpB,IAAI,CAAC,QAAQ,OACX,OAAO;GAGT,OAAO;IACP;EACH"}
package/dist/state.mjs CHANGED
@@ -1,29 +1,29 @@
1
- import { ref, computed } from "vue";
1
+ import { computed, ref } from "vue";
2
+ //#region src/state.ts
3
+ /**
4
+ * 只改变一次的值
5
+ * @param value 初始值
6
+ * @param options 选项
7
+ * @returns 包含 change 方法和 value 响应式值的对象
8
+ */
2
9
  function useOnceState(value, options) {
3
- let lastValue = value;
4
- const changed = ref(false);
5
- const { equal = Object.is } = options || {};
6
- return {
7
- change(newValue) {
8
- if (equal(newValue, lastValue)) {
9
- return;
10
- }
11
- if (changed.value) {
12
- return;
13
- }
14
- changed.value = true;
15
- lastValue = newValue;
16
- },
17
- // 这里需要使用 computed 确保返回的是原始值,而不是 reactive 包装后的对象
18
- state: computed(() => {
19
- if (!changed.value) {
20
- return value;
21
- }
22
- return lastValue;
23
- })
24
- };
10
+ let lastValue = value;
11
+ const changed = ref(false);
12
+ const { equal = Object.is } = options || {};
13
+ return {
14
+ change(newValue) {
15
+ if (equal(newValue, lastValue)) return;
16
+ if (changed.value) return;
17
+ changed.value = true;
18
+ lastValue = newValue;
19
+ },
20
+ state: computed(() => {
21
+ if (!changed.value) return value;
22
+ return lastValue;
23
+ })
24
+ };
25
25
  }
26
- export {
27
- useOnceState
28
- };
29
- //# sourceMappingURL=state.mjs.map
26
+ //#endregion
27
+ export { useOnceState };
28
+
29
+ //# sourceMappingURL=state.mjs.map