@simplysm/core-common 13.0.76 → 13.0.78

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 (126) hide show
  1. package/README.md +64 -21
  2. package/dist/extensions/arr-ext.d.ts +1 -1
  3. package/dist/extensions/arr-ext.d.ts.map +1 -1
  4. package/dist/extensions/arr-ext.helpers.d.ts +8 -0
  5. package/dist/extensions/arr-ext.helpers.d.ts.map +1 -1
  6. package/dist/extensions/arr-ext.helpers.js +65 -0
  7. package/dist/extensions/arr-ext.helpers.js.map +2 -2
  8. package/dist/extensions/arr-ext.js +16 -124
  9. package/dist/extensions/arr-ext.js.map +2 -2
  10. package/dist/extensions/arr-ext.types.d.ts +40 -32
  11. package/dist/extensions/arr-ext.types.d.ts.map +1 -1
  12. package/dist/extensions/map-ext.js.map +1 -1
  13. package/dist/extensions/set-ext.js.map +1 -1
  14. package/dist/features/event-emitter.d.ts +4 -4
  15. package/dist/features/event-emitter.d.ts.map +1 -1
  16. package/dist/features/event-emitter.js.map +1 -1
  17. package/dist/features/serial-queue.js +2 -2
  18. package/dist/features/serial-queue.js.map +1 -1
  19. package/dist/index.d.ts +13 -13
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +27 -13
  22. package/dist/index.js.map +1 -1
  23. package/dist/types/date-only.js +2 -2
  24. package/dist/types/date-only.js.map +1 -1
  25. package/dist/types/date-time.js +2 -2
  26. package/dist/types/date-time.js.map +1 -1
  27. package/dist/types/time.js +2 -2
  28. package/dist/types/time.js.map +1 -1
  29. package/dist/types/uuid.d.ts +2 -2
  30. package/dist/types/uuid.d.ts.map +1 -1
  31. package/dist/types/uuid.js +1 -1
  32. package/dist/types/uuid.js.map +1 -1
  33. package/dist/utils/bytes.d.ts +10 -10
  34. package/dist/utils/bytes.d.ts.map +1 -1
  35. package/dist/utils/bytes.js +10 -10
  36. package/dist/utils/bytes.js.map +1 -1
  37. package/dist/utils/date-format.d.ts +1 -1
  38. package/dist/utils/date-format.d.ts.map +1 -1
  39. package/dist/utils/date-format.js +2 -2
  40. package/dist/utils/date-format.js.map +1 -1
  41. package/dist/utils/error.d.ts +1 -1
  42. package/dist/utils/error.d.ts.map +1 -1
  43. package/dist/utils/error.js +2 -2
  44. package/dist/utils/error.js.map +1 -1
  45. package/dist/utils/json.d.ts +4 -2
  46. package/dist/utils/json.d.ts.map +1 -1
  47. package/dist/utils/json.js +9 -9
  48. package/dist/utils/json.js.map +1 -1
  49. package/dist/utils/num.d.ts +10 -10
  50. package/dist/utils/num.d.ts.map +1 -1
  51. package/dist/utils/num.js +11 -11
  52. package/dist/utils/num.js.map +1 -1
  53. package/dist/utils/obj.d.ts +40 -40
  54. package/dist/utils/obj.d.ts.map +1 -1
  55. package/dist/utils/obj.js +102 -99
  56. package/dist/utils/obj.js.map +1 -1
  57. package/dist/utils/path.d.ts +3 -3
  58. package/dist/utils/path.d.ts.map +1 -1
  59. package/dist/utils/path.js +6 -6
  60. package/dist/utils/path.js.map +1 -1
  61. package/dist/utils/primitive.d.ts +1 -1
  62. package/dist/utils/primitive.d.ts.map +1 -1
  63. package/dist/utils/primitive.js +2 -2
  64. package/dist/utils/primitive.js.map +1 -1
  65. package/dist/utils/str.d.ts +16 -16
  66. package/dist/utils/str.d.ts.map +1 -1
  67. package/dist/utils/str.js +16 -16
  68. package/dist/utils/str.js.map +1 -1
  69. package/dist/utils/transferable.d.ts +3 -3
  70. package/dist/utils/transferable.d.ts.map +1 -1
  71. package/dist/utils/transferable.js +10 -10
  72. package/dist/utils/transferable.js.map +1 -1
  73. package/dist/utils/wait.d.ts +2 -2
  74. package/dist/utils/wait.d.ts.map +1 -1
  75. package/dist/utils/wait.js +5 -5
  76. package/dist/utils/wait.js.map +1 -1
  77. package/dist/utils/xml.d.ts +2 -2
  78. package/dist/utils/xml.d.ts.map +1 -1
  79. package/dist/utils/xml.js +4 -4
  80. package/dist/utils/xml.js.map +1 -1
  81. package/dist/{zip/sd-zip.d.ts → utils/zip.d.ts} +1 -1
  82. package/dist/utils/zip.d.ts.map +1 -0
  83. package/dist/{zip/sd-zip.js → utils/zip.js} +1 -1
  84. package/dist/{zip/sd-zip.js.map → utils/zip.js.map} +1 -1
  85. package/package.json +1 -1
  86. package/src/extensions/arr-ext.helpers.ts +86 -0
  87. package/src/extensions/arr-ext.ts +22 -170
  88. package/src/extensions/arr-ext.types.ts +76 -48
  89. package/src/extensions/map-ext.ts +3 -3
  90. package/src/extensions/set-ext.ts +2 -2
  91. package/src/features/event-emitter.ts +6 -6
  92. package/src/features/serial-queue.ts +2 -2
  93. package/src/index.ts +16 -16
  94. package/src/types/date-only.ts +2 -2
  95. package/src/types/date-time.ts +2 -2
  96. package/src/types/time.ts +2 -2
  97. package/src/types/uuid.ts +2 -2
  98. package/src/utils/bytes.ts +15 -15
  99. package/src/utils/date-format.ts +1 -1
  100. package/src/utils/error.ts +1 -1
  101. package/src/utils/json.ts +9 -7
  102. package/src/utils/num.ts +15 -15
  103. package/src/utils/obj.ts +119 -116
  104. package/src/utils/path.ts +3 -3
  105. package/src/utils/primitive.ts +1 -1
  106. package/src/utils/str.ts +16 -16
  107. package/src/utils/transferable.ts +9 -9
  108. package/src/utils/wait.ts +3 -3
  109. package/src/utils/xml.ts +2 -2
  110. package/tests/extensions/array-extension.spec.ts +7 -5
  111. package/tests/types/uuid.spec.ts +4 -4
  112. package/tests/utils/bytes-utils.spec.ts +42 -49
  113. package/tests/utils/date-format.spec.ts +89 -88
  114. package/tests/utils/debounce-queue.spec.ts +3 -1
  115. package/tests/utils/json.spec.ts +61 -68
  116. package/tests/utils/number.spec.ts +41 -46
  117. package/tests/utils/object.spec.ts +120 -139
  118. package/tests/utils/path.spec.ts +19 -19
  119. package/tests/utils/primitive.spec.ts +12 -12
  120. package/tests/utils/string.spec.ts +66 -74
  121. package/tests/utils/transferable.spec.ts +55 -62
  122. package/tests/utils/wait.spec.ts +10 -10
  123. package/tests/utils/xml.spec.ts +25 -25
  124. package/dist/zip/sd-zip.d.ts.map +0 -1
  125. /package/src/{zip/sd-zip.ts → utils/zip.ts} +0 -0
  126. /package/tests/{zip/sd-zip.spec.ts → utils/zip.spec.ts} +0 -0
