@fast-china/utils 1.0.37 → 2.0.0

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 (286) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/CONTRIBUTING.md +87 -0
  3. package/README.md +111 -50
  4. package/README.zh.md +111 -50
  5. package/SECURITY.md +46 -0
  6. package/dist/array/index.d.mts +87 -0
  7. package/dist/array/index.d.mts.map +1 -0
  8. package/dist/array/index.mjs +161 -0
  9. package/dist/array/index.mjs.map +1 -0
  10. package/dist/async/index.d.mts +146 -0
  11. package/dist/async/index.d.mts.map +1 -0
  12. package/dist/async/index.mjs +336 -0
  13. package/dist/async/index.mjs.map +1 -0
  14. package/dist/base64/index.d.mts +105 -0
  15. package/dist/base64/index.d.mts.map +1 -0
  16. package/dist/base64/index.mjs +427 -0
  17. package/dist/base64/index.mjs.map +1 -0
  18. package/dist/color/index.d.mts +90 -0
  19. package/dist/color/index.d.mts.map +1 -0
  20. package/dist/color/index.mjs +178 -0
  21. package/dist/color/index.mjs.map +1 -0
  22. package/dist/crypto/index.d.mts +157 -0
  23. package/dist/crypto/index.d.mts.map +1 -0
  24. package/dist/crypto/index.mjs +541 -0
  25. package/dist/crypto/index.mjs.map +1 -0
  26. package/dist/date/index.d.mts +191 -0
  27. package/dist/date/index.d.mts.map +1 -0
  28. package/dist/date/index.mjs +383 -0
  29. package/dist/date/index.mjs.map +1 -0
  30. package/dist/dom/style.d.mts +30 -0
  31. package/dist/dom/style.d.mts.map +1 -0
  32. package/dist/dom/style.mjs +74 -0
  33. package/dist/dom/style.mjs.map +1 -0
  34. package/dist/env/index.d.mts +63 -0
  35. package/dist/env/index.d.mts.map +1 -0
  36. package/dist/env/index.mjs +97 -0
  37. package/dist/env/index.mjs.map +1 -0
  38. package/dist/identity/index.d.mts +78 -0
  39. package/dist/identity/index.d.mts.map +1 -0
  40. package/dist/identity/index.mjs +87 -0
  41. package/dist/identity/index.mjs.map +1 -0
  42. package/dist/index.d.mts +24 -0
  43. package/dist/index.mjs +23 -0
  44. package/dist/internal/text.mjs +36 -0
  45. package/dist/internal/text.mjs.map +1 -0
  46. package/dist/logger/index.d.mts +87 -0
  47. package/dist/logger/index.d.mts.map +1 -0
  48. package/dist/logger/index.mjs +124 -0
  49. package/dist/logger/index.mjs.map +1 -0
  50. package/dist/number/index.d.mts +89 -0
  51. package/dist/number/index.d.mts.map +1 -0
  52. package/dist/number/index.mjs +215 -0
  53. package/dist/number/index.mjs.map +1 -0
  54. package/dist/object/index.d.mts +76 -0
  55. package/dist/object/index.d.mts.map +1 -0
  56. package/dist/object/index.mjs +134 -0
  57. package/dist/object/index.mjs.map +1 -0
  58. package/dist/storage/index.d.mts +104 -0
  59. package/dist/storage/index.d.mts.map +1 -0
  60. package/dist/storage/index.mjs +324 -0
  61. package/dist/storage/index.mjs.map +1 -0
  62. package/dist/string/index.d.mts +130 -0
  63. package/dist/string/index.d.mts.map +1 -0
  64. package/dist/string/index.mjs +275 -0
  65. package/dist/string/index.mjs.map +1 -0
  66. package/dist/vue/emits.d.mts +24 -0
  67. package/dist/vue/emits.d.mts.map +1 -0
  68. package/dist/vue/emits.mjs +47 -0
  69. package/dist/vue/emits.mjs.map +1 -0
  70. package/dist/vue/expose.d.mts +12 -0
  71. package/dist/vue/expose.d.mts.map +1 -0
  72. package/dist/vue/expose.mjs +16 -0
  73. package/dist/vue/expose.mjs.map +1 -0
  74. package/dist/vue/func.d.mts +14 -0
  75. package/dist/vue/func.d.mts.map +1 -0
  76. package/dist/vue/func.mjs +16 -0
  77. package/dist/vue/func.mjs.map +1 -0
  78. package/dist/vue/index.d.mts +9 -0
  79. package/dist/vue/install.d.mts +69 -0
  80. package/dist/vue/install.d.mts.map +1 -0
  81. package/dist/vue/install.mjs +123 -0
  82. package/dist/vue/install.mjs.map +1 -0
  83. package/dist/vue/props.d.mts +23 -0
  84. package/dist/vue/props.d.mts.map +1 -0
  85. package/dist/vue/props.mjs +41 -0
  86. package/dist/vue/props.mjs.map +1 -0
  87. package/dist/vue/render.d.mts +13 -0
  88. package/dist/vue/render.d.mts.map +1 -0
  89. package/dist/vue/render.mjs +23 -0
  90. package/dist/vue/render.mjs.map +1 -0
  91. package/dist/vue/slots.d.mts +19 -0
  92. package/dist/vue/slots.d.mts.map +1 -0
  93. package/dist/vue/slots.mjs +13 -0
  94. package/dist/vue/slots.mjs.map +1 -0
  95. package/dist/vue/with.d.mts +12 -0
  96. package/dist/vue/with.d.mts.map +1 -0
  97. package/dist/vue/with.mjs +15 -0
  98. package/dist/vue/with.mjs.map +1 -0
  99. package/docs/API.md +96 -0
  100. package/docs/API.zh-CN.md +96 -0
  101. package/docs/DEVELOPMENT_RELEASE.zh-CN.md +65 -0
  102. package/docs/RUNTIME_CONTRACT.md +37 -0
  103. package/package.json +65 -73
  104. package/src/array/index.ts +173 -0
  105. package/src/async/index.ts +475 -0
  106. package/src/base64/index.ts +374 -0
  107. package/src/color/index.ts +208 -0
  108. package/src/crypto/index.ts +670 -0
  109. package/src/date/index.ts +451 -0
  110. package/src/dom/index.ts +6 -0
  111. package/src/dom/style.ts +92 -0
  112. package/src/env/index.ts +169 -0
  113. package/src/identity/index.ts +144 -0
  114. package/src/index.ts +20 -0
  115. package/src/internal/text.ts +46 -0
  116. package/src/logger/index.ts +219 -0
  117. package/src/number/index.ts +235 -0
  118. package/src/object/index.ts +160 -0
  119. package/src/storage/index.ts +524 -0
  120. package/src/string/index.ts +328 -0
  121. package/src/vue/emits.ts +71 -0
  122. package/src/vue/expose.ts +11 -0
  123. package/src/vue/func.ts +17 -0
  124. package/src/vue/index.ts +13 -0
  125. package/src/vue/install.ts +185 -0
  126. package/src/vue/props.ts +39 -0
  127. package/src/vue/render.ts +41 -0
  128. package/src/vue/slots.ts +23 -0
  129. package/src/vue/with.ts +10 -0
  130. package/Fast.png +0 -0
  131. package/dist/index.global.js +0 -14500
  132. package/dist/index.global.js.map +0 -1
  133. package/dist/index.global.min.js +0 -2
  134. package/dist/index.global.min.js.map +0 -1
  135. package/es/array/index.d.ts +0 -19
  136. package/es/array/index.mjs +0 -2
  137. package/es/array/index.mjs.map +0 -1
  138. package/es/base64/index.d.ts +0 -21
  139. package/es/base64/index.mjs +0 -2
  140. package/es/base64/index.mjs.map +0 -1
  141. package/es/click/index.d.ts +0 -33
  142. package/es/click/index.mjs +0 -2
  143. package/es/click/index.mjs.map +0 -1
  144. package/es/color/index.d.ts +0 -33
  145. package/es/color/index.mjs +0 -2
  146. package/es/color/index.mjs.map +0 -1
  147. package/es/console/index.d.ts +0 -31
  148. package/es/console/index.mjs +0 -2
  149. package/es/console/index.mjs.map +0 -1
  150. package/es/crypto/index.d.ts +0 -46
  151. package/es/crypto/index.mjs +0 -2
  152. package/es/crypto/index.mjs.map +0 -1
  153. package/es/date/index.d.ts +0 -44
  154. package/es/date/index.mjs +0 -2
  155. package/es/date/index.mjs.map +0 -1
  156. package/es/dom/index.d.ts +0 -1
  157. package/es/dom/index.mjs +0 -2
  158. package/es/dom/index.mjs.map +0 -1
  159. package/es/dom/style.d.ts +0 -12
  160. package/es/dom/style.mjs +0 -2
  161. package/es/dom/style.mjs.map +0 -1
  162. package/es/env/index.d.ts +0 -25
  163. package/es/env/index.mjs +0 -2
  164. package/es/env/index.mjs.map +0 -1
  165. package/es/error/index.d.ts +0 -3
  166. package/es/error/index.mjs +0 -2
  167. package/es/error/index.mjs.map +0 -1
  168. package/es/identity/index.d.ts +0 -14
  169. package/es/identity/index.mjs +0 -2
  170. package/es/identity/index.mjs.map +0 -1
  171. package/es/index.d.ts +0 -15
  172. package/es/index.es.d.ts +0 -2
  173. package/es/index.mjs +0 -2
  174. package/es/index.mjs.map +0 -1
  175. package/es/object/index.d.ts +0 -13
  176. package/es/object/index.mjs +0 -2
  177. package/es/object/index.mjs.map +0 -1
  178. package/es/storage/index.d.ts +0 -96
  179. package/es/storage/index.mjs +0 -2
  180. package/es/storage/index.mjs.map +0 -1
  181. package/es/string/index.d.ts +0 -114
  182. package/es/string/index.mjs +0 -2
  183. package/es/string/index.mjs.map +0 -1
  184. package/es/vue/emits.d.ts +0 -8
  185. package/es/vue/emits.mjs +0 -2
  186. package/es/vue/emits.mjs.map +0 -1
  187. package/es/vue/expose.d.ts +0 -4
  188. package/es/vue/expose.mjs +0 -2
  189. package/es/vue/expose.mjs.map +0 -1
  190. package/es/vue/func.d.ts +0 -6
  191. package/es/vue/func.mjs +0 -2
  192. package/es/vue/func.mjs.map +0 -1
  193. package/es/vue/index.d.ts +0 -8
  194. package/es/vue/index.mjs +0 -2
  195. package/es/vue/index.mjs.map +0 -1
  196. package/es/vue/install.d.ts +0 -5
  197. package/es/vue/install.mjs +0 -2
  198. package/es/vue/install.mjs.map +0 -1
  199. package/es/vue/props.d.ts +0 -9
  200. package/es/vue/props.mjs +0 -2
  201. package/es/vue/props.mjs.map +0 -1
  202. package/es/vue/slots.d.ts +0 -11
  203. package/es/vue/slots.mjs +0 -2
  204. package/es/vue/slots.mjs.map +0 -1
  205. package/es/vue/useRender.d.ts +0 -6
  206. package/es/vue/useRender.mjs +0 -2
  207. package/es/vue/useRender.mjs.map +0 -1
  208. package/es/vue/with.d.ts +0 -5
  209. package/es/vue/with.mjs +0 -2
  210. package/es/vue/with.mjs.map +0 -1
  211. package/lib/array/index.d.ts +0 -19
  212. package/lib/array/index.js +0 -2
  213. package/lib/array/index.js.map +0 -1
  214. package/lib/base64/index.d.ts +0 -21
  215. package/lib/base64/index.js +0 -2
  216. package/lib/base64/index.js.map +0 -1
  217. package/lib/click/index.d.ts +0 -33
  218. package/lib/click/index.js +0 -2
  219. package/lib/click/index.js.map +0 -1
  220. package/lib/color/index.d.ts +0 -33
  221. package/lib/color/index.js +0 -2
  222. package/lib/color/index.js.map +0 -1
  223. package/lib/console/index.d.ts +0 -31
  224. package/lib/console/index.js +0 -2
  225. package/lib/console/index.js.map +0 -1
  226. package/lib/crypto/index.d.ts +0 -46
  227. package/lib/crypto/index.js +0 -2
  228. package/lib/crypto/index.js.map +0 -1
  229. package/lib/date/index.d.ts +0 -44
  230. package/lib/date/index.js +0 -2
  231. package/lib/date/index.js.map +0 -1
  232. package/lib/dom/index.d.ts +0 -1
  233. package/lib/dom/index.js +0 -2
  234. package/lib/dom/index.js.map +0 -1
  235. package/lib/dom/style.d.ts +0 -12
  236. package/lib/dom/style.js +0 -2
  237. package/lib/dom/style.js.map +0 -1
  238. package/lib/env/index.d.ts +0 -25
  239. package/lib/env/index.js +0 -2
  240. package/lib/env/index.js.map +0 -1
  241. package/lib/error/index.d.ts +0 -3
  242. package/lib/error/index.js +0 -2
  243. package/lib/error/index.js.map +0 -1
  244. package/lib/identity/index.d.ts +0 -14
  245. package/lib/identity/index.js +0 -2
  246. package/lib/identity/index.js.map +0 -1
  247. package/lib/index.d.ts +0 -15
  248. package/lib/index.es.d.ts +0 -2
  249. package/lib/index.js +0 -2
  250. package/lib/index.js.map +0 -1
  251. package/lib/object/index.d.ts +0 -13
  252. package/lib/object/index.js +0 -2
  253. package/lib/object/index.js.map +0 -1
  254. package/lib/storage/index.d.ts +0 -96
  255. package/lib/storage/index.js +0 -2
  256. package/lib/storage/index.js.map +0 -1
  257. package/lib/string/index.d.ts +0 -114
  258. package/lib/string/index.js +0 -2
  259. package/lib/string/index.js.map +0 -1
  260. package/lib/vue/emits.d.ts +0 -8
  261. package/lib/vue/emits.js +0 -2
  262. package/lib/vue/emits.js.map +0 -1
  263. package/lib/vue/expose.d.ts +0 -4
  264. package/lib/vue/expose.js +0 -2
  265. package/lib/vue/expose.js.map +0 -1
  266. package/lib/vue/func.d.ts +0 -6
  267. package/lib/vue/func.js +0 -2
  268. package/lib/vue/func.js.map +0 -1
  269. package/lib/vue/index.d.ts +0 -8
  270. package/lib/vue/index.js +0 -2
  271. package/lib/vue/index.js.map +0 -1
  272. package/lib/vue/install.d.ts +0 -5
  273. package/lib/vue/install.js +0 -2
  274. package/lib/vue/install.js.map +0 -1
  275. package/lib/vue/props.d.ts +0 -9
  276. package/lib/vue/props.js +0 -2
  277. package/lib/vue/props.js.map +0 -1
  278. package/lib/vue/slots.d.ts +0 -11
  279. package/lib/vue/slots.js +0 -2
  280. package/lib/vue/slots.js.map +0 -1
  281. package/lib/vue/useRender.d.ts +0 -6
  282. package/lib/vue/useRender.js +0 -2
  283. package/lib/vue/useRender.js.map +0 -1
  284. package/lib/vue/with.d.ts +0 -5
  285. package/lib/vue/with.js +0 -2
  286. package/lib/vue/with.js.map +0 -1
