@fast-china/utils 2.1.3 → 2.1.5

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 (63) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +2 -0
  3. package/README.zh.md +2 -0
  4. package/dist/array/index.d.mts +19 -12
  5. package/dist/array/index.mjs +15 -1
  6. package/dist/array/index.mjs.map +1 -1
  7. package/dist/async/index.d.mts +13 -14
  8. package/dist/async/index.mjs +7 -5
  9. package/dist/async/index.mjs.map +1 -1
  10. package/dist/base64/index.d.mts +13 -13
  11. package/dist/color/index.d.mts +10 -11
  12. package/dist/color/index.mjs.map +1 -1
  13. package/dist/crypto/index.d.mts +38 -39
  14. package/dist/crypto/index.mjs +9 -4
  15. package/dist/crypto/index.mjs.map +1 -1
  16. package/dist/date/index.d.mts +23 -24
  17. package/dist/date/index.mjs.map +1 -1
  18. package/dist/dom/style.d.mts +5 -6
  19. package/dist/env/index.d.mts +9 -10
  20. package/dist/env/index.mjs +17 -10
  21. package/dist/env/index.mjs.map +1 -1
  22. package/dist/function/index.d.mts +13 -0
  23. package/dist/function/index.mjs +38 -0
  24. package/dist/function/index.mjs.map +1 -0
  25. package/dist/identity/index.d.mts +5 -6
  26. package/dist/index.d.mts +4 -3
  27. package/dist/index.global.min.js +2 -2
  28. package/dist/index.global.min.js.map +1 -1
  29. package/dist/index.mjs +4 -3
  30. package/dist/internal/runtime.mjs +12 -0
  31. package/dist/internal/runtime.mjs.map +1 -0
  32. package/dist/internal/text.d.mts +1 -2
  33. package/dist/internal/text.mjs +1 -1
  34. package/dist/internal/text.mjs.map +1 -1
  35. package/dist/logger/index.d.mts +7 -8
  36. package/dist/logger/index.mjs +6 -7
  37. package/dist/logger/index.mjs.map +1 -1
  38. package/dist/number/index.d.mts +9 -10
  39. package/dist/number/index.mjs +4 -3
  40. package/dist/number/index.mjs.map +1 -1
  41. package/dist/object/index.d.mts +49 -11
  42. package/dist/object/index.mjs +258 -14
  43. package/dist/object/index.mjs.map +1 -1
  44. package/dist/storage/index.d.mts +10 -11
  45. package/dist/storage/index.mjs +3 -2
  46. package/dist/storage/index.mjs.map +1 -1
  47. package/dist/string/index.d.mts +18 -19
  48. package/dist/string/index.mjs +15 -13
  49. package/dist/string/index.mjs.map +1 -1
  50. package/dist/vue/emits.d.mts +2 -3
  51. package/dist/vue/emits.mjs.map +1 -1
  52. package/dist/vue/expose.d.mts +1 -2
  53. package/dist/vue/func.d.mts +2 -3
  54. package/dist/vue/install.d.mts +6 -7
  55. package/dist/vue/install.mjs.map +1 -1
  56. package/dist/vue/props.d.mts +2 -3
  57. package/dist/vue/render.d.mts +1 -2
  58. package/dist/vue/render.mjs.map +1 -1
  59. package/dist/vue/slots.d.mts +3 -4
  60. package/dist/vue/with.d.mts +1 -2
  61. package/docs/API.md +3 -2
  62. package/docs/API.zh-CN.md +3 -2
  63. package/package.json +11 -11
@@ -9,11 +9,10 @@ const isQueryPrimitiveArray = (value) => Array.isArray(value);
9
9
  /**
10
10
  * 安全写入结果对象的自有可枚举属性。
11
11
  *
12
- * @remarks 使用 `defineProperty` 避免 `__proto__` 触发 Setter,并显式拒绝三个原型污染键。
12
+ * @remarks 使用 `defineProperty` 避免 `__proto__` 触发 Setter,并统一创建可写、可配置的自有可枚举数据属性。
13
13
  * @param target - 要写入的结果对象。
14
14
  * @param key - 自有属性键。
15
15
  * @param value - 属性值。
16
- * @throws `TypeError` 当键为 `__proto__`、`prototype` 或 `constructor`。
17
16
  */
