@helpers4/object 2.0.0-beta.0 → 2.0.0-beta.3
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.
- package/README.md +12 -4
- package/lib/index.d.ts +184 -34
- package/lib/index.js +305 -95
- package/lib/index.js.map +1 -1
- package/llms.txt +293 -66
- package/meta/api.json +301 -85
- package/meta/examples.json +82 -17
- package/package.json +8 -4
package/lib/index.js
CHANGED
|
@@ -32,27 +32,109 @@ function deepClone(obj) {
|
|
|
32
32
|
return cloned;
|
|
33
33
|
}
|
|
34
34
|
//#endregion
|
|
35
|
-
//#region helpers/
|
|
35
|
+
//#region helpers/type/isPlainObject.ts
|
|
36
|
+
/**
|
|
37
|
+
* This file is part of helpers4.
|
|
38
|
+
* Copyright (C) 2025 baxyz
|
|
39
|
+
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
40
|
+
*/
|
|
41
|
+
/**
|
|
42
|
+
* Checks if a value is a plain object.
|
|
43
|
+
*
|
|
44
|
+
* A plain object is created by `{}`, `new Object()`, or `Object.create(null)`.
|
|
45
|
+
* Returns `false` for arrays, Date, Map, Set, RegExp, class instances, etc.
|
|
46
|
+
*
|
|
47
|
+
* @param value - The value to check
|
|
48
|
+
* @returns True if value is a plain object
|
|
49
|
+
* @example
|
|
50
|
+
* isPlainObject({}) // => true
|
|
51
|
+
* isPlainObject({ a: 1 }) // => true
|
|
52
|
+
* isPlainObject(new Date()) // => false
|
|
53
|
+
* isPlainObject([]) // => false
|
|
54
|
+
* isPlainObject(null) // => false
|
|
55
|
+
* @since 2.0.0
|
|
56
|
+
*/
|
|
57
|
+
function isPlainObject(value) {
|
|
58
|
+
if (value === null || typeof value !== "object") return false;
|
|
59
|
+
const proto = Object.getPrototypeOf(value);
|
|
60
|
+
return proto === Object.prototype || proto === null;
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
//#region helpers/object/deepMerge.ts
|
|
64
|
+
/**
|
|
65
|
+
* This file is part of helpers4.
|
|
66
|
+
* Copyright (C) 2025 baxyz
|
|
67
|
+
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
68
|
+
*/
|
|
69
|
+
var UNSAFE_KEYS$1 = new Set([
|
|
70
|
+
"__proto__",
|
|
71
|
+
"constructor",
|
|
72
|
+
"prototype"
|
|
73
|
+
]);
|
|
74
|
+
function deepMerge(target, ...sources) {
|
|
75
|
+
if (target === void 0 || target === null) return target;
|
|
76
|
+
if (!sources.length) return target;
|
|
77
|
+
const source = sources.shift();
|
|
78
|
+
if (!source) return deepMerge(target, ...sources);
|
|
79
|
+
for (const key in source) {
|
|
80
|
+
if (!Object.hasOwn(source, key) || UNSAFE_KEYS$1.has(key)) continue;
|
|
81
|
+
const targetValue = target[key];
|
|
82
|
+
const sourceValue = source[key];
|
|
83
|
+
if (isPlainObject(targetValue) && isPlainObject(sourceValue)) target[key] = deepMerge(targetValue, sourceValue);
|
|
84
|
+
else if (sourceValue !== void 0) target[key] = sourceValue;
|
|
85
|
+
}
|
|
86
|
+
return deepMerge(target, ...sources);
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
89
|
+
//#region helpers/array/equalsDeep.ts
|
|
36
90
|
/**
|
|
37
91
|
* This file is part of helpers4.
|
|
38
92
|
* Copyright (C) 2025 baxyz
|
|
39
93
|
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
40
94
|
*/
|
|
41
95
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
96
|
+
* Recursive structural array equality.
|
|
97
|
+
*
|
|
98
|
+
* Two arrays are equal when they have the same length and each pair of
|
|
99
|
+
* elements at the same index is structurally equal:
|
|
100
|
+
* - Arrays recurse with `equalsDeep`.
|
|
101
|
+
* - Plain objects recurse key-by-key with structural comparison.
|
|
102
|
+
* - `Date` instances are compared by their epoch value.
|
|
103
|
+
* - All other values use strict equality (`===`), which means `NaN !== NaN`
|
|
104
|
+
* and special objects (Map, Set, RegExp, Promise, class instances\u2026) are
|
|
105
|
+
* compared by reference.
|
|
106
|
+
*
|
|
107
|
+
* For positional one-level comparison use {@link equalsShallow}. For
|
|
108
|
+
* order-independent comparison use {@link equalsUnordered}.
|
|
44
109
|
*
|
|
45
110
|
* @param arrA - First array to compare
|
|
46
111
|
* @param arrB - Second array to compare
|
|
47
|
-
* @returns `true` if arrays are
|
|
112
|
+
* @returns `true` if arrays are deeply equal, `false` otherwise.
|
|
48
113
|
* @since 2.0.0
|
|
49
114
|
*/
|
|
50
|
-
function
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
115
|
+
function equalsDeep$1(arrA, arrB) {
|
|
116
|
+
if (arrA === arrB) return true;
|
|
117
|
+
if (!Array.isArray(arrA) || !Array.isArray(arrB)) return false;
|
|
118
|
+
if (arrA.length !== arrB.length) return false;
|
|
119
|
+
for (let i = 0; i < arrA.length; i++) if (!valuesEqual(arrA[i], arrB[i])) return false;
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
function valuesEqual(a, b) {
|
|
123
|
+
if (a === b) return true;
|
|
124
|
+
if (Array.isArray(a) && Array.isArray(b)) return equalsDeep$1(a, b);
|
|
125
|
+
if (a instanceof Date && b instanceof Date) return a.getTime() === b.getTime();
|
|
126
|
+
if (isPlainObject(a) && isPlainObject(b)) {
|
|
127
|
+
const ao = a;
|
|
128
|
+
const bo = b;
|
|
129
|
+
const keysA = Object.keys(ao);
|
|
130
|
+
if (keysA.length !== Object.keys(bo).length) return false;
|
|
131
|
+
for (const key of keysA) {
|
|
132
|
+
if (!Object.prototype.hasOwnProperty.call(bo, key)) return false;
|
|
133
|
+
if (!valuesEqual(ao[key], bo[key])) return false;
|
|
134
|
+
}
|
|
135
|
+
return true;
|
|
55
136
|
}
|
|
137
|
+
return false;
|
|
56
138
|
}
|
|
57
139
|
//#endregion
|
|
58
140
|
//#region helpers/date/timestamp.ts
|
|
@@ -207,104 +289,158 @@ function isSpecialObject(value) {
|
|
|
207
289
|
return false;
|
|
208
290
|
}
|
|
209
291
|
//#endregion
|
|
210
|
-
//#region helpers/object/
|
|
292
|
+
//#region helpers/object/diff.ts
|
|
211
293
|
/**
|
|
212
294
|
* This file is part of helpers4.
|
|
213
295
|
* Copyright (C) 2025 baxyz
|
|
214
296
|
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
215
297
|
*/
|
|
216
298
|
/**
|
|
217
|
-
*
|
|
299
|
+
* Structural object diff.
|
|
300
|
+
*
|
|
301
|
+
* Returns `true` when both inputs are deeply equal, otherwise a
|
|
302
|
+
* {@link DiffResult} describing the differences key by key.
|
|
303
|
+
*
|
|
304
|
+
* Comparison rules:
|
|
305
|
+
* - Same reference \u2192 `true`.
|
|
306
|
+
* - Either side is `null`/`undefined` (and not both) \u2192 `false`.
|
|
307
|
+
* - Both `Date` \u2192 epoch comparison.
|
|
308
|
+
* - Both arrays \u2192 compared with `array/equalsDeep` (leaf, no diff drill-down).
|
|
309
|
+
* - Special objects (Map, Set, RegExp, Promise, class instances\u2026) \u2192 reference equality.
|
|
310
|
+
* - Plain objects \u2192 key-by-key, recursing up to `options.depth` levels.
|
|
311
|
+
* - Mixed types (e.g. array vs object, Date vs object) \u2192 `false`.
|
|
218
312
|
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
313
|
+
* For a boolean wrapper see {@link equalsDeep} from this category.
|
|
314
|
+
* For a one-level boolean check see {@link equalsShallow} from this category.
|
|
315
|
+
*
|
|
316
|
+
* @param objA - First value (object, `null`, or `undefined`).
|
|
317
|
+
* @param objB - Second value (object, `null`, or `undefined`).
|
|
318
|
+
* @param options - See {@link DiffOptions}.
|
|
319
|
+
* @returns `true` when equal, otherwise a {@link DiffResult}, or `false` for incompatible types.
|
|
222
320
|
* @since 2.0.0
|
|
223
321
|
*/
|
|
224
|
-
function
|
|
322
|
+
function diff(objA, objB, options = {}) {
|
|
323
|
+
const depth = options.depth ?? Infinity;
|
|
225
324
|
if (objA === objB) return true;
|
|
226
325
|
if (objA == null || objB == null) return false;
|
|
227
326
|
if (objA instanceof Date && objB instanceof Date) return compare(objA, objB);
|
|
228
|
-
if (Array.isArray(objA) && Array.isArray(objB)) return
|
|
327
|
+
if (Array.isArray(objA) && Array.isArray(objB)) return equalsDeep$1(objA, objB);
|
|
229
328
|
if (Array.isArray(objA) || Array.isArray(objB)) return false;
|
|
230
329
|
if (isSpecialObject(objA) || isSpecialObject(objB)) return objA === objB;
|
|
330
|
+
return diffPlainObjects(objA, objB, depth);
|
|
331
|
+
}
|
|
332
|
+
function diffPlainObjects(objA, objB, depth) {
|
|
231
333
|
const keys = Array.from(new Set([...Object.keys(objA), ...Object.keys(objB)]));
|
|
232
|
-
const differences =
|
|
334
|
+
const differences = Object.create(null);
|
|
233
335
|
for (const key of keys) {
|
|
234
|
-
const hasA = key
|
|
235
|
-
const hasB = key
|
|
236
|
-
if (!hasA && hasB)
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
336
|
+
const hasA = Object.prototype.hasOwnProperty.call(objA, key);
|
|
337
|
+
const hasB = Object.prototype.hasOwnProperty.call(objB, key);
|
|
338
|
+
if (!hasA && hasB) {
|
|
339
|
+
differences[key] = "onlyB";
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
if (hasA && !hasB) {
|
|
343
|
+
differences[key] = "onlyA";
|
|
344
|
+
continue;
|
|
345
|
+
}
|
|
346
|
+
const valueA = objA[key];
|
|
347
|
+
const valueB = objB[key];
|
|
348
|
+
if (valueA === valueB) continue;
|
|
349
|
+
if (Array.isArray(valueA) && Array.isArray(valueB)) {
|
|
350
|
+
if (!equalsDeep$1(valueA, valueB)) differences[key] = false;
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
if (Array.isArray(valueA) || Array.isArray(valueB)) {
|
|
354
|
+
differences[key] = false;
|
|
355
|
+
continue;
|
|
251
356
|
}
|
|
357
|
+
if (valueA instanceof Date && valueB instanceof Date) {
|
|
358
|
+
if (!compare(valueA, valueB)) differences[key] = false;
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
if (valueA instanceof Date || valueB instanceof Date) {
|
|
362
|
+
differences[key] = false;
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
if (isSpecialObject(valueA) || isSpecialObject(valueB)) {
|
|
366
|
+
differences[key] = false;
|
|
367
|
+
continue;
|
|
368
|
+
}
|
|
369
|
+
if (!(valueA !== null && valueB !== null && typeof valueA === "object" && typeof valueB === "object")) {
|
|
370
|
+
differences[key] = false;
|
|
371
|
+
continue;
|
|
372
|
+
}
|
|
373
|
+
if (depth <= 0) {
|
|
374
|
+
differences[key] = false;
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
const nested = diffPlainObjects(valueA, valueB, depth - 1);
|
|
378
|
+
if (nested !== true) differences[key] = nested;
|
|
252
379
|
}
|
|
253
380
|
return Object.keys(differences).length > 0 ? differences : true;
|
|
254
381
|
}
|
|
255
382
|
//#endregion
|
|
256
|
-
//#region helpers/
|
|
383
|
+
//#region helpers/object/equalsDeep.ts
|
|
257
384
|
/**
|
|
258
385
|
* This file is part of helpers4.
|
|
259
386
|
* Copyright (C) 2025 baxyz
|
|
260
387
|
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
261
388
|
*/
|
|
262
389
|
/**
|
|
263
|
-
*
|
|
390
|
+
* Recursive structural object equality.
|
|
264
391
|
*
|
|
265
|
-
*
|
|
266
|
-
*
|
|
392
|
+
* Boolean wrapper around {@link diff} \u2014 returns `true` when the two values
|
|
393
|
+
* are deeply equal according to the same rules. Use this when you only
|
|
394
|
+
* need a yes/no answer; use {@link diff} when you also need to know
|
|
395
|
+
* *what* differs.
|
|
267
396
|
*
|
|
268
|
-
*
|
|
269
|
-
*
|
|
270
|
-
* @
|
|
271
|
-
*
|
|
272
|
-
*
|
|
273
|
-
* isPlainObject(new Date()) // => false
|
|
274
|
-
* isPlainObject([]) // => false
|
|
275
|
-
* isPlainObject(null) // => false
|
|
397
|
+
* For a one-level boolean check use {@link equalsShallow}.
|
|
398
|
+
*
|
|
399
|
+
* @param objA - First value (object, `null`, or `undefined`).
|
|
400
|
+
* @param objB - Second value (object, `null`, or `undefined`).
|
|
401
|
+
* @returns `true` if both inputs are deeply equal, `false` otherwise.
|
|
276
402
|
* @since 2.0.0
|
|
277
403
|
*/
|
|
278
|
-
function
|
|
279
|
-
|
|
280
|
-
const proto = Object.getPrototypeOf(value);
|
|
281
|
-
return proto === Object.prototype || proto === null;
|
|
404
|
+
function equalsDeep(objA, objB) {
|
|
405
|
+
return diff(objA, objB) === true;
|
|
282
406
|
}
|
|
283
407
|
//#endregion
|
|
284
|
-
//#region helpers/object/
|
|
408
|
+
//#region helpers/object/equalsShallow.ts
|
|
285
409
|
/**
|
|
286
410
|
* This file is part of helpers4.
|
|
287
411
|
* Copyright (C) 2025 baxyz
|
|
288
412
|
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
289
413
|
*/
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
414
|
+
/**
|
|
415
|
+
* One-level (shallow) object equality.
|
|
416
|
+
*
|
|
417
|
+
* Two objects are equal when they share the exact same set of own
|
|
418
|
+
* enumerable string keys and each pair of values satisfies strict equality
|
|
419
|
+
* (`===`). No recursion: nested objects/arrays are compared by reference.
|
|
420
|
+
*
|
|
421
|
+
* Falls back to strict equality when either input is `null`, `undefined`
|
|
422
|
+
* or not an object \u2014 so primitives match if and only if they are `===`.
|
|
423
|
+
* Arrays are not supported; they always return `false` (unless identical
|
|
424
|
+
* references). Use `array/equalsShallow` instead.
|
|
425
|
+
*
|
|
426
|
+
* For recursive structural comparison use {@link equalsDeep}. For a diff
|
|
427
|
+
* structure use {@link diff}.
|
|
428
|
+
*
|
|
429
|
+
* @param objA - First value to compare
|
|
430
|
+
* @param objB - Second value to compare
|
|
431
|
+
* @returns `true` if values are shallowly equal, `false` otherwise.
|
|
432
|
+
* @since 2.0.0
|
|
433
|
+
*/
|
|
434
|
+
function equalsShallow(objA, objB) {
|
|
435
|
+
if (objA === objB) return true;
|
|
436
|
+
if (objA === null || objB === null || typeof objA !== "object" || typeof objB !== "object") return false;
|
|
437
|
+
const a = objA;
|
|
438
|
+
const b = objB;
|
|
439
|
+
if (Array.isArray(objA) || Array.isArray(objB)) return false;
|
|
440
|
+
const keysA = Object.keys(a);
|
|
441
|
+
if (keysA.length !== Object.keys(b).length) return false;
|
|
442
|
+
for (const key of keysA) if (!Object.prototype.hasOwnProperty.call(b, key) || a[key] !== b[key]) return false;
|
|
443
|
+
return true;
|
|
308
444
|
}
|
|
309
445
|
//#endregion
|
|
310
446
|
//#region helpers/object/get.ts
|
|
@@ -331,6 +467,105 @@ function get(obj, path, defaultValue) {
|
|
|
331
467
|
return result !== void 0 ? result : defaultValue;
|
|
332
468
|
}
|
|
333
469
|
//#endregion
|
|
470
|
+
//#region helpers/object/groupBy.ts
|
|
471
|
+
/**
|
|
472
|
+
* This file is part of helpers4.
|
|
473
|
+
* Copyright (C) 2025 baxyz
|
|
474
|
+
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
475
|
+
*/
|
|
476
|
+
/**
|
|
477
|
+
* Groups an array of items by a key derived from each item.
|
|
478
|
+
*
|
|
479
|
+
* A thin, typed wrapper around `Object.groupBy` (ES2024) that works on
|
|
480
|
+
* older targets and provides stricter return-type inference.
|
|
481
|
+
*
|
|
482
|
+
* @param items - The array to group
|
|
483
|
+
* @param keyFn - Function that returns the group key for each item
|
|
484
|
+
* @returns A record mapping each key to the array of items with that key
|
|
485
|
+
* @example
|
|
486
|
+
* groupBy([1, 2, 3, 4], n => n % 2 === 0 ? 'even' : 'odd')
|
|
487
|
+
* // => { odd: [1, 3], even: [2, 4] }
|
|
488
|
+
* @since next
|
|
489
|
+
*/
|
|
490
|
+
function groupBy(items, keyFn) {
|
|
491
|
+
const result = {};
|
|
492
|
+
for (const item of items) {
|
|
493
|
+
const key = keyFn(item);
|
|
494
|
+
if (result[key] === void 0) result[key] = [];
|
|
495
|
+
result[key].push(item);
|
|
496
|
+
}
|
|
497
|
+
return result;
|
|
498
|
+
}
|
|
499
|
+
//#endregion
|
|
500
|
+
//#region helpers/object/invert.ts
|
|
501
|
+
/**
|
|
502
|
+
* This file is part of helpers4.
|
|
503
|
+
* Copyright (C) 2025 baxyz
|
|
504
|
+
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
505
|
+
*/
|
|
506
|
+
/**
|
|
507
|
+
* Returns a new object with keys and values swapped.
|
|
508
|
+
* If multiple keys share the same value, the last one wins.
|
|
509
|
+
*
|
|
510
|
+
* @param obj - The object whose keys and values are to be swapped
|
|
511
|
+
* @returns A new object with values as keys and original keys as values
|
|
512
|
+
* @example
|
|
513
|
+
* invert({ a: 'x', b: 'y', c: 'z' })
|
|
514
|
+
* // => { x: 'a', y: 'b', z: 'c' }
|
|
515
|
+
*
|
|
516
|
+
* invert({ one: 1, two: 2 })
|
|
517
|
+
* // => { 1: 'one', 2: 'two' }
|
|
518
|
+
* @since next
|
|
519
|
+
*/
|
|
520
|
+
function invert(obj) {
|
|
521
|
+
const result = {};
|
|
522
|
+
for (const key in obj) if (Object.prototype.hasOwnProperty.call(obj, key)) result[obj[key]] = key;
|
|
523
|
+
return result;
|
|
524
|
+
}
|
|
525
|
+
//#endregion
|
|
526
|
+
//#region helpers/object/map.ts
|
|
527
|
+
/**
|
|
528
|
+
* This file is part of helpers4.
|
|
529
|
+
* Copyright (C) 2025 baxyz
|
|
530
|
+
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
531
|
+
*/
|
|
532
|
+
/**
|
|
533
|
+
* Transforms the values and/or keys of a plain object in a single pass.
|
|
534
|
+
*
|
|
535
|
+
* Both callbacks are optional and default to identity (no transformation).
|
|
536
|
+
* When `mapValue` is omitted the original values are preserved;
|
|
537
|
+
* when `mapKey` is omitted the original keys are preserved.
|
|
538
|
+
*
|
|
539
|
+
* Note: if two different keys map to the same output key the last one wins
|
|
540
|
+
* (insertion order).
|
|
541
|
+
*
|
|
542
|
+
* @param obj - The source object
|
|
543
|
+
* @param mapValue - Callback called with `(value, key)` for each entry.
|
|
544
|
+
* Defaults to identity.
|
|
545
|
+
* @param mapKey - Callback called with `(key, value)` for each entry.
|
|
546
|
+
* Defaults to identity.
|
|
547
|
+
* @returns A new object with transformed keys and/or values
|
|
548
|
+
* @example
|
|
549
|
+
* map({ a: 1, b: 2 }, v => v * 10)
|
|
550
|
+
* // => { a: 10, b: 20 }
|
|
551
|
+
*
|
|
552
|
+
* map({ a: 1, b: 2 }, undefined, k => k.toUpperCase())
|
|
553
|
+
* // => { A: 1, B: 2 }
|
|
554
|
+
*
|
|
555
|
+
* map({ a: 1, b: 2 }, v => v * 10, k => k.toUpperCase())
|
|
556
|
+
* // => { A: 10, B: 20 }
|
|
557
|
+
* @since next
|
|
558
|
+
*/
|
|
559
|
+
function map(obj, mapValue, mapKey) {
|
|
560
|
+
const result = {};
|
|
561
|
+
for (const key of Object.keys(obj)) {
|
|
562
|
+
const value = obj[key];
|
|
563
|
+
const newKey = mapKey ? mapKey(key, value) : key;
|
|
564
|
+
result[newKey] = mapValue ? mapValue(value, key) : value;
|
|
565
|
+
}
|
|
566
|
+
return result;
|
|
567
|
+
}
|
|
568
|
+
//#endregion
|
|
334
569
|
//#region helpers/object/omit.ts
|
|
335
570
|
function omit(obj, keys) {
|
|
336
571
|
if (obj === void 0 || obj === null) return obj;
|
|
@@ -432,31 +667,6 @@ function set(obj, path, value) {
|
|
|
432
667
|
return obj;
|
|
433
668
|
}
|
|
434
669
|
//#endregion
|
|
435
|
-
|
|
436
|
-
/**
|
|
437
|
-
* This file is part of helpers4.
|
|
438
|
-
* Copyright (C) 2025 baxyz
|
|
439
|
-
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
440
|
-
*/
|
|
441
|
-
/**
|
|
442
|
-
* Quick comparison of two objects using JSON.stringify.
|
|
443
|
-
* This is a fast but simple comparison that may not work for all edge cases.
|
|
444
|
-
*
|
|
445
|
-
* @param objA - First object to compare
|
|
446
|
-
* @param objB - Second object to compare
|
|
447
|
-
* @returns `true` if objects are identical according to JSON.stringify, `false` otherwise
|
|
448
|
-
* @since 2.0.0
|
|
449
|
-
*/
|
|
450
|
-
function shallowEquals(objA, objB) {
|
|
451
|
-
if (objA === objB) return true;
|
|
452
|
-
if (typeof objA === "function" || typeof objB === "function") return objA === objB;
|
|
453
|
-
try {
|
|
454
|
-
return JSON.stringify(objA) === JSON.stringify(objB);
|
|
455
|
-
} catch {
|
|
456
|
-
return objA === objB;
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
//#endregion
|
|
460
|
-
export { compact, deepClone, deepCompare, deepMerge, get, omit, pick, removeUndefinedNull, safeJsonParse, set, shallowEquals };
|
|
670
|
+
export { compact, deepClone, deepMerge, diff, equalsDeep, equalsShallow, get, groupBy, invert, map, omit, pick, removeUndefinedNull, safeJsonParse, set };
|
|
461
671
|
|
|
462
672
|
//# sourceMappingURL=index.js.map
|