@fast-china/utils 2.1.10 → 2.1.11

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 (70) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +5 -2
  3. package/README.zh.md +5 -2
  4. package/dist/array/index.mjs +21 -21
  5. package/dist/array/index.mjs.map +1 -1
  6. package/dist/async/index.mjs +32 -32
  7. package/dist/async/index.mjs.map +1 -1
  8. package/dist/base64/index.mjs +44 -51
  9. package/dist/base64/index.mjs.map +1 -1
  10. package/dist/color/index.mjs +33 -33
  11. package/dist/color/index.mjs.map +1 -1
  12. package/dist/crypto/index.mjs +153 -155
  13. package/dist/crypto/index.mjs.map +1 -1
  14. package/dist/date/index.mjs +79 -46
  15. package/dist/date/index.mjs.map +1 -1
  16. package/dist/dom/style.mjs +7 -7
  17. package/dist/dom/style.mjs.map +1 -1
  18. package/dist/env/index.mjs +9 -14
  19. package/dist/env/index.mjs.map +1 -1
  20. package/dist/function/index.mjs +4 -4
  21. package/dist/function/index.mjs.map +1 -1
  22. package/dist/identity/index.mjs +7 -7
  23. package/dist/identity/index.mjs.map +1 -1
  24. package/dist/index.d.mts +371 -366
  25. package/dist/index.global.min.js +2 -2
  26. package/dist/index.global.min.js.map +1 -1
  27. package/dist/internal/text.mjs +70 -26
  28. package/dist/internal/text.mjs.map +1 -1
  29. package/dist/logger/index.mjs +12 -13
  30. package/dist/logger/index.mjs.map +1 -1
  31. package/dist/number/index.mjs +63 -42
  32. package/dist/number/index.mjs.map +1 -1
  33. package/dist/object/index.mjs +32 -31
  34. package/dist/object/index.mjs.map +1 -1
  35. package/dist/storage/index.mjs +58 -63
  36. package/dist/storage/index.mjs.map +1 -1
  37. package/dist/string/index.mjs +60 -64
  38. package/dist/string/index.mjs.map +1 -1
  39. package/dist/vue/breakpoints.mjs +14 -10
  40. package/dist/vue/breakpoints.mjs.map +1 -1
  41. package/dist/vue/element-size.mjs +4 -4
  42. package/dist/vue/element-size.mjs.map +1 -1
  43. package/dist/vue/emits.mjs +7 -7
  44. package/dist/vue/emits.mjs.map +1 -1
  45. package/dist/vue/event-listener.mjs +5 -5
  46. package/dist/vue/event-listener.mjs.map +1 -1
  47. package/dist/vue/expose.mjs +3 -3
  48. package/dist/vue/expose.mjs.map +1 -1
  49. package/dist/vue/func.mjs +2 -2
  50. package/dist/vue/func.mjs.map +1 -1
  51. package/dist/vue/install.mjs +24 -24
  52. package/dist/vue/install.mjs.map +1 -1
  53. package/dist/vue/now.mjs +4 -5
  54. package/dist/vue/now.mjs.map +1 -1
  55. package/dist/vue/props.mjs +5 -5
  56. package/dist/vue/props.mjs.map +1 -1
  57. package/dist/vue/render.mjs +2 -2
  58. package/dist/vue/render.mjs.map +1 -1
  59. package/dist/vue/resize-observer.mjs +4 -6
  60. package/dist/vue/resize-observer.mjs.map +1 -1
  61. package/dist/vue/slots.mjs.map +1 -1
  62. package/dist/vue/transition.mjs +5 -7
  63. package/dist/vue/transition.mjs.map +1 -1
  64. package/dist/vue/window-size.mjs +2 -4
  65. package/dist/vue/window-size.mjs.map +1 -1
  66. package/dist/vue/with.mjs +1 -1
  67. package/dist/vue/with.mjs.map +1 -1
  68. package/package.json +2 -1
  69. package/dist/internal/runtime.mjs +0 -32
  70. package/dist/internal/runtime.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/function/index.ts"],"sourcesContent":["/** 函数首次调用前的内部状态。 */\ninterface PendingOnceState {\n\treadonly status: \"pending\";\n}\n\n/** 函数成功返回后的内部状态。 */\ninterface ReturnedOnceState<Result> {\n\treadonly status: \"returned\";\n\treadonly value: Result;\n}\n\n/** 函数同步抛错后的内部状态。 */\ninterface ThrewOnceState {\n\treadonly error: unknown;\n\treadonly status: \"threw\";\n}\n\n/** 首次调用尚未返回的内部状态 */\ninterface RunningOnceState {\n\treadonly status: \"running\";\n}\n\ntype OnceState<Result> = PendingOnceState | RunningOnceState | ReturnedOnceState<Result> | ThrewOnceState;\n\n/**\n * 创建最多执行一次并缓存首次结果的函数。\n *\n * @remarks 首次成功返回后,后续调用返回同一结果;Promise 会保持引用不变。首次同步抛错时缓存错误,后续调用重新抛出同一错误。\n * 包装函数使用首次调用时的参数和 `this`,之后传入的参数不会再次执行原函数。\n * 首次调用尚未返回时同步重入会抛出 `Error`,不会重复执行原函数;该错误如向外传播,会作为首次错误缓存。\n * @param callback - 只允许执行一次的函数。\n * @returns 保持原参数与返回类型的包装函数。\n * @throws `TypeError` 当 `callback` 不是函数。\n */\nexport function once<This, Arguments extends unknown[], Result>(\n\tcallback: (this: This, ...arguments_: Arguments) => Result\n): (this: This, ...arguments_: Arguments) => Result {\n\tif (typeof callback !== \"function\") throw new TypeError(\"`callback` 必须是函数。\");\n\tlet state: OnceState<Result> = { status: \"pending\" };\n\treturn function (this: This, ...arguments_: Arguments): Result {\n\t\tswitch (state.status) {\n\t\t\tcase \"returned\":\n\t\t\t\treturn state.value;\n\t\t\tcase \"threw\":\n\t\t\t\tthrow state.error;\n\t\t\tcase \"running\":\n\t\t\t\tthrow new Error(\"`once` 回调尚未返回,不能同步重入。\");\n\t\t\tcase \"pending\":\n\t\t\t\tstate = { status: \"running\" };\n\t\t\t\ttry {\n\t\t\t\t\tconst value = callback.apply(this, arguments_);\n\t\t\t\t\tstate = { status: \"returned\", value };\n\t\t\t\t\treturn value;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tstate = { error, status: \"threw\" };\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t}\n\t};\n}\n"],"mappings":";;;;;;;;;;;AAkCA,SAAgB,KACf,UACmD;CACnD,IAAI,OAAO,aAAa,YAAY,MAAM,IAAI,UAAU,mBAAmB;CAC3E,IAAI,QAA2B,EAAE,QAAQ,UAAU;CACnD,OAAO,SAAsB,GAAG,YAA+B;EAC9D,QAAQ,MAAM,QAAd;GACC,KAAK,YACJ,OAAO,MAAM;GACd,KAAK,SACJ,MAAM,MAAM;GACb,KAAK,WACJ,MAAM,IAAI,MAAM,uBAAuB;GACxC,KAAK;IACJ,QAAQ,EAAE,QAAQ,UAAU;IAC5B,IAAI;KACH,MAAM,QAAQ,SAAS,MAAM,MAAM,UAAU;KAC7C,QAAQ;MAAE,QAAQ;MAAY;KAAM;KACpC,OAAO;IACR,SAAS,OAAO;KACf,QAAQ;MAAE;MAAO,QAAQ;KAAQ;KACjC,MAAM;IACP;EACF;CACD;AACD"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/function/index.ts"],"sourcesContent":["/** 函数首次调用前的内部状态 */\ninterface PendingOnceState {\n\treadonly status: \"pending\";\n}\n\n/** 函数成功返回后的内部状态。 */\ninterface ReturnedOnceState<Result> {\n\treadonly status: \"returned\";\n\treadonly value: Result;\n}\n\n/** 函数同步抛错后的内部状态 */\ninterface ThrewOnceState {\n\treadonly error: unknown;\n\treadonly status: \"threw\";\n}\n\n/** 首次调用尚未返回的内部状态 */\ninterface RunningOnceState {\n\treadonly status: \"running\";\n}\n\ntype OnceState<Result> = PendingOnceState | RunningOnceState | ReturnedOnceState<Result> | ThrewOnceState;\n\n/**\n * 创建最多执行一次并缓存首次结果的函数。\n *\n * @remarks 首次成功返回后,后续调用返回同一结果;Promise 会保持引用不变。首次同步抛错时缓存错误,后续调用重新抛出同一错误。\n * 包装函数使用首次调用时的参数和 `this`,之后传入的参数不会再次执行原函数。\n * 首次调用尚未返回时同步重入会抛出 `Error`,不会重复执行原函数;该错误如向外传播,会作为首次错误缓存。\n * @param callback - 只允许执行一次的函数\n * @returns 保持原参数与返回类型的包装函数\n * @throws `TypeError` 当 `callback` 不是函数。\n */\nexport function once<This, Arguments extends unknown[], Result>(\n\tcallback: (this: This, ...arguments_: Arguments) => Result\n): (this: This, ...arguments_: Arguments) => Result {\n\tif (typeof callback !== \"function\") throw new TypeError(\"`callback` must be a function.\");\n\tlet state: OnceState<Result> = { status: \"pending\" };\n\treturn function (this: This, ...arguments_: Arguments): Result {\n\t\tswitch (state.status) {\n\t\t\tcase \"returned\":\n\t\t\t\treturn state.value;\n\t\t\tcase \"threw\":\n\t\t\t\tthrow state.error;\n\t\t\tcase \"running\":\n\t\t\t\tthrow new Error(\"The `once` callback has not returned and cannot be reentered synchronously.\");\n\t\t\tcase \"pending\":\n\t\t\t\tstate = { status: \"running\" };\n\t\t\t\ttry {\n\t\t\t\t\tconst value = callback.apply(this, arguments_);\n\t\t\t\t\tstate = { status: \"returned\", value };\n\t\t\t\t\treturn value;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tstate = { error, status: \"threw\" };\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t}\n\t};\n}\n"],"mappings":";;;;;;;;;;;AAkCA,SAAgB,KACf,UACmD;CACnD,IAAI,OAAO,aAAa,YAAY,MAAM,IAAI,UAAU,gCAAgC;CACxF,IAAI,QAA2B,EAAE,QAAQ,UAAU;CACnD,OAAO,SAAsB,GAAG,YAA+B;EAC9D,QAAQ,MAAM,QAAd;GACC,KAAK,YACJ,OAAO,MAAM;GACd,KAAK,SACJ,MAAM,MAAM;GACb,KAAK,WACJ,MAAM,IAAI,MAAM,6EAA6E;GAC9F,KAAK;IACJ,QAAQ,EAAE,QAAQ,UAAU;IAC5B,IAAI;KACH,MAAM,QAAQ,SAAS,MAAM,MAAM,UAAU;KAC7C,QAAQ;MAAE,QAAQ;MAAY;KAAM;KACpC,OAAO;IACR,SAAS,OAAO;KACf,QAAQ;MAAE;MAAO,QAAQ;KAAQ;KACjC,MAAM;IACP;EACF;CACD;AACD"}
