@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
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * 判断 Query Value 是否为重复参数数组。
4
4
  *
5
- * @param value - 单值或数组形式的 Query Value。
5
+ * @param value - 单值或数组形式的 Query Value
6
6
  * @returns 是只读原始值数组时返回 `true`。
7
7
  */
8
8
  const isQueryPrimitiveArray = (value) => Array.isArray(value);
@@ -10,9 +10,9 @@ const isQueryPrimitiveArray = (value) => Array.isArray(value);
10
10
  * 安全写入结果对象的自有可枚举属性。
11
11
  *
12
12
  * @remarks 使用 `defineProperty` 避免 `__proto__` 触发 Setter,并统一创建可写、可配置的自有可枚举数据属性。
13
- * @param target - 要写入的结果对象。
14
- * @param key - 自有属性键。
15
- * @param value - 属性值。
13
+ * @param target - 要写入的结果对象
14
+ * @param key - 自有属性键
15
+ * @param value - 属性值
16
16
  */
17
17
  const defineEnumerableProperty = (target, key, value) => {
18
18
  Object.defineProperty(target, key, {
@@ -198,7 +198,7 @@ const equalObjects = (left, right, state) => {
198
198
  const leftKeys = getEnumerableOwnKeys(left);
199
199
  const rightKeys = getEnumerableOwnKeys(right);
200
200
  if (leftKeys.length !== rightKeys.length) return false;
201
- for (const key of leftKeys) if (!Object.hasOwn(right, key)) return false;
201
+ for (const key of leftKeys) if (!Object.prototype.hasOwnProperty.call(right, key)) return false;
202
202
  return compareTrackedPair(left, right, state, () => {
203
203
  let compareConstructors = true;
204
204
  for (const key of leftKeys) {
@@ -246,7 +246,7 @@ function isEqualValue(left, right, state) {
246
246
  /**
247
247
  * 判断值是否是普通对象。
248
248
  *
249
- * @param value - 任意待检查值。
249
+ * @param value - 任意待检查值
250
250
  * @returns 原型为 `Object.prototype` 或 `null` 时返回 `true`。
251
251
  */
252
252
  function isPlainObject(value) {
@@ -258,19 +258,19 @@ function isPlainObject(value) {
258
258
  * 安全判断对象是否拥有自己的属性。
259
259
  *
260
260
  * @remarks 不调用可能被对象覆盖的 `hasOwnProperty`。
261
- * @param value - 待检查对象。
262
- * @param key - 字符串、数字或 Symbol 属性键。
261
+ * @param value - 待检查对象
262
+ * @param key - 字符串、数字或 Symbol 属性键
263
263
  * @returns 属性为对象自有属性时返回 `true`,并收窄键类型。
264
264
  */
265
265
  function hasOwn(value, key) {
266
- return Object.hasOwn(value, key);
266
+ return Object.prototype.hasOwnProperty.call(value, key);
267
267
  }
268
268
  /**
269
269
  * 递归创建值的深层副本。
270
270
  *
271
271
  * @remarks 支持循环引用、共享引用、Symbol 键、对象原型、ArrayBuffer、DataView、Date、Map、RegExp、Set 和 TypedArray。
272
272
  * Map 的键保持原引用,函数及其他不可克隆值在嵌套位置保持原引用;只复制自有可枚举属性。
273
- * @param value - 需要深复制的任意值。
273
+ * @param value - 需要深复制的任意值
274
274
  * @returns 与输入类型一致且不共享可克隆嵌套值的新值;原始类型直接返回自身。
275
275
  */
276
276
  function cloneDeep(value) {
@@ -281,8 +281,8 @@ function cloneDeep(value) {
281
281
  *
282
282
  * @remarks 原始值使用 SameValueZero 语义;支持循环引用、数组、对象、ArrayBuffer、DataView、Date、Error、Map、RegExp、Set、Symbol 和 TypedArray。
283
283
  * 对象只比较自有可枚举字符串与 Symbol 属性,函数及其他不支持的宿主对象仅在引用相同时相等。
284
- * @param left - 第一待比较值。
285
- * @param right - 第二待比较值。
284
+ * @param left - 第一待比较值
285
+ * @param right - 第二待比较值
286
286
  * @returns 两个值深度等价时返回 `true`。
287
287
  */
288
288
  function isEqual(left, right) {
@@ -304,9 +304,9 @@ function omit(source, keys) {
304
304
  /**
305
305
  * 按条件排除对象的自有可枚举属性。
306
306
  *
307
- * @param source - 不会被修改的源对象。
307
+ * @param source - 不会被修改的源对象
308
308
  * @param predicate - 接收属性值、键和源对象;返回真值时排除该属性。
309
- * @returns 由未匹配属性组成的新对象。
309
+ * @returns 由未匹配属性组成的新对象
310
310
  */
311
311
  function omitBy(source, predicate) {
312
312
  const result = {};
@@ -316,9 +316,9 @@ function omitBy(source, predicate) {
316
316
  /**
317
317
  * 按条件选择对象的自有可枚举属性。
318
318
  *
319
- * @param source - 不会被修改的源对象。
319
+ * @param source - 不会被修改的源对象
320
320
  * @param predicate - 接收属性值、键和源对象;返回真值时保留该属性。
321
- * @returns 由匹配属性组成的新对象。
321
+ * @returns 由匹配属性组成的新对象
322
322
  */
323
323
  function pickBy(source, predicate) {
324
324
  const result = {};
@@ -328,9 +328,9 @@ function pickBy(source, predicate) {
328
328
  /**
329
329
  * 映射对象的自有可枚举属性值。
330
330
  *
331
- * @param source - 不会被修改的源对象。
332
- * @param mapper - 接收值、键和源对象的映射函数。
333
- * @returns 保留原键的新对象。
331
+ * @param source - 不会被修改的源对象
332
+ * @param mapper - 接收值、键和源对象的映射函数
333
+ * @returns 保留原键的新对象
334
334
  */
335
335
  function mapValues(source, mapper) {
336
336
  const result = {};
@@ -341,8 +341,8 @@ function mapValues(source, mapper) {
341
341
  * 对自有可枚举属性执行 SameValue 浅比较。
342
342
  *
343
343
  * @remarks 嵌套对象只比较引用;`NaN` 相等,`0` 与 `-0` 不相等。
344
- * @param left - 第一对象。
345
- * @param right - 第二对象。
344
+ * @param left - 第一对象
345
+ * @param right - 第二对象
346
346
  * @returns 自有可枚举键集合与对应值均满足 SameValue 时返回 `true`。
347
347
  */
348
348
  function shallowEqual(left, right) {
@@ -350,38 +350,39 @@ function shallowEqual(left, right) {
350
350
  const leftKeys = Reflect.ownKeys(left).filter((key) => Object.prototype.propertyIsEnumerable.call(left, key));
351
351
  const rightKeys = Reflect.ownKeys(right).filter((key) => Object.prototype.propertyIsEnumerable.call(right, key));
352
352
  if (leftKeys.length !== rightKeys.length) return false;
353
- return leftKeys.every((key) => Object.hasOwn(right, key) && Object.is(Reflect.get(left, key), Reflect.get(right, key)));
353
+ return leftKeys.every((key) => Object.prototype.hasOwnProperty.call(right, key) && Object.is(Reflect.get(left, key), Reflect.get(right, key)));
354
354
  }
355
355
  /**
356
356
  * 把 Query 原始值规范化为文本。
357
357
  *
358
- * @param value - 已排除空值的字符串、数字、布尔值或 BigInt。
359
- * @returns 与 URLSearchParams 兼容的文本值。
358
+ * @param value - 已排除空值的字符串、数字、布尔值或 BigInt
359
+ * @returns 与 URLSearchParams 兼容的文本值
360
360
  * @throws `RangeError` 当数字不是有限值。
361
361
  */
362
362
  const serializeQueryValue = (value) => {
363
- if (typeof value === "number" && !Number.isFinite(value)) throw new RangeError("查询参数中的数字必须是有限数。");
363
+ if (typeof value === "number" && !Number.isFinite(value)) throw new RangeError("Query parameter numbers must be finite.");
364
364
  return String(value);
365
365
  };
366
366
  /**
367
367
  * 将对象序列化为标准 URL 查询字符串。
368
368
  *
369
369
  * @remarks `null` 与 `undefined` 被跳过;数组使用重复键;返回值不会修改输入。
370
- * @param value - 查询参数对象。
371
- * @param options - 排序、空格和问号前缀选项。
370
+ * @param value - 查询参数对象
371
+ * @param options - 排序、空格和问号前缀选项
372
372
  * @returns URL 编码后的查询字符串;没有参数时始终返回空字符串。
373
373
  * @throws `RangeError` 当参数包含 `NaN` 或无穷数字。
374
+ * @throws `URIError` 当键或值包含孤立的 UTF-16 代理项。
374
375
  */
375
376
  function toQueryString(value, options = {}) {
376
377
  const entries = Object.entries(value);
377
378
  if (options.sort) entries.sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0);
378
- const parameters = new URLSearchParams();
379
+ const parameters = [];
379
380
  for (const [key, rawValue] of entries) {
380
381
  const values = isQueryPrimitiveArray(rawValue) ? rawValue : [rawValue];
381
- for (const item of values) if (item !== null && item !== void 0) parameters.append(key, serializeQueryValue(item));
382
+ for (const item of values) if (item !== null && item !== void 0) parameters.push(`${encodeURIComponent(key)}=${encodeURIComponent(serializeQueryValue(item))}`);
382
383
  }
383
- let result = parameters.toString();
384
- if (options.space === "percent") result = result.replace(/\+/gu, "%20");
384
+ let result = parameters.join("&").replace(/[!'()~]/gu, (character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`);
385
+ if (options.space !== "percent") result = result.replace(/%20/gu, "+");
385
386
  return result && options.prefixQuestionMark ? `?${result}` : result;
386
387
  }
387
388
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/object/index.ts"],"sourcesContent":["/** URL 查询参数支持的单值类型。 */\nexport type QueryPrimitive = bigint | boolean | number | string | null | undefined;\n\n/** URL 查询参数值;数组使用重复键表示。 */\nexport type QueryValue = QueryPrimitive | readonly QueryPrimitive[];\n\n/**\n * 判断 Query Value 是否为重复参数数组。\n *\n * @param value - 单值或数组形式的 Query Value。\n * @returns 是只读原始值数组时返回 `true`。\n */\nconst isQueryPrimitiveArray = (value: QueryValue): value is readonly QueryPrimitive[] => Array.isArray(value);\n\n/** {@link toQueryString} 的序列化选项。 */\nexport interface QueryStringOptions {\n\t/** 返回非空结果时是否添加 `?`;默认 `false`。 */\n\tprefixQuestionMark?: boolean;\n\t/** 是否按键的 UTF-16 码元顺序稳定排序;默认保留对象枚举顺序。 */\n\tsort?: boolean;\n\t/** 空格编码方式;默认遵循表单编码并输出 `+`。 */\n\tspace?: \"percent\" | \"plus\";\n}\n\n/**\n * 安全写入结果对象的自有可枚举属性。\n *\n * @remarks 使用 `defineProperty` 避免 `__proto__` 触发 Setter,并统一创建可写、可配置的自有可枚举数据属性。\n * @param target - 要写入的结果对象。\n * @param key - 自有属性键。\n * @param value - 属性值。\n */\nconst defineEnumerableProperty = (target: object, key: PropertyKey, value: unknown): void => {\n\tObject.defineProperty(target, key, { configurable: true, enumerable: true, value, writable: true });\n};\n\nconst typedArrayTags = new Set([\n\t\"[object BigInt64Array]\",\n\t\"[object BigUint64Array]\",\n\t\"[object Float32Array]\",\n\t\"[object Float64Array]\",\n\t\"[object Int8Array]\",\n\t\"[object Int16Array]\",\n\t\"[object Int32Array]\",\n\t\"[object Uint8Array]\",\n\t\"[object Uint8ClampedArray]\",\n\t\"[object Uint16Array]\",\n\t\"[object Uint32Array]\",\n]);\n\n/** 使用源值的构造器创建同类空实例。 */\nconst createUsingConstructor = (value: object, arguments_: readonly unknown[]): object => {\n\tconst constructor: unknown = Reflect.get(value, \"constructor\");\n\treturn typeof constructor === \"function\" ? (Reflect.construct(constructor, arguments_) as object) : {};\n};\n\n/** 复制 ArrayBufferLike 的当前字节,不与源值共享底层内存。 */\nconst cloneArrayBuffer = (value: ArrayBufferLike): ArrayBufferLike => {\n\tconst result = createUsingConstructor(value, [value.byteLength]) as ArrayBufferLike;\n\tnew Uint8Array(result).set(new Uint8Array(value));\n\treturn result;\n};\n\n/** 递归复制值,并记录已复制对象以还原循环引用和共享引用。 */\nconst cloneDeepValue = (value: unknown, clones: WeakMap<object, object>, isRoot: boolean): unknown => {\n\tif ((typeof value !== \"object\" && typeof value !== \"function\") || value === null) return value;\n\n\tconst source = value;\n\tconst existing = clones.get(source);\n\tif (existing !== undefined) return existing;\n\tif (typeof source === \"function\" && !isRoot) return source;\n\n\tconst tag = Object.prototype.toString.call(source);\n\tlet result: object;\n\tlet pendingBuffer: { source: ArrayBufferLike; result: ArrayBufferLike } | undefined;\n\t// 先登记底层缓冲区,视图登记后再复制其附加属性,避免缓冲区与视图相互引用时重复构造。\n\tconst getBufferClone = (buffer: ArrayBufferLike): ArrayBufferLike => {\n\t\tconst existingBuffer = clones.get(buffer);\n\t\tif (existingBuffer !== undefined) return existingBuffer as ArrayBufferLike;\n\t\tconst clonedBuffer = cloneArrayBuffer(buffer);\n\t\tclones.set(buffer, clonedBuffer);\n\t\tpendingBuffer = { source: buffer, result: clonedBuffer };\n\t\treturn clonedBuffer;\n\t};\n\tif (Array.isArray(source)) {\n\t\t// 只复制实际存在的自有可枚举键,保留空洞、附加字符串属性和 Symbol 属性。\n\t\tresult = createUsingConstructor(source, [source.length]);\n\t} else if (typeof source === \"function\") {\n\t\tresult = {};\n\t} else {\n\t\tswitch (tag) {\n\t\t\tcase \"[object Arguments]\":\n\t\t\t\tresult = {};\n\t\t\t\tbreak;\n\t\t\tcase \"[object ArrayBuffer]\":\n\t\t\tcase \"[object SharedArrayBuffer]\":\n\t\t\t\tresult = cloneArrayBuffer(source as ArrayBufferLike);\n\t\t\t\tbreak;\n\t\t\tcase \"[object Boolean]\":\n\t\t\t\tresult = createUsingConstructor(source, [(source as { valueOf: () => boolean }).valueOf()]);\n\t\t\t\tbreak;\n\t\t\tcase \"[object DataView]\": {\n\t\t\t\tconst view = source as DataView;\n\t\t\t\tresult = createUsingConstructor(source, [getBufferClone(view.buffer), view.byteOffset, view.byteLength]);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"[object Date]\":\n\t\t\t\tresult = createUsingConstructor(source, [(source as Date).getTime()]);\n\t\t\t\tbreak;\n\t\t\tcase \"[object Map]\":\n\t\t\tcase \"[object Set]\":\n\t\t\t\tresult = createUsingConstructor(source, []);\n\t\t\t\tbreak;\n\t\t\tcase \"[object Number]\":\n\t\t\t\tresult = createUsingConstructor(source, [(source as { valueOf: () => number }).valueOf()]);\n\t\t\t\tbreak;\n\t\t\tcase \"[object Object]\": {\n\t\t\t\tconst prototype = Object.getPrototypeOf(source) as object | null;\n\t\t\t\tresult = Object.create(prototype) as object;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"[object RegExp]\": {\n\t\t\t\tconst expression = source as RegExp;\n\t\t\t\tconst clonedExpression = new RegExp(expression.source, expression.flags);\n\t\t\t\tclonedExpression.lastIndex = expression.lastIndex;\n\t\t\t\tresult = clonedExpression;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"[object String]\":\n\t\t\t\tresult = createUsingConstructor(source, [(source as { valueOf: () => string }).valueOf()]);\n\t\t\t\tbreak;\n\t\t\tcase \"[object Symbol]\":\n\t\t\t\tresult = Object((source as { valueOf: () => symbol }).valueOf()) as object;\n\t\t\t\tbreak;\n\t\t\tdefault: {\n\t\t\t\tif (!typedArrayTags.has(tag)) return isRoot ? {} : source;\n\t\t\t\tconst view = source as ArrayBufferView & { readonly length: number };\n\t\t\t\tresult = createUsingConstructor(source, [getBufferClone(view.buffer), view.byteOffset, view.length]);\n\t\t\t}\n\t\t}\n\t}\n\n\tclones.set(source, result);\n\tif (pendingBuffer !== undefined) {\n\t\tcopyCloneProperties(pendingBuffer.source, pendingBuffer.result, clones);\n\t}\n\tif (tag === \"[object Map]\") {\n\t\tfor (const [key, item] of source as Map<unknown, unknown>) {\n\t\t\t(result as Map<unknown, unknown>).set(key, cloneDeepValue(item, clones, false));\n\t\t}\n\t} else if (tag === \"[object Set]\") {\n\t\tfor (const item of source as Set<unknown>) {\n\t\t\t(result as Set<unknown>).add(cloneDeepValue(item, clones, false));\n\t\t}\n\t}\n\n\tcopyCloneProperties(source, result, clones);\n\treturn result;\n};\n\n/** 复制自有可枚举属性,不触发结果原型上的 setter。 */\nfunction copyCloneProperties(source: object, result: object, clones: WeakMap<object, object>): void {\n\tfor (const key of Reflect.ownKeys(source)) {\n\t\tif (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;\n\t\tconst descriptor = Object.getOwnPropertyDescriptor(result, key);\n\t\t// String 包装对象的字符索引由构造器建立,不能重新定义。\n\t\tif (descriptor?.configurable === false && descriptor.writable === false) continue;\n\t\tdefineEnumerableProperty(result, key, cloneDeepValue(Reflect.get(source, key), clones, false));\n\t}\n}\n\n/** 深度比较过程中用于识别循环引用的双向对象映射。 */\ninterface EqualityState {\n\treadonly leftObjects: WeakMap<object, object>;\n\treadonly rightObjects: WeakMap<object, object>;\n}\n\n/** 判断两个值是否满足 SameValueZero 相等。 */\nconst sameValueZero = (left: unknown, right: unknown): boolean =>\n\tleft === right || (typeof left === \"number\" && typeof right === \"number\" && Number.isNaN(left) && Number.isNaN(right));\n\n/** 返回对象的自有可枚举字符串与 Symbol 键。 */\nconst getEnumerableOwnKeys = (value: object): PropertyKey[] =>\n\tReflect.ownKeys(value).filter((key) => Object.prototype.propertyIsEnumerable.call(value, key));\n\n/** 在一次递归分支内记录对象对应关系。 */\nconst compareTrackedPair = (left: object, right: object, state: EqualityState, compare: () => boolean): boolean => {\n\tconst existingRight = state.leftObjects.get(left);\n\tconst existingLeft = state.rightObjects.get(right);\n\tif (existingRight !== undefined || existingLeft !== undefined) return existingRight === right && existingLeft === left;\n\tstate.leftObjects.set(left, right);\n\tstate.rightObjects.set(right, left);\n\ttry {\n\t\treturn compare();\n\t} finally {\n\t\tstate.leftObjects.delete(left);\n\t\tstate.rightObjects.delete(right);\n\t}\n};\n\n/** 按字节比较两个 ArrayBufferLike。 */\nconst equalArrayBuffers = (left: ArrayBufferLike, right: ArrayBufferLike): boolean => {\n\tif (left.byteLength !== right.byteLength) return false;\n\tconst leftBytes = new Uint8Array(left);\n\tconst rightBytes = new Uint8Array(right);\n\tfor (let index = 0; index < leftBytes.length; index += 1) {\n\t\tif (leftBytes[index] !== rightBytes[index]) return false;\n\t}\n\treturn true;\n};\n\n/** 按顺序比较数组或 TypedArray 的元素。 */\nconst equalIndexedValues = (\n\tleft: { readonly [index: number]: unknown; readonly length: number },\n\tright: { readonly [index: number]: unknown; readonly length: number },\n\tstate: EqualityState\n): boolean => {\n\tif (left.length !== right.length) return false;\n\treturn compareTrackedPair(left, right, state, () => {\n\t\tfor (let index = 0; index < left.length; index += 1) {\n\t\t\tif (!isEqualValue(left[index], right[index], state)) return false;\n\t\t}\n\t\treturn true;\n\t});\n};\n\n/** 无序比较 Map 条目或 Set 元素。 */\nconst equalUnorderedValues = (left: readonly unknown[], right: readonly unknown[], state: EqualityState): boolean => {\n\tif (left.length !== right.length) return false;\n\tconst matchedIndexes = new Set<number>();\n\tfor (const leftValue of left) {\n\t\tlet matchedIndex = -1;\n\t\tfor (let index = 0; index < right.length; index += 1) {\n\t\t\tif (matchedIndexes.has(index) || !isEqualValue(leftValue, right[index], state)) continue;\n\t\t\tmatchedIndex = index;\n\t\t\tbreak;\n\t\t}\n\t\tif (matchedIndex < 0) return false;\n\t\tmatchedIndexes.add(matchedIndex);\n\t}\n\treturn true;\n};\n\n/** 比较普通对象或 Arguments 的自有可枚举属性与构造器。 */\nconst equalObjects = (left: object, right: object, state: EqualityState): boolean => {\n\tconst leftKeys = getEnumerableOwnKeys(left);\n\tconst rightKeys = getEnumerableOwnKeys(right);\n\tif (leftKeys.length !== rightKeys.length) return false;\n\tfor (const key of leftKeys) {\n\t\tif (!Object.hasOwn(right, key)) return false;\n\t}\n\n\treturn compareTrackedPair(left, right, state, () => {\n\t\tlet compareConstructors = true;\n\t\tfor (const key of leftKeys) {\n\t\t\tif (!isEqualValue(Reflect.get(left, key), Reflect.get(right, key), state)) return false;\n\t\t\tif (key === \"constructor\") compareConstructors = false;\n\t\t}\n\t\tif (!compareConstructors) return true;\n\t\tconst leftConstructor: unknown = Reflect.get(left, \"constructor\");\n\t\tconst rightConstructor: unknown = Reflect.get(right, \"constructor\");\n\t\tif (leftConstructor === rightConstructor || !(\"constructor\" in left && \"constructor\" in right)) return true;\n\t\treturn (\n\t\t\ttypeof leftConstructor === \"function\" &&\n\t\t\ttypeof rightConstructor === \"function\" &&\n\t\t\tleftConstructor instanceof leftConstructor &&\n\t\t\trightConstructor instanceof rightConstructor\n\t\t);\n\t});\n};\n\n/** 递归比较两个值。 */\nfunction isEqualValue(left: unknown, right: unknown, state: EqualityState): boolean {\n\tif (sameValueZero(left, right)) return true;\n\tif (left === null || left === undefined || right === null || right === undefined) return false;\n\n\tconst leftTag = Object.prototype.toString.call(left);\n\tconst rightTag = Object.prototype.toString.call(right);\n\tconst normalizedLeftTag = leftTag === \"[object Arguments]\" ? \"[object Object]\" : leftTag;\n\tconst normalizedRightTag = rightTag === \"[object Arguments]\" ? \"[object Object]\" : rightTag;\n\tif (normalizedLeftTag !== normalizedRightTag) return false;\n\n\tswitch (normalizedLeftTag) {\n\t\tcase \"[object Boolean]\":\n\t\tcase \"[object Date]\":\n\t\tcase \"[object Number]\":\n\t\t\treturn sameValueZero(Number(left), Number(right));\n\t\tcase \"[object Error]\":\n\t\t\treturn (left as Error).name === (right as Error).name && (left as Error).message === (right as Error).message;\n\t\tcase \"[object RegExp]\":\n\t\t\treturn RegExp.prototype.toString.call(left) === RegExp.prototype.toString.call(right);\n\t\tcase \"[object String]\":\n\t\t\treturn String.prototype.valueOf.call(left) === String.prototype.valueOf.call(right);\n\t\tcase \"[object Symbol]\":\n\t\t\treturn Symbol.prototype.valueOf.call(left) === Symbol.prototype.valueOf.call(right);\n\t}\n\n\tif (typeof left !== \"object\" || typeof right !== \"object\") return false;\n\tif (Array.isArray(left) && Array.isArray(right)) return equalIndexedValues(left, right, state);\n\tif (normalizedLeftTag === \"[object ArrayBuffer]\" || normalizedLeftTag === \"[object SharedArrayBuffer]\") {\n\t\treturn equalArrayBuffers(left as ArrayBufferLike, right as ArrayBufferLike);\n\t}\n\tif (normalizedLeftTag === \"[object DataView]\") {\n\t\tconst leftView = left as DataView;\n\t\tconst rightView = right as DataView;\n\t\treturn (\n\t\t\tleftView.byteLength === rightView.byteLength &&\n\t\t\tleftView.byteOffset === rightView.byteOffset &&\n\t\t\tequalArrayBuffers(leftView.buffer, rightView.buffer)\n\t\t);\n\t}\n\tif (typedArrayTags.has(normalizedLeftTag)) {\n\t\treturn equalIndexedValues(\n\t\t\tleft as ArrayBufferView & { readonly [index: number]: unknown; readonly length: number },\n\t\t\tright as ArrayBufferView & { readonly [index: number]: unknown; readonly length: number },\n\t\t\tstate\n\t\t);\n\t}\n\tif (normalizedLeftTag === \"[object Map]\") {\n\t\treturn compareTrackedPair(left, right, state, () =>\n\t\t\tequalUnorderedValues([...(left as Map<unknown, unknown>)], [...(right as Map<unknown, unknown>)], state)\n\t\t);\n\t}\n\tif (normalizedLeftTag === \"[object Set]\") {\n\t\treturn compareTrackedPair(left, right, state, () => equalUnorderedValues([...(left as Set<unknown>)], [...(right as Set<unknown>)], state));\n\t}\n\tif (normalizedLeftTag === \"[object Object]\") return equalObjects(left, right, state);\n\treturn false;\n}\n\n/**\n * 判断值是否是普通对象。\n *\n * @param value - 任意待检查值。\n * @returns 原型为 `Object.prototype` 或 `null` 时返回 `true`。\n */\nexport function isPlainObject(value: unknown): value is Record<PropertyKey, unknown> {\n\tif (typeof value !== \"object\" || value === null) return false;\n\tconst prototype = Object.getPrototypeOf(value) as object | null;\n\treturn prototype === null || prototype === Object.prototype;\n}\n\n/**\n * 安全判断对象是否拥有自己的属性。\n *\n * @remarks 不调用可能被对象覆盖的 `hasOwnProperty`。\n * @param value - 待检查对象。\n * @param key - 字符串、数字或 Symbol 属性键。\n * @returns 属性为对象自有属性时返回 `true`,并收窄键类型。\n */\nexport function hasOwn<ObjectType extends object, Key extends PropertyKey>(value: ObjectType, key: Key): key is Key & keyof ObjectType {\n\treturn Object.hasOwn(value, key);\n}\n\n/**\n * 递归创建值的深层副本。\n *\n * @remarks 支持循环引用、共享引用、Symbol 键、对象原型、ArrayBuffer、DataView、Date、Map、RegExp、Set 和 TypedArray。\n * Map 的键保持原引用,函数及其他不可克隆值在嵌套位置保持原引用;只复制自有可枚举属性。\n * @param value - 需要深复制的任意值。\n * @returns 与输入类型一致且不共享可克隆嵌套值的新值;原始类型直接返回自身。\n */\nexport function cloneDeep<Value>(value: Value): Value {\n\treturn cloneDeepValue(value, new WeakMap(), true) as Value;\n}\n\n/**\n * 深度比较两个值是否等价。\n *\n * @remarks 原始值使用 SameValueZero 语义;支持循环引用、数组、对象、ArrayBuffer、DataView、Date、Error、Map、RegExp、Set、Symbol 和 TypedArray。\n * 对象只比较自有可枚举字符串与 Symbol 属性,函数及其他不支持的宿主对象仅在引用相同时相等。\n * @param left - 第一待比较值。\n * @param right - 第二待比较值。\n * @returns 两个值深度等价时返回 `true`。\n */\nexport function isEqual(left: unknown, right: unknown): boolean {\n\treturn isEqualValue(left, right, { leftObjects: new WeakMap(), rightObjects: new WeakMap() });\n}\n\n/**\n * 从对象中选择指定自有可枚举属性。\n *\n * @remarks 固定键元组保留精确返回类型;动态数组中可能被选择或排除的键在返回类型中保持可选。\n * @param source - 不会被修改的源对象。\n * @param keys - 需要保留的键;不存在的键被忽略。\n * @returns 新对象,保持 `keys` 的遍历顺序。\n */\nexport function pick<Source extends object, const Keys extends readonly (keyof Source)[]>(\n\tsource: Source,\n\tkeys: Keys\n): number extends Keys[\"length\"] ? Partial<Pick<Source, Keys[number]>> : Pick<Source, Keys[number]>;\nexport function pick<Source extends object>(source: Source, keys: readonly PropertyKey[]): Partial<Source>;\nexport function pick<Source extends object>(source: Source, keys: readonly PropertyKey[]): Partial<Source> {\n\tconst result: Partial<Source> = {};\n\tfor (const key of keys) {\n\t\tif (Object.prototype.propertyIsEnumerable.call(source, key)) defineEnumerableProperty(result, key, Reflect.get(source, key));\n\t}\n\treturn result;\n}\n\n/**\n * 浅复制对象并删除指定属性。\n *\n * @remarks 固定键元组保留精确返回类型;动态数组中可能被选择或排除的键在返回类型中保持可选。\n * @param source - 不会被修改的源对象。\n * @param keys - 需要排除的键。\n * @returns 包含其余自有可枚举字符串与 Symbol 属性的新对象。\n */\nexport function omit<Source extends object, const Keys extends readonly (keyof Source)[]>(\n\tsource: Source,\n\tkeys: Keys\n): number extends Keys[\"length\"] ? Omit<Source, Keys[number]> & Partial<Pick<Source, Keys[number]>> : Omit<Source, Keys[number]>;\nexport function omit<Source extends object>(source: Source, keys: readonly PropertyKey[]): Partial<Source>;\nexport function omit<Source extends object>(source: Source, keys: readonly PropertyKey[]): Partial<Source> {\n\tconst result = { ...source };\n\tfor (const key of keys) Reflect.deleteProperty(result, key);\n\treturn result;\n}\n\n/**\n * 按条件排除对象的自有可枚举属性。\n *\n * @param source - 不会被修改的源对象。\n * @param predicate - 接收属性值、键和源对象;返回真值时排除该属性。\n * @returns 由未匹配属性组成的新对象。\n */\nexport function omitBy<Source extends object>(\n\tsource: Source,\n\tpredicate: (value: Source[keyof Source], key: keyof Source, source: Source) => unknown\n): Partial<Source> {\n\tconst result: Partial<Source> = {};\n\tfor (const key of getEnumerableOwnKeys(source) as (keyof Source)[]) {\n\t\tif (!predicate(source[key], key, source)) defineEnumerableProperty(result, key, source[key]);\n\t}\n\treturn result;\n}\n\n/**\n * 按条件选择对象的自有可枚举属性。\n *\n * @param source - 不会被修改的源对象。\n * @param predicate - 接收属性值、键和源对象;返回真值时保留该属性。\n * @returns 由匹配属性组成的新对象。\n */\nexport function pickBy<Source extends object>(\n\tsource: Source,\n\tpredicate: (value: Source[keyof Source], key: keyof Source, source: Source) => unknown\n): Partial<Source> {\n\tconst result: Partial<Source> = {};\n\tfor (const key of getEnumerableOwnKeys(source) as (keyof Source)[]) {\n\t\tif (predicate(source[key], key, source)) defineEnumerableProperty(result, key, source[key]);\n\t}\n\treturn result;\n}\n\n/**\n * 映射对象的自有可枚举属性值。\n *\n * @param source - 不会被修改的源对象。\n * @param mapper - 接收值、键和源对象的映射函数。\n * @returns 保留原键的新对象。\n */\nexport function mapValues<Source extends object, Result>(\n\tsource: Source,\n\tmapper: (value: Source[keyof Source], key: keyof Source, source: Source) => Result\n): { [Key in keyof Source]: Result } {\n\tconst result = {} as { [Key in keyof Source]: Result };\n\tfor (const key of Reflect.ownKeys(source) as (keyof Source)[]) {\n\t\tif (Object.prototype.propertyIsEnumerable.call(source, key)) defineEnumerableProperty(result, key, mapper(source[key], key, source));\n\t}\n\treturn result;\n}\n\n/**\n * 对自有可枚举属性执行 SameValue 浅比较。\n *\n * @remarks 嵌套对象只比较引用;`NaN` 相等,`0` 与 `-0` 不相等。\n * @param left - 第一对象。\n * @param right - 第二对象。\n * @returns 自有可枚举键集合与对应值均满足 SameValue 时返回 `true`。\n */\nexport function shallowEqual(left: object, right: object): boolean {\n\tif (Object.is(left, right)) return true;\n\tconst leftKeys = Reflect.ownKeys(left).filter((key) => Object.prototype.propertyIsEnumerable.call(left, key));\n\tconst rightKeys = Reflect.ownKeys(right).filter((key) => Object.prototype.propertyIsEnumerable.call(right, key));\n\tif (leftKeys.length !== rightKeys.length) return false;\n\treturn leftKeys.every((key) => Object.hasOwn(right, key) && Object.is(Reflect.get(left, key), Reflect.get(right, key)));\n}\n\n/**\n * 把 Query 原始值规范化为文本。\n *\n * @param value - 已排除空值的字符串、数字、布尔值或 BigInt。\n * @returns 与 URLSearchParams 兼容的文本值。\n * @throws `RangeError` 当数字不是有限值。\n */\nconst serializeQueryValue = (value: Exclude<QueryPrimitive, null | undefined>): string => {\n\tif (typeof value === \"number\" && !Number.isFinite(value)) {\n\t\tthrow new RangeError(\"查询参数中的数字必须是有限数。\");\n\t}\n\treturn String(value);\n};\n\n/**\n * 将对象序列化为标准 URL 查询字符串。\n *\n * @remarks `null` 与 `undefined` 被跳过;数组使用重复键;返回值不会修改输入。\n * @param value - 查询参数对象。\n * @param options - 排序、空格和问号前缀选项。\n * @returns URL 编码后的查询字符串;没有参数时始终返回空字符串。\n * @throws `RangeError` 当参数包含 `NaN` 或无穷数字。\n */\nexport function toQueryString(value: Readonly<Record<string, QueryValue>>, options: QueryStringOptions = {}): string {\n\tconst entries = Object.entries(value);\n\tif (options.sort) entries.sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0));\n\tconst parameters = new URLSearchParams();\n\tfor (const [key, rawValue] of entries) {\n\t\tconst values = isQueryPrimitiveArray(rawValue) ? rawValue : [rawValue];\n\t\tfor (const item of values) {\n\t\t\tif (item !== null && item !== undefined) parameters.append(key, serializeQueryValue(item));\n\t\t}\n\t}\n\tlet result = parameters.toString();\n\tif (options.space === \"percent\") result = result.replace(/\\+/gu, \"%20\");\n\treturn result && options.prefixQuestionMark ? `?${result}` : result;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/object/index.ts"],"sourcesContent":["/** URL 查询参数支持的单值类型。 */\nexport type QueryPrimitive = bigint | boolean | number | string | null | undefined;\n\n/** URL 查询参数值;数组使用重复键表示。 */\nexport type QueryValue = QueryPrimitive | readonly QueryPrimitive[];\n\n/**\n * 判断 Query Value 是否为重复参数数组。\n *\n * @param value - 单值或数组形式的 Query Value\n * @returns 是只读原始值数组时返回 `true`。\n */\nconst isQueryPrimitiveArray = (value: QueryValue): value is readonly QueryPrimitive[] => Array.isArray(value);\n\n/** {@link toQueryString} 的序列化选项 */\nexport interface QueryStringOptions {\n\t/** 返回非空结果时是否添加 `?`;默认 `false`。 */\n\tprefixQuestionMark?: boolean;\n\t/** 是否按键的 UTF-16 码元顺序稳定排序;默认保留对象枚举顺序。 */\n\tsort?: boolean;\n\t/** 空格编码方式;默认遵循表单编码并输出 `+`。 */\n\tspace?: \"percent\" | \"plus\";\n}\n\n/**\n * 安全写入结果对象的自有可枚举属性。\n *\n * @remarks 使用 `defineProperty` 避免 `__proto__` 触发 Setter,并统一创建可写、可配置的自有可枚举数据属性。\n * @param target - 要写入的结果对象\n * @param key - 自有属性键\n * @param value - 属性值\n */\nconst defineEnumerableProperty = (target: object, key: PropertyKey, value: unknown): void => {\n\tObject.defineProperty(target, key, { configurable: true, enumerable: true, value, writable: true });\n};\n\nconst typedArrayTags = new Set([\n\t\"[object BigInt64Array]\",\n\t\"[object BigUint64Array]\",\n\t\"[object Float32Array]\",\n\t\"[object Float64Array]\",\n\t\"[object Int8Array]\",\n\t\"[object Int16Array]\",\n\t\"[object Int32Array]\",\n\t\"[object Uint8Array]\",\n\t\"[object Uint8ClampedArray]\",\n\t\"[object Uint16Array]\",\n\t\"[object Uint32Array]\",\n]);\n\n/** 使用源值的构造器创建同类空实例。 */\nconst createUsingConstructor = (value: object, arguments_: readonly unknown[]): object => {\n\tconst constructor: unknown = Reflect.get(value, \"constructor\");\n\treturn typeof constructor === \"function\" ? (Reflect.construct(constructor, arguments_) as object) : {};\n};\n\n/** 复制 ArrayBufferLike 的当前字节,不与源值共享底层内存。 */\nconst cloneArrayBuffer = (value: ArrayBufferLike): ArrayBufferLike => {\n\tconst result = createUsingConstructor(value, [value.byteLength]) as ArrayBufferLike;\n\tnew Uint8Array(result).set(new Uint8Array(value));\n\treturn result;\n};\n\n/** 递归复制值,并记录已复制对象以还原循环引用和共享引用。 */\nconst cloneDeepValue = (value: unknown, clones: WeakMap<object, object>, isRoot: boolean): unknown => {\n\tif ((typeof value !== \"object\" && typeof value !== \"function\") || value === null) return value;\n\n\tconst source = value;\n\tconst existing = clones.get(source);\n\tif (existing !== undefined) return existing;\n\tif (typeof source === \"function\" && !isRoot) return source;\n\n\tconst tag = Object.prototype.toString.call(source);\n\tlet result: object;\n\tlet pendingBuffer: { source: ArrayBufferLike; result: ArrayBufferLike } | undefined;\n\t// 先登记底层缓冲区,视图登记后再复制其附加属性,避免缓冲区与视图相互引用时重复构造。\n\tconst getBufferClone = (buffer: ArrayBufferLike): ArrayBufferLike => {\n\t\tconst existingBuffer = clones.get(buffer);\n\t\tif (existingBuffer !== undefined) return existingBuffer as ArrayBufferLike;\n\t\tconst clonedBuffer = cloneArrayBuffer(buffer);\n\t\tclones.set(buffer, clonedBuffer);\n\t\tpendingBuffer = { source: buffer, result: clonedBuffer };\n\t\treturn clonedBuffer;\n\t};\n\tif (Array.isArray(source)) {\n\t\t// 只复制实际存在的自有可枚举键,保留空洞、附加字符串属性和 Symbol 属性。\n\t\tresult = createUsingConstructor(source, [source.length]);\n\t} else if (typeof source === \"function\") {\n\t\tresult = {};\n\t} else {\n\t\tswitch (tag) {\n\t\t\tcase \"[object Arguments]\":\n\t\t\t\tresult = {};\n\t\t\t\tbreak;\n\t\t\tcase \"[object ArrayBuffer]\":\n\t\t\tcase \"[object SharedArrayBuffer]\":\n\t\t\t\tresult = cloneArrayBuffer(source as ArrayBufferLike);\n\t\t\t\tbreak;\n\t\t\tcase \"[object Boolean]\":\n\t\t\t\tresult = createUsingConstructor(source, [(source as { valueOf: () => boolean }).valueOf()]);\n\t\t\t\tbreak;\n\t\t\tcase \"[object DataView]\": {\n\t\t\t\tconst view = source as DataView;\n\t\t\t\tresult = createUsingConstructor(source, [getBufferClone(view.buffer), view.byteOffset, view.byteLength]);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"[object Date]\":\n\t\t\t\tresult = createUsingConstructor(source, [(source as Date).getTime()]);\n\t\t\t\tbreak;\n\t\t\tcase \"[object Map]\":\n\t\t\tcase \"[object Set]\":\n\t\t\t\tresult = createUsingConstructor(source, []);\n\t\t\t\tbreak;\n\t\t\tcase \"[object Number]\":\n\t\t\t\tresult = createUsingConstructor(source, [(source as { valueOf: () => number }).valueOf()]);\n\t\t\t\tbreak;\n\t\t\tcase \"[object Object]\": {\n\t\t\t\tconst prototype = Object.getPrototypeOf(source) as object | null;\n\t\t\t\tresult = Object.create(prototype) as object;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"[object RegExp]\": {\n\t\t\t\tconst expression = source as RegExp;\n\t\t\t\tconst clonedExpression = new RegExp(expression.source, expression.flags);\n\t\t\t\tclonedExpression.lastIndex = expression.lastIndex;\n\t\t\t\tresult = clonedExpression;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"[object String]\":\n\t\t\t\tresult = createUsingConstructor(source, [(source as { valueOf: () => string }).valueOf()]);\n\t\t\t\tbreak;\n\t\t\tcase \"[object Symbol]\":\n\t\t\t\tresult = Object((source as { valueOf: () => symbol }).valueOf()) as object;\n\t\t\t\tbreak;\n\t\t\tdefault: {\n\t\t\t\tif (!typedArrayTags.has(tag)) return isRoot ? {} : source;\n\t\t\t\tconst view = source as ArrayBufferView & { readonly length: number };\n\t\t\t\tresult = createUsingConstructor(source, [getBufferClone(view.buffer), view.byteOffset, view.length]);\n\t\t\t}\n\t\t}\n\t}\n\n\tclones.set(source, result);\n\tif (pendingBuffer !== undefined) {\n\t\tcopyCloneProperties(pendingBuffer.source, pendingBuffer.result, clones);\n\t}\n\tif (tag === \"[object Map]\") {\n\t\tfor (const [key, item] of source as Map<unknown, unknown>) {\n\t\t\t(result as Map<unknown, unknown>).set(key, cloneDeepValue(item, clones, false));\n\t\t}\n\t} else if (tag === \"[object Set]\") {\n\t\tfor (const item of source as Set<unknown>) {\n\t\t\t(result as Set<unknown>).add(cloneDeepValue(item, clones, false));\n\t\t}\n\t}\n\n\tcopyCloneProperties(source, result, clones);\n\treturn result;\n};\n\n/** 复制自有可枚举属性,不触发结果原型上的 setter。 */\nfunction copyCloneProperties(source: object, result: object, clones: WeakMap<object, object>): void {\n\tfor (const key of Reflect.ownKeys(source)) {\n\t\tif (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;\n\t\tconst descriptor = Object.getOwnPropertyDescriptor(result, key);\n\t\t// String 包装对象的字符索引由构造器建立,不能重新定义。\n\t\tif (descriptor?.configurable === false && descriptor.writable === false) continue;\n\t\tdefineEnumerableProperty(result, key, cloneDeepValue(Reflect.get(source, key), clones, false));\n\t}\n}\n\n/** 深度比较过程中用于识别循环引用的双向对象映射 */\ninterface EqualityState {\n\treadonly leftObjects: WeakMap<object, object>;\n\treadonly rightObjects: WeakMap<object, object>;\n}\n\n/** 判断两个值是否满足 SameValueZero 相等。 */\nconst sameValueZero = (left: unknown, right: unknown): boolean =>\n\tleft === right || (typeof left === \"number\" && typeof right === \"number\" && Number.isNaN(left) && Number.isNaN(right));\n\n/** 返回对象的自有可枚举字符串与 Symbol 键。 */\nconst getEnumerableOwnKeys = (value: object): PropertyKey[] =>\n\tReflect.ownKeys(value).filter((key) => Object.prototype.propertyIsEnumerable.call(value, key));\n\n/** 在一次递归分支内记录对象对应关系。 */\nconst compareTrackedPair = (left: object, right: object, state: EqualityState, compare: () => boolean): boolean => {\n\tconst existingRight = state.leftObjects.get(left);\n\tconst existingLeft = state.rightObjects.get(right);\n\tif (existingRight !== undefined || existingLeft !== undefined) return existingRight === right && existingLeft === left;\n\tstate.leftObjects.set(left, right);\n\tstate.rightObjects.set(right, left);\n\ttry {\n\t\treturn compare();\n\t} finally {\n\t\tstate.leftObjects.delete(left);\n\t\tstate.rightObjects.delete(right);\n\t}\n};\n\n/** 按字节比较两个 ArrayBufferLike。 */\nconst equalArrayBuffers = (left: ArrayBufferLike, right: ArrayBufferLike): boolean => {\n\tif (left.byteLength !== right.byteLength) return false;\n\tconst leftBytes = new Uint8Array(left);\n\tconst rightBytes = new Uint8Array(right);\n\tfor (let index = 0; index < leftBytes.length; index += 1) {\n\t\tif (leftBytes[index] !== rightBytes[index]) return false;\n\t}\n\treturn true;\n};\n\n/** 按顺序比较数组或 TypedArray 的元素。 */\nconst equalIndexedValues = (\n\tleft: { readonly [index: number]: unknown; readonly length: number },\n\tright: { readonly [index: number]: unknown; readonly length: number },\n\tstate: EqualityState\n): boolean => {\n\tif (left.length !== right.length) return false;\n\treturn compareTrackedPair(left, right, state, () => {\n\t\tfor (let index = 0; index < left.length; index += 1) {\n\t\t\tif (!isEqualValue(left[index], right[index], state)) return false;\n\t\t}\n\t\treturn true;\n\t});\n};\n\n/** 无序比较 Map 条目或 Set 元素。 */\nconst equalUnorderedValues = (left: readonly unknown[], right: readonly unknown[], state: EqualityState): boolean => {\n\tif (left.length !== right.length) return false;\n\tconst matchedIndexes = new Set<number>();\n\tfor (const leftValue of left) {\n\t\tlet matchedIndex = -1;\n\t\tfor (let index = 0; index < right.length; index += 1) {\n\t\t\tif (matchedIndexes.has(index) || !isEqualValue(leftValue, right[index], state)) continue;\n\t\t\tmatchedIndex = index;\n\t\t\tbreak;\n\t\t}\n\t\tif (matchedIndex < 0) return false;\n\t\tmatchedIndexes.add(matchedIndex);\n\t}\n\treturn true;\n};\n\n/** 比较普通对象或 Arguments 的自有可枚举属性与构造器。 */\nconst equalObjects = (left: object, right: object, state: EqualityState): boolean => {\n\tconst leftKeys = getEnumerableOwnKeys(left);\n\tconst rightKeys = getEnumerableOwnKeys(right);\n\tif (leftKeys.length !== rightKeys.length) return false;\n\tfor (const key of leftKeys) {\n\t\tif (!Object.prototype.hasOwnProperty.call(right, key)) return false;\n\t}\n\n\treturn compareTrackedPair(left, right, state, () => {\n\t\tlet compareConstructors = true;\n\t\tfor (const key of leftKeys) {\n\t\t\tif (!isEqualValue(Reflect.get(left, key), Reflect.get(right, key), state)) return false;\n\t\t\tif (key === \"constructor\") compareConstructors = false;\n\t\t}\n\t\tif (!compareConstructors) return true;\n\t\tconst leftConstructor: unknown = Reflect.get(left, \"constructor\");\n\t\tconst rightConstructor: unknown = Reflect.get(right, \"constructor\");\n\t\tif (leftConstructor === rightConstructor || !(\"constructor\" in left && \"constructor\" in right)) return true;\n\t\treturn (\n\t\t\ttypeof leftConstructor === \"function\" &&\n\t\t\ttypeof rightConstructor === \"function\" &&\n\t\t\tleftConstructor instanceof leftConstructor &&\n\t\t\trightConstructor instanceof rightConstructor\n\t\t);\n\t});\n};\n\n/** 递归比较两个值。 */\nfunction isEqualValue(left: unknown, right: unknown, state: EqualityState): boolean {\n\tif (sameValueZero(left, right)) return true;\n\tif (left === null || left === undefined || right === null || right === undefined) return false;\n\n\tconst leftTag = Object.prototype.toString.call(left);\n\tconst rightTag = Object.prototype.toString.call(right);\n\tconst normalizedLeftTag = leftTag === \"[object Arguments]\" ? \"[object Object]\" : leftTag;\n\tconst normalizedRightTag = rightTag === \"[object Arguments]\" ? \"[object Object]\" : rightTag;\n\tif (normalizedLeftTag !== normalizedRightTag) return false;\n\n\tswitch (normalizedLeftTag) {\n\t\tcase \"[object Boolean]\":\n\t\tcase \"[object Date]\":\n\t\tcase \"[object Number]\":\n\t\t\treturn sameValueZero(Number(left), Number(right));\n\t\tcase \"[object Error]\":\n\t\t\treturn (left as Error).name === (right as Error).name && (left as Error).message === (right as Error).message;\n\t\tcase \"[object RegExp]\":\n\t\t\treturn RegExp.prototype.toString.call(left) === RegExp.prototype.toString.call(right);\n\t\tcase \"[object String]\":\n\t\t\treturn String.prototype.valueOf.call(left) === String.prototype.valueOf.call(right);\n\t\tcase \"[object Symbol]\":\n\t\t\treturn Symbol.prototype.valueOf.call(left) === Symbol.prototype.valueOf.call(right);\n\t}\n\n\tif (typeof left !== \"object\" || typeof right !== \"object\") return false;\n\tif (Array.isArray(left) && Array.isArray(right)) return equalIndexedValues(left, right, state);\n\tif (normalizedLeftTag === \"[object ArrayBuffer]\" || normalizedLeftTag === \"[object SharedArrayBuffer]\") {\n\t\treturn equalArrayBuffers(left as ArrayBufferLike, right as ArrayBufferLike);\n\t}\n\tif (normalizedLeftTag === \"[object DataView]\") {\n\t\tconst leftView = left as DataView;\n\t\tconst rightView = right as DataView;\n\t\treturn (\n\t\t\tleftView.byteLength === rightView.byteLength &&\n\t\t\tleftView.byteOffset === rightView.byteOffset &&\n\t\t\tequalArrayBuffers(leftView.buffer, rightView.buffer)\n\t\t);\n\t}\n\tif (typedArrayTags.has(normalizedLeftTag)) {\n\t\treturn equalIndexedValues(\n\t\t\tleft as ArrayBufferView & { readonly [index: number]: unknown; readonly length: number },\n\t\t\tright as ArrayBufferView & { readonly [index: number]: unknown; readonly length: number },\n\t\t\tstate\n\t\t);\n\t}\n\tif (normalizedLeftTag === \"[object Map]\") {\n\t\treturn compareTrackedPair(left, right, state, () =>\n\t\t\tequalUnorderedValues([...(left as Map<unknown, unknown>)], [...(right as Map<unknown, unknown>)], state)\n\t\t);\n\t}\n\tif (normalizedLeftTag === \"[object Set]\") {\n\t\treturn compareTrackedPair(left, right, state, () => equalUnorderedValues([...(left as Set<unknown>)], [...(right as Set<unknown>)], state));\n\t}\n\tif (normalizedLeftTag === \"[object Object]\") return equalObjects(left, right, state);\n\treturn false;\n}\n\n/**\n * 判断值是否是普通对象。\n *\n * @param value - 任意待检查值\n * @returns 原型为 `Object.prototype` 或 `null` 时返回 `true`。\n */\nexport function isPlainObject(value: unknown): value is Record<PropertyKey, unknown> {\n\tif (typeof value !== \"object\" || value === null) return false;\n\tconst prototype = Object.getPrototypeOf(value) as object | null;\n\treturn prototype === null || prototype === Object.prototype;\n}\n\n/**\n * 安全判断对象是否拥有自己的属性。\n *\n * @remarks 不调用可能被对象覆盖的 `hasOwnProperty`。\n * @param value - 待检查对象\n * @param key - 字符串、数字或 Symbol 属性键\n * @returns 属性为对象自有属性时返回 `true`,并收窄键类型。\n */\nexport function hasOwn<ObjectType extends object, Key extends PropertyKey>(value: ObjectType, key: Key): key is Key & keyof ObjectType {\n\treturn Object.prototype.hasOwnProperty.call(value, key);\n}\n\n/**\n * 递归创建值的深层副本。\n *\n * @remarks 支持循环引用、共享引用、Symbol 键、对象原型、ArrayBuffer、DataView、Date、Map、RegExp、Set 和 TypedArray。\n * Map 的键保持原引用,函数及其他不可克隆值在嵌套位置保持原引用;只复制自有可枚举属性。\n * @param value - 需要深复制的任意值\n * @returns 与输入类型一致且不共享可克隆嵌套值的新值;原始类型直接返回自身。\n */\nexport function cloneDeep<Value>(value: Value): Value {\n\treturn cloneDeepValue(value, new WeakMap(), true) as Value;\n}\n\n/**\n * 深度比较两个值是否等价。\n *\n * @remarks 原始值使用 SameValueZero 语义;支持循环引用、数组、对象、ArrayBuffer、DataView、Date、Error、Map、RegExp、Set、Symbol 和 TypedArray。\n * 对象只比较自有可枚举字符串与 Symbol 属性,函数及其他不支持的宿主对象仅在引用相同时相等。\n * @param left - 第一待比较值\n * @param right - 第二待比较值\n * @returns 两个值深度等价时返回 `true`。\n */\nexport function isEqual(left: unknown, right: unknown): boolean {\n\treturn isEqualValue(left, right, { leftObjects: new WeakMap(), rightObjects: new WeakMap() });\n}\n\n/**\n * 从对象中选择指定自有可枚举属性。\n *\n * @remarks 固定键元组保留精确返回类型;动态数组中可能被选择或排除的键在返回类型中保持可选。\n * @param source - 不会被修改的源对象\n * @param keys - 需要保留的键;不存在的键被忽略。\n * @returns 新对象,保持 `keys` 的遍历顺序。\n */\nexport function pick<Source extends object, const Keys extends readonly (keyof Source)[]>(\n\tsource: Source,\n\tkeys: Keys\n): number extends Keys[\"length\"] ? Partial<Pick<Source, Keys[number]>> : Pick<Source, Keys[number]>;\nexport function pick<Source extends object>(source: Source, keys: readonly PropertyKey[]): Partial<Source>;\nexport function pick<Source extends object>(source: Source, keys: readonly PropertyKey[]): Partial<Source> {\n\tconst result: Partial<Source> = {};\n\tfor (const key of keys) {\n\t\tif (Object.prototype.propertyIsEnumerable.call(source, key)) defineEnumerableProperty(result, key, Reflect.get(source, key));\n\t}\n\treturn result;\n}\n\n/**\n * 浅复制对象并删除指定属性。\n *\n * @remarks 固定键元组保留精确返回类型;动态数组中可能被选择或排除的键在返回类型中保持可选。\n * @param source - 不会被修改的源对象\n * @param keys - 需要排除的键\n * @returns 包含其余自有可枚举字符串与 Symbol 属性的新对象\n */\nexport function omit<Source extends object, const Keys extends readonly (keyof Source)[]>(\n\tsource: Source,\n\tkeys: Keys\n): number extends Keys[\"length\"] ? Omit<Source, Keys[number]> & Partial<Pick<Source, Keys[number]>> : Omit<Source, Keys[number]>;\nexport function omit<Source extends object>(source: Source, keys: readonly PropertyKey[]): Partial<Source>;\nexport function omit<Source extends object>(source: Source, keys: readonly PropertyKey[]): Partial<Source> {\n\tconst result = { ...source };\n\tfor (const key of keys) Reflect.deleteProperty(result, key);\n\treturn result;\n}\n\n/**\n * 按条件排除对象的自有可枚举属性。\n *\n * @param source - 不会被修改的源对象\n * @param predicate - 接收属性值、键和源对象;返回真值时排除该属性。\n * @returns 由未匹配属性组成的新对象\n */\nexport function omitBy<Source extends object>(\n\tsource: Source,\n\tpredicate: (value: Source[keyof Source], key: keyof Source, source: Source) => unknown\n): Partial<Source> {\n\tconst result: Partial<Source> = {};\n\tfor (const key of getEnumerableOwnKeys(source) as (keyof Source)[]) {\n\t\tif (!predicate(source[key], key, source)) defineEnumerableProperty(result, key, source[key]);\n\t}\n\treturn result;\n}\n\n/**\n * 按条件选择对象的自有可枚举属性。\n *\n * @param source - 不会被修改的源对象\n * @param predicate - 接收属性值、键和源对象;返回真值时保留该属性。\n * @returns 由匹配属性组成的新对象\n */\nexport function pickBy<Source extends object>(\n\tsource: Source,\n\tpredicate: (value: Source[keyof Source], key: keyof Source, source: Source) => unknown\n): Partial<Source> {\n\tconst result: Partial<Source> = {};\n\tfor (const key of getEnumerableOwnKeys(source) as (keyof Source)[]) {\n\t\tif (predicate(source[key], key, source)) defineEnumerableProperty(result, key, source[key]);\n\t}\n\treturn result;\n}\n\n/**\n * 映射对象的自有可枚举属性值。\n *\n * @param source - 不会被修改的源对象\n * @param mapper - 接收值、键和源对象的映射函数\n * @returns 保留原键的新对象\n */\nexport function mapValues<Source extends object, Result>(\n\tsource: Source,\n\tmapper: (value: Source[keyof Source], key: keyof Source, source: Source) => Result\n): { [Key in keyof Source]: Result } {\n\tconst result = {} as { [Key in keyof Source]: Result };\n\tfor (const key of Reflect.ownKeys(source) as (keyof Source)[]) {\n\t\tif (Object.prototype.propertyIsEnumerable.call(source, key)) defineEnumerableProperty(result, key, mapper(source[key], key, source));\n\t}\n\treturn result;\n}\n\n/**\n * 对自有可枚举属性执行 SameValue 浅比较。\n *\n * @remarks 嵌套对象只比较引用;`NaN` 相等,`0` 与 `-0` 不相等。\n * @param left - 第一对象\n * @param right - 第二对象\n * @returns 自有可枚举键集合与对应值均满足 SameValue 时返回 `true`。\n */\nexport function shallowEqual(left: object, right: object): boolean {\n\tif (Object.is(left, right)) return true;\n\tconst leftKeys = Reflect.ownKeys(left).filter((key) => Object.prototype.propertyIsEnumerable.call(left, key));\n\tconst rightKeys = Reflect.ownKeys(right).filter((key) => Object.prototype.propertyIsEnumerable.call(right, key));\n\tif (leftKeys.length !== rightKeys.length) return false;\n\treturn leftKeys.every((key) => Object.prototype.hasOwnProperty.call(right, key) && Object.is(Reflect.get(left, key), Reflect.get(right, key)));\n}\n\n/**\n * 把 Query 原始值规范化为文本。\n *\n * @param value - 已排除空值的字符串、数字、布尔值或 BigInt\n * @returns 与 URLSearchParams 兼容的文本值\n * @throws `RangeError` 当数字不是有限值。\n */\nconst serializeQueryValue = (value: Exclude<QueryPrimitive, null | undefined>): string => {\n\tif (typeof value === \"number\" && !Number.isFinite(value)) {\n\t\tthrow new RangeError(\"Query parameter numbers must be finite.\");\n\t}\n\treturn String(value);\n};\n\n/**\n * 将对象序列化为标准 URL 查询字符串。\n *\n * @remarks `null` 与 `undefined` 被跳过;数组使用重复键;返回值不会修改输入。\n * @param value - 查询参数对象\n * @param options - 排序、空格和问号前缀选项\n * @returns URL 编码后的查询字符串;没有参数时始终返回空字符串。\n * @throws `RangeError` 当参数包含 `NaN` 或无穷数字。\n * @throws `URIError` 当键或值包含孤立的 UTF-16 代理项。\n */\nexport function toQueryString(value: Readonly<Record<string, QueryValue>>, options: QueryStringOptions = {}): string {\n\tconst entries = Object.entries(value);\n\tif (options.sort) entries.sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0));\n\tconst parameters: string[] = [];\n\tfor (const [key, rawValue] of entries) {\n\t\tconst values = isQueryPrimitiveArray(rawValue) ? rawValue : [rawValue];\n\t\tfor (const item of values) {\n\t\t\tif (item !== null && item !== undefined) {\n\t\t\t\tparameters.push(`${encodeURIComponent(key)}=${encodeURIComponent(serializeQueryValue(item))}`);\n\t\t\t}\n\t\t}\n\t}\n\t// 补齐表单编码字符集,保留已有查询字符串的输出格式。\n\tlet result = parameters.join(\"&\").replace(/[!'()~]/gu, (character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`);\n\tif (options.space !== \"percent\") result = result.replace(/%20/gu, \"+\");\n\treturn result && options.prefixQuestionMark ? `?${result}` : result;\n}\n"],"mappings":"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"}
@@ -1,26 +1,22 @@
1
- import { getRuntimeUni, runtimeGlobals } from "../internal/runtime.mjs";
2
1
  import { decodeSecureBase64, encodeSecureBase64 } from "../base64/index.mjs";
3
2
  //#region src/storage/index.ts
4
3
  /**
5
4
  * 读取并校验当前运行时的全局 uni-app 同步 Storage。
6
5
  *
7
- * @returns 检测到 uni-app 时返回同步 Storage;普通浏览器环境返回 `undefined`。
6
+ * @returns 检测到可用的 uni-app 同步 Storage 时返回 `true`。
8
7
  * @throws `TypeError` 当全局 `uni` 存在但缺少本库需要的同步 Storage 方法。
9
8
  */
10
- const getGlobalUniStorage = () => {
11
- const value = getRuntimeUni();
12
- if (value === void 0) return void 0;
13
- if (typeof value !== "object" && typeof value !== "function" || value === null) throw new TypeError("全局 uni 对象未提供同步 Storage API。");
14
- const storage = value;
15
- if (typeof storage.getStorageSync !== "function" || typeof storage.getStorageInfoSync !== "function" || typeof storage.removeStorageSync !== "function" || typeof storage.setStorageSync !== "function") throw new TypeError("全局 uni 对象未提供同步 Storage API。");
16
- return storage;
9
+ const hasGlobalUniStorage = () => {
10
+ if (typeof uni === "undefined") return false;
11
+ if (uni === null || typeof uni.getStorageSync !== "function" || typeof uni.getStorageInfoSync !== "function" || typeof uni.removeStorageSync !== "function" || typeof uni.setStorageSync !== "function") throw new TypeError("The global uni object does not provide synchronous Storage APIs.");
12
+ return true;
17
13
  };
18
14
  /** 默认 JSON Codec;显式拒绝会被 JSON.stringify 静默丢弃的顶层值。 */
19
15
  const jsonCodec = {
20
16
  decode: (value) => JSON.parse(value),
21
17
  encode: (value) => {
22
18
  const encoded = JSON.stringify(value);
23
- if (typeof encoded !== "string") throw new TypeError("存储值无法序列化为 JSON。");
19
+ if (typeof encoded !== "string") throw new TypeError("The storage value cannot be serialized as JSON.");
24
20
  return encoded;
25
21
  }
26
22
  };
@@ -29,7 +25,7 @@ const base64StorageCodec = {
29
25
  decode: (value) => JSON.parse(decodeSecureBase64(value)),
30
26
  encode: (value) => {
31
27
  const encoded = JSON.stringify(value);
32
- if (typeof encoded !== "string") throw new TypeError("存储值无法序列化为 JSON。");
28
+ if (typeof encoded !== "string") throw new TypeError("The storage value cannot be serialized as JSON.");
33
29
  return encodeSecureBase64(encoded);
34
30
  }
35
31
  };
@@ -38,30 +34,30 @@ let activeConfiguration;
38
34
  /**
39
35
  * 判断未知值是否为非数组对象记录。
40
36
  *
41
- * @param value - JSON.parse 返回的未知值。
37
+ * @param value - JSON.parse 返回的未知值
42
38
  * @returns 值为非空、非数组对象时返回 `true`。
43
39
  */
44
40
  const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
45
41
  /**
46
42
  * 校验 Storage 业务键。
47
43
  *
48
- * @param key - 不含全局 Prefix 的业务键或业务键前缀。
44
+ * @param key - 不含全局 Prefix 的业务键或业务键前缀
49
45
  * @throws `TypeError` 当值不是非空字符串。
50
46
  */
51
47
  const assertKey = (key) => {
52
- if (typeof key !== "string" || key.length === 0) throw new TypeError("Storage 键必须是非空字符串。");
48
+ if (typeof key !== "string" || key.length === 0) throw new TypeError("Storage keys must be nonempty strings.");
53
49
  };
54
50
  /**
55
51
  * 创建浏览器 Storage 后端。
56
52
  *
57
53
  * @remarks 平台对象在调用阶段读取,因此导入模块不会访问浏览器全局对象。
58
54
  * @param kind - 选择 `localStorage` 或 `sessionStorage`。
59
- * @returns 统一的内部同步后端。
55
+ * @returns 统一的内部同步后端
60
56
  * @throws `Error` 当所选 Storage 在当前环境不可用。
61
57
  */
62
58
  const createWebStorageBackend = (kind) => {
63
- const storage = kind === "local" ? runtimeGlobals.localStorage : runtimeGlobals.sessionStorage;
64
- if (storage === void 0) throw new Error(`当前运行环境不支持 ${kind}Storage。`);
59
+ const storage = kind === "local" ? typeof localStorage === "undefined" ? void 0 : localStorage : typeof sessionStorage === "undefined" ? void 0 : sessionStorage;
60
+ if (storage === void 0) throw new Error(`The current runtime does not support ${kind}Storage.`);
65
61
  return {
66
62
  getItem: (key) => storage.getItem(key),
67
63
  keys: () => {
@@ -84,91 +80,90 @@ const createWebStorageBackend = (kind) => {
84
80
  * 把 uni-app 同步 Storage 适配为内部后端。
85
81
  *
86
82
  * @remarks uni-app 以空字符串同时表示“键缺失”和“真实空值”,因此空字符串需要结合键清单消除歧义。
87
- * @param storage - 已从全局 `uni` 读取并校验的同步 API。
88
- * @returns 统一的内部同步后端。
83
+ * @returns 统一的内部同步后端
89
84
  */
90
- const createUniStorageBackend = (storage) => ({
85
+ const createUniStorageBackend = () => ({
91
86
  getItem: (key) => {
92
- const value = storage.getStorageSync(key);
87
+ const value = uni.getStorageSync(key);
93
88
  if (value !== "") return value;
94
- return storage.getStorageInfoSync().keys.includes(key) ? value : void 0;
89
+ return uni.getStorageInfoSync().keys.includes(key) ? value : void 0;
95
90
  },
96
- keys: () => [...storage.getStorageInfoSync().keys],
91
+ keys: () => [...uni.getStorageInfoSync().keys],
97
92
  removeItem: (key) => {
98
- storage.removeStorageSync(key);
93
+ uni.removeStorageSync(key);
99
94
  },
100
95
  setItem: (key, value) => {
101
- storage.setStorageSync(key, value);
96
+ uni.setStorageSync(key, value);
102
97
  }
103
98
  });
104
99
  /**
105
100
  * 解析并校验版本化 Storage 包络。
106
101
  *
107
- * @param rawValue - 后端返回的原始值。
108
- * @param key - 用于错误定位的完整物理键。
109
- * @returns 当前 v3 包络。
102
+ * @param rawValue - 后端返回的原始值
103
+ * @param key - 用于错误定位的完整物理键
104
+ * @returns 当前 v3 包络
110
105
  * @throws `TypeError` 当原始值不是字符串、JSON 损坏、版本不支持或字段类型非法。
111
106
  */
112
107
  const parseStoredEnvelope = (rawValue, key) => {
113
- if (typeof rawValue !== "string") throw new TypeError(`Storage 条目“${key}”不是字符串。`);
108
+ if (typeof rawValue !== "string") throw new TypeError(`Storage entry "${key}" is not a string.`);
114
109
  try {
115
110
  const parsed = JSON.parse(rawValue);
116
- if (!isRecord(parsed) || parsed["version"] !== 3 || typeof parsed["data"] !== "string" || !(parsed["expiresAt"] === null || typeof parsed["expiresAt"] === "number" && Number.isFinite(parsed["expiresAt"]))) throw new TypeError("不支持该存储包络。");
111
+ if (!isRecord(parsed) || parsed["version"] !== 3 || typeof parsed["data"] !== "string" || !(parsed["expiresAt"] === null || typeof parsed["expiresAt"] === "number" && Number.isFinite(parsed["expiresAt"]))) throw new TypeError("Unsupported storage envelope.");
117
112
  return {
118
113
  data: parsed["data"],
119
114
  expiresAt: parsed["expiresAt"],
120
115
  version: 3
121
116
  };
122
117
  } catch (cause) {
123
- throw new TypeError(`Storage 条目“${key}”已损坏或不受支持。`, { cause });
118
+ throw new TypeError(`Storage entry "${key}" is corrupted or unsupported.`, { cause });
124
119
  }
125
120
  };
126
121
  /**
127
122
  * 创建绑定命名空间、Codec 与时钟的 Storage Area。
128
123
  *
129
124
  * @param backendFactory - 每次操作时解析平台后端的工厂,保证导入安全并反映平台可用性。
130
- * @param prefix - 已校验的全局物理键前缀。
131
- * @param codec - 业务值与包络文本之间的 Codec。
132
- * @param now - TTL 计算使用的可注入时钟。
133
- * @returns 完整的命名空间 Storage 操作集合。
125
+ * @param prefix - 已校验的全局物理键前缀
126
+ * @param codec - 业务值与包络文本之间的 Codec
127
+ * @param now - TTL 计算使用的可注入时钟
128
+ * @returns 完整的命名空间 Storage 操作集合
134
129
  */
135
130
  const createStorageArea = (backendFactory, prefix, codec, now) => {
136
131
  /**
137
132
  * 拼接物理键。
138
133
  *
139
- * @param key - 已校验业务键。
140
- * @returns 带当前命名空间前缀的物理键。
134
+ * @param key - 已校验业务键
135
+ * @returns 带当前命名空间前缀的物理键
141
136
  */
142
137
  const toStorageKey = (key) => `${prefix}${key}`;
143
138
  /**
144
139
  * 解析本次读写实际使用的 Codec。
145
140
  *
146
141
  * @param crypto - 单次 Base64 混淆开关;省略时沿用 Area 全局 Codec。
147
- * @returns 本次操作使用的全局、JSON 或 Base64 Codec。
142
+ * @returns 本次操作使用的全局、JSON 或 Base64 Codec
148
143
  * @throws `TypeError` 当 JavaScript 调用方传入非布尔值。
149
144
  */
150
145
  const resolveOperationCodec = (crypto) => {
151
146
  if (crypto === void 0) return codec;
152
- if (typeof crypto !== "boolean") throw new TypeError("Storage 单次 `crypto` 选项必须是布尔值。");
147
+ if (typeof crypto !== "boolean") throw new TypeError("The per-operation Storage `crypto` option must be a boolean.");
153
148
  return crypto ? base64StorageCodec : jsonCodec;
154
149
  };
155
150
  /**
156
151
  * 枚举当前命名空间中的业务键。
157
152
  *
158
- * @param backend - 本次操作使用的后端。
159
- * @returns 已移除物理前缀、去重并排序的业务键。
153
+ * @param backend - 本次操作使用的后端
154
+ * @returns 已移除物理前缀、去重并排序的业务键
160
155
  * @throws `TypeError` 当后端返回非字符串键。
161
156
  */
162
157
  const listBusinessKeys = (backend) => {
163
158
  const keys = backend.keys();
164
- if (!Array.isArray(keys) || !keys.every((key) => typeof key === "string")) throw new TypeError("Storage 后端返回的键必须是字符串。");
159
+ if (!Array.isArray(keys) || !keys.every((key) => typeof key === "string")) throw new TypeError("Keys returned by the Storage backend must be strings.");
165
160
  return [...new Set(keys.filter((key) => key.startsWith(prefix)).map((key) => key.slice(prefix.length)))].sort();
166
161
  };
167
162
  /**
168
163
  * 读取并处理单个包络。
169
164
  *
170
- * @param backend - 本次操作使用的后端。
171
- * @param key - 业务键。
165
+ * @param backend - 本次操作使用的后端
166
+ * @param key - 业务键
172
167
  * @returns 未过期包络;键缺失或已经过期时返回 `undefined`。
173
168
  * @throws `TypeError` 当键或包络非法。
174
169
  * @throws `RangeError` 当注入时钟返回非有限时间戳。
@@ -181,7 +176,7 @@ const createStorageArea = (backendFactory, prefix, codec, now) => {
181
176
  const envelope = parseStoredEnvelope(rawValue, storageKey);
182
177
  if (envelope.expiresAt === null) return envelope;
183
178
  const timestamp = now();
184
- if (!Number.isFinite(timestamp)) throw new RangeError("Storage 时钟必须返回有限时间戳。");
179
+ if (!Number.isFinite(timestamp)) throw new RangeError("The Storage clock must return a finite timestamp.");
185
180
  if (timestamp < envelope.expiresAt) return envelope;
186
181
  backend.removeItem(storageKey);
187
182
  };
@@ -197,7 +192,7 @@ const createStorageArea = (backendFactory, prefix, codec, now) => {
197
192
  try {
198
193
  return resolveOperationCodec(options.crypto).decode(envelope.data);
199
194
  } catch (cause) {
200
- throw new TypeError(`无法解码 Storage 条目“${toStorageKey(key)}”。`, { cause });
195
+ throw new TypeError(`Unable to decode Storage entry "${toStorageKey(key)}".`, { cause });
201
196
  }
202
197
  },
203
198
  has: (key) => readStoredEnvelope(backendFactory(), key) !== void 0,
@@ -222,20 +217,20 @@ const createStorageArea = (backendFactory, prefix, codec, now) => {
222
217
  },
223
218
  set(key, value, options = {}) {
224
219
  assertKey(key);
225
- if (value === void 0) throw new TypeError("不能存储顶层 `undefined`,请改为移除对应的键。");
220
+ if (value === void 0) throw new TypeError("Cannot store top-level `undefined`; remove the key instead.");
226
221
  let expiresAt = null;
227
222
  if (options.ttlMs !== void 0) {
228
- if (!Number.isFinite(options.ttlMs) || options.ttlMs <= 0) throw new RangeError("`ttlMs` 必须是大于 0 的有限数。");
223
+ if (!Number.isFinite(options.ttlMs) || options.ttlMs <= 0) throw new RangeError("`ttlMs` must be a finite number greater than 0.");
229
224
  const timestamp = now();
230
- if (!Number.isFinite(timestamp) || !Number.isFinite(timestamp + options.ttlMs)) throw new RangeError("Storage 过期时间超出支持的时间戳范围。");
225
+ if (!Number.isFinite(timestamp) || !Number.isFinite(timestamp + options.ttlMs)) throw new RangeError("The Storage expiration time exceeds the supported timestamp range.");
231
226
  expiresAt = timestamp + options.ttlMs;
232
227
  }
233
228
  let data;
234
229
  try {
235
230
  data = resolveOperationCodec(options.crypto).encode(value);
236
- if (typeof data !== "string") throw new TypeError("Storage Codec 必须返回字符串。");
231
+ if (typeof data !== "string") throw new TypeError("The Storage codec must return a string.");
237
232
  } catch (cause) {
238
- throw new TypeError("无法编码存储值。", { cause });
233
+ throw new TypeError("Unable to encode the storage value.", { cause });
239
234
  }
240
235
  backendFactory().setItem(toStorageKey(key), JSON.stringify({
241
236
  data,
@@ -248,30 +243,30 @@ const createStorageArea = (backendFactory, prefix, codec, now) => {
248
243
  /**
249
244
  * 获取已激活的全局 Storage 配置。
250
245
  *
251
- * @returns 显式配置或首次 Storage 操作创建的默认配置。
246
+ * @returns 显式配置或首次 Storage 操作创建的默认配置
252
247
  */
253
248
  const requireStorageConfiguration = () => {
254
249
  if (activeConfiguration === void 0) configureStorage();
255
- if (activeConfiguration === void 0) throw new Error("无法初始化 Storage 配置。");
250
+ if (activeConfiguration === void 0) throw new Error("Unable to initialize the Storage configuration.");
256
251
  return activeConfiguration;
257
252
  };
258
253
  /**
259
254
  * 创建稳定的公开 Storage 门面。
260
255
  *
261
- * @param select - 从激活配置选择 Local 或 Session 的函数。
262
- * @param name - 用于不可用错误的公开门面名称。
256
+ * @param select - 从激活配置选择 Local 或 Session 的函数
257
+ * @param name - 用于不可用错误的公开门面名称
263
258
  * @returns 可安全导入、并在首次调用时解析默认或显式配置的稳定对象。
264
259
  */
265
260
  const createStorageAreaProxy = (select, name) => {
266
261
  /**
267
262
  * 解析当前实际 Area。
268
263
  *
269
- * @returns 配置中的 Local 或 Session Area。
264
+ * @returns 配置中的 Local 或 Session Area
270
265
  * @throws `Error` 当 uni-app 模式请求 Session。
271
266
  */
272
267
  const getArea = () => {
273
268
  const area = select(requireStorageConfiguration());
274
- if (area === void 0) throw new Error(`uni-app 中不支持 ${name}。`);
269
+ if (area === void 0) throw new Error(`${name} is not supported in uni-app.`);
275
270
  return area;
276
271
  };
277
272
  return {
@@ -311,22 +306,22 @@ const Session = createStorageAreaProxy((configuration) => configuration.session,
311
306
  */
312
307
  function configureStorage(options = {}) {
313
308
  const prefix = options.prefix ?? "fast__";
314
- if (typeof prefix !== "string" || prefix.length === 0) throw new TypeError("Storage 前缀必须是非空字符串。");
315
- if (options.codec !== void 0 && options.crypto === true) throw new TypeError("Storage 的 Codec 和加密选项不能同时使用。");
309
+ if (typeof prefix !== "string" || prefix.length === 0) throw new TypeError("The Storage prefix must be a nonempty string.");
310
+ if (options.codec !== void 0 && options.crypto === true) throw new TypeError("Storage codec and crypto options cannot be used together.");
316
311
  const codec = options.codec ?? (options.crypto === true ? base64StorageCodec : jsonCodec);
317
312
  const now = options.now ?? Date.now;
318
313
  if (activeConfiguration !== void 0) {
319
314
  if (activeConfiguration.prefix === prefix && activeConfiguration.codec === codec && activeConfiguration.now === now) return;
320
- throw new Error("Storage 已使用其他选项完成配置。");
315
+ throw new Error("Storage is already configured with different options.");
321
316
  }
322
- const uni = getGlobalUniStorage();
317
+ const usesUniStorage = hasGlobalUniStorage();
323
318
  const configuration = {
324
319
  codec,
325
- local: createStorageArea(uni === void 0 ? () => createWebStorageBackend("local") : () => createUniStorageBackend(uni), prefix, codec, now),
320
+ local: createStorageArea(usesUniStorage ? () => createUniStorageBackend() : () => createWebStorageBackend("local"), prefix, codec, now),
326
321
  now,
327
322
  prefix
328
323
  };
329
- if (uni === void 0) configuration.session = createStorageArea(() => createWebStorageBackend("session"), prefix, codec, now);
324
+ if (!usesUniStorage) configuration.session = createStorageArea(() => createWebStorageBackend("session"), prefix, codec, now);
330
325
  activeConfiguration = configuration;
331
326
  }
332
327
  /** 返回 Storage 是否已经显式配置,或由首次 Storage 操作激活默认配置。 */