package/src/utils/obj.ts CHANGED
@@ -4,7 +4,7 @@ import { Time } from "../types/time";
4
4
  import { Uuid } from "../types/uuid";
5
5
  import { ArgumentError } from "../errors/argument-error";
6
6
 
7
- //#region objClone
7
+ //#region clone
8
8
 
9
9
  /**
10
10
  * Deep clone
@@ -16,11 +16,11 @@ import { ArgumentError } from "../errors/argument-error";
16
16
  * @note Prototype chain is maintained (using Object.setPrototypeOf)
17
17
  * @note Getters/setters are evaluated as current values and copied (accessor properties themselves are not copied)
18
18
  */
19
- export function objClone<TSource>(source: TSource): TSource {
20
- return objCloneImpl(source) as TSource;
19
+ export function clone<TObj>(source: TObj): TObj {
20
+ return cloneImpl(source) as TObj;
21
21
  }
22
22
 
23
- function objCloneImpl(source: unknown, prevClones?: WeakMap<object, unknown>): unknown {
23
+ function cloneImpl(source: unknown, prevClones?: WeakMap<object, unknown>): unknown {
24
24
  // Primitives are returned as-is
25
25
  if (typeof source !== "object" || source === null) {
26
26
  return source;
@@ -67,15 +67,18 @@ function objCloneImpl(source: unknown, prevClones?: WeakMap<object, unknown>): u
67
67
  cloned.name = source.name;
68
68
  cloned.stack = source.stack;
69
69
  if (source.cause !== undefined) {
70
- cloned.cause = objCloneImpl(source.cause, currPrevClones);
70
+ cloned.cause = cloneImpl(source.cause, currPrevClones);
71
71
  }
72
72
  // Copy custom Error properties
73
73
  for (const key of Object.keys(source)) {
74
74
  if (!["message", "name", "stack", "cause"].includes(key)) {
75
- (cloned as unknown as Record<string, unknown>)[key] = objCloneImpl(
76
- (source as unknown as Record<string, unknown>)[key],
77
- currPrevClones,
78
- );
75
+ const desc = Object.getOwnPropertyDescriptor(source, key);
76
+ if (desc !== undefined) {
77
+ Object.defineProperty(cloned, key, {
78
+ ...desc,
79
+ value: "value" in desc ? cloneImpl(desc.value, currPrevClones) : desc.value,
80
+ });
81
+ }
79
82
  }
80
83
  }
81
84
  return cloned;
@@ -91,7 +94,7 @@ function objCloneImpl(source: unknown, prevClones?: WeakMap<object, unknown>): u
91
94
  const result: unknown[] = [];
92
95
  currPrevClones.set(source, result);
93
96
  for (const item of source) {
94
- result.push(objCloneImpl(item, currPrevClones));
97
+ result.push(cloneImpl(item, currPrevClones));
95
98
  }
96
99
  return result;
97
100
  }
@@ -100,7 +103,7 @@ function objCloneImpl(source: unknown, prevClones?: WeakMap<object, unknown>): u
100
103
  const result = new Map();
101
104
  currPrevClones.set(source, result);
102
105
  for (const [key, value] of source) {
103
- result.set(objCloneImpl(key, currPrevClones), objCloneImpl(value, currPrevClones));
106
+ result.set(cloneImpl(key, currPrevClones), cloneImpl(value, currPrevClones));
104
107
  }
105
108
  return result;
106
109
  }
@@ -109,7 +112,7 @@ function objCloneImpl(source: unknown, prevClones?: WeakMap<object, unknown>): u
109
112
  const result = new Set();
110
113
  currPrevClones.set(source, result);
111
114
  for (const item of source) {
112
- result.add(objCloneImpl(item, currPrevClones));
115
+ result.add(cloneImpl(item, currPrevClones));
113
116
  }
114
117
  return result;
115
118
  }
@@ -121,7 +124,7 @@ function objCloneImpl(source: unknown, prevClones?: WeakMap<object, unknown>): u
121
124
 
122
125
  for (const key of Object.keys(source)) {
123
126
  const value = (source as Record<string, unknown>)[key];
124
- result[key] = objCloneImpl(value, currPrevClones);
127
+ result[key] = cloneImpl(value, currPrevClones);
125
128
  }
126
129
 
127
130
  return result;
@@ -129,9 +132,9 @@ function objCloneImpl(source: unknown, prevClones?: WeakMap<object, unknown>): u
129
132
 
130
133
  //#endregion
131
134
 
132
- //#region objEqual
135
+ //#region equal
133
136
 
134
- /** objEqual options type */
137
+ /** equal options type */
135
138
  export interface EqualOptions {
136
139
  /** List of keys to compare. When specified, only those keys are compared (applies only to top level) */
137
140
  topLevelIncludes?: string[];
@@ -140,7 +143,7 @@ export interface EqualOptions {
140
143
  /** Whether to ignore array order. O(n²) complexity when true */
141
144
  ignoreArrayIndex?: boolean;
142
145
  /** Whether to do shallow comparison. Only compare 1 level (reference comparison) when true */
143
- onlyOneDepth?: boolean;
146
+ shallow?: boolean;
144
147
  }
145
148
 
146
149
  /**
@@ -154,7 +157,7 @@ export interface EqualOptions {
154
157
  * @param options.topLevelExcludes List of keys to exclude from comparison (applies only to top level)
155
158
  * @example `{ topLevelExcludes: ["updatedAt"] }` - Compare excluding updatedAt key
156
159
  * @param options.ignoreArrayIndex Whether to ignore array order. O(n²) complexity when true
157
- * @param options.onlyOneDepth Whether to do shallow comparison. Only compare 1 level (reference comparison) when true
160
+ * @param options.shallow Whether to do shallow comparison. Only compare 1 level (reference comparison) when true
158
161
  *
159
162
  * @note topLevelIncludes/topLevelExcludes options apply only to object property keys.
160
163
  * All keys in Map are always included in comparison.
@@ -166,7 +169,7 @@ export interface EqualOptions {
166
169
  * - Ignore array order and check if elements are permutations of the same set
167
170
  * - Example: `[1,2,3]` and `[3,2,1]` → true, `[1,1,1]` and `[1,2,3]` → false
168
171
  */
169
- export function objEqual(source: unknown, target: unknown, options?: EqualOptions): boolean {
172
+ export function equal(source: unknown, target: unknown, options?: EqualOptions): boolean {
170
173
  if (source === target) return true;
171
174
  if (source == null || target == null) return false;
172
175
  if (typeof source !== typeof target) return false;
@@ -192,19 +195,19 @@ export function objEqual(source: unknown, target: unknown, options?: EqualOption
192
195
  }
193
196
 
194
197
  if (source instanceof Array && target instanceof Array) {
195
- return objEqualArray(source, target, options);
198
+ return equalArray(source, target, options);
196
199
  }
197
200
 
198
201
  if (source instanceof Map && target instanceof Map) {
199
- return objEqualMap(source, target, options);
202
+ return equalMap(source, target, options);
200
203
  }
201
204
 
202
205
  if (source instanceof Set && target instanceof Set) {
203
- return objEqualSet(source, target, options);
206
+ return equalSet(source, target, options);
204
207
  }
205
208
 
206
209
  if (typeof source === "object" && typeof target === "object") {
207
- return objEqualObject(
210
+ return equalObject(
208
211
  source as Record<string, unknown>,
209
212
  target as Record<string, unknown>,
210
213
  options,
@@ -214,7 +217,7 @@ export function objEqual(source: unknown, target: unknown, options?: EqualOption
214
217
  return false;
215
218
  }
216
219
 
217
- function objEqualArray(source: unknown[], target: unknown[], options?: EqualOptions): boolean {
220
+ function equalArray(source: unknown[], target: unknown[], options?: EqualOptions): boolean {
218
221
  if (source.length !== target.length) {
219
222
  return false;
220
223
  }
@@ -222,7 +225,7 @@ function objEqualArray(source: unknown[], target: unknown[], options?: EqualOpti
222
225
  if (options?.ignoreArrayIndex) {
223
226
  const matchedIndices = new Set<number>();
224
227
 
225
- if (options.onlyOneDepth) {
228
+ if (options.shallow) {
226
229
  return source.every((sourceItem) => {
227
230
  const idx = target.findIndex((t, i) => !matchedIndices.has(i) && t === sourceItem);
228
231
  if (idx !== -1) {
@@ -235,11 +238,11 @@ function objEqualArray(source: unknown[], target: unknown[], options?: EqualOpti
235
238
  // On recursive calls, topLevelIncludes/topLevelExcludes options apply only to top level, so exclude them
236
239
  const recursiveOptions = {
237
240
  ignoreArrayIndex: options.ignoreArrayIndex,
238
- onlyOneDepth: options.onlyOneDepth,
241
+ shallow: options.shallow,
239
242
  };
240
243
  return source.every((sourceItem) => {
241
244
  const idx = target.findIndex(
242
- (t, i) => !matchedIndices.has(i) && objEqual(t, sourceItem, recursiveOptions),
245
+ (t, i) => !matchedIndices.has(i) && equal(t, sourceItem, recursiveOptions),
243
246
  );
244
247
  if (idx !== -1) {
245
248
  matchedIndices.add(idx);
@@ -249,7 +252,7 @@ function objEqualArray(source: unknown[], target: unknown[], options?: EqualOpti
249
252
  });
250
253
  }
251
254
  } else {
252
- if (options?.onlyOneDepth) {
255
+ if (options?.shallow) {
253
256
  for (let i = 0; i < source.length; i++) {
254
257
  if (source[i] !== target[i]) {
255
258
  return false;
@@ -259,9 +262,9 @@ function objEqualArray(source: unknown[], target: unknown[], options?: EqualOpti
259
262
  // On recursive calls, topLevelIncludes/topLevelExcludes options apply only to top level, so exclude them
260
263
  for (let i = 0; i < source.length; i++) {
261
264
  if (
262
- !objEqual(source[i], target[i], {
265
+ !equal(source[i], target[i], {
263
266
  ignoreArrayIndex: options?.ignoreArrayIndex,
264
- onlyOneDepth: options?.onlyOneDepth,
267
+ shallow: options?.shallow,
265
268
  })
266
269
  ) {
267
270
  return false;
@@ -276,9 +279,9 @@ function objEqualArray(source: unknown[], target: unknown[], options?: EqualOpti
276
279
  /**
277
280
  * Map object comparison
278
281
  * @note O(n²) complexity when handling non-string keys (objects, arrays, etc.)
279
- * @note Recommended to use onlyOneDepth: true option for large datasets (improves to O(n) with reference comparison)
282
+ * @note Recommended to use shallow: true option for large datasets (improves to O(n) with reference comparison)
280
283
  */
281
- function objEqualMap(
284
+ function equalMap(
282
285
  source: Map<unknown, unknown>,
283
286
  target: Map<unknown, unknown>,
284
287
  options?: EqualOptions,
@@ -297,13 +300,13 @@ function objEqualMap(
297
300
  if (typeof sourceKey === "string") {
298
301
  const sourceValue = source.get(sourceKey);
299
302
  const targetValue = target.get(sourceKey);
300
- if (options?.onlyOneDepth) {
303
+ if (options?.shallow) {
301
304
  if (sourceValue !== targetValue) return false;
302
305
  } else {
303
306
  if (
304
- !objEqual(sourceValue, targetValue, {
307
+ !equal(sourceValue, targetValue, {
305
308
  ignoreArrayIndex: options?.ignoreArrayIndex,
306
- onlyOneDepth: options?.onlyOneDepth,
309
+ shallow: options?.shallow,
307
310
  })
308
311
  ) {
309
312
  return false;
@@ -315,17 +318,17 @@ function objEqualMap(
315
318
  for (let i = 0; i < targetKeys.length; i++) {
316
319
  const targetKey = targetKeys[i];
317
320
  if (typeof targetKey === "string" || usedTargetKeys.has(i)) continue;
318
- if (options?.onlyOneDepth ? sourceKey === targetKey : objEqual(sourceKey, targetKey)) {
321
+ if (options?.shallow ? sourceKey === targetKey : equal(sourceKey, targetKey)) {
319
322
  usedTargetKeys.add(i);
320
323
  const sourceValue = source.get(sourceKey);
321
324
  const targetValue = target.get(targetKey);
322
- if (options?.onlyOneDepth) {
325
+ if (options?.shallow) {
323
326
  if (sourceValue !== targetValue) return false;
324
327
  } else {
325
328
  if (
326
- !objEqual(sourceValue, targetValue, {
329
+ !equal(sourceValue, targetValue, {
327
330
  ignoreArrayIndex: options?.ignoreArrayIndex,
328
- onlyOneDepth: options?.onlyOneDepth,
331
+ shallow: options?.shallow,
329
332
  })
330
333
  ) {
331
334
  return false;
@@ -342,7 +345,7 @@ function objEqualMap(
342
345
  return true;
343
346
  }
344
347
 
345
- function objEqualObject(
348
+ function equalObject(
346
349
  source: Record<string, unknown>,
347
350
  target: Record<string, unknown>,
348
351
  options?: EqualOptions,
@@ -365,13 +368,13 @@ function objEqualObject(
365
368
  }
366
369
 
367
370
  for (const key of sourceKeys) {
368
- if (options?.onlyOneDepth) {
371
+ if (options?.shallow) {
369
372
  if (source[key] !== target[key]) {
370
373
  return false;
371
374
  }
372
375
  } else {
373
376
  if (
374
- !objEqual(source[key], target[key], {
377
+ !equal(source[key], target[key], {
375
378
  ignoreArrayIndex: options?.ignoreArrayIndex,
376
379
  })
377
380
  ) {
@@ -385,15 +388,15 @@ function objEqualObject(
385
388
 
386
389
  /**
387
390
  * Set deep equality comparison
388
- * @note Deep equal comparison (`onlyOneDepth: false`) has O(n²) time complexity.
389
- * Recommended to use `onlyOneDepth: true` for primitive Sets or when performance is critical
391
+ * @note Deep equal comparison (`shallow: false`) has O(n²) time complexity.
392
+ * Recommended to use `shallow: true` for primitive Sets or when performance is critical
390
393
  */
391
- function objEqualSet(source: Set<unknown>, target: Set<unknown>, options?: EqualOptions): boolean {
394
+ function equalSet(source: Set<unknown>, target: Set<unknown>, options?: EqualOptions): boolean {
392
395
  if (source.size !== target.size) {
393
396
  return false;
394
397
  }
395
398
 
396
- if (options?.onlyOneDepth) {
399
+ if (options?.shallow) {
397
400
  for (const sourceItem of source) {
398
401
  if (!target.has(sourceItem)) {
399
402
  return false;
@@ -406,7 +409,7 @@ function objEqualSet(source: Set<unknown>, target: Set<unknown>, options?: Equal
406
409
  const matchedIndices = new Set<number>();
407
410
  for (const sourceItem of source) {
408
411
  const idx = targetArr.findIndex(
409
- (t, i) => !matchedIndices.has(i) && objEqual(sourceItem, t, options),
412
+ (t, i) => !matchedIndices.has(i) && equal(sourceItem, t, options),
410
413
  );
411
414
  if (idx === -1) {
412
415
  return false;
@@ -420,10 +423,10 @@ function objEqualSet(source: Set<unknown>, target: Set<unknown>, options?: Equal
420
423
 
421
424
  //#endregion
422
425
 
423
- //#region objMerge
426
+ //#region merge
424
427
 
425
- /** objMerge options type */
426
- export interface ObjMergeOptions {
428
+ /** merge options type */
429
+ export interface MergeOptions {
427
430
  /** Array processing method. "replace": replace with target (default), "concat": merge (deduplicate) */
428
431
  arrayProcess?: "replace" | "concat";
429
432
  /** Whether to delete the key when target is null */
@@ -448,23 +451,23 @@ export interface ObjMergeOptions {
448
451
  * and for object arrays, deduplication is determined by reference (address) comparison
449
452
  * @note If types are different, overwrite with target value
450
453
  */
451
- export function objMerge<TSource, TMergeTarget>(
454
+ export function merge<TSource, TMergeTarget>(
452
455
  source: TSource,
453
456
  target: TMergeTarget,
454
- opt?: ObjMergeOptions,
457
+ opt?: MergeOptions,
455
458
  ): TSource & TMergeTarget {
456
459
  if (source == null) {
457
- return objClone(target) as TSource & TMergeTarget;
460
+ return clone(target) as TSource & TMergeTarget;
458
461
  }
459
462
 
460
463
  if (target === undefined) {
461
- return objClone(source) as TSource & TMergeTarget;
464
+ return clone(source) as TSource & TMergeTarget;
462
465
  }
463
466
 
464
467
  if (target === null) {
465
468
  return opt?.useDelTargetNull
466
469
  ? (undefined as TSource & TMergeTarget)
467
- : (objClone(source) as TSource & TMergeTarget);
470
+ : (clone(source) as TSource & TMergeTarget);
468
471
  }
469
472
 
470
473
  if (typeof target !== "object") {
@@ -480,21 +483,21 @@ export function objMerge<TSource, TMergeTarget>(
480
483
  target instanceof Uint8Array ||
481
484
  (opt?.arrayProcess === "replace" && target instanceof Array)
482
485
  ) {
483
- return objClone(target) as TSource & TMergeTarget;
486
+ return clone(target) as TSource & TMergeTarget;
484
487
  }
485
488
 
486
489
  // If source is not an object or source and target are different types of objects, overwrite with target
487
490
  if (typeof source !== "object" || source.constructor !== target.constructor) {
488
- return objClone(target) as TSource & TMergeTarget;
491
+ return clone(target) as TSource & TMergeTarget;
489
492
  }
490
493
 
491
494
  if (source instanceof Map && target instanceof Map) {
492
- const result = objClone(source);
495
+ const result = clone(source);
493
496
  for (const key of target.keys()) {
494
497
  if (result.has(key)) {
495
- result.set(key, objMerge(result.get(key), target.get(key), opt));
498
+ result.set(key, merge(result.get(key), target.get(key), opt));
496
499
  } else {
497
- result.set(key, objClone(target.get(key)));
500
+ result.set(key, clone(target.get(key)));
498
501
  }
499
502
  }
500
503
  return result as TSource & TMergeTarget;
@@ -510,9 +513,9 @@ export function objMerge<TSource, TMergeTarget>(
510
513
 
511
514
  const sourceRec = source as Record<string, unknown>;
512
515
  const targetRec = target as Record<string, unknown>;
513
- const resultRec = objClone(sourceRec);
516
+ const resultRec = clone(sourceRec);
514
517
  for (const key of Object.keys(target)) {
515
- resultRec[key] = objMerge(sourceRec[key], targetRec[key], opt);
518
+ resultRec[key] = merge(sourceRec[key], targetRec[key], opt);
516
519
  if (resultRec[key] === undefined) {
517
520
  delete resultRec[key];
518
521
  }
@@ -522,7 +525,7 @@ export function objMerge<TSource, TMergeTarget>(
522
525
  }
523
526
 
524
527
  /** merge3 options type */
525
- export interface ObjMerge3KeyOptions {
528
+ export interface Merge3KeyOptions {
526
529
  /** List of sub-keys to compare (same as equal's topLevelIncludes) */
527
530
  keys?: string[];
528
531
  /** List of sub-keys to exclude from comparison */
@@ -557,7 +560,7 @@ export interface ObjMerge3KeyOptions {
557
560
  * );
558
561
  * // conflict: false, result: { a: 2, b: 2 }
559
562
  */
560
- export function objMerge3<
563
+ export function merge3<
561
564
  S extends Record<string, unknown>,
562
565
  O extends Record<string, unknown>,
563
566
  T extends Record<string, unknown>,
@@ -565,21 +568,21 @@ export function objMerge3<
565
568
  source: S,
566
569
  origin: O,
567
570
  target: T,
568
- optionsObj?: Record<string, ObjMerge3KeyOptions>,
571
+ optionsObj?: Record<string, Merge3KeyOptions>,
569
572
  ): {
570
573
  conflict: boolean;
571
574
  result: O & S & T;
572
575
  } {
573
576
  let conflict = false;
574
- const result = objClone(origin) as Record<string, unknown>;
577
+ const result = clone(origin) as Record<string, unknown>;
575
578
  const allKeys = new Set([...Object.keys(source), ...Object.keys(target), ...Object.keys(origin)]);
576
579
  for (const key of allKeys) {
577
- if (objEqual(source[key], result[key], optionsObj?.[key])) {
578
- result[key] = objClone(target[key]);
579
- } else if (objEqual(target[key], result[key], optionsObj?.[key])) {
580
- result[key] = objClone(source[key]);
581
- } else if (objEqual(source[key], target[key], optionsObj?.[key])) {
582
- result[key] = objClone(source[key]);
580
+ if (equal(source[key], result[key], optionsObj?.[key])) {
581
+ result[key] = clone(target[key]);
582
+ } else if (equal(target[key], result[key], optionsObj?.[key])) {
583
+ result[key] = clone(source[key]);
584
+ } else if (equal(source[key], target[key], optionsObj?.[key])) {
585
+ result[key] = clone(source[key]);
583
586
  } else {
584
587
  conflict = true;
585
588
  }
@@ -593,7 +596,7 @@ export function objMerge3<
593
596
 
594
597
  //#endregion
595
598
 
596
- //#region objOmit / objPick
599
+ //#region omit / pick
597
600
 
598
601
  /**
599
602
  * Exclude specific keys from object
@@ -602,10 +605,10 @@ export function objMerge3<
602
605
  * @returns New object with specified keys excluded
603
606
  * @example
604
607
  * const user = { name: "Alice", age: 30, email: "alice@example.com" };
605
- * objOmit(user, ["email"]);
608
+ * omit(user, ["email"]);
606
609
  * // { name: "Alice", age: 30 }
607
610
  */
608
- export function objOmit<T extends Record<string, unknown>, K extends keyof T>(
611
+ export function omit<T extends Record<string, unknown>, K extends keyof T>(
609
612
  item: T,
610
613
  omitKeys: K[],
611
614
  ): Omit<T, K> {
@@ -626,10 +629,10 @@ export function objOmit<T extends Record<string, unknown>, K extends keyof T>(
626
629
  * @returns New object with keys matching condition excluded
627
630
  * @example
628
631
  * const data = { name: "Alice", _internal: "secret", age: 30 };
629
- * objOmitByFilter(data, (key) => key.startsWith("_"));
632
+ * omitByFilter(data, (key) => key.startsWith("_"));
630
633
  * // { name: "Alice", age: 30 }
631
634
  */
632
- export function objOmitByFilter<T extends Record<string, unknown>>(
635
+ export function omitByFilter<T extends Record<string, unknown>>(
633
636
  item: T,
634
637
  omitKeyFn: (key: keyof T) => boolean,
635
638
  ): T {
@@ -649,15 +652,15 @@ export function objOmitByFilter<T extends Record<string, unknown>>(
649
652
  * @returns New object containing only specified keys
650
653
  * @example
651
654
  * const user = { name: "Alice", age: 30, email: "alice@example.com" };
652
- * objPick(user, ["name", "age"]);
655
+ * pick(user, ["name", "age"]);
653
656
  * // { name: "Alice", age: 30 }
654
657
  */
655
- export function objPick<T extends Record<string, unknown>, K extends keyof T>(
658
+ export function pick<T extends Record<string, unknown>, K extends keyof T>(
656
659
  item: T,
657
- keys: K[],
660
+ pickKeys: K[],
658
661
  ): Pick<T, K> {
659
662
  const result: Record<string, unknown> = {};
660
- for (const key of keys) {
663
+ for (const key of pickKeys) {
661
664
  result[key as string] = item[key];
662
665
  }
663
666
  return result as Pick<T, K>;
@@ -665,7 +668,7 @@ export function objPick<T extends Record<string, unknown>, K extends keyof T>(
665
668
 
666
669
  //#endregion
667
670
 
668
- //#region objGetChainValue / objSetChainValue / objDeleteChainValue
671
+ //#region getChainValue / setChainValue / deleteChainValue
669
672
 
670
673
  // Regex caching (created once at module load)
671
674
  const chainSplitRegex = /[.[\]]/g;
@@ -691,11 +694,11 @@ function getChainSplits(chain: string): (string | number)[] {
691
694
 
692
695
  /**
693
696
  * Get value by chain path
694
- * @example objGetChainValue(obj, "a.b[0].c")
697
+ * @example getChainValue(obj, "a.b[0].c")
695
698
  */
696
- export function objGetChainValue(obj: unknown, chain: string, optional: true): unknown | undefined;
697
- export function objGetChainValue(obj: unknown, chain: string): unknown;
698
- export function objGetChainValue(
699
+ export function getChainValue(obj: unknown, chain: string, optional: true): unknown | undefined;
700
+ export function getChainValue(obj: unknown, chain: string): unknown;
701
+ export function getChainValue(
699
702
  obj: unknown,
700
703
  chain: string,
701
704
  optional?: true,
@@ -720,20 +723,20 @@ export function objGetChainValue(
720
723
  * @param depth Depth to descend (1 or more)
721
724
  * @param optional If true, return undefined without error if null/undefined found in the middle
722
725
  * @throws ArgumentError If depth is less than 1
723
- * @example objGetChainValueByDepth({ parent: { parent: { name: 'a' } } }, 'parent', 2) => { name: 'a' }
726
+ * @example getChainValueByDepth({ parent: { parent: { name: 'a' } } }, 'parent', 2) => { name: 'a' }
724
727
  */
725
- export function objGetChainValueByDepth<TObject, TKey extends keyof TObject>(
728
+ export function getChainValueByDepth<TObject, TKey extends keyof TObject>(
726
729
  obj: TObject,
727
730
  key: TKey,
728
731
  depth: number,
729
732
  optional: true,
730
733
  ): TObject[TKey] | undefined;
731
- export function objGetChainValueByDepth<TObject, TKey extends keyof TObject>(
734
+ export function getChainValueByDepth<TObject, TKey extends keyof TObject>(
732
735
  obj: TObject,
733
736
  key: TKey,
734
737
  depth: number,
735
738
  ): TObject[TKey];
736
- export function objGetChainValueByDepth<TObject, TKey extends keyof TObject>(
739
+ export function getChainValueByDepth<TObject, TKey extends keyof TObject>(
737
740
  obj: TObject,
738
741
  key: TKey,
739
742
  depth: number,
@@ -755,9 +758,9 @@ export function objGetChainValueByDepth<TObject, TKey extends keyof TObject>(
755
758
 
756
759
  /**
757
760
  * Set value by chain path
758
- * @example objSetChainValue(obj, "a.b[0].c", value)
761
+ * @example setChainValue(obj, "a.b[0].c", value)
759
762
  */
760
- export function objSetChainValue(obj: unknown, chain: string, value: unknown): void {
763
+ export function setChainValue(obj: unknown, chain: string, value: unknown): void {
761
764
  const splits = getChainSplits(chain);
762
765
  if (splits.length === 0) {
763
766
  throw new ArgumentError("Chain is empty", { chain });
@@ -775,9 +778,9 @@ export function objSetChainValue(obj: unknown, chain: string, value: unknown): v
775
778
 
776
779
  /**
777
780
  * Delete value by chain path
778
- * @example objDeleteChainValue(obj, "a.b[0].c")
781
+ * @example deleteChainValue(obj, "a.b[0].c")
779
782
  */
780
- export function objDeleteChainValue(obj: unknown, chain: string): void {
783
+ export function deleteChainValue(obj: unknown, chain: string): void {
781
784
  const splits = getChainSplits(chain);
782
785
  if (splits.length === 0) {
783
786
  throw new ArgumentError("Chain is empty", { chain });
@@ -799,7 +802,7 @@ export function objDeleteChainValue(obj: unknown, chain: string): void {
799
802
 
800
803
  //#endregion
801
804
 
802
- //#region objClearUndefined / objClear / objNullToUndefined / objUnflatten
805
+ //#region clearUndefined / clear / nullToUndefined / unflatten
803
806
 
804
807
  /**
805
808
  * Delete keys with undefined values from object
@@ -807,7 +810,7 @@ export function objDeleteChainValue(obj: unknown, chain: string): void {
807
810
  *
808
811
  * @mutates Modifies the original object directly
809
812
  */
810
- export function objClearUndefined<T extends object>(obj: T): T {
813
+ export function clearUndefined<T extends object>(obj: T): T {
811
814
  const record = obj as Record<string, unknown>;
812
815
  for (const key of Object.keys(record)) {
813
816
  if (record[key] === undefined) {
@@ -823,7 +826,7 @@ export function objClearUndefined<T extends object>(obj: T): T {
823
826
  *
824
827
  * @mutates Modifies the original object directly
825
828
  */
826
- export function objClear<T extends Record<string, unknown>>(obj: T): Record<string, never> {
829
+ export function clear<T extends Record<string, unknown>>(obj: T): Record<string, never> {
827
830
  for (const key of Object.keys(obj)) {
828
831
  delete obj[key];
829
832
  }
@@ -836,11 +839,11 @@ export function objClear<T extends Record<string, unknown>>(obj: T): Record<stri
836
839
  *
837
840
  * @mutates Modifies the original array/object directly
838
841
  */
839
- export function objNullToUndefined<TObject>(obj: TObject): TObject | undefined {
840
- return objNullToUndefinedImpl(obj, new WeakSet());
842
+ export function nullToUndefined<TObject>(obj: TObject): TObject | undefined {
843
+ return nullToUndefinedImpl(obj, new WeakSet());
841
844
  }
842
845
 
843
- function objNullToUndefinedImpl<TObject>(obj: TObject, seen: WeakSet<object>): TObject | undefined {
846
+ function nullToUndefinedImpl<TObject>(obj: TObject, seen: WeakSet<object>): TObject | undefined {
844
847
  if (obj == null) {
845
848
  return undefined;
846
849
  }
@@ -859,7 +862,7 @@ function objNullToUndefinedImpl<TObject>(obj: TObject, seen: WeakSet<object>): T
859
862
  if (seen.has(obj)) return obj;
860
863
  seen.add(obj);
861
864
  for (let i = 0; i < obj.length; i++) {
862
- obj[i] = objNullToUndefinedImpl(obj[i], seen);
865
+ obj[i] = nullToUndefinedImpl(obj[i], seen);
863
866
  }
864
867
  return obj;
865
868
  }
@@ -869,7 +872,7 @@ function objNullToUndefinedImpl<TObject>(obj: TObject, seen: WeakSet<object>): T
869
872
  seen.add(obj as object);
870
873
  const objRec = obj as Record<string, unknown>;
871
874
  for (const key of Object.keys(obj)) {
872
- objRec[key] = objNullToUndefinedImpl(objRec[key], seen);
875
+ objRec[key] = nullToUndefinedImpl(objRec[key], seen);
873
876
  }
874
877
 
875
878
  return obj;
@@ -881,9 +884,9 @@ function objNullToUndefinedImpl<TObject>(obj: TObject, seen: WeakSet<object>): T
881
884
  /**
882
885
  * Convert flattened object to nested object
883
886
  * @internal
884
- * @example objUnflatten({ "a.b.c": 1 }) => { a: { b: { c: 1 } } }
887
+ * @example unflatten({ "a.b.c": 1 }) => { a: { b: { c: 1 } } }
885
888
  */
886
- export function objUnflatten(flatObj: Record<string, unknown>): Record<string, unknown> {
889
+ export function unflatten(flatObj: Record<string, unknown>): Record<string, unknown> {
887
890
  const result: Record<string, unknown> = {};
888
891
 
889
892
  for (const key in flatObj) {
@@ -915,7 +918,7 @@ export function objUnflatten(flatObj: Record<string, unknown>): Record<string, u
915
918
  * Convert properties with undefined to optional
916
919
  * @example { a: string; b: string | undefined } → { a: string; b?: string | undefined }
917
920
  */
918
- export type ObjUndefToOptional<TObject> = {
921
+ export type UndefToOptional<TObject> = {
919
922
  [K in keyof TObject as undefined extends TObject[K] ? K : never]?: TObject[K];
920
923
  } & { [K in keyof TObject as undefined extends TObject[K] ? never : K]: TObject[K] };
921
924
 
@@ -923,7 +926,7 @@ export type ObjUndefToOptional<TObject> = {
923
926
  * Convert optional properties to required + undefined union
924
927
  * @example { a: string; b?: string } → { a: string; b: string | undefined }
925
928
  */
926
- export type ObjOptionalToUndef<TObject> = {
929
+ export type OptionalToUndef<TObject> = {
927
930
  [K in keyof TObject]-?: {} extends Pick<TObject, K> ? TObject[K] | undefined : TObject[K];
928
931
  };
929
932
 
@@ -934,7 +937,7 @@ export type ObjOptionalToUndef<TObject> = {
934
937
  * @param obj Object to extract keys from
935
938
  * @returns Array of object keys
936
939
  */
937
- export function objKeys<T extends object>(obj: T): (keyof T)[] {
940
+ export function keys<T extends object>(obj: T): (keyof T)[] {
938
941
  return Object.keys(obj) as (keyof T)[];
939
942
  }
940
943
 
@@ -943,8 +946,8 @@ export function objKeys<T extends object>(obj: T): (keyof T)[] {
943
946
  * @param obj Object to extract entries from
944
947
  * @returns Array of [key, value] tuples
945
948
  */
946
- export function objEntries<T extends object>(obj: T): ObjEntries<T> {
947
- return Object.entries(obj) as ObjEntries<T>;
949
+ export function entries<T extends object>(obj: T): Entries<T> {
950
+ return Object.entries(obj) as Entries<T>;
948
951
  }
949
952
 
950
953
  /**
@@ -952,11 +955,11 @@ export function objEntries<T extends object>(obj: T): ObjEntries<T> {
952
955
  * @param entries Array of [key, value] tuples
953
956
  * @returns Created object
954
957
  */
955
- export function objFromEntries<T extends [string, unknown]>(entries: T[]): { [K in T[0]]: T[1] } {
956
- return Object.fromEntries(entries) as { [K in T[0]]: T[1] };
958
+ export function fromEntries<T extends [string, unknown]>(entryPairs: T[]): { [K in T[0]]: T[1] } {
959
+ return Object.fromEntries(entryPairs) as { [K in T[0]]: T[1] };
957
960
  }
958
961
 
959
- type ObjEntries<TObject> = { [K in keyof TObject]: [K, TObject[K]] }[keyof TObject][];
962
+ type Entries<TObject> = { [K in keyof TObject]: [K, TObject[K]] }[keyof TObject][];
960
963
 
961
964
  /**
962
965
  * Transform each entry of object and return new object
@@ -967,21 +970,21 @@ type ObjEntries<TObject> = { [K in keyof TObject]: [K, TObject[K]] }[keyof TObje
967
970
  * const colors = { primary: "255, 0, 0", secondary: "0, 255, 0" };
968
971
  *
969
972
  * // Transform only values
970
- * objMap(colors, (key, rgb) => [null, `rgb(${rgb})`]);
973
+ * map(colors, (key, rgb) => [null, `rgb(${rgb})`]);
971
974
  * // { primary: "rgb(255, 0, 0)", secondary: "rgb(0, 255, 0)" }
972
975
  *
973
976
  * // Transform both keys and values
974
- * objMap(colors, (key, rgb) => [`${key}Light`, `rgb(${rgb})`]);
977
+ * map(colors, (key, rgb) => [`${key}Light`, `rgb(${rgb})`]);
975
978
  * // { primaryLight: "rgb(255, 0, 0)", secondaryLight: "rgb(0, 255, 0)" }
976
979
  */
977
- export function objMap<TSource extends object, TNewKey extends string, TNewValue>(
980
+ export function map<TSource extends object, TNewKey extends string, TNewValue>(
978
981
  obj: TSource,
979
982
  fn: (key: keyof TSource, value: TSource[keyof TSource]) => [TNewKey | null, TNewValue],
980
983
  ): Record<TNewKey | Extract<keyof TSource, string>, TNewValue> {
981
- return objMapImpl(obj, fn);
984
+ return mapImpl(obj, fn);
982
985
  }
983
986
 
984
- function objMapImpl<TSource extends object, TNewKey extends string, TNewValue>(
987
+ function mapImpl<TSource extends object, TNewKey extends string, TNewValue>(
985
988
  obj: TSource,
986
989
  fn: (key: keyof TSource, value: TSource[keyof TSource]) => [TNewKey | null, TNewValue],
987
990
  ): Record<string, TNewValue> {