@fast-china/utils 2.1.5 → 2.1.7

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 (55) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +14 -4
  3. package/README.zh.md +14 -4
  4. package/THIRD_PARTY_LICENSES.md +26 -0
  5. package/dist/crypto/index.mjs +2240 -33
  6. package/dist/crypto/index.mjs.map +1 -1
  7. package/dist/dom/index.mjs +2 -0
  8. package/dist/index.d.mts +1918 -26
  9. package/dist/index.global.min.js +1 -1
  10. package/dist/index.global.min.js.map +1 -1
  11. package/dist/index.mjs +9 -1
  12. package/dist/internal/runtime.mjs.map +1 -1
  13. package/dist/vue/breakpoints.mjs +46 -0
  14. package/dist/vue/breakpoints.mjs.map +1 -0
  15. package/dist/vue/element-size.mjs +33 -0
  16. package/dist/vue/element-size.mjs.map +1 -0
  17. package/dist/vue/event-listener.mjs +30 -0
  18. package/dist/vue/event-listener.mjs.map +1 -0
  19. package/dist/vue/index.mjs +15 -0
  20. package/dist/vue/now.mjs +29 -0
  21. package/dist/vue/now.mjs.map +1 -0
  22. package/dist/vue/resize-observer.mjs +31 -0
  23. package/dist/vue/resize-observer.mjs.map +1 -0
  24. package/dist/vue/window-size.mjs +32 -0
  25. package/dist/vue/window-size.mjs.map +1 -0
  26. package/package.json +4 -6
  27. package/dist/array/index.d.mts +0 -94
  28. package/dist/async/index.d.mts +0 -145
  29. package/dist/base64/index.d.mts +0 -106
  30. package/dist/color/index.d.mts +0 -89
  31. package/dist/crypto/index.d.mts +0 -327
  32. package/dist/date/index.d.mts +0 -190
  33. package/dist/dom/style.d.mts +0 -29
  34. package/dist/env/index.d.mts +0 -62
  35. package/dist/function/index.d.mts +0 -13
  36. package/dist/identity/index.d.mts +0 -77
  37. package/dist/internal/text.d.mts +0 -15
  38. package/dist/logger/index.d.mts +0 -90
  39. package/dist/number/index.d.mts +0 -89
  40. package/dist/object/index.d.mts +0 -114
  41. package/dist/storage/index.d.mts +0 -115
  42. package/dist/string/index.d.mts +0 -141
  43. package/dist/vue/emits.d.mts +0 -23
  44. package/dist/vue/expose.d.mts +0 -11
  45. package/dist/vue/func.d.mts +0 -13
  46. package/dist/vue/index.d.mts +0 -9
  47. package/dist/vue/install.d.mts +0 -50
  48. package/dist/vue/props.d.mts +0 -22
  49. package/dist/vue/render.d.mts +0 -11
  50. package/dist/vue/slots.d.mts +0 -18
  51. package/dist/vue/with.d.mts +0 -11
  52. package/docs/API.md +0 -155
  53. package/docs/API.zh-CN.md +0 -154
  54. package/docs/DEVELOPMENT_RELEASE.zh-CN.md +0 -65
  55. package/docs/RUNTIME_CONTRACT.md +0 -42