18
17
  const defineEnumerableProperty = (target, key, value) => {
19
18
  Object.defineProperty(target, key, {
@@ -23,6 +22,215 @@ const defineEnumerableProperty = (target, key, value) => {
23
22
  writable: true
24
23
  });
25
24
  };
25
+ const typedArrayTags = /* @__PURE__ */ new Set([
26
+ "[object BigInt64Array]",
27
+ "[object BigUint64Array]",
28
+ "[object Float32Array]",
29
+ "[object Float64Array]",
30
+ "[object Int8Array]",
31
+ "[object Int16Array]",
32
+ "[object Int32Array]",
33
+ "[object Uint8Array]",
34
+ "[object Uint8ClampedArray]",
35
+ "[object Uint16Array]",
36
+ "[object Uint32Array]"
37
+ ]);
38
+ /** 使用源值的构造器创建同类空实例。 */
39
+ const createUsingConstructor = (value, arguments_) => {
40
+ const constructor = Reflect.get(value, "constructor");
41
+ return typeof constructor === "function" ? Reflect.construct(constructor, arguments_) : {};
42
+ };
43
+ /** 复制 ArrayBufferLike 的当前字节,不与源值共享底层内存。 */
44
+ const cloneArrayBuffer = (value) => {
45
+ const result = createUsingConstructor(value, [value.byteLength]);
46
+ new Uint8Array(result).set(new Uint8Array(value));
47
+ return result;
48
+ };
49
+ /** 递归复制值,并记录已复制对象以还原循环引用和共享引用。 */
50
+ const cloneDeepValue = (value, clones, isRoot) => {
51
+ if (typeof value !== "object" && typeof value !== "function" || value === null) return value;
52
+ const source = value;
53
+ const existing = clones.get(source);
54
+ if (existing !== void 0) return existing;
55
+ if (typeof source === "function" && !isRoot) return source;
56
+ if (Array.isArray(source)) {
57
+ const result = createUsingConstructor(source, [source.length]);
58
+ clones.set(source, result);
59
+ for (let index = 0; index < source.length; index += 1) defineEnumerableProperty(result, index, cloneDeepValue(source[index], clones, false));
60
+ return result;
61
+ }
62
+ const tag = Object.prototype.toString.call(source);
63
+ let result;
64
+ if (typeof source === "function") result = {};
65
+ else switch (tag) {
66
+ case "[object Arguments]":
67
+ result = {};
68
+ break;
69
+ case "[object ArrayBuffer]":
70
+ case "[object SharedArrayBuffer]":
71
+ result = cloneArrayBuffer(source);
72
+ break;
73
+ case "[object Boolean]":
74
+ result = createUsingConstructor(source, [source.valueOf()]);
75
+ break;
76
+ case "[object DataView]": {
77
+ const view = source;
78
+ result = createUsingConstructor(source, [
79
+ cloneArrayBuffer(view.buffer),
80
+ view.byteOffset,
81
+ view.byteLength
82
+ ]);
83
+ break;
84
+ }
85
+ case "[object Date]":
86
+ result = createUsingConstructor(source, [source.getTime()]);
87
+ break;
88
+ case "[object Map]":
89
+ case "[object Set]":
90
+ result = createUsingConstructor(source, []);
91
+ break;
92
+ case "[object Number]":
93
+ result = createUsingConstructor(source, [source.valueOf()]);
94
+ break;
95
+ case "[object Object]": {
96
+ const prototype = Object.getPrototypeOf(source);
97
+ result = Object.create(prototype);
98
+ break;
99
+ }
100
+ case "[object RegExp]": {
101
+ const expression = source;
102
+ const clonedExpression = new RegExp(expression.source, expression.flags);
103
+ clonedExpression.lastIndex = expression.lastIndex;
104
+ result = clonedExpression;
105
+ break;
106
+ }
107
+ case "[object String]":
108
+ result = createUsingConstructor(source, [source.valueOf()]);
109
+ break;
110
+ case "[object Symbol]":
111
+ result = Object(source.valueOf());
112
+ break;
113
+ default: {
114
+ if (!typedArrayTags.has(tag)) return isRoot ? {} : source;
115
+ const view = source;
116
+ result = createUsingConstructor(source, [
117
+ cloneArrayBuffer(view.buffer),
118
+ view.byteOffset,
119
+ view.length
120
+ ]);
121
+ }
122
+ }
123
+ clones.set(source, result);
124
+ if (tag === "[object Map]") for (const [key, item] of source) result.set(key, cloneDeepValue(item, clones, false));
125
+ else if (tag === "[object Set]") for (const item of source) result.add(cloneDeepValue(item, clones, false));
126
+ for (const key of Reflect.ownKeys(source)) {
127
+ if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
128
+ const clonedValue = cloneDeepValue(Reflect.get(source, key), clones, false);
129
+ if (key === "__proto__") defineEnumerableProperty(result, key, clonedValue);
130
+ else Reflect.set(result, key, clonedValue);
131
+ }
132
+ return result;
133
+ };
134
+ /** 判断两个值是否满足 SameValueZero 相等。 */
135
+ const sameValueZero = (left, right) => left === right || typeof left === "number" && typeof right === "number" && Number.isNaN(left) && Number.isNaN(right);
136
+ /** 返回对象的自有可枚举字符串与 Symbol 键。 */
137
+ const getEnumerableOwnKeys = (value) => Reflect.ownKeys(value).filter((key) => Object.prototype.propertyIsEnumerable.call(value, key));
138
+ /** 在一次递归分支内记录对象对应关系。 */
139
+ const compareTrackedPair = (left, right, state, compare) => {
140
+ const existingRight = state.leftObjects.get(left);
141
+ const existingLeft = state.rightObjects.get(right);
142
+ if (existingRight !== void 0 || existingLeft !== void 0) return existingRight === right && existingLeft === left;
143
+ state.leftObjects.set(left, right);
144
+ state.rightObjects.set(right, left);
145
+ try {
146
+ return compare();
147
+ } finally {
148
+ state.leftObjects.delete(left);
149
+ state.rightObjects.delete(right);
150
+ }
151
+ };
152
+ /** 按字节比较两个 ArrayBufferLike。 */
153
+ const equalArrayBuffers = (left, right) => {
154
+ if (left.byteLength !== right.byteLength) return false;
155
+ const leftBytes = new Uint8Array(left);
156
+ const rightBytes = new Uint8Array(right);
157
+ for (let index = 0; index < leftBytes.length; index += 1) if (leftBytes[index] !== rightBytes[index]) return false;
158
+ return true;
159
+ };
160
+ /** 按顺序比较数组或 TypedArray 的元素。 */
161
+ const equalIndexedValues = (left, right, state) => {
162
+ if (left.length !== right.length) return false;
163
+ return compareTrackedPair(left, right, state, () => {
164
+ for (let index = 0; index < left.length; index += 1) if (!isEqualValue(left[index], right[index], state)) return false;
165
+ return true;
166
+ });
167
+ };
168
+ /** 无序比较 Map 条目或 Set 元素。 */
169
+ const equalUnorderedValues = (left, right, state) => {
170
+ if (left.length !== right.length) return false;
171
+ const matchedIndexes = /* @__PURE__ */ new Set();
172
+ for (const leftValue of left) {
173
+ let matchedIndex = -1;
174
+ for (let index = 0; index < right.length; index += 1) {
175
+ if (matchedIndexes.has(index) || !isEqualValue(leftValue, right[index], state)) continue;
176
+ matchedIndex = index;
177
+ break;
178
+ }
179
+ if (matchedIndex < 0) return false;
180
+ matchedIndexes.add(matchedIndex);
181
+ }
182
+ return true;
183
+ };
184
+ /** 比较普通对象或 Arguments 的自有可枚举属性与构造器。 */
185
+ const equalObjects = (left, right, state) => {
186
+ const leftKeys = getEnumerableOwnKeys(left);
187
+ const rightKeys = getEnumerableOwnKeys(right);
188
+ if (leftKeys.length !== rightKeys.length) return false;
189
+ for (const key of leftKeys) if (!Object.hasOwn(right, key)) return false;
190
+ return compareTrackedPair(left, right, state, () => {
191
+ let compareConstructors = true;
192
+ for (const key of leftKeys) {
193
+ if (!isEqualValue(Reflect.get(left, key), Reflect.get(right, key), state)) return false;
194
+ if (key === "constructor") compareConstructors = false;
195
+ }
196
+ if (!compareConstructors) return true;
197
+ const leftConstructor = Reflect.get(left, "constructor");
198
+ const rightConstructor = Reflect.get(right, "constructor");
199
+ if (leftConstructor === rightConstructor || !("constructor" in left && "constructor" in right)) return true;
200
+ return typeof leftConstructor === "function" && typeof rightConstructor === "function" && leftConstructor instanceof leftConstructor && rightConstructor instanceof rightConstructor;
201
+ });
202
+ };
203
+ /** 递归比较两个值。 */
204
+ function isEqualValue(left, right, state) {
205
+ if (sameValueZero(left, right)) return true;
206
+ if (left === null || left === void 0 || right === null || right === void 0) return false;
207
+ const leftTag = Object.prototype.toString.call(left);
208
+ const rightTag = Object.prototype.toString.call(right);
209
+ const normalizedLeftTag = leftTag === "[object Arguments]" ? "[object Object]" : leftTag;
210
+ if (normalizedLeftTag !== (rightTag === "[object Arguments]" ? "[object Object]" : rightTag)) return false;
211
+ switch (normalizedLeftTag) {
212
+ case "[object Boolean]":
213
+ case "[object Date]":
214
+ case "[object Number]": return sameValueZero(Number(left), Number(right));
215
+ case "[object Error]": return left.name === right.name && left.message === right.message;
216
+ case "[object RegExp]": return RegExp.prototype.toString.call(left) === RegExp.prototype.toString.call(right);
217
+ case "[object String]": return String.prototype.valueOf.call(left) === String.prototype.valueOf.call(right);
218
+ case "[object Symbol]": return Symbol.prototype.valueOf.call(left) === Symbol.prototype.valueOf.call(right);
219
+ }
220
+ if (typeof left !== "object" || typeof right !== "object") return false;
221
+ if (Array.isArray(left) && Array.isArray(right)) return equalIndexedValues(left, right, state);
222
+ if (normalizedLeftTag === "[object ArrayBuffer]" || normalizedLeftTag === "[object SharedArrayBuffer]") return equalArrayBuffers(left, right);
223
+ if (normalizedLeftTag === "[object DataView]") {
224
+ const leftView = left;
225
+ const rightView = right;
226
+ return leftView.byteLength === rightView.byteLength && leftView.byteOffset === rightView.byteOffset && equalArrayBuffers(leftView.buffer, rightView.buffer);
227
+ }
228
+ if (typedArrayTags.has(normalizedLeftTag)) return equalIndexedValues(left, right, state);
229
+ if (normalizedLeftTag === "[object Map]") return compareTrackedPair(left, right, state, () => equalUnorderedValues([...left], [...right], state));
230
+ if (normalizedLeftTag === "[object Set]") return compareTrackedPair(left, right, state, () => equalUnorderedValues([...left], [...right], state));
231
+ if (normalizedLeftTag === "[object Object]") return equalObjects(left, right, state);
232
+ return false;
233
+ }
26
234
  /**
27
235
  * 判断值是否是普通对象。
28
236
  *
@@ -46,27 +254,63 @@ function hasOwn(value, key) {
46
254
  return Object.hasOwn(value, key);
47
255
  }
48
256
  /**
49
- * 从对象中选择指定自有可枚举属性。
257
+ * 递归创建值的深层副本。
50
258
  *
51
- * @param source - 不会被修改的源对象。
52
- * @param keys - 需要保留的键;不存在的键被忽略。
53
- * @returns 新对象,保持 `keys` 的遍历顺序。
259
+ * @remarks 支持循环引用、共享引用、Symbol 键、对象原型、ArrayBuffer、DataView、Date、Map、RegExp、Set 和 TypedArray。
260
+ * Map 的键保持原引用,函数及其他不可克隆值在嵌套位置保持原引用;只复制自有可枚举属性。
261
+ * @param value - 需要深复制的任意值。
262
+ * @returns 与输入类型一致且不共享可克隆嵌套值的新值;原始类型直接返回自身。
54
263
  */
264
+ function cloneDeep(value) {
265
+ return cloneDeepValue(value, /* @__PURE__ */ new WeakMap(), true);
266
+ }
267
+ /**
268
+ * 深度比较两个值是否等价。
269
+ *
270
+ * @remarks 原始值使用 SameValueZero 语义;支持循环引用、数组、对象、ArrayBuffer、DataView、Date、Error、Map、RegExp、Set、Symbol 和 TypedArray。
271
+ * 对象只比较自有可枚举字符串与 Symbol 属性,函数及其他不支持的宿主对象仅在引用相同时相等。
272
+ * @param left - 第一待比较值。
273
+ * @param right - 第二待比较值。
274
+ * @returns 两个值深度等价时返回 `true`。
275
+ */
276
+ function isEqual(left, right) {
277
+ return isEqualValue(left, right, {
278
+ leftObjects: /* @__PURE__ */ new WeakMap(),
279
+ rightObjects: /* @__PURE__ */ new WeakMap()
280
+ });
281
+ }
55
282
  function pick(source, keys) {
56
283
  const result = {};
57
- for (const key of keys) if (Object.prototype.propertyIsEnumerable.call(source, key)) defineEnumerableProperty(result, key, source[key]);
284
+ for (const key of keys) if (Object.prototype.propertyIsEnumerable.call(source, key)) defineEnumerableProperty(result, key, Reflect.get(source, key));
285
+ return result;
286
+ }
287
+ function omit(source, keys) {
288
+ const result = { ...source };
289
+ for (const key of keys) Reflect.deleteProperty(result, key);
290
+ return result;
291
+ }
292
+ /**
293
+ * 按条件排除对象的自有可枚举属性。
294
+ *
295
+ * @param source - 不会被修改的源对象。
296
+ * @param predicate - 接收属性值、键和源对象;返回真值时排除该属性。
297
+ * @returns 由未匹配属性组成的新对象。
298
+ */
299
+ function omitBy(source, predicate) {
300
+ const result = {};
301
+ for (const key of getEnumerableOwnKeys(source)) if (!predicate(source[key], key, source)) defineEnumerableProperty(result, key, source[key]);
58
302
  return result;
59
303
  }
60
304
  /**
61
- * 浅复制对象并删除指定属性。
305
+ * 按条件选择对象的自有可枚举属性。
62
306
  *
63
307
  * @param source - 不会被修改的源对象。
64
- * @param keys - 需要排除的键。
65
- * @returns 包含其余自有可枚举字符串与 Symbol 属性的新对象。
308
+ * @param predicate - 接收属性值、键和源对象;返回真值时保留该属性。
309
+ * @returns 由匹配属性组成的新对象。
66
310
  */
67
- function omit(source, keys) {
68
- const result = { ...source };
69
- for (const key of keys) Reflect.deleteProperty(result, key);
311
+ function pickBy(source, predicate) {
312
+ const result = {};
313
+ for (const key of getEnumerableOwnKeys(source)) if (predicate(source[key], key, source)) defineEnumerableProperty(result, key, source[key]);
70
314
  return result;
71
315
  }
72
316
  /**
@@ -129,6 +373,6 @@ function toQueryString(value, options = {}) {
129
373
  return result && options.prefixQuestionMark ? `?${result}` : result;
130
374
  }
131
375
  //#endregion
132
- export { hasOwn, isPlainObject, mapValues, omit, pick, shallowEqual, toQueryString };
376
+ export { cloneDeep, hasOwn, isEqual, isPlainObject, mapValues, omit, omitBy, pick, pickBy, shallowEqual, toQueryString };
133
377
 
134
378
  //# sourceMappingURL=index.mjs.map
@@ -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 * @throws `TypeError` 当键为 `__proto__`、`prototype` 或 `constructor`。\n */\nconst defineEnumerableProperty = (target: object, key: PropertyKey, value: unknown): void => {\n\tObject.defineProperty(target, key, { configurable: true, enumerable: true, value, writable: true });\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 * @param source - 不会被修改的源对象。\n * @param keys - 需要保留的键;不存在的键被忽略。\n * @returns 新对象,保持 `keys` 的遍历顺序。\n */\nexport function pick<Source extends object, Keys extends readonly (keyof Source)[]>(source: Source, keys: Keys): Pick<Source, Keys[number]> {\n\tconst result = {} as Pick<Source, Keys[number]>;\n\tfor (const key of keys) {\n\t\tif (Object.prototype.propertyIsEnumerable.call(source, key)) defineEnumerableProperty(result, key, source[key]);\n\t}\n\treturn result;\n}\n\n/**\n * 浅复制对象并删除指定属性。\n *\n * @param source - 不会被修改的源对象。\n * @param keys - 需要排除的键。\n * @returns 包含其余自有可枚举字符串与 Symbol 属性的新对象。\n */\nexport function omit<Source extends object, Keys extends readonly (keyof Source)[]>(source: Source, keys: Keys): Omit<Source, Keys[number]> {\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 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":";;;;;;;AAYA,MAAM,yBAAyB,UAA0D,MAAM,QAAQ,KAAK;;;;;;;;;;AAqB5G,MAAM,4BAA4B,QAAgB,KAAkB,UAAyB;CAC5F,OAAO,eAAe,QAAQ,KAAK;EAAE,cAAc;EAAM,YAAY;EAAM;EAAO,UAAU;CAAK,CAAC;AACnG;;;;;;;AAQA,SAAgB,cAAc,OAAuD;CACpF,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO;CACxD,MAAM,YAAY,OAAO,eAAe,KAAK;CAC7C,OAAO,cAAc,QAAQ,cAAc,OAAO;AACnD;;;;;;;;;AAUA,SAAgB,OAA2D,OAAmB,KAAyC;CACtI,OAAO,OAAO,OAAO,OAAO,GAAG;AAChC;;;;;;;;AASA,SAAgB,KAAoE,QAAgB,MAAwC;CAC3I,MAAM,SAAS,CAAC;CAChB,KAAK,MAAM,OAAO,MACjB,IAAI,OAAO,UAAU,qBAAqB,KAAK,QAAQ,GAAG,GAAG,yBAAyB,QAAQ,KAAK,OAAO,IAAI;CAE/G,OAAO;AACR;;;;;;;;AASA,SAAgB,KAAoE,QAAgB,MAAwC;CAC3I,MAAM,SAAS,EAAE,GAAG,OAAO;CAC3B,KAAK,MAAM,OAAO,MAAM,QAAQ,eAAe,QAAQ,GAAG;CAC1D,OAAO;AACR;;;;;;;;AASA,SAAgB,UACf,QACA,QACoC;CACpC,MAAM,SAAS,CAAC;CAChB,KAAK,MAAM,OAAO,QAAQ,QAAQ,MAAM,GACvC,IAAI,OAAO,UAAU,qBAAqB,KAAK,QAAQ,GAAG,GAAG,yBAAyB,QAAQ,KAAK,OAAO,OAAO,MAAM,KAAK,MAAM,CAAC;CAEpI,OAAO;AACR;;;;;;;;;AAUA,SAAgB,aAAa,MAAc,OAAwB;CAClE,IAAI,OAAO,GAAG,MAAM,KAAK,GAAG,OAAO;CACnC,MAAM,WAAW,QAAQ,QAAQ,IAAI,CAAC,CAAC,QAAQ,QAAQ,OAAO,UAAU,qBAAqB,KAAK,MAAM,GAAG,CAAC;CAC5G,MAAM,YAAY,QAAQ,QAAQ,KAAK,CAAC,CAAC,QAAQ,QAAQ,OAAO,UAAU,qBAAqB,KAAK,OAAO,GAAG,CAAC;CAC/G,IAAI,SAAS,WAAW,UAAU,QAAQ,OAAO;CACjD,OAAO,SAAS,OAAO,QAAQ,OAAO,OAAO,OAAO,GAAG,KAAK,OAAO,GAAG,QAAQ,IAAI,MAAM,GAAG,GAAG,QAAQ,IAAI,OAAO,GAAG,CAAC,CAAC;AACvH;;;;;;;;AASA,MAAM,uBAAuB,UAA6D;CACzF,IAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GACtD,MAAM,IAAI,WAAW,iBAAiB;CAEvC,OAAO,OAAO,KAAK;AACpB;;;;;;;;;;AAWA,SAAgB,cAAc,OAA6C,UAA8B,CAAC,GAAW;CACpH,MAAM,UAAU,OAAO,QAAQ,KAAK;CACpC,IAAI,QAAQ,MAAM,QAAQ,MAAM,CAAC,OAAO,CAAC,WAAY,OAAO,QAAQ,KAAK,OAAO,QAAQ,IAAI,CAAE;CAC9F,MAAM,aAAa,IAAI,gBAAgB;CACvC,KAAK,MAAM,CAAC,KAAK,aAAa,SAAS;EACtC,MAAM,SAAS,sBAAsB,QAAQ,IAAI,WAAW,CAAC,QAAQ;EACrE,KAAK,MAAM,QAAQ,QAClB,IAAI,SAAS,QAAQ,SAAS,KAAA,GAAW,WAAW,OAAO,KAAK,oBAAoB,IAAI,CAAC;CAE3F;CACA,IAAI,SAAS,WAAW,SAAS;CACjC,IAAI,QAAQ,UAAU,WAAW,SAAS,OAAO,QAAQ,QAAQ,KAAK;CACtE,OAAO,UAAU,QAAQ,qBAAqB,IAAI,WAAW;AAC9D"}
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\tif (Array.isArray(source)) {\n\t\tconst result = createUsingConstructor(source, [source.length]);\n\t\tclones.set(source, result);\n\t\tfor (let index = 0; index < source.length; index += 1) {\n\t\t\tdefineEnumerableProperty(result, index, cloneDeepValue(source[index], clones, false));\n\t\t}\n\t\treturn result;\n\t}\n\n\tconst tag = Object.prototype.toString.call(source);\n\tlet result: object;\n\tif (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, [cloneArrayBuffer(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, [cloneArrayBuffer(view.buffer), view.byteOffset, view.length]);\n\t\t\t}\n\t\t}\n\t}\n\n\tclones.set(source, result);\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\tfor (const key of Reflect.ownKeys(source)) {\n\t\tif (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;\n\t\tconst clonedValue = cloneDeepValue(Reflect.get(source, key), clones, false);\n\t\tif (key === \"__proto__\") defineEnumerableProperty(result, key, clonedValue);\n\t\telse Reflect.set(result, key, clonedValue);\n\t}\n\treturn result;\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 字面量键数组保留精确返回类型;普通 `string[]` 等动态键数组返回 `Partial<Source>`。\n * @param source - 不会被修改的源对象。\n * @param keys - 需要保留的键;不存在的键被忽略。\n * @returns 新对象,保持 `keys` 的遍历顺序。\n */\nexport function pick<Source extends object, const Keys extends readonly (keyof Source)[]>(source: Source, keys: Keys): 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 字面量键数组保留精确返回类型;普通 `string[]` 等动态键数组返回 `Partial<Source>`。\n * @param source - 不会被修改的源对象。\n * @param keys - 需要排除的键。\n * @returns 包含其余自有可枚举字符串与 Symbol 属性的新对象。\n */\nexport function omit<Source extends object, const Keys extends readonly (keyof Source)[]>(source: Source, keys: Keys): 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,6 +1,6 @@
1
1
  //#region src/storage/index.d.ts
2
2
  /** Storage 业务值编码器。 */
3
- interface StorageCodec {
3
+ export interface StorageCodec {
4
4
  /**
5
5
  * 把已编码文本恢复为业务值。
6
6
  * @param value - 由同一 Codec 的 `encode` 生成并持久化的文本。
@@ -17,7 +17,7 @@ interface StorageCodec {
17
17
  encode: (value: unknown) => string;
18
18
  }
19
19
  /** 程序入口调用 {@link configureStorage} 时使用的全局配置。 */
20
- interface StorageConfiguration {
20
+ export interface StorageConfiguration {
21
21
  /** 自定义值编码器;默认使用严格 JSON Codec,同一应用生命周期内必须保持同一引用。 */
22
22
  codec?: StorageCodec;
23
23
  /** 启用 Base64 可逆混淆;不提供加密、完整性或认证,不能与 `codec` 同时使用。 */
@@ -28,7 +28,7 @@ interface StorageConfiguration {
28
28
  prefix?: string;
29
29
  }
30
30
  /** 单次 Storage 读取配置。 */
31
- interface StorageReadOptions {
31
+ export interface StorageReadOptions {
32
32
  /**
33
33
  * 仅覆盖本次读取使用的 Codec;`true` 使用 Base64 混淆,`false` 使用 JSON,省略时使用全局配置。
34
34
  * 必须与写入该条目时使用的单次设置一致。
@@ -36,12 +36,12 @@ interface StorageReadOptions {
36
36
  crypto?: boolean;
37
37
  }
38
38
  /** 单次 Storage 写入配置。 */
39
- interface StorageWriteOptions extends StorageReadOptions {
39
+ export interface StorageWriteOptions extends StorageReadOptions {
40
40
  /** 从写入时刻开始的有效毫秒数;必须是大于 0 的有限数,省略时永久有效。 */
41
41
  ttlMs?: number;
42
42
  }
43
43
  /** `Local` 与 `Session` 的统一操作接口。 */
44
- interface StorageArea {
44
+ export interface StorageArea {
45
45
  /** 当前全局 Storage 配置的物理键前缀;首次读取会激活默认配置。 */
46
46
  readonly prefix: string;
47
47
  /**
@@ -94,11 +94,11 @@ interface StorageArea {
94
94
  set: <Value>(key: string, value: Value, options?: StorageWriteOptions) => void;
95
95
  }
96
96
  /** Base64 混淆 Codec;只隐藏明文外观,不提供加密、完整性或认证。 */
97
- declare const base64StorageCodec: StorageCodec;
97
+ export declare const base64StorageCodec: StorageCodec;
98
98
  /** 浏览器 localStorage 或自动检测的 uni-app Storage 全局业务入口。 */
99
- declare const Local: StorageArea;
99
+ export declare const Local: StorageArea;
100
100
  /** 浏览器 sessionStorage 的全局业务入口;uni-app 不提供会话存储。 */
101
- declare const Session: StorageArea;
101
+ export declare const Session: StorageArea;
102
102
  /**
103
103
  * 在首次 Storage 操作前可选配置 `Local` 与 `Session`。
104
104
  *
@@ -108,9 +108,8 @@ declare const Session: StorageArea;
108
108
  * @param options - 可选的全局键前缀、Codec、旧版混淆选项与时钟。
109
109
  * @throws 配置非法、重复配置冲突或目标平台 Storage 不可用时抛出错误。
110
110
  */
111
- declare function configureStorage(options?: StorageConfiguration): void;
111
+ export declare function configureStorage(options?: StorageConfiguration): void;
112
112
  /** 返回全局 Storage 是否已经由应用入口配置。 */
113
- declare function isStorageConfigured(): boolean;
113
+ export declare function isStorageConfigured(): boolean;
114
114
  //#endregion
115
- export { Local, Session, StorageArea, StorageCodec, StorageConfiguration, StorageReadOptions, StorageWriteOptions, base64StorageCodec, configureStorage, isStorageConfigured };
116
115
  //# sourceMappingURL=index.d.mts.map
@@ -1,3 +1,4 @@
1
+ import { runtimeGlobals } from "../internal/runtime.mjs";
1
2
  import { decodeSecureBase64, encodeSecureBase64 } from "../base64/index.mjs";
2
3
  //#region src/storage/index.ts
3
4
  /**
@@ -7,7 +8,7 @@ import { decodeSecureBase64, encodeSecureBase64 } from "../base64/index.mjs";
7
8
  * @throws `TypeError` 当全局 `uni` 存在但缺少本库需要的同步 Storage 方法。
8
9
  */
9
10
  const getGlobalUniStorage = () => {
10
- const value = Reflect.get(globalThis, "uni");
11
+ const value = runtimeGlobals.uni;
11
12
  if (value === void 0) return void 0;
12
13
  if (typeof value !== "object" && typeof value !== "function" || value === null) throw new TypeError("全局 uni 对象未提供同步 Storage API。");
13
14
  const storage = value;
@@ -59,7 +60,7 @@ const assertKey = (key) => {
59
60
  * @throws `Error` 当所选 Storage 在当前环境不可用。
60
61
  */
61
62
  const createWebStorageBackend = (kind) => {
62
- const storage = kind === "local" ? globalThis.localStorage : globalThis.sessionStorage;
63
+ const storage = kind === "local" ? runtimeGlobals.localStorage : runtimeGlobals.sessionStorage;
63
64
  if (storage === void 0) throw new Error(`当前运行环境不支持 ${kind}Storage。`);
64
65
  return {
65
66
  getItem: (key) => storage.getItem(key),