@cloudcome/utils-vue
Version:
cloudcome utils for vue
1 lines • 8.66 kB
Source Map (JSON)
{"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 { 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 if (requestId && shareAble) {\n const shared = shareStorage.get(requestId);\n if (shared) {\n hitShare.value = true;\n return await shared.data;\n }\n }\n\n if (requestId && cacheAble) {\n const cached = await cacheStorage.get(requestId);\n\n if (cached) {\n const data = cached.data;\n hitCache.value = true;\n onCacheHit?.(cached);\n onSuccess?.(data, ...inputs);\n return data;\n }\n }\n\n const promise = fn(...inputs);\n\n if (requestId && shareAble) {\n shareStorage.set(requestId, promise, shareOptions);\n }\n\n const data = await promise;\n\n if (requestId && cacheAble) {\n cacheStorage.set(requestId, data, cacheOptions);\n }\n\n return data;\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":["data"],"mappings":";;;;AAgJA,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,QAAI,aAAa,WAAW;AACpB,YAAA,SAAS,aAAa,IAAI,SAAS;AACzC,UAAI,QAAQ;AACV,iBAAS,QAAQ;AACjB,eAAO,MAAM,OAAO;AAAA,MAAA;AAAA,IACtB;AAGF,QAAI,aAAa,WAAW;AAC1B,YAAM,SAAS,MAAM,aAAa,IAAI,SAAS;AAE/C,UAAI,QAAQ;AACV,cAAMA,QAAO,OAAO;AACpB,iBAAS,QAAQ;AACjB,qBAAa,MAAM;AACPA,oBAAAA,OAAM,GAAG,MAAM;AACpBA,eAAAA;AAAAA,MAAA;AAAA,IACT;AAGI,UAAA,UAAU,GAAG,GAAG,MAAM;AAE5B,QAAI,aAAa,WAAW;AACb,mBAAA,IAAI,WAAW,SAAS,YAAY;AAAA,IAAA;AAGnD,UAAM,OAAO,MAAM;AAEnB,QAAI,aAAa,WAAW;AACb,mBAAA,IAAI,WAAW,MAAM,YAAY;AAAA,IAAA;AAGzC,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;"}