@@ -0,0 +1,74 @@
1
+ //#region src/dom/style.ts
2
+ /**
3
+ * 判断 StyleInput 是否为递归样式数组。
4
+ *
5
+ * @param value - 待缩小的样式输入。
6
+ * @returns 是只读样式数组时返回 `true`。
7
+ */
8
+ const isStyleArray = (value) => Array.isArray(value);
9
+ /**
10
+ * 判断文本是否可按十进制数值追加 CSS 单位。
11
+ *
12
+ * @param value - 已去除外围空白的文本。
13
+ * @returns 有限十进制数值返回 `true`;二、八、十六进制前缀返回 `false`。
14
+ */
15
+ const isNumericString = (value) => {
16
+ if (value.length === 0 || !Number.isFinite(Number(value))) return false;
17
+ const unsigned = value.startsWith("+") || value.startsWith("-") ? value.slice(1) : value;
18
+ return !/^0[box]/iu.test(unsigned);
19
+ };
20
+ /**
21
+ * 把 JavaScript 样式属性名转换为 CSS 属性名。
22
+ *
23
+ * @param key - camelCase、kebab-case 或 CSS 自定义属性名。
24
+ * @returns kebab-case 属性名;`--` 自定义属性保持原样。
25
+ */
26
+ const toCssPropertyName = (key) => {
27
+ if (key.startsWith("--")) return key;
28
+ return (key.startsWith("ms") ? `-${key}` : key).replace(/([A-Z])/gu, "-$1").toLowerCase();
29
+ };
30
+ /**
31
+ * 为数值或纯数字字符串添加 CSS 单位。
32
+ *
33
+ * @param value - 数字、数字字符串或已有单位的 CSS 值;空值返回空字符串。
34
+ * @param unit - 非零数字使用的单位,默认 `px`。
35
+ * @returns 零统一返回 `"0"`;非数字字符串保持原样。
36
+ * @throws `RangeError` 当数字非有限或单位为空。
37
+ */
38
+ function addCssUnit(value, unit = "px") {
39
+ if (value === null || value === void 0 || value === "") return "";
40
+ if (unit.length === 0) throw new RangeError("unit cannot be empty.");
41
+ if (typeof value === "number") {
42
+ if (!Number.isFinite(value)) throw new RangeError("value must be finite.");
43
+ return value === 0 ? "0" : `${value}${unit}`;
44
+ }
45
+ const trimmed = value.trim();
46
+ if (!isNumericString(trimmed)) return value;
47
+ return Number(trimmed) === 0 ? "0" : `${trimmed}${unit}`;
48
+ }
49
+ /**
50
+ * 将样式字符串、对象或嵌套数组序列化为内联 CSS。
51
+ *
52
+ * @remarks 本函数只负责结构转换,不是 CSS 安全清洗器。不可信值必须由调用方按照
53
+ * 实际渲染上下文验证,尤其不能允许用户控制属性名、`url()` 或自定义属性内容。
54
+ * 数字不会自动附加单位;需要长度单位时应先调用 {@link addCssUnit}。
55
+ * @param styles - 可嵌套样式输入;后出现的声明由 CSS 层叠规则覆盖先前声明。
56
+ * @returns 以分号结束、以空格分隔的 CSS 声明字符串。
57
+ * @throws `RangeError` 当对象中包含 `NaN` 或无穷数字。
58
+ */
59
+ function serializeStyle(styles) {
60
+ if (styles === null || styles === void 0 || styles === "") return "";
61
+ if (isStyleArray(styles)) return styles.map((item) => serializeStyle(item)).filter((item) => item.length > 0).join(" ");
62
+ if (typeof styles === "string") {
63
+ const value = styles.trim();
64
+ return value.length === 0 ? "" : value.endsWith(";") ? value : `${value};`;
65
+ }
66
+ return Object.entries(styles).filter(([, value]) => value !== null && value !== void 0 && value !== "").map(([key, value]) => {
67
+ if (typeof value === "number" && !Number.isFinite(value)) throw new RangeError(`Style property "${key}" must be finite.`);
68
+ return `${toCssPropertyName(key)}:${String(value)};`;
69
+ }).join(" ");
70
+ }
71
+ //#endregion
72
+ export { addCssUnit, serializeStyle };
73
+
74
+ //# sourceMappingURL=style.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style.mjs","names":[],"sources":["../../src/dom/style.ts"],"sourcesContent":["/** 可序列化为内联 CSS 的单个值。 */\nexport type StyleValue = number | string | null | undefined;\n\n/** camelCase、kebab-case 或 CSS 自定义属性组成的只读样式对象。 */\nexport type StyleObject = Readonly<Record<string, StyleValue>>;\n\n/** 字符串、样式对象、嵌套数组或空值。 */\nexport type StyleInput = string | StyleObject | readonly StyleInput[] | null | undefined;\n\n/**\n * 判断 StyleInput 是否为递归样式数组。\n *\n * @param value - 待缩小的样式输入。\n * @returns 是只读样式数组时返回 `true`。\n */\nconst isStyleArray = (value: StyleInput): value is readonly StyleInput[] => Array.isArray(value);\n\n/**\n * 判断文本是否可按十进制数值追加 CSS 单位。\n *\n * @param value - 已去除外围空白的文本。\n * @returns 有限十进制数值返回 `true`;二、八、十六进制前缀返回 `false`。\n */\nconst isNumericString = (value: string): boolean => {\n\tif (value.length === 0 || !Number.isFinite(Number(value))) return false;\n\tconst unsigned = value.startsWith(\"+\") || value.startsWith(\"-\") ? value.slice(1) : value;\n\treturn !/^0[box]/iu.test(unsigned);\n};\n\n/**\n * 把 JavaScript 样式属性名转换为 CSS 属性名。\n *\n * @param key - camelCase、kebab-case 或 CSS 自定义属性名。\n * @returns kebab-case 属性名;`--` 自定义属性保持原样。\n */\nconst toCssPropertyName = (key: string): string => {\n\tif (key.startsWith(\"--\")) return key;\n\tconst normalized = key.startsWith(\"ms\") ? `-${key}` : key;\n\treturn normalized.replace(/([A-Z])/gu, \"-$1\").toLowerCase();\n};\n\n/**\n * 为数值或纯数字字符串添加 CSS 单位。\n *\n * @param value - 数字、数字字符串或已有单位的 CSS 值;空值返回空字符串。\n * @param unit - 非零数字使用的单位,默认 `px`。\n * @returns 零统一返回 `\"0\"`;非数字字符串保持原样。\n * @throws `RangeError` 当数字非有限或单位为空。\n */\nexport function addCssUnit(value?: string | number | null, unit = \"px\"): string {\n\tif (value === null || value === undefined || value === \"\") return \"\";\n\tif (unit.length === 0) throw new RangeError(\"unit cannot be empty.\");\n\tif (typeof value === \"number\") {\n\t\tif (!Number.isFinite(value)) throw new RangeError(\"value must be finite.\");\n\t\treturn value === 0 ? \"0\" : `${value}${unit}`;\n\t}\n\tconst trimmed = value.trim();\n\tif (!isNumericString(trimmed)) return value;\n\treturn Number(trimmed) === 0 ? \"0\" : `${trimmed}${unit}`;\n}\n\n/**\n * 将样式字符串、对象或嵌套数组序列化为内联 CSS。\n *\n * @remarks 本函数只负责结构转换,不是 CSS 安全清洗器。不可信值必须由调用方按照\n * 实际渲染上下文验证,尤其不能允许用户控制属性名、`url()` 或自定义属性内容。\n * 数字不会自动附加单位;需要长度单位时应先调用 {@link addCssUnit}。\n * @param styles - 可嵌套样式输入;后出现的声明由 CSS 层叠规则覆盖先前声明。\n * @returns 以分号结束、以空格分隔的 CSS 声明字符串。\n * @throws `RangeError` 当对象中包含 `NaN` 或无穷数字。\n */\nexport function serializeStyle(styles: StyleInput): string {\n\tif (styles === null || styles === undefined || styles === \"\") return \"\";\n\tif (isStyleArray(styles)) {\n\t\treturn styles\n\t\t\t.map((item) => serializeStyle(item))\n\t\t\t.filter((item) => item.length > 0)\n\t\t\t.join(\" \");\n\t}\n\tif (typeof styles === \"string\") {\n\t\tconst value = styles.trim();\n\t\treturn value.length === 0 ? \"\" : value.endsWith(\";\") ? value : `${value};`;\n\t}\n\n\treturn Object.entries(styles)\n\t\t.filter(([, value]) => value !== null && value !== undefined && value !== \"\")\n\t\t.map(([key, value]) => {\n\t\t\tif (typeof value === \"number\" && !Number.isFinite(value)) throw new RangeError(`Style property \"${key}\" must be finite.`);\n\t\t\treturn `${toCssPropertyName(key)}:${String(value)};`;\n\t\t})\n\t\t.join(\" \");\n}\n"],"mappings":";;;;;;;AAeA,MAAM,gBAAgB,UAAsD,MAAM,QAAQ,KAAK;;;;;;;AAQ/F,MAAM,mBAAmB,UAA2B;CACnD,IAAI,MAAM,WAAW,KAAK,CAAC,OAAO,SAAS,OAAO,KAAK,CAAC,GAAG,OAAO;CAClE,MAAM,WAAW,MAAM,WAAW,GAAG,KAAK,MAAM,WAAW,GAAG,IAAI,MAAM,MAAM,CAAC,IAAI;CACnF,OAAO,CAAC,YAAY,KAAK,QAAQ;AAClC;;;;;;;AAQA,MAAM,qBAAqB,QAAwB;CAClD,IAAI,IAAI,WAAW,IAAI,GAAG,OAAO;CAEjC,QADmB,IAAI,WAAW,IAAI,IAAI,IAAI,QAAQ,IAAA,CACpC,QAAQ,aAAa,KAAK,CAAC,CAAC,YAAY;AAC3D;;;;;;;;;AAUA,SAAgB,WAAW,OAAgC,OAAO,MAAc;CAC/E,IAAI,UAAU,QAAQ,UAAU,KAAA,KAAa,UAAU,IAAI,OAAO;CAClE,IAAI,KAAK,WAAW,GAAG,MAAM,IAAI,WAAW,uBAAuB;CACnE,IAAI,OAAO,UAAU,UAAU;EAC9B,IAAI,CAAC,OAAO,SAAS,KAAK,GAAG,MAAM,IAAI,WAAW,uBAAuB;EACzE,OAAO,UAAU,IAAI,MAAM,GAAG,QAAQ;CACvC;CACA,MAAM,UAAU,MAAM,KAAK;CAC3B,IAAI,CAAC,gBAAgB,OAAO,GAAG,OAAO;CACtC,OAAO,OAAO,OAAO,MAAM,IAAI,MAAM,GAAG,UAAU;AACnD;;;;;;;;;;;AAYA,SAAgB,eAAe,QAA4B;CAC1D,IAAI,WAAW,QAAQ,WAAW,KAAA,KAAa,WAAW,IAAI,OAAO;CACrE,IAAI,aAAa,MAAM,GACtB,OAAO,OACL,KAAK,SAAS,eAAe,IAAI,CAAC,CAAC,CACnC,QAAQ,SAAS,KAAK,SAAS,CAAC,CAAC,CACjC,KAAK,GAAG;CAEX,IAAI,OAAO,WAAW,UAAU;EAC/B,MAAM,QAAQ,OAAO,KAAK;EAC1B,OAAO,MAAM,WAAW,IAAI,KAAK,MAAM,SAAS,GAAG,IAAI,QAAQ,GAAG,MAAM;CACzE;CAEA,OAAO,OAAO,QAAQ,MAAM,CAAC,CAC3B,QAAQ,GAAG,WAAW,UAAU,QAAQ,UAAU,KAAA,KAAa,UAAU,EAAE,CAAC,CAC5E,KAAK,CAAC,KAAK,WAAW;EACtB,IAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GAAG,MAAM,IAAI,WAAW,mBAAmB,IAAI,kBAAkB;EACxH,OAAO,GAAG,kBAAkB,GAAG,EAAE,GAAG,OAAO,KAAK,EAAE;CACnD,CAAC,CAAC,CACD,KAAK,GAAG;AACX"}
@@ -0,0 +1,63 @@
1
+ //#region src/env/index.d.ts
2
+ /** 可识别的主要 JavaScript 运行环境。 */
3
+ type RuntimeKind = "browser" | "node" | "unknown" | "worker";
4
+ /**
5
+ * 判断当前运行时是否具有浏览器 `window` 与 `document`。
6
+ *
7
+ * @returns 两项能力均存在时返回 `true`;不读取 DOM 内容。
8
+ */
9
+ declare function isBrowser(): boolean;
10
+ /**
11
+ * 判断当前运行时是否像 Web Worker 且不是 Window。
12
+ *
13
+ * @remarks 经典、模块、Shared 与 Service Worker 全局通常都暴露 `importScripts`;模块
14
+ * Worker 中调用它可能抛错,本检测只检查能力存在,不会执行。
15
+ * @returns 具有 `importScripts` 且不是浏览器 Window 时返回 `true`。
16
+ */
17
+ declare function isWebWorker(): boolean;
18
+ /**
19
+ * 判断当前运行时是否暴露 Node.js 版本标记。
20
+ *
21
+ * @returns `process.versions.node` 为字符串时返回 `true`。
22
+ */
23
+ declare function isNode(): boolean;
24
+ /**
25
+ * 判断当前运行时是否暴露 uni-app 的 `uni` 全局对象。
26
+ *
27
+ * @returns 全局属性存在且不为 `undefined` 时返回 `true`;不调用任何平台 API。
28
+ */
29
+ declare function isUniApp(): boolean;
30
+ /**
31
+ * 判断当前运行时是否具备本库完整加密 API 所需的 Web Crypto 能力。
32
+ *
33
+ * @remarks 只具有 `getRandomValues` 的平台仍可调用随机数与随机字符串 API,但本函数
34
+ * 会返回 `false`,因为摘要、PBKDF2、AES-GCM、RSA 与 ECC 还需要完整的 `SubtleCrypto` 方法集。
35
+ * @returns 同时提供本库 Web Crypto 功能所需方法时返回 `true`。
36
+ */
37
+ declare function hasWebCrypto(): boolean;
38
+ /**
39
+ * 返回当前主要运行环境。
40
+ *
41
+ * @remarks 在使用 DOM 模拟器的 Node.js 进程中优先报告 `browser`,因为可观察能力比宿主进程名称更有用。
42
+ * @returns `browser`、`worker`、`node` 或无法识别时的 `unknown`。
43
+ */
44
+ declare function detectRuntime(): RuntimeKind;
45
+ /**
46
+ * 基于 User-Agent 启发式判断手机设备。
47
+ *
48
+ * @param userAgent - 默认读取当前 `navigator.userAgent`;平台对象不存在时使用空字符串。
49
+ * @remarks User-Agent 可以被伪造,不得用于鉴权、安全策略或永久功能分流。
50
+ * @returns 命中手机特征时返回 `true`。
51
+ */
52
+ declare function isMobileUserAgent(userAgent?: string): boolean;
53
+ /**
54
+ * 基于 User-Agent 与触点数量启发式判断平板设备。
55
+ *
56
+ * @param userAgent - 默认读取当前 User-Agent。
57
+ * @param maxTouchPoints - 用于识别桌面 User-Agent 模式下的 iPadOS,默认读取当前触点数。
58
+ * @returns 命中平板特征时返回 `true`。
59
+ */
60
+ declare function isTabletUserAgent(userAgent?: string, maxTouchPoints?: number): boolean;
61
+ //#endregion
62
+ export { RuntimeKind, detectRuntime, hasWebCrypto, isBrowser, isMobileUserAgent, isNode, isTabletUserAgent, isUniApp, isWebWorker };
63
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/env/index.ts"],"mappings":";;KACY;;;;;;iBA2EI;;;;;;;;iBAYA;;;;;;iBASA;;;;;;iBASA;;;;;;;;iBAWA;;;;;;;iBAwBA,iBAAiB;;;;;;;;iBAcjB,kBAAkB;;;;;;;;iBAWlB,kBAAkB,oBAAwC"}
@@ -0,0 +1,97 @@
1
+ //#region src/env/index.ts
2
+ const runtimeGlobals = globalThis;
3
+ /**
4
+ * 延迟读取当前 User-Agent。
5
+ *
6
+ * @returns Navigator 不存在或字段类型异常时返回空字符串。
7
+ */
8
+ const currentUserAgent = () => typeof runtimeGlobals.navigator?.userAgent === "string" ? runtimeGlobals.navigator.userAgent : "";
9
+ /**
10
+ * 延迟读取当前设备报告的最大触点数。
11
+ *
12
+ * @returns Navigator 不存在或字段类型异常时返回 `0`。
13
+ */
14
+ const currentTouchPoints = () => typeof runtimeGlobals.navigator?.maxTouchPoints === "number" ? runtimeGlobals.navigator.maxTouchPoints : 0;
15
+ /**
16
+ * 判断当前运行时是否具有浏览器 `window` 与 `document`。
17
+ *
18
+ * @returns 两项能力均存在时返回 `true`;不读取 DOM 内容。
19
+ */
20
+ function isBrowser() {
21
+ const window = runtimeGlobals.window;
22
+ return window !== void 0 && window !== null && window.document !== null && typeof window.document === "object";
23
+ }
24
+ /**
25
+ * 判断当前运行时是否像 Web Worker 且不是 Window。
26
+ *
27
+ * @remarks 经典、模块、Shared 与 Service Worker 全局通常都暴露 `importScripts`;模块
28
+ * Worker 中调用它可能抛错,本检测只检查能力存在,不会执行。
29
+ * @returns 具有 `importScripts` 且不是浏览器 Window 时返回 `true`。
30
+ */
31
+ function isWebWorker() {
32
+ return !isBrowser() && typeof runtimeGlobals.importScripts === "function";
33
+ }
34
+ /**
35
+ * 判断当前运行时是否暴露 Node.js 版本标记。
36
+ *
37
+ * @returns `process.versions.node` 为字符串时返回 `true`。
38
+ */
39
+ function isNode() {
40
+ return typeof runtimeGlobals.process?.versions?.node === "string";
41
+ }
42
+ /**
43
+ * 判断当前运行时是否暴露 uni-app 的 `uni` 全局对象。
44
+ *
45
+ * @returns 全局属性存在且不为 `undefined` 时返回 `true`;不调用任何平台 API。
46
+ */
47
+ function isUniApp() {
48
+ return runtimeGlobals.uni !== void 0;
49
+ }
50
+ /**
51
+ * 判断当前运行时是否具备本库完整加密 API 所需的 Web Crypto 能力。
52
+ *
53
+ * @remarks 只具有 `getRandomValues` 的平台仍可调用随机数与随机字符串 API,但本函数
54
+ * 会返回 `false`,因为摘要、PBKDF2、AES-GCM、RSA 与 ECC 还需要完整的 `SubtleCrypto` 方法集。
55
+ * @returns 同时提供本库 Web Crypto 功能所需方法时返回 `true`。
56
+ */
57
+ function hasWebCrypto() {
58
+ const crypto = runtimeGlobals.crypto;
59
+ const subtle = crypto?.subtle;
60
+ return typeof crypto?.getRandomValues === "function" && typeof subtle?.decrypt === "function" && typeof subtle.deriveBits === "function" && typeof subtle.deriveKey === "function" && typeof subtle.digest === "function" && typeof subtle.encrypt === "function" && typeof subtle.exportKey === "function" && typeof subtle.generateKey === "function" && typeof subtle.importKey === "function" && typeof subtle.sign === "function" && typeof subtle.verify === "function";
61
+ }
62
+ /**
63
+ * 返回当前主要运行环境。
64
+ *
65
+ * @remarks 在使用 DOM 模拟器的 Node.js 进程中优先报告 `browser`,因为可观察能力比宿主进程名称更有用。
66
+ * @returns `browser`、`worker`、`node` 或无法识别时的 `unknown`。
67
+ */
68
+ function detectRuntime() {
69
+ if (isBrowser()) return "browser";
70
+ if (isWebWorker()) return "worker";
71
+ if (isNode()) return "node";
72
+ return "unknown";
73
+ }
74
+ /**
75
+ * 基于 User-Agent 启发式判断手机设备。
76
+ *
77
+ * @param userAgent - 默认读取当前 `navigator.userAgent`;平台对象不存在时使用空字符串。
78
+ * @remarks User-Agent 可以被伪造,不得用于鉴权、安全策略或永久功能分流。
79
+ * @returns 命中手机特征时返回 `true`。
80
+ */
81
+ function isMobileUserAgent(userAgent = currentUserAgent()) {
82
+ return /Mobile|iPhone|Android.*Mobile|Windows Phone/iu.test(userAgent);
83
+ }
84
+ /**
85
+ * 基于 User-Agent 与触点数量启发式判断平板设备。
86
+ *
87
+ * @param userAgent - 默认读取当前 User-Agent。
88
+ * @param maxTouchPoints - 用于识别桌面 User-Agent 模式下的 iPadOS,默认读取当前触点数。
89
+ * @returns 命中平板特征时返回 `true`。
90
+ */
91
+ function isTabletUserAgent(userAgent = currentUserAgent(), maxTouchPoints = currentTouchPoints()) {
92
+ return /iPad|Android(?!.*Mobile)|Tablet/iu.test(userAgent) || /Macintosh/iu.test(userAgent) && maxTouchPoints > 1;
93
+ }
94
+ //#endregion
95
+ export { detectRuntime, hasWebCrypto, isBrowser, isMobileUserAgent, isNode, isTabletUserAgent, isUniApp, isWebWorker };
96
+
97
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/env/index.ts"],"sourcesContent":["/** 可识别的主要 JavaScript 运行环境。 */\nexport type RuntimeKind = \"browser\" | \"node\" | \"unknown\" | \"worker\";\n\n/** 环境检测需要逐项确认的 SubtleCrypto 最小能力集合。 */\ntype RuntimeSubtleCrypto = Partial<\n\tPick<SubtleCrypto, \"decrypt\" | \"deriveBits\" | \"deriveKey\" | \"digest\" | \"encrypt\" | \"exportKey\" | \"generateKey\" | \"importKey\" | \"sign\" | \"verify\">\n>;\n\n/** 环境检测读取的 Web Crypto 最小视图。 */\ninterface RuntimeEnvironmentCrypto extends Partial<Pick<Crypto, \"getRandomValues\">> {\n\t/** 可选 SubtleCrypto 能力;只有所需方法全部存在时才视为完整 Web Crypto。 */\n\tsubtle?: RuntimeSubtleCrypto;\n}\n\n/** 环境检测读取的最小 Navigator 视图。 */\ninterface RuntimeNavigator {\n\t/** 平台报告的最大同时触点数;类型异常时按 `0` 处理。 */\n\tmaxTouchPoints?: unknown;\n\t/** 平台报告的 User-Agent;类型异常时按空字符串处理。 */\n\tuserAgent?: unknown;\n}\n\n/** 环境检测读取的最小 Node 进程视图。 */\ninterface RuntimeProcess {\n\t/** 可选运行时版本表。 */\n\tversions?: RuntimeVersions;\n}\n\n/** 环境检测读取的最小运行时版本表。 */\ninterface RuntimeVersions {\n\t/** Node.js 版本文本;存在字符串值时识别为 Node 环境。 */\n\tnode?: unknown;\n}\n\n/** 环境检测读取的最小 Window 视图。 */\ninterface RuntimeWindow {\n\t/** DOM 文档标记;只检查是否为非空对象。 */\n\tdocument?: unknown;\n}\n\n/** 可选平台全局对象的结构化视图,避免导入 Node 或 uni-app 全局类型。 */\ninterface RuntimeGlobals {\n\t/** 可选 Web Crypto 能力;所有方法都在调用前逐项检查,不因对象存在而假定完整实现。 */\n\tcrypto?: RuntimeEnvironmentCrypto;\n\t/** Web Worker 中通常存在的脚本导入函数;只检查其类型,不会在检测阶段调用。 */\n\timportScripts?: unknown;\n\t/** 浏览器或 WebView 暴露的最小 Navigator 字段;未知类型会被能力读取函数视为缺失。 */\n\tnavigator?: RuntimeNavigator;\n\t/** 工具或测试环境可能暴露的 Node 版本标记;仅用于检测,不代表 Node 属于应用运行时契约。 */\n\tprocess?: RuntimeProcess;\n\t/** uni-app 平台标记;Storage 会在调用 `configureStorage` 时读取并校验该全局对象。 */\n\tuni?: unknown;\n\t/** 浏览器 Window 的最小结构;`document` 只用于能力判定,不在模块导入阶段读取 DOM 内容。 */\n\twindow?: RuntimeWindow | null;\n}\n\nconst runtimeGlobals = globalThis as unknown as RuntimeGlobals;\n\n/**\n * 延迟读取当前 User-Agent。\n *\n * @returns Navigator 不存在或字段类型异常时返回空字符串。\n */\nconst currentUserAgent = (): string => (typeof runtimeGlobals.navigator?.userAgent === \"string\" ? runtimeGlobals.navigator.userAgent : \"\");\n/**\n * 延迟读取当前设备报告的最大触点数。\n *\n * @returns Navigator 不存在或字段类型异常时返回 `0`。\n */\nconst currentTouchPoints = (): number => (typeof runtimeGlobals.navigator?.maxTouchPoints === \"number\" ? runtimeGlobals.navigator.maxTouchPoints : 0);\n\n/**\n * 判断当前运行时是否具有浏览器 `window` 与 `document`。\n *\n * @returns 两项能力均存在时返回 `true`;不读取 DOM 内容。\n */\nexport function isBrowser(): boolean {\n\tconst window = runtimeGlobals.window;\n\treturn window !== undefined && window !== null && window.document !== null && typeof window.document === \"object\";\n}\n\n/**\n * 判断当前运行时是否像 Web Worker 且不是 Window。\n *\n * @remarks 经典、模块、Shared 与 Service Worker 全局通常都暴露 `importScripts`;模块\n * Worker 中调用它可能抛错,本检测只检查能力存在,不会执行。\n * @returns 具有 `importScripts` 且不是浏览器 Window 时返回 `true`。\n */\nexport function isWebWorker(): boolean {\n\treturn !isBrowser() && typeof runtimeGlobals.importScripts === \"function\";\n}\n\n/**\n * 判断当前运行时是否暴露 Node.js 版本标记。\n *\n * @returns `process.versions.node` 为字符串时返回 `true`。\n */\nexport function isNode(): boolean {\n\treturn typeof runtimeGlobals.process?.versions?.node === \"string\";\n}\n\n/**\n * 判断当前运行时是否暴露 uni-app 的 `uni` 全局对象。\n *\n * @returns 全局属性存在且不为 `undefined` 时返回 `true`;不调用任何平台 API。\n */\nexport function isUniApp(): boolean {\n\treturn runtimeGlobals.uni !== undefined;\n}\n\n/**\n * 判断当前运行时是否具备本库完整加密 API 所需的 Web Crypto 能力。\n *\n * @remarks 只具有 `getRandomValues` 的平台仍可调用随机数与随机字符串 API,但本函数\n * 会返回 `false`,因为摘要、PBKDF2、AES-GCM、RSA 与 ECC 还需要完整的 `SubtleCrypto` 方法集。\n * @returns 同时提供本库 Web Crypto 功能所需方法时返回 `true`。\n */\nexport function hasWebCrypto(): boolean {\n\tconst crypto = runtimeGlobals.crypto;\n\tconst subtle = crypto?.subtle;\n\treturn (\n\t\ttypeof crypto?.getRandomValues === \"function\" &&\n\t\ttypeof subtle?.decrypt === \"function\" &&\n\t\ttypeof subtle.deriveBits === \"function\" &&\n\t\ttypeof subtle.deriveKey === \"function\" &&\n\t\ttypeof subtle.digest === \"function\" &&\n\t\ttypeof subtle.encrypt === \"function\" &&\n\t\ttypeof subtle.exportKey === \"function\" &&\n\t\ttypeof subtle.generateKey === \"function\" &&\n\t\ttypeof subtle.importKey === \"function\" &&\n\t\ttypeof subtle.sign === \"function\" &&\n\t\ttypeof subtle.verify === \"function\"\n\t);\n}\n\n/**\n * 返回当前主要运行环境。\n *\n * @remarks 在使用 DOM 模拟器的 Node.js 进程中优先报告 `browser`,因为可观察能力比宿主进程名称更有用。\n * @returns `browser`、`worker`、`node` 或无法识别时的 `unknown`。\n */\nexport function detectRuntime(): RuntimeKind {\n\tif (isBrowser()) return \"browser\";\n\tif (isWebWorker()) return \"worker\";\n\tif (isNode()) return \"node\";\n\treturn \"unknown\";\n}\n\n/**\n * 基于 User-Agent 启发式判断手机设备。\n *\n * @param userAgent - 默认读取当前 `navigator.userAgent`;平台对象不存在时使用空字符串。\n * @remarks User-Agent 可以被伪造,不得用于鉴权、安全策略或永久功能分流。\n * @returns 命中手机特征时返回 `true`。\n */\nexport function isMobileUserAgent(userAgent: string = currentUserAgent()): boolean {\n\treturn /Mobile|iPhone|Android.*Mobile|Windows Phone/iu.test(userAgent);\n}\n\n/**\n * 基于 User-Agent 与触点数量启发式判断平板设备。\n *\n * @param userAgent - 默认读取当前 User-Agent。\n * @param maxTouchPoints - 用于识别桌面 User-Agent 模式下的 iPadOS,默认读取当前触点数。\n * @returns 命中平板特征时返回 `true`。\n */\nexport function isTabletUserAgent(userAgent: string = currentUserAgent(), maxTouchPoints: number = currentTouchPoints()): boolean {\n\treturn /iPad|Android(?!.*Mobile)|Tablet/iu.test(userAgent) || (/Macintosh/iu.test(userAgent) && maxTouchPoints > 1);\n}\n"],"mappings":";AAwDA,MAAM,iBAAiB;;;;;;AAOvB,MAAM,yBAAkC,OAAO,eAAe,WAAW,cAAc,WAAW,eAAe,UAAU,YAAY;;;;;;AAMvI,MAAM,2BAAoC,OAAO,eAAe,WAAW,mBAAmB,WAAW,eAAe,UAAU,iBAAiB;;;;;;AAOnJ,SAAgB,YAAqB;CACpC,MAAM,SAAS,eAAe;CAC9B,OAAO,WAAW,KAAA,KAAa,WAAW,QAAQ,OAAO,aAAa,QAAQ,OAAO,OAAO,aAAa;AAC1G;;;;;;;;AASA,SAAgB,cAAuB;CACtC,OAAO,CAAC,UAAU,KAAK,OAAO,eAAe,kBAAkB;AAChE;;;;;;AAOA,SAAgB,SAAkB;CACjC,OAAO,OAAO,eAAe,SAAS,UAAU,SAAS;AAC1D;;;;;;AAOA,SAAgB,WAAoB;CACnC,OAAO,eAAe,QAAQ,KAAA;AAC/B;;;;;;;;AASA,SAAgB,eAAwB;CACvC,MAAM,SAAS,eAAe;CAC9B,MAAM,SAAS,QAAQ;CACvB,OACC,OAAO,QAAQ,oBAAoB,cACnC,OAAO,QAAQ,YAAY,cAC3B,OAAO,OAAO,eAAe,cAC7B,OAAO,OAAO,cAAc,cAC5B,OAAO,OAAO,WAAW,cACzB,OAAO,OAAO,YAAY,cAC1B,OAAO,OAAO,cAAc,cAC5B,OAAO,OAAO,gBAAgB,cAC9B,OAAO,OAAO,cAAc,cAC5B,OAAO,OAAO,SAAS,cACvB,OAAO,OAAO,WAAW;AAE3B;;;;;;;AAQA,SAAgB,gBAA6B;CAC5C,IAAI,UAAU,GAAG,OAAO;CACxB,IAAI,YAAY,GAAG,OAAO;CAC1B,IAAI,OAAO,GAAG,OAAO;CACrB,OAAO;AACR;;;;;;;;AASA,SAAgB,kBAAkB,YAAoB,iBAAiB,GAAY;CAClF,OAAO,gDAAgD,KAAK,SAAS;AACtE;;;;;;;;AASA,SAAgB,kBAAkB,YAAoB,iBAAiB,GAAG,iBAAyB,mBAAmB,GAAY;CACjI,OAAO,oCAAoC,KAAK,SAAS,KAAM,cAAc,KAAK,SAAS,KAAK,iBAAiB;AAClH"}
@@ -0,0 +1,78 @@
1
+ //#region src/identity/index.d.ts
2
+ /** {@link configureInstallationIdentity} 接收的安装标识配置。 */
3
+ interface InstallationIdentityConfiguration {
4
+ /**
5
+ * `Local` 中使用的业务键,默认 `identity:installation-id`。
6
+ *
7
+ * @remarks 必须是无外围空白的非空字符串,并在首次访问 Identity API 前配置;物理键仍会叠加 Storage 全局前缀。
8
+ */
9
+ cacheKey?: string;
10
+ }
11
+ /** 浏览器或 uni-app 当前安装实例标识。 */
12
+ interface InstallationIdentity {
13
+ /**
14
+ * `Local` 中使用的业务键。
15
+ *
16
+ * @remarks 首次读取会锁定默认配置;之后不能再切换为其他业务键。
17
+ */
18
+ readonly cacheKey: string;
19
+ /**
20
+ * 当前内存中的安装标识;尚未取得标识或调用 {@link InstallationIdentity.clear clear} 后为空字符串。
21
+ *
22
+ * @remarks 直接赋值只改变内存,不会校验或持久化;通常应调用 {@link InstallationIdentity.getOrCreate getOrCreate}。
23
+ */
24
+ deviceId: string;
25
+ /**
26
+ * 删除当前 `cacheKey` 对应的持久化标识,并把 `deviceId` 重置为空字符串。
27
+ *
28
+ * @throws `Error` 当 Storage 尚未配置或当前平台存储不可用。
29
+ */
30
+ clear: () => void;
31
+ /**
32
+ * 按“显式参数、当前内存、持久化值、安全生成值”的优先级取得安装标识。
33
+ *
34
+ * @param installationId - 可选 UUID v4;传入时覆盖内存值和当前持久化值。
35
+ * @returns 已校验并同时写入 `deviceId` 与 `Local` 的 UUID v4。
36
+ * @throws `TypeError` 当显式参数、内存值或持久化值不是 UUID v4。
37
+ * @throws `Error` 当 Storage 尚未配置,或生成新值时平台缺少 Web Crypto。
38
+ */
39
+ getOrCreate: (installationId?: string) => string;
40
+ /**
41
+ * 读取并校验当前 `cacheKey` 对应的持久化标识。
42
+ *
43
+ * @remarks 该方法不修改 `deviceId`,只负责读取;过期记录由 Storage 视为缺失。
44
+ * @returns 已持久化的 UUID v4;键缺失或过期时返回 `undefined`。
45
+ * @throws `TypeError` 当持久化值不是字符串或不是 UUID v4。
46
+ * @throws `Error` 当 Storage 尚未配置或当前平台存储不可用。
47
+ */
48
+ read: () => string | undefined;
49
+ }
50
+ /**
51
+ * 在应用入口配置安装标识使用的 Storage 业务键。
52
+ *
53
+ * @remarks 必须在首次读取 `installationIdentity.cacheKey` 或调用其他安装标识 API 前执行。相同配置
54
+ * 可以幂等重复调用;切换到不同键会抛错,避免同一页面产生分裂状态。
55
+ * @param options - 安装标识配置;省略 `cacheKey` 时使用 `identity:installation-id`。
56
+ * @throws `TypeError` 当 `cacheKey` 不是非空字符串或包含外围空白。
57
+ * @throws `Error` 当安装标识已经使用另一个业务键初始化。
58
+ */
59
+ declare function configureInstallationIdentity(options?: InstallationIdentityConfiguration): void;
60
+ /**
61
+ * 全局安装标识状态。
62
+ *
63
+ * @remarks 使用前必须在应用入口调用 `configureStorage()`。默认随机源只使用 Web Crypto,
64
+ * 能力缺失时明确抛错,不回退到 `Math.random()`。该值不是硬件标识、认证凭证或安全边界。
65
+ */
66
+ declare const installationIdentity: InstallationIdentity;
67
+ /**
68
+ * 返回已有安装标识,否则创建并持久化一个安全 UUID v4。
69
+ *
70
+ * @param installationId - 可选的显式安装标识;传入时会校验并覆盖当前持久化值。
71
+ * @returns 显式值、内存值、持久化值或新生成值中的最终安装标识。
72
+ * @throws `TypeError` 当显式值或持久化值不是 UUID v4。
73
+ * @throws `Error` 当 Storage 尚未配置或平台缺少 Web Crypto。
74
+ */
75
+ declare function getOrCreateInstallationId(installationId?: string): string;
76
+ //#endregion
77
+ export { InstallationIdentity, InstallationIdentityConfiguration, configureInstallationIdentity, getOrCreateInstallationId, installationIdentity };
78
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/identity/index.ts"],"mappings":";;UAMiB;;;;;;EAMhB;;;UAIgB;;;;;;WAMP;;;;;;EAMT;;;;;;EAMA;;;;;;;;;EASA,cAAc;;;;;;;;;EASd;;;;;;;;;;;iBAmCe,8BAA8B,UAAS;;;;;;;cAkB1C,sBAAsB;;;;;;;;;iBAoCnB,0BAA0B"}
@@ -0,0 +1,87 @@
1
+ import { Local } from "../storage/index.mjs";
2
+ import { generateUuidV4, isUuidV4 } from "../string/index.mjs";
3
+ //#region src/identity/index.ts
4
+ const defaultInstallationIdentityStorageKey = "identity:installation-id";
5
+ /**
6
+ * 校验安装标识格式。
7
+ *
8
+ * @param value - 外部传入或从 Storage 读取的候选值。
9
+ * @throws `TypeError` 当值不是 RFC 4122 UUID v4。
10
+ */
11
+ const assertInstallationId = (value) => {
12
+ if (!isUuidV4(value)) throw new TypeError("Installation Identity values must be RFC 4122 version 4 UUIDs.");
13
+ };
14
+ let activeStorageKey;
15
+ /**
16
+ * 取得已经锁定的安装标识业务键。
17
+ *
18
+ * @remarks 首次读取会锁定默认值,防止标识已经写入后再切换键而产生两个安装标识。
19
+ * @returns 应用于后续全部 Identity 操作的业务键。
20
+ */
21
+ const getInstallationIdentityStorageKey = () => {
22
+ activeStorageKey ??= defaultInstallationIdentityStorageKey;
23
+ return activeStorageKey;
24
+ };
25
+ /**
26
+ * 在应用入口配置安装标识使用的 Storage 业务键。
27
+ *
28
+ * @remarks 必须在首次读取 `installationIdentity.cacheKey` 或调用其他安装标识 API 前执行。相同配置
29
+ * 可以幂等重复调用;切换到不同键会抛错,避免同一页面产生分裂状态。
30
+ * @param options - 安装标识配置;省略 `cacheKey` 时使用 `identity:installation-id`。
31
+ * @throws `TypeError` 当 `cacheKey` 不是非空字符串或包含外围空白。
32
+ * @throws `Error` 当安装标识已经使用另一个业务键初始化。
33
+ */
34
+ function configureInstallationIdentity(options = {}) {
35
+ const cacheKey = options.cacheKey ?? defaultInstallationIdentityStorageKey;
36
+ if (typeof cacheKey !== "string" || cacheKey.length === 0 || cacheKey.trim() !== cacheKey) throw new TypeError("Installation Identity cacheKey must be a non-empty string without surrounding whitespace.");
37
+ if (activeStorageKey === void 0) {
38
+ activeStorageKey = cacheKey;
39
+ return;
40
+ }
41
+ if (activeStorageKey !== cacheKey) throw new Error("Installation Identity has already been configured with a different cacheKey.");
42
+ }
43
+ /**
44
+ * 全局安装标识状态。
45
+ *
46
+ * @remarks 使用前必须在应用入口调用 `configureStorage()`。默认随机源只使用 Web Crypto,
47
+ * 能力缺失时明确抛错,不回退到 `Math.random()`。该值不是硬件标识、认证凭证或安全边界。
48
+ */
49
+ const installationIdentity = {
50
+ get cacheKey() {
51
+ return getInstallationIdentityStorageKey();
52
+ },
53
+ deviceId: "",
54
+ clear() {
55
+ Local.remove(installationIdentity.cacheKey);
56
+ installationIdentity.deviceId = "";
57
+ },
58
+ getOrCreate(installationId) {
59
+ const candidate = installationId ?? (installationIdentity.deviceId.length > 0 ? installationIdentity.deviceId : installationIdentity.read()) ?? generateUuidV4();
60
+ assertInstallationId(candidate);
61
+ Local.set(installationIdentity.cacheKey, candidate);
62
+ installationIdentity.deviceId = candidate;
63
+ return candidate;
64
+ },
65
+ read() {
66
+ const stored = Local.get(installationIdentity.cacheKey);
67
+ if (stored === void 0) return void 0;
68
+ if (typeof stored !== "string") throw new TypeError("The stored identity is corrupted.");
69
+ assertInstallationId(stored);
70
+ return stored;
71
+ }
72
+ };
73
+ /**
74
+ * 返回已有安装标识,否则创建并持久化一个安全 UUID v4。
75
+ *
76
+ * @param installationId - 可选的显式安装标识;传入时会校验并覆盖当前持久化值。
77
+ * @returns 显式值、内存值、持久化值或新生成值中的最终安装标识。
78
+ * @throws `TypeError` 当显式值或持久化值不是 UUID v4。
79
+ * @throws `Error` 当 Storage 尚未配置或平台缺少 Web Crypto。
80
+ */
81
+ function getOrCreateInstallationId(installationId) {
82
+ return installationIdentity.getOrCreate(installationId);
83
+ }
84
+ //#endregion
85
+ export { configureInstallationIdentity, getOrCreateInstallationId, installationIdentity };
86
+
87
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/identity/index.ts"],"sourcesContent":["import { Local } from \"../storage/index.js\";\nimport { generateUuidV4, isUuidV4 } from \"../string/index.js\";\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` 当 Storage 尚未配置或当前平台存储不可用。\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` 当 Storage 尚未配置,或生成新值时平台缺少 Web Crypto。\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` 当 Storage 尚未配置或当前平台存储不可用。\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(\"Installation Identity values must be RFC 4122 version 4 UUIDs.\");\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(\"Installation Identity cacheKey must be a non-empty 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(\"Installation Identity has already been configured with a different cacheKey.\");\n}\n\n/**\n * 全局安装标识状态。\n *\n * @remarks 使用前必须在应用入口调用 `configureStorage()`。默认随机源只使用 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 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` 当 Storage 尚未配置或平台缺少 Web Crypto。\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,gEAAgE;AAC3G;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,2FAA2F;CAEhH,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,mCAAmC;EACvF,qBAAqB,MAAM;EAC3B,OAAO;CACR;AACD;;;;;;;;;AAUA,SAAgB,0BAA0B,gBAAiC;CAC1E,OAAO,qBAAqB,YAAY,cAAc;AACvD"}
@@ -0,0 +1,24 @@
1
+ import { KeySelector, allEqualBy, chunk, difference, groupBy, hasDuplicatesBy, intersection, partition, removeNullishValues, unique, uniqueBy } from "./array/index.mjs";
2
+ import { AbortOptions, ConcurrentMapOptions, DebouncedFunction, RetryContext, RetryOptions, ThrottledFunction, TimeoutOptions, debounce, mapConcurrent, retry, sleep, throttle, withTimeout } from "./async/index.mjs";
3
+ import { decodeBase64, decodeBase64Bytes, decodeBase64Url, decodeBase64UrlBytes, decodeLatin1Base64, decodeSecureBase64, encodeBase64, encodeBase64Bytes, encodeBase64Url, encodeBase64UrlBytes, encodeLatin1Base64, encodeSecureBase64 } from "./base64/index.mjs";
4
+ import { RgbColor, RgbaColor, contrastRatio, formatHexColor, mixHexColorWithBlack, mixHexColorWithWhite, mixHexColors, parseHexColor, pickHigherContrastColor, relativeLuminance } from "./color/index.mjs";
5
+ import { EcNamedCurve, LegacyAesCipherMode, PasswordEncryptionOptions, PemKeyPair, RsaKeyPairOptions, TextOrBytes, areBytesEqualWithoutEarlyExit, decryptLegacyAesCbc, decryptLegacyAesEcb, decryptLegacyAesValue, decryptRsaOaep, decryptTextWithPassword, deriveEcdhSecret, encryptLegacyAes, encryptLegacyAesCbc, encryptLegacyAesEcb, encryptRsaOaep, encryptTextWithPassword, generateEcdhKeyPair, generateEcdsaKeyPair, generateRandomBytes, generateRsaOaepKeyPair, md5Hex, md5UpperHex, sha1Hex, sha1UpperHex, sha256Bytes, sha256Hex, signEcdsa, verifyEcdsa } from "./crypto/index.mjs";
6
+ import { DateInput, DateRangeShortcut, DateShortcut, RelativeTimeOptions, addDays, addMonths, addYears, createDateRangeShortcuts, createDateShortcuts, createOneMonthRangeFromToday, endOfDay, formatChineseRelativeTime, formatRelativeTime, getLocalDayBounds, getLocalTimeGreeting, getStartOfToday, isDateAfterNow, isFuture, isSameDay, isValidDate, isWithinInterval, startOfDay, toDate } from "./date/index.mjs";
7
+ import { StyleInput, StyleObject, StyleValue, addCssUnit, serializeStyle } from "./dom/style.mjs";
8
+ import { RuntimeKind, detectRuntime, hasWebCrypto, isBrowser, isMobileUserAgent, isNode, isTabletUserAgent, isUniApp, isWebWorker } from "./env/index.mjs";
9
+ import { InstallationIdentity, InstallationIdentityConfiguration, configureInstallationIdentity, getOrCreateInstallationId, installationIdentity } from "./identity/index.mjs";
10
+ import { LogLevel, Logger, LoggerOptions, LoggerSink, createLogger, logger } from "./logger/index.mjs";
11
+ import { FormatBytesOptions, average, clamp, formatBytes, inRange, lerp, roundTo, secureRandomInt, sum } from "./number/index.mjs";
12
+ import { QueryPrimitive, QueryStringOptions, QueryValue, hasOwn, isPlainObject, mapValues, omit, pick, shallowEqual, toQueryString } from "./object/index.mjs";
13
+ import { Local, Session, StorageArea, StorageCodec, StorageConfiguration, StorageWriteOptions, base64StorageCodec, configureStorage, isStorageConfigured } from "./storage/index.mjs";
14
+ import { ParsedQueryParameters, StringLocale, camelCase, decodeURIComponentRepeatedly, escapeHtml, generateUuidV4, isUuidV4, isValidJson, kebabCase, lowerFirst, normalizeWhitespace, parseQueryString, pascalCase, secureRandomString, splitWords, truncateGraphemes, upperFirst } from "./string/index.mjs";
15
+ import { EmitHandlers, useEmits } from "./vue/emits.mjs";
16
+ import { useExpose } from "./vue/expose.mjs";
17
+ import { AwaitableFunction, callOptionalFunction } from "./vue/func.mjs";
18
+ import { Installable, TSXWithInstall, VueInstallValue, VueRegistrationTarget, withInstall, withInstallDirective, withNoopInstall } from "./vue/install.mjs";
19
+ import { definePropType, useProps } from "./vue/props.mjs";
20
+ import { useRender } from "./vue/render.mjs";
21
+ import { TypedSlots, TypedSlotsDeclaration, makeSlots } from "./vue/slots.mjs";
22
+ import { withDefineType } from "./vue/with.mjs";
23
+ import "./vue/index.mjs";
24
+ export { AbortOptions, AwaitableFunction, ConcurrentMapOptions, DateInput, DateRangeShortcut, DateShortcut, DebouncedFunction, EcNamedCurve, EmitHandlers, FormatBytesOptions, Installable, InstallationIdentity, InstallationIdentityConfiguration, KeySelector, LegacyAesCipherMode, Local, LogLevel, Logger, LoggerOptions, LoggerSink, ParsedQueryParameters, PasswordEncryptionOptions, PemKeyPair, QueryPrimitive, QueryStringOptions, QueryValue, RelativeTimeOptions, RetryContext, RetryOptions, RgbColor, RgbaColor, RsaKeyPairOptions, RuntimeKind, Session, StorageArea, StorageCodec, StorageConfiguration, StorageWriteOptions, StringLocale, StyleInput, StyleObject, StyleValue, TSXWithInstall, TextOrBytes, ThrottledFunction, TimeoutOptions, TypedSlots, TypedSlotsDeclaration, VueInstallValue, VueRegistrationTarget, addCssUnit, addDays, addMonths, addYears, allEqualBy, areBytesEqualWithoutEarlyExit, average, base64StorageCodec, callOptionalFunction, camelCase, chunk, clamp, configureInstallationIdentity, configureStorage, contrastRatio, createDateRangeShortcuts, createDateShortcuts, createLogger, createOneMonthRangeFromToday, debounce, decodeBase64, decodeBase64Bytes, decodeBase64Url, decodeBase64UrlBytes, decodeLatin1Base64, decodeSecureBase64, decodeURIComponentRepeatedly, decryptLegacyAesCbc, decryptLegacyAesEcb, decryptLegacyAesValue, decryptRsaOaep, decryptTextWithPassword, definePropType, deriveEcdhSecret, detectRuntime, difference, encodeBase64, encodeBase64Bytes, encodeBase64Url, encodeBase64UrlBytes, encodeLatin1Base64, encodeSecureBase64, encryptLegacyAes, encryptLegacyAesCbc, encryptLegacyAesEcb, encryptRsaOaep, encryptTextWithPassword, endOfDay, escapeHtml, formatBytes, formatChineseRelativeTime, formatHexColor, formatRelativeTime, generateEcdhKeyPair, generateEcdsaKeyPair, generateRandomBytes, generateRsaOaepKeyPair, generateUuidV4, getLocalDayBounds, getLocalTimeGreeting, getOrCreateInstallationId, getStartOfToday, groupBy, hasDuplicatesBy, hasOwn, hasWebCrypto, inRange, installationIdentity, intersection, isBrowser, isDateAfterNow, isFuture, isMobileUserAgent, isNode, isPlainObject, isSameDay, isStorageConfigured, isTabletUserAgent, isUniApp, isUuidV4, isValidDate, isValidJson, isWebWorker, isWithinInterval, kebabCase, lerp, logger, lowerFirst, makeSlots, mapConcurrent, mapValues, md5Hex, md5UpperHex, mixHexColorWithBlack, mixHexColorWithWhite, mixHexColors, normalizeWhitespace, omit, parseHexColor, parseQueryString, partition, pascalCase, pick, pickHigherContrastColor, relativeLuminance, removeNullishValues, retry, roundTo, secureRandomInt, secureRandomString, serializeStyle, sha1Hex, sha1UpperHex, sha256Bytes, sha256Hex, shallowEqual, signEcdsa, sleep, splitWords, startOfDay, sum, throttle, toDate, toQueryString, truncateGraphemes, unique, uniqueBy, upperFirst, useEmits, useExpose, useProps, useRender, verifyEcdsa, withDefineType, withInstall, withInstallDirective, withNoopInstall, withTimeout };
package/dist/index.mjs ADDED
@@ -0,0 +1,23 @@
1
+ import { allEqualBy, chunk, difference, groupBy, hasDuplicatesBy, intersection, partition, removeNullishValues, unique, uniqueBy } from "./array/index.mjs";
2
+ import { debounce, mapConcurrent, retry, sleep, throttle, withTimeout } from "./async/index.mjs";
3
+ import { average, clamp, formatBytes, inRange, lerp, roundTo, secureRandomInt, sum } from "./number/index.mjs";
4
+ import { decodeBase64, decodeBase64Bytes, decodeBase64Url, decodeBase64UrlBytes, decodeLatin1Base64, decodeSecureBase64, encodeBase64, encodeBase64Bytes, encodeBase64Url, encodeBase64UrlBytes, encodeLatin1Base64, encodeSecureBase64 } from "./base64/index.mjs";
5
+ import { contrastRatio, formatHexColor, mixHexColorWithBlack, mixHexColorWithWhite, mixHexColors, parseHexColor, pickHigherContrastColor, relativeLuminance } from "./color/index.mjs";
6
+ import { areBytesEqualWithoutEarlyExit, decryptLegacyAesCbc, decryptLegacyAesEcb, decryptLegacyAesValue, decryptRsaOaep, decryptTextWithPassword, deriveEcdhSecret, encryptLegacyAes, encryptLegacyAesCbc, encryptLegacyAesEcb, encryptRsaOaep, encryptTextWithPassword, generateEcdhKeyPair, generateEcdsaKeyPair, generateRandomBytes, generateRsaOaepKeyPair, md5Hex, md5UpperHex, sha1Hex, sha1UpperHex, sha256Bytes, sha256Hex, signEcdsa, verifyEcdsa } from "./crypto/index.mjs";
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
+ import { addCssUnit, serializeStyle } from "./dom/style.mjs";
9
+ import { detectRuntime, hasWebCrypto, isBrowser, isMobileUserAgent, isNode, isTabletUserAgent, isUniApp, isWebWorker } from "./env/index.mjs";
10
+ import { Local, Session, base64StorageCodec, configureStorage, isStorageConfigured } from "./storage/index.mjs";
11
+ import { camelCase, decodeURIComponentRepeatedly, escapeHtml, generateUuidV4, isUuidV4, isValidJson, kebabCase, lowerFirst, normalizeWhitespace, parseQueryString, pascalCase, secureRandomString, splitWords, truncateGraphemes, upperFirst } from "./string/index.mjs";
12
+ import { configureInstallationIdentity, getOrCreateInstallationId, installationIdentity } from "./identity/index.mjs";
13
+ import { createLogger, logger } from "./logger/index.mjs";
14
+ import { hasOwn, isPlainObject, mapValues, omit, pick, shallowEqual, toQueryString } from "./object/index.mjs";
15
+ import { useEmits } from "./vue/emits.mjs";
16
+ import { useExpose } from "./vue/expose.mjs";
17
+ import { callOptionalFunction } from "./vue/func.mjs";
18
+ import { withInstall, withInstallDirective, withNoopInstall } from "./vue/install.mjs";
19
+ import { definePropType, useProps } from "./vue/props.mjs";
20
+ import { useRender } from "./vue/render.mjs";
21
+ import { makeSlots } from "./vue/slots.mjs";
22
+ import { withDefineType } from "./vue/with.mjs";
23
+ export { Local, Session, addCssUnit, addDays, addMonths, addYears, allEqualBy, areBytesEqualWithoutEarlyExit, average, base64StorageCodec, callOptionalFunction, camelCase, chunk, clamp, configureInstallationIdentity, configureStorage, contrastRatio, createDateRangeShortcuts, createDateShortcuts, createLogger, createOneMonthRangeFromToday, debounce, decodeBase64, decodeBase64Bytes, decodeBase64Url, decodeBase64UrlBytes, decodeLatin1Base64, decodeSecureBase64, decodeURIComponentRepeatedly, decryptLegacyAesCbc, decryptLegacyAesEcb, decryptLegacyAesValue, decryptRsaOaep, decryptTextWithPassword, definePropType, deriveEcdhSecret, detectRuntime, difference, encodeBase64, encodeBase64Bytes, encodeBase64Url, encodeBase64UrlBytes, encodeLatin1Base64, encodeSecureBase64, encryptLegacyAes, encryptLegacyAesCbc, encryptLegacyAesEcb, encryptRsaOaep, encryptTextWithPassword, endOfDay, escapeHtml, formatBytes, formatChineseRelativeTime, formatHexColor, formatRelativeTime, generateEcdhKeyPair, generateEcdsaKeyPair, generateRandomBytes, generateRsaOaepKeyPair, generateUuidV4, getLocalDayBounds, getLocalTimeGreeting, getOrCreateInstallationId, getStartOfToday, groupBy, hasDuplicatesBy, hasOwn, hasWebCrypto, inRange, installationIdentity, intersection, isBrowser, isDateAfterNow, isFuture, isMobileUserAgent, isNode, isPlainObject, isSameDay, isStorageConfigured, isTabletUserAgent, isUniApp, isUuidV4, isValidDate, isValidJson, isWebWorker, isWithinInterval, kebabCase, lerp, logger, lowerFirst, makeSlots, mapConcurrent, mapValues, md5Hex, md5UpperHex, mixHexColorWithBlack, mixHexColorWithWhite, mixHexColors, normalizeWhitespace, omit, parseHexColor, parseQueryString, partition, pascalCase, pick, pickHigherContrastColor, relativeLuminance, removeNullishValues, retry, roundTo, secureRandomInt, secureRandomString, serializeStyle, sha1Hex, sha1UpperHex, sha256Bytes, sha256Hex, shallowEqual, signEcdsa, sleep, splitWords, startOfDay, sum, throttle, toDate, toQueryString, truncateGraphemes, unique, uniqueBy, upperFirst, useEmits, useExpose, useProps, useRender, verifyEcdsa, withDefineType, withInstall, withInstallDirective, withNoopInstall, withTimeout };
@@ -0,0 +1,36 @@
1
+ //#region src/internal/text.ts
2
+ const runtimeEncodingGlobals = globalThis;
3
+ /**
4
+ * 延迟解析 UTF-8 TextDecoder,确保模块导入阶段不依赖 Encoding API。
5
+ *
6
+ * @returns 启用 Fatal 模式的新解码器,非法 UTF-8 会直接失败。
7
+ * @throws `Error` 当当前平台没有提供 `TextDecoder`。
8
+ */
9
+ const getTextDecoder = () => {
10
+ const TextDecoderConstructor = runtimeEncodingGlobals.TextDecoder;
11
+ if (typeof TextDecoderConstructor !== "function") throw new Error("TextDecoder is unavailable in the current runtime.");
12
+ return new TextDecoderConstructor("utf-8", { fatal: true });
13
+ };
14
+ /**
15
+ * 延迟解析 TextEncoder,让纯字节 API 在缺少 Encoding API 的平台仍可导入。
16
+ *
17
+ * @returns 新建的 UTF-8 编码器。
18
+ * @throws `Error` 当当前平台没有提供 `TextEncoder`。
19
+ */
20
+ const getTextEncoder = () => {
21
+ const TextEncoderConstructor = runtimeEncodingGlobals.TextEncoder;
22
+ if (typeof TextEncoderConstructor !== "function") throw new Error("TextEncoder is unavailable in the current runtime.");
23
+ return new TextEncoderConstructor();
24
+ };
25
+ /**
26
+ * 在确认平台能力后把 JavaScript 字符串编码为 UTF-8。
27
+ *
28
+ * @param value - 待编码文本。
29
+ * @returns 使用独立 ArrayBuffer 的 UTF-8 字节数组。
30
+ * @throws `Error` 当当前平台没有提供 `TextEncoder`。
31
+ */
32
+ const encodeUtf8 = (value) => getTextEncoder().encode(value);
33
+ //#endregion
34
+ export { encodeUtf8, getTextDecoder, getTextEncoder };
35
+
36
+ //# sourceMappingURL=text.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.mjs","names":[],"sources":["../../src/internal/text.ts"],"sourcesContent":["/** 延迟访问 Encoding API 时使用的平台全局对象最小视图。 */\ninterface RuntimeEncodingGlobals {\n\t/** 可选 TextDecoder 构造器;缺失时只允许不依赖文本解码的 API 继续工作。 */\n\tTextDecoder?: typeof TextDecoder;\n\t/** 可选 TextEncoder 构造器;缺失时只允许纯字节 API 继续工作。 */\n\tTextEncoder?: typeof TextEncoder;\n}\n\nconst runtimeEncodingGlobals = globalThis as unknown as RuntimeEncodingGlobals;\n\n/**\n * 延迟解析 UTF-8 TextDecoder,确保模块导入阶段不依赖 Encoding API。\n *\n * @returns 启用 Fatal 模式的新解码器,非法 UTF-8 会直接失败。\n * @throws `Error` 当当前平台没有提供 `TextDecoder`。\n */\nexport const getTextDecoder = (): TextDecoder => {\n\tconst TextDecoderConstructor = runtimeEncodingGlobals.TextDecoder;\n\tif (typeof TextDecoderConstructor !== \"function\") {\n\t\tthrow new Error(\"TextDecoder is unavailable in the current runtime.\");\n\t}\n\treturn new TextDecoderConstructor(\"utf-8\", { fatal: true });\n};\n\n/**\n * 延迟解析 TextEncoder,让纯字节 API 在缺少 Encoding API 的平台仍可导入。\n *\n * @returns 新建的 UTF-8 编码器。\n * @throws `Error` 当当前平台没有提供 `TextEncoder`。\n */\nexport const getTextEncoder = (): TextEncoder => {\n\tconst TextEncoderConstructor = runtimeEncodingGlobals.TextEncoder;\n\tif (typeof TextEncoderConstructor !== \"function\") {\n\t\tthrow new Error(\"TextEncoder is unavailable in the current runtime.\");\n\t}\n\treturn new TextEncoderConstructor();\n};\n\n/**\n * 在确认平台能力后把 JavaScript 字符串编码为 UTF-8。\n *\n * @param value - 待编码文本。\n * @returns 使用独立 ArrayBuffer 的 UTF-8 字节数组。\n * @throws `Error` 当当前平台没有提供 `TextEncoder`。\n */\nexport const encodeUtf8 = (value: string): Uint8Array<ArrayBuffer> => getTextEncoder().encode(value);\n"],"mappings":";AAQA,MAAM,yBAAyB;;;;;;;AAQ/B,MAAa,uBAAoC;CAChD,MAAM,yBAAyB,uBAAuB;CACtD,IAAI,OAAO,2BAA2B,YACrC,MAAM,IAAI,MAAM,oDAAoD;CAErE,OAAO,IAAI,uBAAuB,SAAS,EAAE,OAAO,KAAK,CAAC;AAC3D;;;;;;;AAQA,MAAa,uBAAoC;CAChD,MAAM,yBAAyB,uBAAuB;CACtD,IAAI,OAAO,2BAA2B,YACrC,MAAM,IAAI,MAAM,oDAAoD;CAErE,OAAO,IAAI,uBAAuB;AACnC;;;;;;;;AASA,MAAa,cAAc,UAA2C,eAAe,CAAC,CAAC,OAAO,KAAK"}