package/dist/index.mjs CHANGED
@@ -6,6 +6,7 @@ import { contrastRatio, formatHexColor, mixHexColorWithBlack, mixHexColorWithWhi
6
6
  import { AESDecrypt, AESDecryptAuthenticated, AESDecryptWithPassword, AESEncrypt, AESEncryptAuthenticated, AESEncryptWithPassword, DeriveECDHKeySHA256, DeriveECDHSecret, ECDSASign, ECDSAVerify, FixedTimeEquals, GenerateECDHKeyPair, GenerateECDSAKeyPair, GenerateRSAKeyPair, GenerateRandomBytes, HKDFSHA256, HMACSHA256Encrypt, HMACSHA384Encrypt, HMACSHA512Encrypt, HashPasswordPBKDF2SHA256, MD5Encrypt, PBKDF2SHA256, RSADecryptOAEP, RSAEncryptOAEP, RSASignPSS, RSAVerifyPSS, SHA1Encrypt, SHA256Bytes, SHA256Encrypt, SHA384Bytes, SHA384Encrypt, SHA512Bytes, SHA512Encrypt, VerifyPasswordPBKDF2SHA256 } from "./crypto/index.mjs";
7
7
  import { addDays, addMonths, addYears, createDateRangeShortcuts, createDateShortcuts, createOneMonthRangeFromToday, endOfDay, formatChineseRelativeTime, formatRelativeTime, getLocalDayBounds, getLocalTimeGreeting, getStartOfToday, isDateAfterNow, isFuture, isSameDay, isValidDate, isWithinInterval, startOfDay, toDate } from "./date/index.mjs";
8
8
  import { addCssUnit, serializeStyle } from "./dom/style.mjs";
9
+ import "./dom/index.mjs";
9
10
  import { detectRuntime, hasWebCrypto, isBrowser, isMobileUserAgent, isNode, isTabletUserAgent, isUniApp, isWebWorker } from "./env/index.mjs";
10
11
  import { once } from "./function/index.mjs";
11
12
  import { Local, Session, base64StorageCodec, configureStorage, isStorageConfigured } from "./storage/index.mjs";
@@ -13,12 +14,19 @@ import { camelCase, copy, decodeURIComponentRepeatedly, escapeHtml, generateUuid
13
14
  import { configureInstallationIdentity, getOrCreateInstallationId, installationIdentity } from "./identity/index.mjs";
14
15
  import { configureLogger, createLogger, logger } from "./logger/index.mjs";
15
16
  import { cloneDeep, hasOwn, isEqual, isPlainObject, mapValues, omit, omitBy, pick, pickBy, shallowEqual, toQueryString } from "./object/index.mjs";
17
+ import { useEventListener } from "./vue/event-listener.mjs";
18
+ import { useBreakpoints } from "./vue/breakpoints.mjs";
19
+ import { useResizeObserver } from "./vue/resize-observer.mjs";
20
+ import { useElementSize } from "./vue/element-size.mjs";
16
21
  import { useEmits } from "./vue/emits.mjs";
17
22
  import { useExpose } from "./vue/expose.mjs";
18
23
  import { callOptionalFunction } from "./vue/func.mjs";
19
24
  import { withInstall, withInstallDirective, withNoopInstall } from "./vue/install.mjs";
25
+ import { useNow } from "./vue/now.mjs";
20
26
  import { definePropType, useProps } from "./vue/props.mjs";
21
27
  import { useRender } from "./vue/render.mjs";
22
28
  import { makeSlots } from "./vue/slots.mjs";
29
+ import { useWindowSize } from "./vue/window-size.mjs";
23
30
  import { withDefineType } from "./vue/with.mjs";
24
- export { AESDecrypt, AESDecryptAuthenticated, AESDecryptWithPassword, AESEncrypt, AESEncryptAuthenticated, AESEncryptWithPassword, DeriveECDHKeySHA256, DeriveECDHSecret, ECDSASign, ECDSAVerify, FixedTimeEquals, GenerateECDHKeyPair, GenerateECDSAKeyPair, GenerateRSAKeyPair, GenerateRandomBytes, HKDFSHA256, HMACSHA256Encrypt, HMACSHA384Encrypt, HMACSHA512Encrypt, HashPasswordPBKDF2SHA256, Local, MD5Encrypt, PBKDF2SHA256, RSADecryptOAEP, RSAEncryptOAEP, RSASignPSS, RSAVerifyPSS, SHA1Encrypt, SHA256Bytes, SHA256Encrypt, SHA384Bytes, SHA384Encrypt, SHA512Bytes, SHA512Encrypt, Session, VerifyPasswordPBKDF2SHA256, addCssUnit, addDays, addMonths, addYears, allEqualBy, average, base64StorageCodec, callOptionalFunction, camelCase, chunk, clamp, cloneDeep, configureInstallationIdentity, configureLogger, configureStorage, contrastRatio, copy, createDateRangeShortcuts, createDateShortcuts, createLogger, createOneMonthRangeFromToday, debounce, decodeBase64, decodeBase64Bytes, decodeBase64Url, decodeBase64UrlBytes, decodeLatin1Base64, decodeSecureBase64, decodeURIComponentRepeatedly, definePropType, detectRuntime, difference, encodeBase64, encodeBase64Bytes, encodeBase64Url, encodeBase64UrlBytes, encodeLatin1Base64, encodeSecureBase64, endOfDay, escapeHtml, formatBytes, formatChineseRelativeTime, formatHexColor, formatRelativeTime, generateUuidV4, getLocalDayBounds, getLocalTimeGreeting, getOrCreateInstallationId, getStartOfToday, groupBy, hasDuplicatesBy, hasOwn, hasWebCrypto, inRange, installationIdentity, intersection, isBrowser, isDateAfterNow, isEqual, isFuture, isMobileUserAgent, isNode, isPlainObject, isSameDay, isStorageConfigured, isTabletUserAgent, isUniApp, isUuidV4, isValidDate, isValidJson, isWebWorker, isWithinInterval, kebabCase, lerp, logger, lowerFirst, makeSlots, mapConcurrent, mapValues, mixHexColorWithBlack, mixHexColorWithWhite, mixHexColors, normalizeWhitespace, omit, omitBy, once, parseHexColor, parseQueryString, partition, pascalCase, pick, pickBy, pickHigherContrastColor, randomInt, randomString, relativeLuminance, removeNullishValues, retry, roundTo, serializeStyle, shallowEqual, sleep, splitWords, startOfDay, sum, symmetricDifference, throttle, toDate, toQueryString, truncateGraphemes, unique, uniqueBy, upperFirst, useEmits, useExpose, useProps, useRender, withDefineType, withInstall, withInstallDirective, withNoopInstall, withTimeout };
31
+ import "./vue/index.mjs";
32
+ export { AESDecrypt, AESDecryptAuthenticated, AESDecryptWithPassword, AESEncrypt, AESEncryptAuthenticated, AESEncryptWithPassword, DeriveECDHKeySHA256, DeriveECDHSecret, ECDSASign, ECDSAVerify, FixedTimeEquals, GenerateECDHKeyPair, GenerateECDSAKeyPair, GenerateRSAKeyPair, GenerateRandomBytes, HKDFSHA256, HMACSHA256Encrypt, HMACSHA384Encrypt, HMACSHA512Encrypt, HashPasswordPBKDF2SHA256, Local, MD5Encrypt, PBKDF2SHA256, RSADecryptOAEP, RSAEncryptOAEP, RSASignPSS, RSAVerifyPSS, SHA1Encrypt, SHA256Bytes, SHA256Encrypt, SHA384Bytes, SHA384Encrypt, SHA512Bytes, SHA512Encrypt, Session, VerifyPasswordPBKDF2SHA256, addCssUnit, addDays, addMonths, addYears, allEqualBy, average, base64StorageCodec, callOptionalFunction, camelCase, chunk, clamp, cloneDeep, configureInstallationIdentity, configureLogger, configureStorage, contrastRatio, copy, createDateRangeShortcuts, createDateShortcuts, createLogger, createOneMonthRangeFromToday, debounce, decodeBase64, decodeBase64Bytes, decodeBase64Url, decodeBase64UrlBytes, decodeLatin1Base64, decodeSecureBase64, decodeURIComponentRepeatedly, definePropType, detectRuntime, difference, encodeBase64, encodeBase64Bytes, encodeBase64Url, encodeBase64UrlBytes, encodeLatin1Base64, encodeSecureBase64, endOfDay, escapeHtml, formatBytes, formatChineseRelativeTime, formatHexColor, formatRelativeTime, generateUuidV4, getLocalDayBounds, getLocalTimeGreeting, getOrCreateInstallationId, getStartOfToday, groupBy, hasDuplicatesBy, hasOwn, hasWebCrypto, inRange, installationIdentity, intersection, isBrowser, isDateAfterNow, isEqual, isFuture, isMobileUserAgent, isNode, isPlainObject, isSameDay, isStorageConfigured, isTabletUserAgent, isUniApp, isUuidV4, isValidDate, isValidJson, isWebWorker, isWithinInterval, kebabCase, lerp, logger, lowerFirst, makeSlots, mapConcurrent, mapValues, mixHexColorWithBlack, mixHexColorWithWhite, mixHexColors, normalizeWhitespace, omit, omitBy, once, parseHexColor, parseQueryString, partition, pascalCase, pick, pickBy, pickHigherContrastColor, randomInt, randomString, relativeLuminance, removeNullishValues, retry, roundTo, serializeStyle, shallowEqual, sleep, splitWords, startOfDay, sum, symmetricDifference, throttle, toDate, toQueryString, truncateGraphemes, unique, uniqueBy, upperFirst, useBreakpoints, useElementSize, useEmits, useEventListener, useExpose, useNow, useProps, useRender, useResizeObserver, useWindowSize, withDefineType, withInstall, withInstallDirective, withNoopInstall, withTimeout };
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.mjs","names":[],"sources":["../../src/internal/runtime.ts"],"sourcesContent":["/** Web、Node、WebView 与 uni-app 宿主可能按需提供的运行时全局能力。 */\ninterface RuntimeGlobals {\n\treadonly Intl?: {\n\t\treadonly Segmenter?: typeof Intl.Segmenter;\n\t};\n\treadonly crypto?: Omit<Partial<Crypto>, \"subtle\"> & {\n\t\treadonly subtle?: Partial<SubtleCrypto>;\n\t};\n\treadonly document?: Partial<Document>;\n\treadonly importScripts?: unknown;\n\treadonly isSecureContext?: boolean;\n\treadonly localStorage?: Storage;\n\treadonly navigator?: Partial<Navigator>;\n\treadonly plus?: unknown;\n\treadonly process?: unknown;\n\treadonly sessionStorage?: Storage;\n\treadonly uni?: unknown;\n\treadonly window?: Partial<Window>;\n}\n\n/**\n * 以可选能力视图读取全局对象。\n *\n * @remarks TypeScript 的 DOM 声明假定浏览器全局始终存在,但本包也会在 Node、WebView\n * 和 uni-app 中运行。这里只放宽能力是否存在,不改变标准 API 的属性与方法类型。\n */\nexport const runtimeGlobals = globalThis as RuntimeGlobals;\n"],"mappings":";;;;;;;AA0BA,MAAa,iBAAiB"}
1
+ {"version":3,"file":"runtime.mjs","names":[],"sources":["../../src/internal/runtime.ts"],"sourcesContent":["/** Web、Node、WebView 与 uni-app 宿主可能按需提供的运行时全局能力。 */\ninterface RuntimeGlobals {\n\treadonly Intl?: {\n\t\treadonly Segmenter?: typeof Intl.Segmenter;\n\t};\n\treadonly crypto?: Omit<Partial<Crypto>, \"subtle\"> & {\n\t\treadonly subtle?: Partial<SubtleCrypto>;\n\t};\n\treadonly document?: Partial<Document>;\n\treadonly importScripts?: unknown;\n\treadonly isSecureContext?: boolean;\n\treadonly localStorage?: Storage;\n\treadonly navigator?: Partial<Navigator>;\n\treadonly plus?: unknown;\n\treadonly process?: unknown;\n\treadonly ResizeObserver?: typeof ResizeObserver;\n\treadonly sessionStorage?: Storage;\n\treadonly uni?: unknown;\n\treadonly window?: Window;\n}\n\n/**\n * 以可选能力视图读取全局对象。\n *\n * @remarks TypeScript 的 DOM 声明假定浏览器全局始终存在,但本包也会在 Node、WebView\n * 和 uni-app 中运行。这里只放宽能力是否存在,不改变标准 API 的属性与方法类型。\n */\nexport const runtimeGlobals = globalThis as RuntimeGlobals;\n"],"mappings":";;;;;;;AA2BA,MAAa,iBAAiB"}
@@ -0,0 +1,46 @@
1
+ import { runtimeGlobals } from "../internal/runtime.mjs";
2
+ import { useEventListener } from "./event-listener.mjs";
3
+ import { computed, getCurrentScope, readonly, shallowRef } from "vue";
4
+ //#region src/vue/breakpoints.ts
5
+ /**
6
+ * 使用原生 Media Query 创建响应式最小宽度断点。
7
+ *
8
+ * @param breakpoints - 断点名称与非负像素宽度的映射。
9
+ * @returns 每个断点的只读状态和当前最大命中断点。
10
+ * @throws `Error` 当浏览器环境中不存在可用于自动清理的 Vue 响应式作用域。
11
+ * @throws `TypeError` 当断点使用保留名称 `active`。
12
+ * @throws `RangeError` 当断点宽度不是非负有限数值。
13
+ */
14
+ function useBreakpoints(breakpoints) {
15
+ const entries = Object.entries(breakpoints);
16
+ entries.sort((left, right) => left[1] - right[1]);
17
+ for (const [name, minimumWidth] of entries) {
18
+ if (name === "active") throw new TypeError("断点名称不能使用保留名称“active”。");
19
+ if (!Number.isFinite(minimumWidth) || minimumWidth < 0) throw new RangeError(`断点“${name}”必须是非负有限数值。`);
20
+ }
21
+ const states = Object.create(null);
22
+ const window = runtimeGlobals.window;
23
+ if (window !== void 0 && getCurrentScope() === void 0) throw new Error("`useBreakpoints` 必须在 Vue 响应式作用域内调用。");
24
+ for (const [name, minimumWidth] of entries) {
25
+ const state = shallowRef(false);
26
+ if (window !== void 0 && typeof window.matchMedia === "function") {
27
+ const mediaQuery = window.matchMedia(`(min-width: ${minimumWidth}px)`);
28
+ const update = () => {
29
+ state.value = mediaQuery.matches;
30
+ };
31
+ update();
32
+ useEventListener(mediaQuery, "change", update);
33
+ }
34
+ states[name] = readonly(state);
35
+ }
36
+ const active = computed(() => {
37
+ let current = "";
38
+ for (const [name] of entries) if (states[name].value) current = name;
39
+ return current;
40
+ });
41
+ return Object.assign(states, { active: () => active });
42
+ }
43
+ //#endregion
44
+ export { useBreakpoints };
45
+
46
+ //# sourceMappingURL=breakpoints.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"breakpoints.mjs","names":[],"sources":["../../src/vue/breakpoints.ts"],"sourcesContent":["import { computed, getCurrentScope, readonly, shallowRef } from \"vue\";\nimport { runtimeGlobals } from \"../internal/runtime\";\nimport { useEventListener } from \"./event-listener\";\nimport type { ComputedRef, ShallowRef } from \"vue\";\n\n/** 断点名称与最小视口宽度的映射。 */\nexport type Breakpoints<Key extends string = string> = Readonly<Record<Key, number>>;\n\n/** `useBreakpoints` 返回的断点状态。 */\nexport type UseBreakpointsReturn<Key extends string> = Readonly<Record<Key, Readonly<ShallowRef<boolean>>>> & {\n\t/** 返回当前命中的最大断点名称。 */\n\tactive: () => ComputedRef<Key | \"\">;\n};\n\n/**\n * 使用原生 Media Query 创建响应式最小宽度断点。\n *\n * @param breakpoints - 断点名称与非负像素宽度的映射。\n * @returns 每个断点的只读状态和当前最大命中断点。\n * @throws `Error` 当浏览器环境中不存在可用于自动清理的 Vue 响应式作用域。\n * @throws `TypeError` 当断点使用保留名称 `active`。\n * @throws `RangeError` 当断点宽度不是非负有限数值。\n */\nexport function useBreakpoints<Key extends string>(breakpoints: Breakpoints<Key>): UseBreakpointsReturn<Key> {\n\tconst entries = Object.entries(breakpoints) as [Key, number][];\n\tentries.sort((left, right) => left[1] - right[1]);\n\tfor (const [name, minimumWidth] of entries) {\n\t\tif (name === \"active\") throw new TypeError(\"断点名称不能使用保留名称“active”。\");\n\t\tif (!Number.isFinite(minimumWidth) || minimumWidth < 0) throw new RangeError(`断点“${name}”必须是非负有限数值。`);\n\t}\n\tconst states = Object.create(null) as Record<Key, Readonly<ShallowRef<boolean>>>;\n\tconst window = runtimeGlobals.window;\n\tif (window !== undefined && getCurrentScope() === undefined) {\n\t\tthrow new Error(\"`useBreakpoints` 必须在 Vue 响应式作用域内调用。\");\n\t}\n\tfor (const [name, minimumWidth] of entries) {\n\t\tconst state = shallowRef(false);\n\t\tif (window !== undefined && typeof window.matchMedia === \"function\") {\n\t\t\tconst mediaQuery = window.matchMedia(`(min-width: ${minimumWidth}px)`);\n\t\t\tconst update = () => {\n\t\t\t\tstate.value = mediaQuery.matches;\n\t\t\t};\n\t\t\tupdate();\n\t\t\tuseEventListener(mediaQuery, \"change\", update);\n\t\t}\n\t\tstates[name] = readonly(state);\n\t}\n\tconst active = computed<Key | \"\">(() => {\n\t\tlet current: Key | \"\" = \"\";\n\t\tfor (const [name] of entries) {\n\t\t\tif (states[name].value) current = name;\n\t\t}\n\t\treturn current;\n\t});\n\treturn Object.assign(states, { active: () => active });\n}\n"],"mappings":";;;;;;;;;;;;;AAuBA,SAAgB,eAAmC,aAA0D;CAC5G,MAAM,UAAU,OAAO,QAAQ,WAAW;CAC1C,QAAQ,MAAM,MAAM,UAAU,KAAK,KAAK,MAAM,EAAE;CAChD,KAAK,MAAM,CAAC,MAAM,iBAAiB,SAAS;EAC3C,IAAI,SAAS,UAAU,MAAM,IAAI,UAAU,uBAAuB;EAClE,IAAI,CAAC,OAAO,SAAS,YAAY,KAAK,eAAe,GAAG,MAAM,IAAI,WAAW,MAAM,KAAK,YAAY;CACrG;CACA,MAAM,SAAS,OAAO,OAAO,IAAI;CACjC,MAAM,SAAS,eAAe;CAC9B,IAAI,WAAW,KAAA,KAAa,gBAAgB,MAAM,KAAA,GACjD,MAAM,IAAI,MAAM,qCAAqC;CAEtD,KAAK,MAAM,CAAC,MAAM,iBAAiB,SAAS;EAC3C,MAAM,QAAQ,WAAW,KAAK;EAC9B,IAAI,WAAW,KAAA,KAAa,OAAO,OAAO,eAAe,YAAY;GACpE,MAAM,aAAa,OAAO,WAAW,eAAe,aAAa,IAAI;GACrE,MAAM,eAAe;IACpB,MAAM,QAAQ,WAAW;GAC1B;GACA,OAAO;GACP,iBAAiB,YAAY,UAAU,MAAM;EAC9C;EACA,OAAO,QAAQ,SAAS,KAAK;CAC9B;CACA,MAAM,SAAS,eAAyB;EACvC,IAAI,UAAoB;EACxB,KAAK,MAAM,CAAC,SAAS,SACpB,IAAI,OAAO,KAAK,CAAC,OAAO,UAAU;EAEnC,OAAO;CACR,CAAC;CACD,OAAO,OAAO,OAAO,QAAQ,EAAE,cAAc,OAAO,CAAC;AACtD"}
@@ -0,0 +1,33 @@
1
+ import { useResizeObserver } from "./resize-observer.mjs";
2
+ import { readonly, shallowRef } from "vue";
3
+ //#region src/vue/element-size.ts
4
+ /**
5
+ * 响应式读取元素 Content Rect 尺寸。
6
+ *
7
+ * @param target - 原生元素、Ref 或 Getter。
8
+ * @param initialSize - 收到首次观察结果前的尺寸,默认均为 `0`。
9
+ * @param options - 原生元素观察选项。
10
+ * @returns 只读宽度、高度和手动停止函数。
11
+ */
12
+ function useElementSize(target, initialSize = {
13
+ height: 0,
14
+ width: 0
15
+ }, options) {
16
+ const width = shallowRef(initialSize.width);
17
+ const height = shallowRef(initialSize.height);
18
+ const stop = useResizeObserver(target, (entries) => {
19
+ const entry = entries[0];
20
+ if (entry === void 0) return;
21
+ width.value = entry.contentRect.width;
22
+ height.value = entry.contentRect.height;
23
+ }, options);
24
+ return {
25
+ height: readonly(height),
26
+ stop,
27
+ width: readonly(width)
28
+ };
29
+ }
30
+ //#endregion
31
+ export { useElementSize };
32
+
33
+ //# sourceMappingURL=element-size.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"element-size.mjs","names":[],"sources":["../../src/vue/element-size.ts"],"sourcesContent":["import { readonly, shallowRef } from \"vue\";\nimport { useResizeObserver } from \"./resize-observer\";\nimport type { ShallowRef } from \"vue\";\nimport type { ResizeObserverTarget } from \"./resize-observer\";\n\n/** 元素的二维尺寸。 */\nexport interface ElementSize {\n\treadonly width: number;\n\treadonly height: number;\n}\n\n/** `useElementSize` 返回的响应式尺寸和停止函数。 */\nexport interface UseElementSizeReturn {\n\treadonly width: Readonly<ShallowRef<number>>;\n\treadonly height: Readonly<ShallowRef<number>>;\n\treadonly stop: () => void;\n}\n\n/**\n * 响应式读取元素 Content Rect 尺寸。\n *\n * @param target - 原生元素、Ref 或 Getter。\n * @param initialSize - 收到首次观察结果前的尺寸,默认均为 `0`。\n * @param options - 原生元素观察选项。\n * @returns 只读宽度、高度和手动停止函数。\n */\nexport function useElementSize(\n\ttarget: ResizeObserverTarget,\n\tinitialSize: ElementSize = { height: 0, width: 0 },\n\toptions?: ResizeObserverOptions\n): UseElementSizeReturn {\n\tconst width = shallowRef(initialSize.width);\n\tconst height = shallowRef(initialSize.height);\n\tconst stop = useResizeObserver(\n\t\ttarget,\n\t\t(entries) => {\n\t\t\tconst entry = entries[0];\n\t\t\tif (entry === undefined) return;\n\t\t\twidth.value = entry.contentRect.width;\n\t\t\theight.value = entry.contentRect.height;\n\t\t},\n\t\toptions\n\t);\n\treturn { height: readonly(height), stop, width: readonly(width) };\n}\n"],"mappings":";;;;;;;;;;;AA0BA,SAAgB,eACf,QACA,cAA2B;CAAE,QAAQ;CAAG,OAAO;AAAE,GACjD,SACuB;CACvB,MAAM,QAAQ,WAAW,YAAY,KAAK;CAC1C,MAAM,SAAS,WAAW,YAAY,MAAM;CAC5C,MAAM,OAAO,kBACZ,SACC,YAAY;EACZ,MAAM,QAAQ,QAAQ;EACtB,IAAI,UAAU,KAAA,GAAW;EACzB,MAAM,QAAQ,MAAM,YAAY;EAChC,OAAO,QAAQ,MAAM,YAAY;CAClC,GACA,OACD;CACA,OAAO;EAAE,QAAQ,SAAS,MAAM;EAAG;EAAM,OAAO,SAAS,KAAK;CAAE;AACjE"}
@@ -0,0 +1,30 @@
1
+ import { onScopeDispose, toValue, watch } from "vue";
2
+ //#region src/vue/event-listener.ts
3
+ /**
4
+ * 注册原生事件监听器,并在目标变化或 Vue 作用域销毁时自动移除。
5
+ *
6
+ * @param target - 原生事件目标、Ref 或 Getter。
7
+ * @param event - 原生事件名称。
8
+ * @param listener - 事件回调。
9
+ * @param options - 原生事件监听选项。
10
+ * @returns 可提前移除监听器的停止函数。
11
+ */
12
+ function useEventListener(target, event, listener, options) {
13
+ const eventListener = listener;
14
+ const stop = watch(() => toValue(target), (currentTarget, _previousTarget, onCleanup) => {
15
+ if (currentTarget === null || currentTarget === void 0) return;
16
+ currentTarget.addEventListener(event, eventListener, options);
17
+ onCleanup(() => {
18
+ currentTarget.removeEventListener(event, eventListener, options);
19
+ });
20
+ }, {
21
+ flush: "sync",
22
+ immediate: true
23
+ });
24
+ onScopeDispose(stop, true);
25
+ return stop;
26
+ }
27
+ //#endregion
28
+ export { useEventListener };
29
+
30
+ //# sourceMappingURL=event-listener.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-listener.mjs","names":[],"sources":["../../src/vue/event-listener.ts"],"sourcesContent":["import { onScopeDispose, toValue, watch } from \"vue\";\nimport type { MaybeRefOrGetter } from \"vue\";\n\n/** `useEventListener` 接受的原生事件目标或响应式事件目标。 */\nexport type EventTargetSource = MaybeRefOrGetter<EventTarget | null | undefined>;\n\n/**\n * 注册原生事件监听器,并在目标变化或 Vue 作用域销毁时自动移除。\n *\n * @param target - 原生事件目标、Ref 或 Getter。\n * @param event - 原生事件名称。\n * @param listener - 事件回调。\n * @param options - 原生事件监听选项。\n * @returns 可提前移除监听器的停止函数。\n */\nexport function useEventListener<EventType extends Event = Event>(\n\ttarget: EventTargetSource,\n\tevent: string,\n\tlistener: (event: EventType) => void,\n\toptions?: boolean | AddEventListenerOptions\n): () => void {\n\tconst eventListener = listener as EventListener;\n\tconst stop = watch(\n\t\t() => toValue(target),\n\t\t(currentTarget, _previousTarget, onCleanup) => {\n\t\t\tif (currentTarget === null || currentTarget === undefined) return;\n\t\t\tcurrentTarget.addEventListener(event, eventListener, options);\n\t\t\tonCleanup(() => {\n\t\t\t\tcurrentTarget.removeEventListener(event, eventListener, options);\n\t\t\t});\n\t\t},\n\t\t{ flush: \"sync\", immediate: true }\n\t);\n\tonScopeDispose(stop, true);\n\treturn stop;\n}\n"],"mappings":";;;;;;;;;;;AAeA,SAAgB,iBACf,QACA,OACA,UACA,SACa;CACb,MAAM,gBAAgB;CACtB,MAAM,OAAO,YACN,QAAQ,MAAM,IACnB,eAAe,iBAAiB,cAAc;EAC9C,IAAI,kBAAkB,QAAQ,kBAAkB,KAAA,GAAW;EAC3D,cAAc,iBAAiB,OAAO,eAAe,OAAO;EAC5D,gBAAgB;GACf,cAAc,oBAAoB,OAAO,eAAe,OAAO;EAChE,CAAC;CACF,GACA;EAAE,OAAO;EAAQ,WAAW;CAAK,CAClC;CACA,eAAe,MAAM,IAAI;CACzB,OAAO;AACR"}
@@ -0,0 +1,15 @@
1
+ import { useEventListener } from "./event-listener.mjs";
2
+ import { useBreakpoints } from "./breakpoints.mjs";
3
+ import { useResizeObserver } from "./resize-observer.mjs";
4
+ import { useElementSize } from "./element-size.mjs";
5
+ import { useEmits } from "./emits.mjs";
6
+ import { useExpose } from "./expose.mjs";
7
+ import { callOptionalFunction } from "./func.mjs";
8
+ import { withInstall, withInstallDirective, withNoopInstall } from "./install.mjs";
9
+ import { useNow } from "./now.mjs";
10
+ import { definePropType, useProps } from "./props.mjs";
11
+ import { useRender } from "./render.mjs";
12
+ import { makeSlots } from "./slots.mjs";
13
+ import { useWindowSize } from "./window-size.mjs";
14
+ import { withDefineType } from "./with.mjs";
15
+ export { callOptionalFunction, definePropType, makeSlots, useBreakpoints, useElementSize, useEmits, useEventListener, useExpose, useNow, useProps, useRender, useResizeObserver, useWindowSize, withDefineType, withInstall, withInstallDirective, withNoopInstall };
@@ -0,0 +1,29 @@
1
+ import { runtimeGlobals } from "../internal/runtime.mjs";
2
+ import { getCurrentScope, onScopeDispose, readonly, shallowRef } from "vue";
3
+ //#region src/vue/now.ts
4
+ /**
5
+ * 按固定间隔提供响应式当前时间。
6
+ *
7
+ * @param intervalMilliseconds - 更新时间间隔,默认 `1000` 毫秒。
8
+ * @returns 当前 Date 的只读 ShallowRef;SSR 环境只返回调用时的时间。
9
+ * @throws `Error` 当浏览器或 uni-app 环境中不存在可用于自动清理的 Vue 响应式作用域。
10
+ * @throws `RangeError` 当间隔不是平台计时器支持的非负有限整数。
11
+ */
12
+ function useNow(intervalMilliseconds = 1e3) {
13
+ if (!Number.isInteger(intervalMilliseconds) || intervalMilliseconds < 0 || intervalMilliseconds > 2147483647) throw new RangeError("`intervalMilliseconds` 必须是 0 至 2,147,483,647 的整数。");
14
+ const now = shallowRef(/* @__PURE__ */ new Date());
15
+ if (runtimeGlobals.window !== void 0 || runtimeGlobals.uni !== void 0) {
16
+ if (getCurrentScope() === void 0) throw new Error("`useNow` 必须在 Vue 响应式作用域内调用。");
17
+ const timer = setInterval(() => {
18
+ now.value = /* @__PURE__ */ new Date();
19
+ }, intervalMilliseconds);
20
+ onScopeDispose(() => {
21
+ clearInterval(timer);
22
+ });
23
+ }
24
+ return readonly(now);
25
+ }
26
+ //#endregion
27
+ export { useNow };
28
+
29
+ //# sourceMappingURL=now.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"now.mjs","names":[],"sources":["../../src/vue/now.ts"],"sourcesContent":["import { getCurrentScope, onScopeDispose, readonly, shallowRef } from \"vue\";\nimport { runtimeGlobals } from \"../internal/runtime\";\nimport type { ShallowRef } from \"vue\";\n\n/**\n * 按固定间隔提供响应式当前时间。\n *\n * @param intervalMilliseconds - 更新时间间隔,默认 `1000` 毫秒。\n * @returns 当前 Date 的只读 ShallowRef;SSR 环境只返回调用时的时间。\n * @throws `Error` 当浏览器或 uni-app 环境中不存在可用于自动清理的 Vue 响应式作用域。\n * @throws `RangeError` 当间隔不是平台计时器支持的非负有限整数。\n */\nexport function useNow(intervalMilliseconds = 1000): Readonly<ShallowRef<Date>> {\n\tif (!Number.isInteger(intervalMilliseconds) || intervalMilliseconds < 0 || intervalMilliseconds > 2_147_483_647) {\n\t\tthrow new RangeError(\"`intervalMilliseconds` 必须是 0 至 2,147,483,647 的整数。\");\n\t}\n\tconst now = shallowRef(new Date());\n\tif (runtimeGlobals.window !== undefined || runtimeGlobals.uni !== undefined) {\n\t\tif (getCurrentScope() === undefined) throw new Error(\"`useNow` 必须在 Vue 响应式作用域内调用。\");\n\t\tconst timer = setInterval(() => {\n\t\t\tnow.value = new Date();\n\t\t}, intervalMilliseconds);\n\t\tonScopeDispose(() => {\n\t\t\tclearInterval(timer);\n\t\t});\n\t}\n\treturn readonly(now);\n}\n"],"mappings":";;;;;;;;;;;AAYA,SAAgB,OAAO,uBAAuB,KAAkC;CAC/E,IAAI,CAAC,OAAO,UAAU,oBAAoB,KAAK,uBAAuB,KAAK,uBAAuB,YACjG,MAAM,IAAI,WAAW,mDAAmD;CAEzE,MAAM,MAAM,2BAAW,IAAI,KAAK,CAAC;CACjC,IAAI,eAAe,WAAW,KAAA,KAAa,eAAe,QAAQ,KAAA,GAAW;EAC5E,IAAI,gBAAgB,MAAM,KAAA,GAAW,MAAM,IAAI,MAAM,6BAA6B;EAClF,MAAM,QAAQ,kBAAkB;GAC/B,IAAI,wBAAQ,IAAI,KAAK;EACtB,GAAG,oBAAoB;EACvB,qBAAqB;GACpB,cAAc,KAAK;EACpB,CAAC;CACF;CACA,OAAO,SAAS,GAAG;AACpB"}
@@ -0,0 +1,31 @@
1
+ import { runtimeGlobals } from "../internal/runtime.mjs";
2
+ import { onScopeDispose, toValue, watch } from "vue";
3
+ //#region src/vue/resize-observer.ts
4
+ /**
5
+ * 监听元素尺寸变化,并随响应式目标切换和 Vue 作用域销毁自动断开。
6
+ *
7
+ * @param target - 原生元素、Ref 或 Getter。
8
+ * @param callback - 原生 ResizeObserver 回调。
9
+ * @param options - 原生元素观察选项。
10
+ * @returns 可提前断开观察的停止函数;运行时不支持 ResizeObserver 时为空操作。
11
+ */
12
+ function useResizeObserver(target, callback, options) {
13
+ const stop = watch(() => toValue(target), (currentTarget, _previousTarget, onCleanup) => {
14
+ const ResizeObserver = runtimeGlobals.ResizeObserver;
15
+ if (currentTarget === null || currentTarget === void 0 || ResizeObserver === void 0) return;
16
+ const observer = new ResizeObserver(callback);
17
+ observer.observe(currentTarget, options);
18
+ onCleanup(() => {
19
+ observer.disconnect();
20
+ });
21
+ }, {
22
+ flush: "sync",
23
+ immediate: true
24
+ });
25
+ onScopeDispose(stop, true);
26
+ return stop;
27
+ }
28
+ //#endregion
29
+ export { useResizeObserver };
30
+
31
+ //# sourceMappingURL=resize-observer.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resize-observer.mjs","names":[],"sources":["../../src/vue/resize-observer.ts"],"sourcesContent":["import { onScopeDispose, toValue, watch } from \"vue\";\nimport { runtimeGlobals } from \"../internal/runtime\";\nimport type { MaybeRefOrGetter } from \"vue\";\n\n/** `useResizeObserver` 接受的元素或响应式元素。 */\nexport type ResizeObserverTarget = MaybeRefOrGetter<Element | null | undefined>;\n\n/**\n * 监听元素尺寸变化,并随响应式目标切换和 Vue 作用域销毁自动断开。\n *\n * @param target - 原生元素、Ref 或 Getter。\n * @param callback - 原生 ResizeObserver 回调。\n * @param options - 原生元素观察选项。\n * @returns 可提前断开观察的停止函数;运行时不支持 ResizeObserver 时为空操作。\n */\nexport function useResizeObserver(target: ResizeObserverTarget, callback: ResizeObserverCallback, options?: ResizeObserverOptions): () => void {\n\tconst stop = watch(\n\t\t() => toValue(target),\n\t\t(currentTarget, _previousTarget, onCleanup) => {\n\t\t\tconst ResizeObserver = runtimeGlobals.ResizeObserver;\n\t\t\tif (currentTarget === null || currentTarget === undefined || ResizeObserver === undefined) return;\n\t\t\tconst observer = new ResizeObserver(callback);\n\t\t\tobserver.observe(currentTarget, options);\n\t\t\tonCleanup(() => {\n\t\t\t\tobserver.disconnect();\n\t\t\t});\n\t\t},\n\t\t{ flush: \"sync\", immediate: true }\n\t);\n\tonScopeDispose(stop, true);\n\treturn stop;\n}\n"],"mappings":";;;;;;;;;;;AAeA,SAAgB,kBAAkB,QAA8B,UAAkC,SAA6C;CAC9I,MAAM,OAAO,YACN,QAAQ,MAAM,IACnB,eAAe,iBAAiB,cAAc;EAC9C,MAAM,iBAAiB,eAAe;EACtC,IAAI,kBAAkB,QAAQ,kBAAkB,KAAA,KAAa,mBAAmB,KAAA,GAAW;EAC3F,MAAM,WAAW,IAAI,eAAe,QAAQ;EAC5C,SAAS,QAAQ,eAAe,OAAO;EACvC,gBAAgB;GACf,SAAS,WAAW;EACrB,CAAC;CACF,GACA;EAAE,OAAO;EAAQ,WAAW;CAAK,CAClC;CACA,eAAe,MAAM,IAAI;CACzB,OAAO;AACR"}
@@ -0,0 +1,32 @@
1
+ import { runtimeGlobals } from "../internal/runtime.mjs";
2
+ import { useEventListener } from "./event-listener.mjs";
3
+ import { getCurrentScope, readonly, shallowRef } from "vue";
4
+ //#region src/vue/window-size.ts
5
+ /**
6
+ * 响应式读取浏览器窗口内部尺寸。
7
+ *
8
+ * @returns 随原生 `resize` 事件更新的只读宽度和高度;非浏览器环境均为 `0`。
9
+ * @throws `Error` 当浏览器环境中不存在可用于自动清理的 Vue 响应式作用域。
10
+ */
11
+ function useWindowSize() {
12
+ const width = shallowRef(0);
13
+ const height = shallowRef(0);
14
+ const window = runtimeGlobals.window;
15
+ if (window !== void 0) {
16
+ if (getCurrentScope() === void 0) throw new Error("`useWindowSize` 必须在 Vue 响应式作用域内调用。");
17
+ const update = () => {
18
+ width.value = window.innerWidth;
19
+ height.value = window.innerHeight;
20
+ };
21
+ update();
22
+ useEventListener(window, "resize", update, { passive: true });
23
+ }
24
+ return {
25
+ height: readonly(height),
26
+ width: readonly(width)
27
+ };
28
+ }
29
+ //#endregion
30
+ export { useWindowSize };
31
+
32
+ //# sourceMappingURL=window-size.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"window-size.mjs","names":[],"sources":["../../src/vue/window-size.ts"],"sourcesContent":["import { getCurrentScope, readonly, shallowRef } from \"vue\";\nimport { runtimeGlobals } from \"../internal/runtime\";\nimport { useEventListener } from \"./event-listener\";\nimport type { ShallowRef } from \"vue\";\n\n/** `useWindowSize` 返回的只读窗口尺寸。 */\nexport interface UseWindowSizeReturn {\n\treadonly width: Readonly<ShallowRef<number>>;\n\treadonly height: Readonly<ShallowRef<number>>;\n}\n\n/**\n * 响应式读取浏览器窗口内部尺寸。\n *\n * @returns 随原生 `resize` 事件更新的只读宽度和高度;非浏览器环境均为 `0`。\n * @throws `Error` 当浏览器环境中不存在可用于自动清理的 Vue 响应式作用域。\n */\nexport function useWindowSize(): UseWindowSizeReturn {\n\tconst width = shallowRef(0);\n\tconst height = shallowRef(0);\n\tconst window = runtimeGlobals.window;\n\tif (window !== undefined) {\n\t\tif (getCurrentScope() === undefined) throw new Error(\"`useWindowSize` 必须在 Vue 响应式作用域内调用。\");\n\t\tconst update = () => {\n\t\t\twidth.value = window.innerWidth;\n\t\t\theight.value = window.innerHeight;\n\t\t};\n\t\tupdate();\n\t\tuseEventListener(window, \"resize\", update, { passive: true });\n\t}\n\treturn { height: readonly(height), width: readonly(width) };\n}\n"],"mappings":";;;;;;;;;;AAiBA,SAAgB,gBAAqC;CACpD,MAAM,QAAQ,WAAW,CAAC;CAC1B,MAAM,SAAS,WAAW,CAAC;CAC3B,MAAM,SAAS,eAAe;CAC9B,IAAI,WAAW,KAAA,GAAW;EACzB,IAAI,gBAAgB,MAAM,KAAA,GAAW,MAAM,IAAI,MAAM,oCAAoC;EACzF,MAAM,eAAe;GACpB,MAAM,QAAQ,OAAO;GACrB,OAAO,QAAQ,OAAO;EACvB;EACA,OAAO;EACP,iBAAiB,QAAQ,UAAU,QAAQ,EAAE,SAAS,KAAK,CAAC;CAC7D;CACA,OAAO;EAAE,QAAQ,SAAS,MAAM;EAAG,OAAO,SAAS,KAAK;CAAE;AAC3D"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fast-china/utils",
3
- "version": "2.1.5",
3
+ "version": "2.1.7",
4
4
  "description": "Typed utilities for modern browsers, WebViews, Vue 3, and uni-app applications.",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -27,8 +27,8 @@
27
27
  "README.md",
28
28
  "README.zh.md",
29
29
  "SECURITY.md",
30
- "dist",
31
- "docs"
30
+ "THIRD_PARTY_LICENSES.md",
31
+ "dist"
32
32
  ],