@@ -5,18 +5,18 @@ const defaultInstallationIdentityStorageKey = "identity:installation-id";
5
5
  /**
6
6
  * 校验安装标识格式。
7
7
  *
8
- * @param value - 外部传入或从 Storage 读取的候选值。
8
+ * @param value - 外部传入或从 Storage 读取的候选值
9
9
  * @throws `TypeError` 当值不是 RFC 4122 UUID v4。
10
10
  */
11
11
  const assertInstallationId = (value) => {
12
- if (!isUuidV4(value)) throw new TypeError("安装标识值必须是符合 RFC 4122 的 UUID v4。");
12
+ if (!isUuidV4(value)) throw new TypeError("The installation identity must be an RFC 4122 UUID v4.");
13
13
  };
14
14
  let activeStorageKey;
15
15
  /**
16
16
  * 取得已经锁定的安装标识业务键。
17
17
  *
18
18
  * @remarks 首次读取会锁定默认值,防止标识已经写入后再切换键而产生两个安装标识。
19
- * @returns 应用于后续全部 Identity 操作的业务键。
19
+ * @returns 应用于后续全部 Identity 操作的业务键
20
20
  */
21
21
  const getInstallationIdentityStorageKey = () => {
22
22
  activeStorageKey ??= defaultInstallationIdentityStorageKey;
@@ -33,12 +33,12 @@ const getInstallationIdentityStorageKey = () => {
33
33
  */
34
34
  function configureInstallationIdentity(options = {}) {
35
35
  const cacheKey = options.cacheKey ?? defaultInstallationIdentityStorageKey;
36
- if (typeof cacheKey !== "string" || cacheKey.length === 0 || cacheKey.trim() !== cacheKey) throw new TypeError("安装标识的 `cacheKey` 必须是无外围空白的非空字符串。");
36
+ if (typeof cacheKey !== "string" || cacheKey.length === 0 || cacheKey.trim() !== cacheKey) throw new TypeError("The installation identity `cacheKey` must be a nonempty string without surrounding whitespace.");
37
37
  if (activeStorageKey === void 0) {
38
38
  activeStorageKey = cacheKey;
39
39
  return;
40
40
  }
41
- if (activeStorageKey !== cacheKey) throw new Error("安装标识已使用其他 `cacheKey` 完成配置。");
41
+ if (activeStorageKey !== cacheKey) throw new Error("The installation identity is already configured with a different `cacheKey`.");
42
42
  }
43
43
  /**
44
44
  * 全局安装标识状态。
@@ -65,7 +65,7 @@ const installationIdentity = {
65
65
  read() {
66
66
  const stored = Local.get(installationIdentity.cacheKey);
67
67
  if (stored === void 0) return void 0;
68
- if (typeof stored !== "string") throw new TypeError("存储的安装标识已损坏。");
68
+ if (typeof stored !== "string") throw new TypeError("The stored installation identity is corrupted.");
69
69
  assertInstallationId(stored);
70
70
  return stored;
71
71
  }
@@ -74,7 +74,7 @@ const installationIdentity = {
74
74
  * 返回已有安装标识,否则创建并持久化一个 UUID v4。
75
75
  *
76
76
  * @param installationId - 可选的显式安装标识;传入时会校验并覆盖当前持久化值。
77
- * @returns 显式值、内存值、持久化值或新生成值中的最终安装标识。
77
+ * @returns 显式值、内存值、持久化值或新生成值中的最终安装标识
78
78
  * @throws `TypeError` 当显式值或持久化值不是 UUID v4。
79
79
  * @throws `Error` 当当前平台存储不可用。
80
80
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/identity/index.ts"],"sourcesContent":["import { Local } from \"../storage/index\";\nimport { generateUuidV4, isUuidV4 } from \"../string/index\";\n\nconst defaultInstallationIdentityStorageKey = \"identity:installation-id\";\n\n/** {@link configureInstallationIdentity} 接收的安装标识配置。 */\nexport interface InstallationIdentityConfiguration {\n\t/**\n\t * `Local` 中使用的业务键,默认 `identity:installation-id`。\n\t *\n\t * @remarks 必须是无外围空白的非空字符串,并在首次访问 Identity API 前配置;物理键仍会叠加 Storage 全局前缀。\n\t */\n\tcacheKey?: string;\n}\n\n/** 浏览器或 uni-app 当前安装实例标识。 */\nexport interface InstallationIdentity {\n\t/**\n\t * `Local` 中使用的业务键。\n\t *\n\t * @remarks 首次读取会锁定默认配置;之后不能再切换为其他业务键。\n\t */\n\treadonly cacheKey: string;\n\t/**\n\t * 当前内存中的安装标识;尚未取得标识或调用 {@link InstallationIdentity.clear clear} 后为空字符串。\n\t *\n\t * @remarks 直接赋值只改变内存,不会校验或持久化;通常应调用 {@link InstallationIdentity.getOrCreate getOrCreate}。\n\t */\n\tdeviceId: string;\n\t/**\n\t * 删除当前 `cacheKey` 对应的持久化标识,并把 `deviceId` 重置为空字符串。\n\t *\n\t * @throws `Error` 当当前平台存储不可用。\n\t */\n\tclear: () => void;\n\t/**\n\t * 按“显式参数、当前内存、持久化值、随机生成值”的优先级取得安装标识。\n\t *\n\t * @param installationId - 可选 UUID v4;传入时覆盖内存值和当前持久化值。\n\t * @returns 已校验并同时写入 `deviceId` 与 `Local` 的 UUID v4。\n\t * @throws `TypeError` 当显式参数、内存值或持久化值不是 UUID v4。\n\t * @throws `Error` 当当前平台存储不可用。\n\t */\n\tgetOrCreate: (installationId?: string) => string;\n\t/**\n\t * 读取并校验当前 `cacheKey` 对应的持久化标识。\n\t *\n\t * @remarks 该方法不修改 `deviceId`,只负责读取;过期记录由 Storage 视为缺失。\n\t * @returns 已持久化的 UUID v4;键缺失或过期时返回 `undefined`。\n\t * @throws `TypeError` 当持久化值不是字符串或不是 UUID v4。\n\t * @throws `Error` 当当前平台存储不可用。\n\t */\n\tread: () => string | undefined;\n}\n\n/**\n * 校验安装标识格式。\n *\n * @param value - 外部传入或从 Storage 读取的候选值。\n * @throws `TypeError` 当值不是 RFC 4122 UUID v4。\n */\nconst assertInstallationId = (value: string): void => {\n\tif (!isUuidV4(value)) throw new TypeError(\"安装标识值必须是符合 RFC 4122 的 UUID v4。\");\n};\n\nlet activeStorageKey: string | undefined;\n\n/**\n * 取得已经锁定的安装标识业务键。\n *\n * @remarks 首次读取会锁定默认值,防止标识已经写入后再切换键而产生两个安装标识。\n * @returns 应用于后续全部 Identity 操作的业务键。\n */\nconst getInstallationIdentityStorageKey = (): string => {\n\tactiveStorageKey ??= defaultInstallationIdentityStorageKey;\n\treturn activeStorageKey;\n};\n\n/**\n * 在应用入口配置安装标识使用的 Storage 业务键。\n *\n * @remarks 必须在首次读取 `installationIdentity.cacheKey` 或调用其他安装标识 API 前执行。相同配置\n * 可以幂等重复调用;切换到不同键会抛错,避免同一页面产生分裂状态。\n * @param options - 安装标识配置;省略 `cacheKey` 时使用 `identity:installation-id`。\n * @throws `TypeError` 当 `cacheKey` 不是非空字符串或包含外围空白。\n * @throws `Error` 当安装标识已经使用另一个业务键初始化。\n */\nexport function configureInstallationIdentity(options: InstallationIdentityConfiguration = {}): void {\n\tconst cacheKey = options.cacheKey ?? defaultInstallationIdentityStorageKey;\n\tif (typeof cacheKey !== \"string\" || cacheKey.length === 0 || cacheKey.trim() !== cacheKey) {\n\t\tthrow new TypeError(\"安装标识的 `cacheKey` 必须是无外围空白的非空字符串。\");\n\t}\n\tif (activeStorageKey === undefined) {\n\t\tactiveStorageKey = cacheKey;\n\t\treturn;\n\t}\n\tif (activeStorageKey !== cacheKey) throw new Error(\"安装标识已使用其他 `cacheKey` 完成配置。\");\n}\n\n/**\n * 全局安装标识状态。\n *\n * @remarks Storage 未显式配置时会使用其默认值。生成 UUID 时优先使用 Web Crypto,能力缺失时\n * 回退到 `Math.random()`。该值不是硬件标识、认证凭证或安全边界。\n */\nexport const installationIdentity: InstallationIdentity = {\n\tget cacheKey(): string {\n\t\treturn getInstallationIdentityStorageKey();\n\t},\n\tdeviceId: \"\",\n\tclear(): void {\n\t\tLocal.remove(installationIdentity.cacheKey);\n\t\tinstallationIdentity.deviceId = \"\";\n\t},\n\tgetOrCreate(installationId?: string): string {\n\t\tconst candidate =\n\t\t\tinstallationId ??\n\t\t\t(installationIdentity.deviceId.length > 0 ? installationIdentity.deviceId : installationIdentity.read()) ??\n\t\t\tgenerateUuidV4();\n\t\tassertInstallationId(candidate);\n\t\tLocal.set(installationIdentity.cacheKey, candidate);\n\t\tinstallationIdentity.deviceId = candidate;\n\t\treturn candidate;\n\t},\n\tread(): string | undefined {\n\t\tconst stored = Local.get(installationIdentity.cacheKey);\n\t\tif (stored === undefined) return undefined;\n\t\tif (typeof stored !== \"string\") throw new TypeError(\"存储的安装标识已损坏。\");\n\t\tassertInstallationId(stored);\n\t\treturn stored;\n\t},\n};\n\n/**\n * 返回已有安装标识,否则创建并持久化一个 UUID v4。\n *\n * @param installationId - 可选的显式安装标识;传入时会校验并覆盖当前持久化值。\n * @returns 显式值、内存值、持久化值或新生成值中的最终安装标识。\n * @throws `TypeError` 当显式值或持久化值不是 UUID v4。\n * @throws `Error` 当当前平台存储不可用。\n */\nexport function getOrCreateInstallationId(installationId?: string): string {\n\treturn installationIdentity.getOrCreate(installationId);\n}\n"],"mappings":";;;AAGA,MAAM,wCAAwC;;;;;;;AA0D9C,MAAM,wBAAwB,UAAwB;CACrD,IAAI,CAAC,SAAS,KAAK,GAAG,MAAM,IAAI,UAAU,gCAAgC;AAC3E;AAEA,IAAI;;;;;;;AAQJ,MAAM,0CAAkD;CACvD,qBAAqB;CACrB,OAAO;AACR;;;;;;;;;;AAWA,SAAgB,8BAA8B,UAA6C,CAAC,GAAS;CACpG,MAAM,WAAW,QAAQ,YAAY;CACrC,IAAI,OAAO,aAAa,YAAY,SAAS,WAAW,KAAK,SAAS,KAAK,MAAM,UAChF,MAAM,IAAI,UAAU,kCAAkC;CAEvD,IAAI,qBAAqB,KAAA,GAAW;EACnC,mBAAmB;EACnB;CACD;CACA,IAAI,qBAAqB,UAAU,MAAM,IAAI,MAAM,4BAA4B;AAChF;;;;;;;AAQA,MAAa,uBAA6C;CACzD,IAAI,WAAmB;EACtB,OAAO,kCAAkC;CAC1C;CACA,UAAU;CACV,QAAc;EACb,MAAM,OAAO,qBAAqB,QAAQ;EAC1C,qBAAqB,WAAW;CACjC;CACA,YAAY,gBAAiC;EAC5C,MAAM,YACL,mBACC,qBAAqB,SAAS,SAAS,IAAI,qBAAqB,WAAW,qBAAqB,KAAK,MACtG,eAAe;EAChB,qBAAqB,SAAS;EAC9B,MAAM,IAAI,qBAAqB,UAAU,SAAS;EAClD,qBAAqB,WAAW;EAChC,OAAO;CACR;CACA,OAA2B;EAC1B,MAAM,SAAS,MAAM,IAAI,qBAAqB,QAAQ;EACtD,IAAI,WAAW,KAAA,GAAW,OAAO,KAAA;EACjC,IAAI,OAAO,WAAW,UAAU,MAAM,IAAI,UAAU,aAAa;EACjE,qBAAqB,MAAM;EAC3B,OAAO;CACR;AACD;;;;;;;;;AAUA,SAAgB,0BAA0B,gBAAiC;CAC1E,OAAO,qBAAqB,YAAY,cAAc;AACvD"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/identity/index.ts"],"sourcesContent":["import { Local } from \"../storage/index\";\nimport { generateUuidV4, isUuidV4 } from \"../string/index\";\n\nconst defaultInstallationIdentityStorageKey = \"identity:installation-id\";\n\n/** {@link configureInstallationIdentity} 接收的安装标识配置 */\nexport interface InstallationIdentityConfiguration {\n\t/**\n\t * `Local` 中使用的业务键,默认 `identity:installation-id`。\n\t *\n\t * @remarks 必须是无外围空白的非空字符串,并在首次访问 Identity API 前配置;物理键仍会叠加 Storage 全局前缀。\n\t */\n\tcacheKey?: string;\n}\n\n/** 浏览器或 uni-app 当前安装实例标识 */\nexport interface InstallationIdentity {\n\t/**\n\t * `Local` 中使用的业务键。\n\t *\n\t * @remarks 首次读取会锁定默认配置;之后不能再切换为其他业务键。\n\t */\n\treadonly cacheKey: string;\n\t/**\n\t * 当前内存中的安装标识;尚未取得标识或调用 {@link InstallationIdentity.clear clear} 后为空字符串。\n\t *\n\t * @remarks 直接赋值只改变内存,不会校验或持久化;通常应调用 {@link InstallationIdentity.getOrCreate getOrCreate}。\n\t */\n\tdeviceId: string;\n\t/**\n\t * 删除当前 `cacheKey` 对应的持久化标识,并把 `deviceId` 重置为空字符串。\n\t *\n\t * @throws `Error` 当当前平台存储不可用。\n\t */\n\tclear: () => void;\n\t/**\n\t * 按“显式参数、当前内存、持久化值、随机生成值”的优先级取得安装标识。\n\t *\n\t * @param installationId - 可选 UUID v4;传入时覆盖内存值和当前持久化值。\n\t * @returns 已校验并同时写入 `deviceId` 与 `Local` 的 UUID v4。\n\t * @throws `TypeError` 当显式参数、内存值或持久化值不是 UUID v4。\n\t * @throws `Error` 当当前平台存储不可用。\n\t */\n\tgetOrCreate: (installationId?: string) => string;\n\t/**\n\t * 读取并校验当前 `cacheKey` 对应的持久化标识。\n\t *\n\t * @remarks 该方法不修改 `deviceId`,只负责读取;过期记录由 Storage 视为缺失。\n\t * @returns 已持久化的 UUID v4;键缺失或过期时返回 `undefined`。\n\t * @throws `TypeError` 当持久化值不是字符串或不是 UUID v4。\n\t * @throws `Error` 当当前平台存储不可用。\n\t */\n\tread: () => string | undefined;\n}\n\n/**\n * 校验安装标识格式。\n *\n * @param value - 外部传入或从 Storage 读取的候选值\n * @throws `TypeError` 当值不是 RFC 4122 UUID v4。\n */\nconst assertInstallationId = (value: string): void => {\n\tif (!isUuidV4(value)) throw new TypeError(\"The installation identity must be an RFC 4122 UUID v4.\");\n};\n\nlet activeStorageKey: string | undefined;\n\n/**\n * 取得已经锁定的安装标识业务键。\n *\n * @remarks 首次读取会锁定默认值,防止标识已经写入后再切换键而产生两个安装标识。\n * @returns 应用于后续全部 Identity 操作的业务键\n */\nconst getInstallationIdentityStorageKey = (): string => {\n\tactiveStorageKey ??= defaultInstallationIdentityStorageKey;\n\treturn activeStorageKey;\n};\n\n/**\n * 在应用入口配置安装标识使用的 Storage 业务键。\n *\n * @remarks 必须在首次读取 `installationIdentity.cacheKey` 或调用其他安装标识 API 前执行。相同配置\n * 可以幂等重复调用;切换到不同键会抛错,避免同一页面产生分裂状态。\n * @param options - 安装标识配置;省略 `cacheKey` 时使用 `identity:installation-id`。\n * @throws `TypeError` 当 `cacheKey` 不是非空字符串或包含外围空白。\n * @throws `Error` 当安装标识已经使用另一个业务键初始化。\n */\nexport function configureInstallationIdentity(options: InstallationIdentityConfiguration = {}): void {\n\tconst cacheKey = options.cacheKey ?? defaultInstallationIdentityStorageKey;\n\tif (typeof cacheKey !== \"string\" || cacheKey.length === 0 || cacheKey.trim() !== cacheKey) {\n\t\tthrow new TypeError(\"The installation identity `cacheKey` must be a nonempty string without surrounding whitespace.\");\n\t}\n\tif (activeStorageKey === undefined) {\n\t\tactiveStorageKey = cacheKey;\n\t\treturn;\n\t}\n\tif (activeStorageKey !== cacheKey) throw new Error(\"The installation identity is already configured with a different `cacheKey`.\");\n}\n\n/**\n * 全局安装标识状态。\n *\n * @remarks Storage 未显式配置时会使用其默认值。生成 UUID 时优先使用 Web Crypto,能力缺失时\n * 回退到 `Math.random()`。该值不是硬件标识、认证凭证或安全边界。\n */\nexport const installationIdentity: InstallationIdentity = {\n\tget cacheKey(): string {\n\t\treturn getInstallationIdentityStorageKey();\n\t},\n\tdeviceId: \"\",\n\tclear(): void {\n\t\tLocal.remove(installationIdentity.cacheKey);\n\t\tinstallationIdentity.deviceId = \"\";\n\t},\n\tgetOrCreate(installationId?: string): string {\n\t\tconst candidate =\n\t\t\tinstallationId ??\n\t\t\t(installationIdentity.deviceId.length > 0 ? installationIdentity.deviceId : installationIdentity.read()) ??\n\t\t\tgenerateUuidV4();\n\t\tassertInstallationId(candidate);\n\t\tLocal.set(installationIdentity.cacheKey, candidate);\n\t\tinstallationIdentity.deviceId = candidate;\n\t\treturn candidate;\n\t},\n\tread(): string | undefined {\n\t\tconst stored = Local.get(installationIdentity.cacheKey);\n\t\tif (stored === undefined) return undefined;\n\t\tif (typeof stored !== \"string\") throw new TypeError(\"The stored installation identity is corrupted.\");\n\t\tassertInstallationId(stored);\n\t\treturn stored;\n\t},\n};\n\n/**\n * 返回已有安装标识,否则创建并持久化一个 UUID v4。\n *\n * @param installationId - 可选的显式安装标识;传入时会校验并覆盖当前持久化值。\n * @returns 显式值、内存值、持久化值或新生成值中的最终安装标识\n * @throws `TypeError` 当显式值或持久化值不是 UUID v4。\n * @throws `Error` 当当前平台存储不可用。\n */\nexport function getOrCreateInstallationId(installationId?: string): string {\n\treturn installationIdentity.getOrCreate(installationId);\n}\n"],"mappings":";;;AAGA,MAAM,wCAAwC;;;;;;;AA0D9C,MAAM,wBAAwB,UAAwB;CACrD,IAAI,CAAC,SAAS,KAAK,GAAG,MAAM,IAAI,UAAU,wDAAwD;AACnG;AAEA,IAAI;;;;;;;AAQJ,MAAM,0CAAkD;CACvD,qBAAqB;CACrB,OAAO;AACR;;;;;;;;;;AAWA,SAAgB,8BAA8B,UAA6C,CAAC,GAAS;CACpG,MAAM,WAAW,QAAQ,YAAY;CACrC,IAAI,OAAO,aAAa,YAAY,SAAS,WAAW,KAAK,SAAS,KAAK,MAAM,UAChF,MAAM,IAAI,UAAU,gGAAgG;CAErH,IAAI,qBAAqB,KAAA,GAAW;EACnC,mBAAmB;EACnB;CACD;CACA,IAAI,qBAAqB,UAAU,MAAM,IAAI,MAAM,8EAA8E;AAClI;;;;;;;AAQA,MAAa,uBAA6C;CACzD,IAAI,WAAmB;EACtB,OAAO,kCAAkC;CAC1C;CACA,UAAU;CACV,QAAc;EACb,MAAM,OAAO,qBAAqB,QAAQ;EAC1C,qBAAqB,WAAW;CACjC;CACA,YAAY,gBAAiC;EAC5C,MAAM,YACL,mBACC,qBAAqB,SAAS,SAAS,IAAI,qBAAqB,WAAW,qBAAqB,KAAK,MACtG,eAAe;EAChB,qBAAqB,SAAS;EAC9B,MAAM,IAAI,qBAAqB,UAAU,SAAS;EAClD,qBAAqB,WAAW;EAChC,OAAO;CACR;CACA,OAA2B;EAC1B,MAAM,SAAS,MAAM,IAAI,qBAAqB,QAAQ;EACtD,IAAI,WAAW,KAAA,GAAW,OAAO,KAAA;EACjC,IAAI,OAAO,WAAW,UAAU,MAAM,IAAI,UAAU,gDAAgD;EACpG,qBAAqB,MAAM;EAC3B,OAAO;CACR;AACD;;;;;;;;;AAUA,SAAgB,0BAA0B,gBAAiC;CAC1E,OAAO,qBAAqB,YAAY,cAAc;AACvD"}