33
33
  "main": "./dist/index.mjs",
34
34
  "module": "./dist/index.mjs",
@@ -64,14 +64,12 @@
64
64
  "peerDependencies": {
65
65
  "vue": "^3.5.11"
66
66
  },
67
- "dependencies": {
68
- "crypto-js": "^4.2.0"
69
- },
70
67
  "devDependencies": {
71
68
  "@eslint/js": "^10.0.1",
72
69
  "@eslint/markdown": "^8.0.3",
73
70
  "@types/crypto-js": "^4.2.2",
74
71
  "@types/node": "^24.13.4",
72
+ "crypto-js": "^4.2.0",
75
73
  "eslint": "^10.10.0",
76
74
  "eslint-config-flat-gitignore": "^2.4.0",
77
75
  "eslint-config-prettier": "^10.1.8",
@@ -1,94 +0,0 @@
1
- //#region src/array/index.d.ts
2
- /** 从数组项中提取可比较键的函数。 */
3
- export type KeySelector<Item, Key> = (item: Item, index: number) => Key;
4
- /**
5
- * 将只读数组按固定大小分组。
6
- *
7
- * @typeParam Item - 数组项类型。
8
- * @param items - 不会被修改的输入数组。
9
- * @param size - 每组最多包含的项目数,必须是正安全整数。
10
- * @returns 新建的二维数组;最后一组可能小于 `size`。
11
- * @throws `RangeError` 当 `size` 不是正安全整数。
12
- */
13
- export declare function chunk<Item>(items: readonly Item[], size: number): Item[][];
14
- /**
15
- * 删除数组中的 `null` 与 `undefined`,保留 `false`、`0` 和空字符串。
16
- *
17
- * @param items - 可包含空值的只读数组。
18
- * @returns 保持原顺序的新数组。
19
- */
20
- export declare function removeNullishValues<Item>(items: readonly (Item | null | undefined)[]): Item[];
21
- /**
22
- * 使用 JavaScript `Set` 的 SameValueZero 语义去重。
23
- *
24
- * @param items - 不会被修改的输入数组。
25
- * @returns 保留每个值首次出现顺序的新数组;稀疏数组空位被忽略。
26
- */
27
- export declare function unique<Item>(items: readonly Item[]): Item[];
28
- /**
29
- * 按选择器返回的键去重。
30
- *
31
- * @param items - 不会被修改的输入数组。
32
- * @param selectKey - 接收项目与索引并返回去重键的函数。
33
- * @returns 保留每个键首次出现项目的新数组;稀疏数组空位被忽略。
34
- */
35
- export declare function uniqueBy<Item, Key>(items: readonly Item[], selectKey: KeySelector<Item, Key>): Item[];
36
- /**
37
- * 按选择器结果分组。
38
- *
39
- * @param items - 不会被修改的输入数组。
40
- * @param selectKey - 返回任意 `Map` 键的函数。
41
- * @returns 按键首次出现顺序排列的 `Map`;每个分组保持输入顺序,稀疏空位被忽略。
42
- */
43
- export declare function groupBy<Item, Key>(items: readonly Item[], selectKey: KeySelector<Item, Key>): Map<Key, Item[]>;
44
- /**
45
- * 按谓词把数组拆分为匹配项和非匹配项。
46
- *
47
- * @param items - 不会被修改的输入数组。
48
- * @param predicate - 接收项目与索引的判断函数。
49
- * @returns 二元组:第一项匹配谓词,第二项不匹配;两组都保持原顺序并忽略稀疏空位。
50
- */
51
- export declare function partition<Item>(items: readonly Item[], predicate: (item: Item, index: number) => boolean): [matched: Item[], unmatched: Item[]];
52
- /**
53
- * 返回只出现在左侧数组中的不同值。
54
- *
55
- * @param left - 主输入数组。
56
- * @param right - 需要排除的值。
57
- * @returns 保留左侧首次出现顺序的去重结果;两侧稀疏空位都被忽略。
58
- */
59
- export declare function difference<Item>(left: readonly Item[], right: readonly Item[]): Item[];
60
- /**
61
- * 返回两个数组共有的不同值。
62
- *
63
- * @param left - 决定结果顺序的数组。
64
- * @param right - 用于成员判断的数组。
65
- * @returns 保留左侧首次出现顺序的去重结果;两侧稀疏空位都被忽略。
66
- */
67
- export declare function intersection<Item>(left: readonly Item[], right: readonly Item[]): Item[];
68
- /**
69
- * 返回只存在于其中一个数组的不同值。
70
- *
71
- * @param left - 决定左侧结果顺序的数组。
72
- * @param right - 决定右侧结果顺序的数组。
73
- * @returns 先按左侧、再按右侧首次出现顺序排列的对称差集;使用 SameValueZero 比较并忽略稀疏空位。
74
- */
75
- export declare function symmetricDifference<Item>(left: readonly Item[], right: readonly Item[]): Item[];
76
- /**
77
- * 判断选择器产生的键是否重复。
78
- *
79
- * @param items - 不会被修改的输入数组。
80
- * @param selectKey - 返回比较键的函数;键使用 SameValueZero 语义比较。
81
- * @returns 存在至少一个重复键时返回 `true`。
82
- */
83
- export declare function hasDuplicatesBy<Item, Key>(items: readonly Item[], selectKey: KeySelector<Item, Key>): boolean;
84
- /**
85
- * 判断所有项目是否具有相同的选择器结果。
86
- *
87
- * @remarks 空数组、只有稀疏空位的数组和单项数组按数学惯例返回 `true`;空位不会调用选择器。
88
- * @param items - 不会被修改的输入数组。
89
- * @param selectKey - 返回比较键的函数。
90
- * @returns 所有键都满足 SameValueZero 相等时返回 `true`。
91
- */
92
- export declare function allEqualBy<Item, Key>(items: readonly Item[], selectKey: KeySelector<Item, Key>): boolean;
93
- //#endregion
94
- //# sourceMappingURL=index.d.mts.map
@@ -1,145 +0,0 @@
1
- //#region src/async/index.d.ts
2
- /** 统一同步返回值与 PromiseLike 返回值的内部回调签名。 */
3
- type AsyncCallback<Arguments extends unknown[], Result> = (...arguments_: Arguments) => Result | PromiseLike<Result>;
4
- /** 可接收取消信号的通用选项。 */
5
- export interface AbortOptions {
6
- /** 已取消时立即失败;运行期间取消时停止等待并拒绝 Promise。 */
7
- signal?: AbortSignal;
8
- }
9
- /** {@link withTimeout} 的行为选项。 */
10
- export interface TimeoutOptions extends AbortOptions {
11
- /** 超时时使用的开发者消息。 */
12
- message?: string;
13
- }
14
- /** 每次重试操作接收的上下文。 */
15
- export interface RetryContext {
16
- /** 从 1 开始的当前尝试次数。 */
17
- attempt: number;
18
- /** 调用方提供的取消信号。 */
19
- signal?: AbortSignal;
20
- }
21
- /** {@link retry} 的策略选项。 */
22
- export interface RetryOptions extends AbortOptions {
23
- /** 最大尝试次数,包含首次调用;默认 `3`。 */
24
- attempts?: number;
25
- /** 首次重试前的等待毫秒数,最大 2,147,483,647;默认 `200`。 */
26
- delayMs?: number;
27
- /** 每次失败后的退避倍数,必须不小于 1;默认 `2`。 */
28
- factor?: number;
29
- /** 单次等待上限,最大 2,147,483,647;默认 `30_000` 毫秒。 */
30
- maxDelayMs?: number;
31
- /**
32
- * 决定当前失败后是否继续下一次尝试;默认重试所有尚未到达上限的错误。
33
- * @param error - 当前操作抛出或拒绝的原始值。
34
- * @param context - 当前尝试次数和调用方取消信号。
35
- * @returns `false` 时立即原样抛出当前错误;支持同步值或 PromiseLike。
36
- */
37
- shouldRetry?: (error: unknown, context: RetryContext) => boolean | PromiseLike<boolean>;
38
- }
39
- /** {@link mapConcurrent} 的执行选项。 */
40
- export interface ConcurrentMapOptions {
41
- /** 已取消时停止调度新任务;已经开始的映射器需要自行响应同一信号。 */
42
- signal?: AbortSignal;
43
- }
44
- /** Promise 感知的防抖函数。 */
45
- export interface DebouncedFunction<Arguments extends unknown[], Result> {
46
- /**
47
- * 调度一次调用;同一等待窗口内的调用共享最后一组参数对应的结果。
48
- * @param arguments_ - 传给原始回调的参数;后续调用会覆盖尚未执行批次保存的参数。
49
- * @returns 当前批次的独立 Promise,最终与共享回调结果保持相同状态。
50
- */
51
- (...arguments_: Arguments): Promise<Result>;
52
- /**
53
- * 取消尚未执行的批次,并拒绝该批次的所有 Promise。
54
- * @param reason - 可选拒绝原因;省略时使用内部取消错误。
55
- */
56
- cancel: (reason?: unknown) => void;
57
- /**
58
- * 立即执行待处理批次,不创建第二次回调执行。
59
- * @returns 待处理批次的共享执行 Promise;没有批次时返回 `undefined`。
60
- */
61
- flush: () => Promise<Result> | undefined;
62
- /** @returns 当前存在尚未开始的批次时返回 `true`;正在执行但没有等待批次时返回 `false`。 */
63
- pending: () => boolean;
64
- }
65
- /** Promise 感知的前缘节流函数。 */
66
- export interface ThrottledFunction<Arguments extends unknown[], Result> {
67
- /**
68
- * 在空闲时立即调用原始回调;执行期和冷却期内的调用共享首次调用的 Promise。
69
- * @param arguments_ - 仅窗口内首次调用的参数会传给原始回调。
70
- * @returns 当前执行窗口共享的 Promise。
71
- */
72
- (...arguments_: Arguments): Promise<Result>;
73
- /** 提前结束冷却期;已经开始的操作不会被取消,结束前仍禁止并发重入。 */
74
- cancel: () => void;
75
- /** @returns 原始回调正在执行或计时器仍处于冷却期时返回 `true`。 */
76
- pending: () => boolean;
77
- }
78
- /**
79
- * 等待指定时间,并支持 `AbortSignal`。
80
- *
81
- * @param milliseconds - 0 至 2,147,483,647 的有限毫秒数。
82
- * @param options - 可选取消信号。
83
- * @returns 到期后完成的 Promise。
84
- * @throws 取消时抛出名称为 `AbortError` 的 `Error`;参数非法时抛出 `RangeError`。
85
- */
86
- export declare function sleep(milliseconds: number, options?: AbortOptions): Promise<void>;
87
- /**
88
- * 为 Promise 增加等待上限。
89
- *
90
- * @remarks 超时或取消只停止等待,不能自动取消底层操作;需要真正取消时应同时把
91
- * 同一个 `AbortSignal` 传给底层 API。
92
- * @param promise - 需要等待的 Promise 或 PromiseLike。
93
- * @param timeoutMs - 0 至 2,147,483,647 的有限等待时间。
94
- * @param options - 取消信号与自定义消息。
95
- * @returns 底层 Promise 的结果。
96
- * @throws 超时抛出 `Error`,取消时抛出名称为 `AbortError` 的 `Error`;等待时间非法时抛出 `RangeError`。
97
- */
98
- export declare function withTimeout<Result>(promise: PromiseLike<Result>, timeoutMs: number, options?: TimeoutOptions): Promise<Result>;
99
- /**
100
- * 使用有上限的指数退避重试操作。
101
- *
102
- * @typeParam Result - 操作结果类型。
103
- * @param operation - 每次尝试都会调用的函数;`attempt` 从 1 开始。
104
- * @param options - 尝试次数、退避和取消策略。
105
- * @returns 首次成功结果。
106
- * @throws 最后一次操作错误、`shouldRetry` 错误或名称为 `AbortError` 的取消错误;策略参数非法时抛出 `RangeError`。
107
- */
108
- export declare function retry<Result>(operation: (context: RetryContext) => Result | PromiseLike<Result>, options?: RetryOptions): Promise<Awaited<Result>>;
109
- /**
110
- * 以固定并发度映射数组,并保持结果顺序。
111
- *
112
- * @remarks 任一映射失败后不会再调度新项目,但已经开始的映射无法自动取消;映射器
113
- * 应使用传入的 `signal` 取消底层工作。
114
- * @param items - 不会被修改的输入数组。
115
- * @param concurrency - 同时运行的最大任务数,必须为正安全整数。
116
- * @param mapper - 接收项目、索引和取消信号的映射函数。
117
- * @param options - 可选取消信号。
118
- * @returns 与输入长度和顺序一致的结果数组;稀疏空位保持为空位且不会调用映射器。
119
- * @throws `RangeError` 当 `concurrency` 不是正安全整数;取消时抛出名称为 `AbortError` 的 `Error`。
120
- */
121
- export declare function mapConcurrent<Item, Result>(items: readonly Item[], concurrency: number, mapper: (item: Item, index: number, signal: AbortSignal | undefined) => Result | PromiseLike<Result>, options?: ConcurrentMapOptions): Promise<Awaited<Result>[]>;
122
- /**
123
- * 创建 Promise 感知的防抖函数。
124
- *
125
- * @remarks 同一窗口内的所有调用都会等待最后一组参数对应的执行结果;回调错误会原样
126
- * 拒绝该批次的全部调用,不会留下永久 pending 的 Promise。
127
- * @param callback - 同步或异步回调。
128
- * @param delayMs - 0 至 2,147,483,647 的有限等待时间,默认 300 毫秒。
129
- * @returns 具有取消、立即执行和状态方法的防抖函数。
130
- * @throws `RangeError` 当延迟不在平台计时器支持范围内。
131
- */
132
- export declare function debounce<Arguments extends unknown[], Result>(callback: AsyncCallback<Arguments, Result>, delayMs?: number): DebouncedFunction<Arguments, Awaited<Result>>;
133
- /**
134
- * 创建 Promise 感知的前缘节流函数。
135
- *
136
- * @remarks 窗口内的调用共享首次调用结果。若回调执行时间超过窗口,后续调用仍会等待
137
- * 当前回调,避免异步操作重入;该函数不安排尾缘调用。
138
- * @param callback - 同步或异步回调。
139
- * @param delayMs - 0 至 2,147,483,647 的有限冷却时间,默认 300 毫秒。
140
- * @returns 具有取消和状态方法的前缘节流函数。
141
- * @throws `RangeError` 当延迟不在平台计时器支持范围内。
142
- */
143
- export declare function throttle<Arguments extends unknown[], Result>(callback: AsyncCallback<Arguments, Result>, delayMs?: number): ThrottledFunction<Arguments, Awaited<Result>>;
144
- //#endregion
145
- //# sourceMappingURL=index.d.mts.map