@fluixi/utils 1.0.0-alpha.100
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/LICENSE +21 -0
- package/README.md +68 -0
- package/dist/index.cjs +2858 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -0
- package/dist/index.mjs +2838 -0
- package/dist/lib/array/advanced.cjs +2227 -0
- package/dist/lib/array/advanced.d.ts +1116 -0
- package/dist/lib/array/advanced.d.ts.map +1 -0
- package/dist/lib/array/advanced.js +2429 -0
- package/dist/lib/array/advanced.mjs +2204 -0
- package/dist/lib/array/array.cjs +57 -0
- package/dist/lib/array/array.d.ts +6 -0
- package/dist/lib/array/array.d.ts.map +1 -0
- package/dist/lib/array/array.js +31 -0
- package/dist/lib/array/array.mjs +36 -0
- package/dist/lib/array/index.cjs +2344 -0
- package/dist/lib/array/index.d.ts +4 -0
- package/dist/lib/array/index.d.ts.map +1 -0
- package/dist/lib/array/index.js +3 -0
- package/dist/lib/array/index.mjs +2322 -0
- package/dist/lib/array/utils.cjs +103 -0
- package/dist/lib/array/utils.d.ts +100 -0
- package/dist/lib/array/utils.d.ts.map +1 -0
- package/dist/lib/array/utils.js +165 -0
- package/dist/lib/array/utils.mjs +82 -0
- package/dist/lib/color/color.cjs +2190 -0
- package/dist/lib/color/color.d.ts +366 -0
- package/dist/lib/color/color.d.ts.map +1 -0
- package/dist/lib/color/color.js +722 -0
- package/dist/lib/color/color.mjs +2167 -0
- package/dist/lib/color/constants.cjs +380 -0
- package/dist/lib/color/constants.d.ts +361 -0
- package/dist/lib/color/constants.d.ts.map +1 -0
- package/dist/lib/color/constants.js +358 -0
- package/dist/lib/color/constants.mjs +359 -0
- package/dist/lib/color/conversions.cjs +629 -0
- package/dist/lib/color/conversions.d.ts +166 -0
- package/dist/lib/color/conversions.d.ts.map +1 -0
- package/dist/lib/color/conversions.js +766 -0
- package/dist/lib/color/conversions.mjs +608 -0
- package/dist/lib/color/helpers.cjs +2534 -0
- package/dist/lib/color/helpers.d.ts +75 -0
- package/dist/lib/color/helpers.d.ts.map +1 -0
- package/dist/lib/color/helpers.js +419 -0
- package/dist/lib/color/helpers.mjs +2511 -0
- package/dist/lib/color/index.cjs +2641 -0
- package/dist/lib/color/index.d.ts +12 -0
- package/dist/lib/color/index.d.ts.map +1 -0
- package/dist/lib/color/index.js +15 -0
- package/dist/lib/color/index.mjs +2619 -0
- package/dist/lib/color/types.cjs +18 -0
- package/dist/lib/color/types.d.ts +179 -0
- package/dist/lib/color/types.d.ts.map +1 -0
- package/dist/lib/color/types.js +1 -0
- package/dist/lib/color/types.mjs +0 -0
- package/dist/lib/color/utils.cjs +962 -0
- package/dist/lib/color/utils.d.ts +199 -0
- package/dist/lib/color/utils.d.ts.map +1 -0
- package/dist/lib/color/utils.js +858 -0
- package/dist/lib/color/utils.mjs +939 -0
- package/dist/lib/compare/comparators.cjs +171 -0
- package/dist/lib/compare/comparators.d.ts +65 -0
- package/dist/lib/compare/comparators.d.ts.map +1 -0
- package/dist/lib/compare/comparators.js +210 -0
- package/dist/lib/compare/comparators.mjs +150 -0
- package/dist/lib/compare/index.cjs +172 -0
- package/dist/lib/compare/index.d.ts +2 -0
- package/dist/lib/compare/index.d.ts.map +1 -0
- package/dist/lib/compare/index.js +1 -0
- package/dist/lib/compare/index.mjs +152 -0
- package/dist/lib/cookie/codec.cjs +72 -0
- package/dist/lib/cookie/codec.d.ts +22 -0
- package/dist/lib/cookie/codec.d.ts.map +1 -0
- package/dist/lib/cookie/codec.js +67 -0
- package/dist/lib/cookie/codec.mjs +51 -0
- package/dist/lib/cookie/index.cjs +75 -0
- package/dist/lib/cookie/index.d.ts +2 -0
- package/dist/lib/cookie/index.d.ts.map +1 -0
- package/dist/lib/cookie/index.js +1 -0
- package/dist/lib/cookie/index.mjs +53 -0
- package/dist/lib/crypto/hash.cjs +83 -0
- package/dist/lib/crypto/hash.d.ts +6 -0
- package/dist/lib/crypto/hash.d.ts.map +1 -0
- package/dist/lib/crypto/hash.js +53 -0
- package/dist/lib/crypto/hash.mjs +62 -0
- package/dist/lib/crypto/index.cjs +85 -0
- package/dist/lib/crypto/index.d.ts +2 -0
- package/dist/lib/crypto/index.d.ts.map +1 -0
- package/dist/lib/crypto/index.js +1 -0
- package/dist/lib/crypto/index.mjs +62 -0
- package/dist/lib/dom/events.cjs +40 -0
- package/dist/lib/dom/events.d.ts +159 -0
- package/dist/lib/dom/events.d.ts.map +1 -0
- package/dist/lib/dom/events.js +50 -0
- package/dist/lib/dom/events.mjs +19 -0
- package/dist/lib/dom/index.cjs +78 -0
- package/dist/lib/dom/index.d.ts +3 -0
- package/dist/lib/dom/index.d.ts.map +1 -0
- package/dist/lib/dom/index.js +2 -0
- package/dist/lib/dom/index.mjs +56 -0
- package/dist/lib/dom/utils.cjs +57 -0
- package/dist/lib/dom/utils.d.ts +6 -0
- package/dist/lib/dom/utils.d.ts.map +1 -0
- package/dist/lib/dom/utils.js +37 -0
- package/dist/lib/dom/utils.mjs +36 -0
- package/dist/lib/functions/functions.cjs +366 -0
- package/dist/lib/functions/functions.d.ts +329 -0
- package/dist/lib/functions/functions.d.ts.map +1 -0
- package/dist/lib/functions/functions.js +585 -0
- package/dist/lib/functions/functions.mjs +345 -0
- package/dist/lib/functions/index.cjs +369 -0
- package/dist/lib/functions/index.d.ts +3 -0
- package/dist/lib/functions/index.d.ts.map +1 -0
- package/dist/lib/functions/index.js +1 -0
- package/dist/lib/functions/index.mjs +347 -0
- package/dist/lib/functions/types.cjs +18 -0
- package/dist/lib/functions/types.d.ts +2 -0
- package/dist/lib/functions/types.d.ts.map +1 -0
- package/dist/lib/functions/types.js +1 -0
- package/dist/lib/functions/types.mjs +0 -0
- package/dist/lib/helpers.cjs +78 -0
- package/dist/lib/helpers.d.ts +13 -0
- package/dist/lib/helpers.d.ts.map +1 -0
- package/dist/lib/helpers.js +66 -0
- package/dist/lib/helpers.mjs +59 -0
- package/dist/lib/index.cjs +2857 -0
- package/dist/lib/index.d.ts +6 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +8 -0
- package/dist/lib/index.mjs +2836 -0
- package/dist/lib/maths/constants.cjs +70 -0
- package/dist/lib/maths/constants.d.ts +84 -0
- package/dist/lib/maths/constants.d.ts.map +1 -0
- package/dist/lib/maths/constants.js +79 -0
- package/dist/lib/maths/constants.mjs +50 -0
- package/dist/lib/maths/fn/advanced.cjs +231 -0
- package/dist/lib/maths/fn/advanced.d.ts +149 -0
- package/dist/lib/maths/fn/advanced.d.ts.map +1 -0
- package/dist/lib/maths/fn/advanced.js +264 -0
- package/dist/lib/maths/fn/advanced.mjs +208 -0
- package/dist/lib/maths/fn/basic.cjs +212 -0
- package/dist/lib/maths/fn/basic.d.ts +182 -0
- package/dist/lib/maths/fn/basic.d.ts.map +1 -0
- package/dist/lib/maths/fn/basic.js +343 -0
- package/dist/lib/maths/fn/basic.mjs +191 -0
- package/dist/lib/maths/fn/complex.cjs +268 -0
- package/dist/lib/maths/fn/complex.d.ts +153 -0
- package/dist/lib/maths/fn/complex.d.ts.map +1 -0
- package/dist/lib/maths/fn/complex.js +383 -0
- package/dist/lib/maths/fn/complex.mjs +247 -0
- package/dist/lib/maths/fn/index.cjs +877 -0
- package/dist/lib/maths/fn/index.d.ts +10 -0
- package/dist/lib/maths/fn/index.d.ts.map +1 -0
- package/dist/lib/maths/fn/index.js +9 -0
- package/dist/lib/maths/fn/index.mjs +855 -0
- package/dist/lib/maths/fn/trigo.cjs +179 -0
- package/dist/lib/maths/fn/trigo.d.ts +147 -0
- package/dist/lib/maths/fn/trigo.d.ts.map +1 -0
- package/dist/lib/maths/fn/trigo.js +227 -0
- package/dist/lib/maths/fn/trigo.mjs +156 -0
- package/dist/lib/maths/fn/vector.cjs +728 -0
- package/dist/lib/maths/fn/vector.d.ts +512 -0
- package/dist/lib/maths/fn/vector.d.ts.map +1 -0
- package/dist/lib/maths/fn/vector.js +1136 -0
- package/dist/lib/maths/fn/vector.mjs +707 -0
- package/dist/lib/maths/formatter.cjs +61 -0
- package/dist/lib/maths/formatter.d.ts +35 -0
- package/dist/lib/maths/formatter.d.ts.map +1 -0
- package/dist/lib/maths/formatter.js +56 -0
- package/dist/lib/maths/formatter.mjs +40 -0
- package/dist/lib/maths/guards.cjs +164 -0
- package/dist/lib/maths/guards.d.ts +166 -0
- package/dist/lib/maths/guards.d.ts.map +1 -0
- package/dist/lib/maths/guards.js +315 -0
- package/dist/lib/maths/guards.mjs +144 -0
- package/dist/lib/maths/index.cjs +1152 -0
- package/dist/lib/maths/index.d.ts +24 -0
- package/dist/lib/maths/index.d.ts.map +1 -0
- package/dist/lib/maths/index.js +29 -0
- package/dist/lib/maths/index.mjs +1130 -0
- package/dist/lib/maths/parser.cjs +75 -0
- package/dist/lib/maths/parser.d.ts +20 -0
- package/dist/lib/maths/parser.d.ts.map +1 -0
- package/dist/lib/maths/parser.js +78 -0
- package/dist/lib/maths/parser.mjs +54 -0
- package/dist/lib/maths/random.cjs +49 -0
- package/dist/lib/maths/random.d.ts +27 -0
- package/dist/lib/maths/random.d.ts.map +1 -0
- package/dist/lib/maths/random.js +49 -0
- package/dist/lib/maths/random.mjs +28 -0
- package/dist/lib/maths/types/advanced.cjs +18 -0
- package/dist/lib/maths/types/advanced.d.ts +357 -0
- package/dist/lib/maths/types/advanced.d.ts.map +1 -0
- package/dist/lib/maths/types/advanced.js +5 -0
- package/dist/lib/maths/types/advanced.mjs +0 -0
- package/dist/lib/maths/types/basic.cjs +18 -0
- package/dist/lib/maths/types/basic.d.ts +95 -0
- package/dist/lib/maths/types/basic.d.ts.map +1 -0
- package/dist/lib/maths/types/basic.js +5 -0
- package/dist/lib/maths/types/basic.mjs +0 -0
- package/dist/lib/maths/types/index.cjs +19 -0
- package/dist/lib/maths/types/index.d.ts +4 -0
- package/dist/lib/maths/types/index.d.ts.map +1 -0
- package/dist/lib/maths/types/index.js +3 -0
- package/dist/lib/maths/types/index.mjs +1 -0
- package/dist/lib/maths/types/negative.cjs +18 -0
- package/dist/lib/maths/types/negative.d.ts +51 -0
- package/dist/lib/maths/types/negative.d.ts.map +1 -0
- package/dist/lib/maths/types/negative.js +5 -0
- package/dist/lib/maths/types/negative.mjs +0 -0
- package/dist/lib/maths/types/operations.cjs +18 -0
- package/dist/lib/maths/types/operations.d.ts +188 -0
- package/dist/lib/maths/types/operations.d.ts.map +1 -0
- package/dist/lib/maths/types/operations.js +6 -0
- package/dist/lib/maths/types/operations.mjs +0 -0
- package/dist/lib/object/clone.cjs +88 -0
- package/dist/lib/object/clone.d.ts +46 -0
- package/dist/lib/object/clone.d.ts.map +1 -0
- package/dist/lib/object/clone.js +104 -0
- package/dist/lib/object/clone.mjs +65 -0
- package/dist/lib/object/diff.cjs +573 -0
- package/dist/lib/object/diff.d.ts +203 -0
- package/dist/lib/object/diff.d.ts.map +1 -0
- package/dist/lib/object/diff.js +805 -0
- package/dist/lib/object/diff.mjs +550 -0
- package/dist/lib/object/getter-setter.cjs +2351 -0
- package/dist/lib/object/getter-setter.d.ts +361 -0
- package/dist/lib/object/getter-setter.d.ts.map +1 -0
- package/dist/lib/object/getter-setter.js +1771 -0
- package/dist/lib/object/getter-setter.mjs +2330 -0
- package/dist/lib/object/index.cjs +3956 -0
- package/dist/lib/object/index.d.ts +13 -0
- package/dist/lib/object/index.d.ts.map +1 -0
- package/dist/lib/object/index.js +12 -0
- package/dist/lib/object/index.mjs +3936 -0
- package/dist/lib/object/merge.cjs +1029 -0
- package/dist/lib/object/merge.d.ts +93 -0
- package/dist/lib/object/merge.d.ts.map +1 -0
- package/dist/lib/object/merge.js +474 -0
- package/dist/lib/object/merge.mjs +1006 -0
- package/dist/lib/object/object.cjs +280 -0
- package/dist/lib/object/object.d.ts +128 -0
- package/dist/lib/object/object.d.ts.map +1 -0
- package/dist/lib/object/object.js +432 -0
- package/dist/lib/object/object.mjs +257 -0
- package/dist/lib/object/omit.cjs +2022 -0
- package/dist/lib/object/omit.d.ts +351 -0
- package/dist/lib/object/omit.d.ts.map +1 -0
- package/dist/lib/object/omit.js +656 -0
- package/dist/lib/object/omit.mjs +1999 -0
- package/dist/lib/object/reconcile.cjs +126 -0
- package/dist/lib/object/reconcile.d.ts +7 -0
- package/dist/lib/object/reconcile.d.ts.map +1 -0
- package/dist/lib/object/reconcile.js +122 -0
- package/dist/lib/object/reconcile.mjs +105 -0
- package/dist/lib/object/selector.cjs +303 -0
- package/dist/lib/object/selector.d.ts +50 -0
- package/dist/lib/object/selector.d.ts.map +1 -0
- package/dist/lib/object/selector.js +371 -0
- package/dist/lib/object/selector.mjs +282 -0
- package/dist/lib/object/sort.cjs +209 -0
- package/dist/lib/object/sort.d.ts +149 -0
- package/dist/lib/object/sort.d.ts.map +1 -0
- package/dist/lib/object/sort.js +298 -0
- package/dist/lib/object/sort.mjs +186 -0
- package/dist/lib/object/transform.cjs +2211 -0
- package/dist/lib/object/transform.d.ts +620 -0
- package/dist/lib/object/transform.d.ts.map +1 -0
- package/dist/lib/object/transform.js +1058 -0
- package/dist/lib/object/transform.mjs +2190 -0
- package/dist/lib/object/types.cjs +18 -0
- package/dist/lib/object/types.d.ts +250 -0
- package/dist/lib/object/types.d.ts.map +1 -0
- package/dist/lib/object/types.js +1 -0
- package/dist/lib/object/types.mjs +0 -0
- package/dist/lib/object/utils.cjs +326 -0
- package/dist/lib/object/utils.d.ts +165 -0
- package/dist/lib/object/utils.d.ts.map +1 -0
- package/dist/lib/object/utils.js +444 -0
- package/dist/lib/object/utils.mjs +305 -0
- package/dist/lib/primitive/boolean/boolean.cjs +407 -0
- package/dist/lib/primitive/boolean/boolean.d.ts +276 -0
- package/dist/lib/primitive/boolean/boolean.d.ts.map +1 -0
- package/dist/lib/primitive/boolean/boolean.js +615 -0
- package/dist/lib/primitive/boolean/boolean.mjs +386 -0
- package/dist/lib/primitive/boolean/index.cjs +382 -0
- package/dist/lib/primitive/boolean/index.d.ts +3 -0
- package/dist/lib/primitive/boolean/index.d.ts.map +1 -0
- package/dist/lib/primitive/boolean/index.js +2 -0
- package/dist/lib/primitive/boolean/index.mjs +359 -0
- package/dist/lib/primitive/boolean/types.cjs +18 -0
- package/dist/lib/primitive/boolean/types.d.ts +14 -0
- package/dist/lib/primitive/boolean/types.d.ts.map +1 -0
- package/dist/lib/primitive/boolean/types.js +1 -0
- package/dist/lib/primitive/boolean/types.mjs +0 -0
- package/dist/lib/primitive/date/date.cjs +1126 -0
- package/dist/lib/primitive/date/date.d.ts +641 -0
- package/dist/lib/primitive/date/date.d.ts.map +1 -0
- package/dist/lib/primitive/date/date.js +1998 -0
- package/dist/lib/primitive/date/date.mjs +1105 -0
- package/dist/lib/primitive/date/index.cjs +1128 -0
- package/dist/lib/primitive/date/index.d.ts +3 -0
- package/dist/lib/primitive/date/index.d.ts.map +1 -0
- package/dist/lib/primitive/date/index.js +2 -0
- package/dist/lib/primitive/date/index.mjs +1105 -0
- package/dist/lib/primitive/date/types.cjs +18 -0
- package/dist/lib/primitive/date/types.d.ts +205 -0
- package/dist/lib/primitive/date/types.d.ts.map +1 -0
- package/dist/lib/primitive/date/types.js +7 -0
- package/dist/lib/primitive/date/types.mjs +0 -0
- package/dist/lib/primitive/index.cjs +2338 -0
- package/dist/lib/primitive/index.d.ts +5 -0
- package/dist/lib/primitive/index.d.ts.map +1 -0
- package/dist/lib/primitive/index.js +4 -0
- package/dist/lib/primitive/index.mjs +2316 -0
- package/dist/lib/primitive/string/index.cjs +875 -0
- package/dist/lib/primitive/string/index.d.ts +3 -0
- package/dist/lib/primitive/string/index.d.ts.map +1 -0
- package/dist/lib/primitive/string/index.js +2 -0
- package/dist/lib/primitive/string/index.mjs +852 -0
- package/dist/lib/primitive/string/parser-2.cjs +543 -0
- package/dist/lib/primitive/string/parser-2.d.ts +17 -0
- package/dist/lib/primitive/string/parser-2.d.ts.map +1 -0
- package/dist/lib/primitive/string/parser-2.js +656 -0
- package/dist/lib/primitive/string/parser-2.mjs +522 -0
- package/dist/lib/primitive/string/parser.cjs +236 -0
- package/dist/lib/primitive/string/parser.d.ts +9 -0
- package/dist/lib/primitive/string/parser.d.ts.map +1 -0
- package/dist/lib/primitive/string/parser.js +775 -0
- package/dist/lib/primitive/string/parser.mjs +215 -0
- package/dist/lib/primitive/string/string.cjs +926 -0
- package/dist/lib/primitive/string/string.d.ts +535 -0
- package/dist/lib/primitive/string/string.d.ts.map +1 -0
- package/dist/lib/primitive/string/string.js +1301 -0
- package/dist/lib/primitive/string/string.mjs +903 -0
- package/dist/lib/primitive/string/types.cjs +18 -0
- package/dist/lib/primitive/string/types.d.ts +318 -0
- package/dist/lib/primitive/string/types.d.ts.map +1 -0
- package/dist/lib/primitive/string/types.js +5 -0
- package/dist/lib/primitive/string/types.mjs +0 -0
- package/dist/lib/primitive/types.cjs +18 -0
- package/dist/lib/primitive/types.d.ts +27 -0
- package/dist/lib/primitive/types.d.ts.map +1 -0
- package/dist/lib/primitive/types.js +1 -0
- package/dist/lib/primitive/types.mjs +0 -0
- package/dist/lib/url/index.cjs +327 -0
- package/dist/lib/url/index.d.ts +3 -0
- package/dist/lib/url/index.d.ts.map +1 -0
- package/dist/lib/url/index.js +2 -0
- package/dist/lib/url/index.mjs +304 -0
- package/dist/lib/url/parser.cjs +325 -0
- package/dist/lib/url/parser.d.ts +216 -0
- package/dist/lib/url/parser.d.ts.map +1 -0
- package/dist/lib/url/parser.js +488 -0
- package/dist/lib/url/parser.mjs +304 -0
- package/dist/lib/url/types.cjs +18 -0
- package/dist/lib/url/types.d.ts +18 -0
- package/dist/lib/url/types.d.ts.map +1 -0
- package/dist/lib/url/types.js +1 -0
- package/dist/lib/url/types.mjs +0 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -0
- package/package.json +127 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { AnyObject, CreateMutable, RecordObject, UnionToIntersection } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Merges multiple objects or multiple arrays deeply without keeping references
|
|
4
|
+
* Creates a new instance with combined properties/items
|
|
5
|
+
*
|
|
6
|
+
* @param sources - Objects or arrays to merge (cannot mix objects and arrays)
|
|
7
|
+
* @returns Merged result (new instance, no references to source objects)
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* // Merging objects
|
|
11
|
+
* const obj1 = { a: 1, b: { c: 2 } };
|
|
12
|
+
* const obj2 = { b: { d: 3 }, e: 4 };
|
|
13
|
+
* const result = merge(obj1, obj2);
|
|
14
|
+
* // result: { a: 1, b: { c: 2, d: 3 }, e: 4 }
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* // Merging arrays
|
|
18
|
+
* const arr1 = [1, 2, { a: 1 }];
|
|
19
|
+
* const arr2 = [3, { a: 2, b: 3 }];
|
|
20
|
+
* const result = merge(arr1, arr2);
|
|
21
|
+
* // result: [1, 2, { a: 1 }, 3, { a: 2, b: 3 }]
|
|
22
|
+
*/
|
|
23
|
+
export declare function merge<T extends AnyObject[]>(...sources: T): T extends (infer U)[] ? CreateMutable<UnionToIntersection<U>> : never;
|
|
24
|
+
export declare function merge<T extends any[][]>(...sources: T): T extends (infer U)[] ? CreateMutable<UnionToIntersection<U>> : never;
|
|
25
|
+
export declare function mergeArrays<T>(arr1: T[], arr2: T[], options?: {
|
|
26
|
+
key?: keyof T;
|
|
27
|
+
override?: boolean;
|
|
28
|
+
}): T[];
|
|
29
|
+
/**
|
|
30
|
+
* Merges objects or arrays with options for reference preservation and strict merging
|
|
31
|
+
*
|
|
32
|
+
* @param target - The target object/array to merge into (can be modified if preserveTarget is true)
|
|
33
|
+
* @param sources - The source objects/arrays to merge from
|
|
34
|
+
* @param options - Configuration options
|
|
35
|
+
* @returns The merged result
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* // With reference preservation
|
|
39
|
+
* const obj1 = { a: 1, b: { c: 2 } };
|
|
40
|
+
* const result = deepMergeWithOptions(obj1, { b: { d: 3 }, e: 4 }, { preserveTarget: true });
|
|
41
|
+
* // result === obj1 (same reference)
|
|
42
|
+
* // result: { a: 1, b: { c: 2, d: 3 }, e: 4 }
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* // With strict merging (only merge properties that exist in target)
|
|
46
|
+
* const obj1 = { a: 1, b: { c: 2 } };
|
|
47
|
+
* const result = deepMergeWithOptions(obj1, { b: { d: 3 }, e: 4 }, { strict: true });
|
|
48
|
+
* // result: { a: 1, b: { c: 2 } } - e is not added as it doesn't exist in obj1
|
|
49
|
+
*/
|
|
50
|
+
export declare function deepMergeWithOptions<T extends object>(target: T, ...args: any[]): T;
|
|
51
|
+
/**
|
|
52
|
+
* Deep merges objects/arrays while preserving the reference to the first object/array
|
|
53
|
+
* Modifies the first object directly rather than creating a new one
|
|
54
|
+
*
|
|
55
|
+
* @param target - The target object that will be modified
|
|
56
|
+
* @param sources - The source objects to merge from
|
|
57
|
+
* @returns The modified target object (same reference)
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* const obj1 = { a: 1, b: { c: 2 } };
|
|
61
|
+
* const result = deepMergeKeepReference(obj1, { b: { d: 3 }, e: 4 });
|
|
62
|
+
* // result === obj1 (same reference)
|
|
63
|
+
* // obj1 is now: { a: 1, b: { c: 2, d: 3 }, e: 4 }
|
|
64
|
+
*/
|
|
65
|
+
export declare function deepMergeKeepReference<T extends object>(target: T, ...sources: object[]): T;
|
|
66
|
+
/**
|
|
67
|
+
* Strict deep merge - only merges properties that already exist in the target
|
|
68
|
+
* Does not add new properties that don't exist in the target
|
|
69
|
+
*
|
|
70
|
+
* @param target - The target object
|
|
71
|
+
* @param sources - The source objects to merge from
|
|
72
|
+
* @param preserveReference - Whether to preserve the reference to target (default: false)
|
|
73
|
+
* @returns The merged object
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* const obj1 = { a: 1, b: { c: 2 } };
|
|
77
|
+
* const result = deepMergeStrict(obj1, { b: { d: 3 }, e: 4 });
|
|
78
|
+
* // result: { a: 1, b: { c: 2 } } - e is not added as it doesn't exist in obj1
|
|
79
|
+
* // d is not added as it doesn't exist in obj1.b
|
|
80
|
+
*/
|
|
81
|
+
export declare function deepMergeStrict<T extends object>(target: T, ...args: any[]): T;
|
|
82
|
+
/**
|
|
83
|
+
* Helper to merge a value into a structure based on selector
|
|
84
|
+
* @param target - Target object to merge into
|
|
85
|
+
* @param selector - Selector string
|
|
86
|
+
* @param value - Value to merge
|
|
87
|
+
* @example
|
|
88
|
+
* mergeIntoStructure({ a: { b: { c: 1 } } }, 'a.b.c', 2);
|
|
89
|
+
* // { a: { b: { c: 2 } } }
|
|
90
|
+
*/
|
|
91
|
+
export declare const mergeIntoStructure: (target: RecordObject, selector: string, value: any) => void;
|
|
92
|
+
export { deepMergeKeepReference as deepMerge, deepMergeStrict as mergeStrict, deepMergeWithOptions as mergeWithOptions, };
|
|
93
|
+
//# sourceMappingURL=merge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../../src/lib/object/merge.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,aAAa,EACb,YAAY,EACZ,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAMpB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,KAAK,CAAC,CAAC,SAAS,SAAS,EAAE,EACzC,GAAG,OAAO,EAAE,CAAC,GACZ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,aAAa,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;AACzE,wBAAgB,KAAK,CAAC,CAAC,SAAS,GAAG,EAAE,EAAE,EACrC,GAAG,OAAO,EAAE,CAAC,GACZ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,aAAa,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;AA4GzE,wBAAgB,WAAW,CAAC,CAAC,EAC3B,IAAI,EAAE,CAAC,EAAE,EACT,IAAI,EAAE,CAAC,EAAE,EACT,OAAO,CAAC,EAAE;IACR,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,GACA,CAAC,EAAE,CA+BL;AA2BD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,MAAM,EACnD,MAAM,EAAE,CAAC,EACT,GAAG,IAAI,EAAE,GAAG,EAAE,GACb,CAAC,CA4KH;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,MAAM,EACrD,MAAM,EAAE,CAAC,EACT,GAAG,OAAO,EAAE,MAAM,EAAE,GACnB,CAAC,CAIH;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,EAC9C,MAAM,EAAE,CAAC,EACT,GAAG,IAAI,EAAE,GAAG,EAAE,GACb,CAAC,CAcH;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,YAAY,EACpB,UAAU,MAAM,EAChB,OAAO,GAAG,KACT,IAqFF,CAAC;AAGF,OAAO,EACL,sBAAsB,IAAI,SAAS,EACnC,eAAe,IAAI,WAAW,EAC9B,oBAAoB,IAAI,gBAAgB,GACzC,CAAC"}
|
|
@@ -0,0 +1,474 @@
|
|
|
1
|
+
import { isPlainObject } from './utils.js';
|
|
2
|
+
import { deepClone } from './clone.js';
|
|
3
|
+
import { diffObjectDetailed, applyDiff, } from './diff.js';
|
|
4
|
+
import { parseSelector } from './selector.js';
|
|
5
|
+
export function merge(...sources) {
|
|
6
|
+
if (sources.length === 0)
|
|
7
|
+
return {};
|
|
8
|
+
// Check if we're merging arrays or objects
|
|
9
|
+
const firstItem = sources[0];
|
|
10
|
+
const isArrayMerge = Array.isArray(firstItem);
|
|
11
|
+
// Ensure consistent types (all objects or all arrays)
|
|
12
|
+
for (const source of sources) {
|
|
13
|
+
if (source && Array.isArray(source) !== isArrayMerge) {
|
|
14
|
+
throw new Error('Cannot mix arrays and objects in deepMerge');
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
// Create appropriate empty result
|
|
18
|
+
let result = isArrayMerge ? [] : {};
|
|
19
|
+
// Merge the sources into the result
|
|
20
|
+
for (const source of sources) {
|
|
21
|
+
// Skip null/undefined sources
|
|
22
|
+
if (source == null)
|
|
23
|
+
continue;
|
|
24
|
+
if (isArrayMerge) {
|
|
25
|
+
// Array merging - concatenate arrays after deep cloning items
|
|
26
|
+
const resultArray = result;
|
|
27
|
+
const sourceArray = source;
|
|
28
|
+
for (const item of sourceArray) {
|
|
29
|
+
resultArray.push(deepClone(item));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
// Object merging
|
|
34
|
+
if (!isPlainObject(source))
|
|
35
|
+
continue;
|
|
36
|
+
const resultObj = result;
|
|
37
|
+
const sourceObj = source;
|
|
38
|
+
// Handle regular properties
|
|
39
|
+
for (const key in sourceObj) {
|
|
40
|
+
if (Object.prototype.hasOwnProperty.call(sourceObj, key)) {
|
|
41
|
+
const value = sourceObj[key];
|
|
42
|
+
const existing = resultObj[key];
|
|
43
|
+
if (existing === undefined) {
|
|
44
|
+
// No existing value, deep clone the new value
|
|
45
|
+
resultObj[key] = deepClone(value);
|
|
46
|
+
}
|
|
47
|
+
else if (Array.isArray(value) && Array.isArray(existing)) {
|
|
48
|
+
// Both are arrays, concatenate them after deep cloning
|
|
49
|
+
resultObj[key] = [
|
|
50
|
+
...existing,
|
|
51
|
+
...value.map((item) => deepClone(item)),
|
|
52
|
+
];
|
|
53
|
+
}
|
|
54
|
+
else if (isPlainObject(value) && isPlainObject(existing)) {
|
|
55
|
+
// Both are plain objects, recursively merge
|
|
56
|
+
resultObj[key] = merge(existing, value);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
// Primitive or type mismatch, replace with cloned value
|
|
60
|
+
resultObj[key] = deepClone(value);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Handle symbols
|
|
65
|
+
const symbols = Object.getOwnPropertySymbols(sourceObj);
|
|
66
|
+
for (const symbol of symbols) {
|
|
67
|
+
const value = sourceObj[symbol];
|
|
68
|
+
const existing = resultObj[symbol];
|
|
69
|
+
if (existing === undefined) {
|
|
70
|
+
// No existing value, deep clone the new value
|
|
71
|
+
resultObj[symbol] = deepClone(value);
|
|
72
|
+
}
|
|
73
|
+
else if (Array.isArray(value) && Array.isArray(existing)) {
|
|
74
|
+
// Both are arrays, concatenate them after deep cloning
|
|
75
|
+
resultObj[symbol] = [
|
|
76
|
+
...existing,
|
|
77
|
+
...value.map((item) => deepClone(item)),
|
|
78
|
+
];
|
|
79
|
+
}
|
|
80
|
+
else if (isPlainObject(value) && isPlainObject(existing)) {
|
|
81
|
+
// Both are plain objects, recursively merge
|
|
82
|
+
resultObj[symbol] = merge(existing, value);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
// Primitive or type mismatch, replace with cloned value
|
|
86
|
+
resultObj[symbol] = deepClone(value);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
function getKey(value, keys) {
|
|
94
|
+
let key;
|
|
95
|
+
if (typeof value === 'undefined' || value === null)
|
|
96
|
+
return;
|
|
97
|
+
const data_keys = keys ? keys : ["id"];
|
|
98
|
+
if (typeof value === 'object') {
|
|
99
|
+
if (!Array.isArray(value)) {
|
|
100
|
+
let i = 0;
|
|
101
|
+
while (!key) {
|
|
102
|
+
key = data_keys[i];
|
|
103
|
+
i += 1;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return key;
|
|
108
|
+
}
|
|
109
|
+
export function mergeArrays(arr1, arr2, options) {
|
|
110
|
+
const { key, override = true } = options || {};
|
|
111
|
+
// 👉 Case 1: primitives
|
|
112
|
+
if (!key) {
|
|
113
|
+
return Array.from(new Set([...arr1, ...arr2]));
|
|
114
|
+
}
|
|
115
|
+
// 👉 Case 2: objects with key
|
|
116
|
+
const map = new Map();
|
|
117
|
+
for (const item of arr1) {
|
|
118
|
+
map.set(item[key], item);
|
|
119
|
+
}
|
|
120
|
+
for (const item of arr2) {
|
|
121
|
+
const existing = map.get(item[key]);
|
|
122
|
+
if (!existing) {
|
|
123
|
+
map.set(item[key], item);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
map.set(item[key], override
|
|
127
|
+
? { ...existing, ...item } // merge + override
|
|
128
|
+
: { ...item, ...existing } // keep original
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return Array.from(map.values());
|
|
133
|
+
}
|
|
134
|
+
function mergeInPlace(target, source) {
|
|
135
|
+
for (const key in source) {
|
|
136
|
+
const tVal = target[key];
|
|
137
|
+
const sVal = source[key];
|
|
138
|
+
const diff = diffObjectDetailed(tVal, sVal);
|
|
139
|
+
if (Array.isArray(tVal) && Array.isArray(sVal)) {
|
|
140
|
+
// keep same array reference
|
|
141
|
+
tVal.length = 0;
|
|
142
|
+
tVal.push(...sVal);
|
|
143
|
+
}
|
|
144
|
+
else if (typeof tVal === 'object' &&
|
|
145
|
+
typeof sVal === 'object' &&
|
|
146
|
+
tVal &&
|
|
147
|
+
sVal &&
|
|
148
|
+
diff.hasChanges) {
|
|
149
|
+
applyDiff(tVal, sVal);
|
|
150
|
+
// mergeInPlace(tVal, sVal);
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
target[key] = sVal;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Merges objects or arrays with options for reference preservation and strict merging
|
|
159
|
+
*
|
|
160
|
+
* @param target - The target object/array to merge into (can be modified if preserveTarget is true)
|
|
161
|
+
* @param sources - The source objects/arrays to merge from
|
|
162
|
+
* @param options - Configuration options
|
|
163
|
+
* @returns The merged result
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* // With reference preservation
|
|
167
|
+
* const obj1 = { a: 1, b: { c: 2 } };
|
|
168
|
+
* const result = deepMergeWithOptions(obj1, { b: { d: 3 }, e: 4 }, { preserveTarget: true });
|
|
169
|
+
* // result === obj1 (same reference)
|
|
170
|
+
* // result: { a: 1, b: { c: 2, d: 3 }, e: 4 }
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* // With strict merging (only merge properties that exist in target)
|
|
174
|
+
* const obj1 = { a: 1, b: { c: 2 } };
|
|
175
|
+
* const result = deepMergeWithOptions(obj1, { b: { d: 3 }, e: 4 }, { strict: true });
|
|
176
|
+
* // result: { a: 1, b: { c: 2 } } - e is not added as it doesn't exist in obj1
|
|
177
|
+
*/
|
|
178
|
+
export function deepMergeWithOptions(target, ...args) {
|
|
179
|
+
if (args.length === 0)
|
|
180
|
+
return deepClone(target);
|
|
181
|
+
// Check if last argument is options
|
|
182
|
+
let options = { preserveTarget: false, strict: false };
|
|
183
|
+
let sources = args;
|
|
184
|
+
const lastArg = args[args.length - 1];
|
|
185
|
+
if (lastArg &&
|
|
186
|
+
typeof lastArg === 'object' &&
|
|
187
|
+
('preserveTarget' in lastArg || 'strict' in lastArg)) {
|
|
188
|
+
options = { ...options, ...lastArg };
|
|
189
|
+
sources = args.slice(0, -1);
|
|
190
|
+
}
|
|
191
|
+
// Create or use target as result base
|
|
192
|
+
const result = options.preserveTarget ? target : deepClone(target);
|
|
193
|
+
// Ensure consistent types (all objects or all arrays)
|
|
194
|
+
const isArrayMerge = Array.isArray(result);
|
|
195
|
+
for (const source of sources) {
|
|
196
|
+
if (source && Array.isArray(source) !== isArrayMerge) {
|
|
197
|
+
throw new Error('Cannot mix arrays and objects in deepMergeWithOptions');
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
// Process each source
|
|
201
|
+
for (const source of sources) {
|
|
202
|
+
if (source == null)
|
|
203
|
+
continue;
|
|
204
|
+
if (isArrayMerge) {
|
|
205
|
+
// Array merging
|
|
206
|
+
const resultArray = result;
|
|
207
|
+
const sourceArray = source;
|
|
208
|
+
if (options.strict) {
|
|
209
|
+
// In strict mode, only modify existing array elements
|
|
210
|
+
for (let i = 0; i < resultArray.length && i < sourceArray.length; i++) {
|
|
211
|
+
if (isPlainObject(resultArray[i]) && isPlainObject(sourceArray[i])) {
|
|
212
|
+
resultArray[i] = deepMergeWithOptions(resultArray[i], sourceArray[i], options);
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
// For non-objects in strict mode, only replace if same type
|
|
216
|
+
if (typeof resultArray[i] === typeof sourceArray[i]) {
|
|
217
|
+
resultArray[i] = deepClone(sourceArray[i]);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
// In non-strict mode, concatenate arrays
|
|
224
|
+
// console.log('pushing', [...resultArray], [...sourceArray])
|
|
225
|
+
mergeInPlace(resultArray, sourceArray);
|
|
226
|
+
// if(sourceArray.length===resultArray.length){
|
|
227
|
+
// for (let i=0; i<sourceArray.length; i++) {
|
|
228
|
+
// const item = sourceArray[i];
|
|
229
|
+
// // const result = resultArray[i];
|
|
230
|
+
// // let index = -1;
|
|
231
|
+
// // if(typeof item === 'object'){
|
|
232
|
+
// // const key = getKey(item);
|
|
233
|
+
// // if(key){
|
|
234
|
+
// // index = resultArray.find(s=>)
|
|
235
|
+
// // }else{
|
|
236
|
+
// // }
|
|
237
|
+
// // }else{
|
|
238
|
+
// // }
|
|
239
|
+
// resultArray.push(deepClone(item));
|
|
240
|
+
// }
|
|
241
|
+
// }else{
|
|
242
|
+
// for (let i=0; i<sourceArray.length; i++) {
|
|
243
|
+
// const item = sourceArray[i]
|
|
244
|
+
// resultArray.push(deepClone(item));
|
|
245
|
+
// }
|
|
246
|
+
// }
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
// Object merging
|
|
251
|
+
if (!isPlainObject(source))
|
|
252
|
+
continue;
|
|
253
|
+
const resultObj = result;
|
|
254
|
+
const sourceObj = source;
|
|
255
|
+
// Handle regular properties
|
|
256
|
+
for (const key in sourceObj) {
|
|
257
|
+
if (!Object.prototype.hasOwnProperty.call(sourceObj, key))
|
|
258
|
+
continue;
|
|
259
|
+
const value = sourceObj[key];
|
|
260
|
+
if (options.strict && !(key in resultObj)) {
|
|
261
|
+
// In strict mode, skip properties that don't exist in the target
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
const existing = resultObj[key];
|
|
265
|
+
if (existing === undefined) {
|
|
266
|
+
// Property doesn't exist in result yet, clone and add it
|
|
267
|
+
resultObj[key] = deepClone(value);
|
|
268
|
+
}
|
|
269
|
+
else if (Array.isArray(value) && Array.isArray(existing)) {
|
|
270
|
+
// Both are arrays, handle according to options
|
|
271
|
+
if (options.strict) {
|
|
272
|
+
// In strict mode, recursively merge array elements
|
|
273
|
+
resultObj[key] = deepMergeWithOptions(existing, value, options);
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
// In non-strict mode, concatenate arrays
|
|
277
|
+
resultObj[key] = [
|
|
278
|
+
...existing,
|
|
279
|
+
...value.map((item) => deepClone(item)),
|
|
280
|
+
];
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
else if (isPlainObject(value) && isPlainObject(existing)) {
|
|
284
|
+
// Both are plain objects, recursively merge
|
|
285
|
+
resultObj[key] = deepMergeWithOptions(existing, value, options);
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
// Primitive or type mismatch, replace with cloned value
|
|
289
|
+
resultObj[key] = deepClone(value);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
// Handle symbols
|
|
293
|
+
const symbols = Object.getOwnPropertySymbols(sourceObj);
|
|
294
|
+
for (const symbol of symbols) {
|
|
295
|
+
if (options.strict && !(symbol in resultObj)) {
|
|
296
|
+
// In strict mode, skip symbols that don't exist in the target
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
const value = sourceObj[symbol];
|
|
300
|
+
const existing = resultObj[symbol];
|
|
301
|
+
if (existing === undefined) {
|
|
302
|
+
// Symbol doesn't exist in result yet, clone and add it
|
|
303
|
+
resultObj[symbol] = deepClone(value);
|
|
304
|
+
}
|
|
305
|
+
else if (Array.isArray(value) && Array.isArray(existing)) {
|
|
306
|
+
// Both are arrays, handle according to options
|
|
307
|
+
if (options.strict) {
|
|
308
|
+
// In strict mode, recursively merge array elements
|
|
309
|
+
resultObj[symbol] = deepMergeWithOptions(existing, value, options);
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
// In non-strict mode, concatenate arrays
|
|
313
|
+
resultObj[symbol] = [
|
|
314
|
+
...existing,
|
|
315
|
+
...value.map((item) => deepClone(item)),
|
|
316
|
+
];
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
else if (isPlainObject(value) && isPlainObject(existing)) {
|
|
320
|
+
// Both are plain objects, recursively merge
|
|
321
|
+
resultObj[symbol] = deepMergeWithOptions(existing, value, options);
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
// Primitive or type mismatch, replace with cloned value
|
|
325
|
+
resultObj[symbol] = deepClone(value);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
return result;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Deep merges objects/arrays while preserving the reference to the first object/array
|
|
334
|
+
* Modifies the first object directly rather than creating a new one
|
|
335
|
+
*
|
|
336
|
+
* @param target - The target object that will be modified
|
|
337
|
+
* @param sources - The source objects to merge from
|
|
338
|
+
* @returns The modified target object (same reference)
|
|
339
|
+
*
|
|
340
|
+
* @example
|
|
341
|
+
* const obj1 = { a: 1, b: { c: 2 } };
|
|
342
|
+
* const result = deepMergeKeepReference(obj1, { b: { d: 3 }, e: 4 });
|
|
343
|
+
* // result === obj1 (same reference)
|
|
344
|
+
* // obj1 is now: { a: 1, b: { c: 2, d: 3 }, e: 4 }
|
|
345
|
+
*/
|
|
346
|
+
export function deepMergeKeepReference(target, ...sources) {
|
|
347
|
+
return deepMergeWithOptions(target, ...sources, {
|
|
348
|
+
preserveTarget: true,
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Strict deep merge - only merges properties that already exist in the target
|
|
353
|
+
* Does not add new properties that don't exist in the target
|
|
354
|
+
*
|
|
355
|
+
* @param target - The target object
|
|
356
|
+
* @param sources - The source objects to merge from
|
|
357
|
+
* @param preserveReference - Whether to preserve the reference to target (default: false)
|
|
358
|
+
* @returns The merged object
|
|
359
|
+
*
|
|
360
|
+
* @example
|
|
361
|
+
* const obj1 = { a: 1, b: { c: 2 } };
|
|
362
|
+
* const result = deepMergeStrict(obj1, { b: { d: 3 }, e: 4 });
|
|
363
|
+
* // result: { a: 1, b: { c: 2 } } - e is not added as it doesn't exist in obj1
|
|
364
|
+
* // d is not added as it doesn't exist in obj1.b
|
|
365
|
+
*/
|
|
366
|
+
export function deepMergeStrict(target, ...args) {
|
|
367
|
+
// Check if last argument is a boolean flag for preserving reference
|
|
368
|
+
let preserveReference = false;
|
|
369
|
+
let sources = args;
|
|
370
|
+
if (args.length > 0 && typeof args[args.length - 1] === 'boolean') {
|
|
371
|
+
preserveReference = args[args.length - 1];
|
|
372
|
+
sources = args.slice(0, -1);
|
|
373
|
+
}
|
|
374
|
+
return deepMergeWithOptions(target, ...sources, {
|
|
375
|
+
preserveTarget: preserveReference,
|
|
376
|
+
strict: true,
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Helper to merge a value into a structure based on selector
|
|
381
|
+
* @param target - Target object to merge into
|
|
382
|
+
* @param selector - Selector string
|
|
383
|
+
* @param value - Value to merge
|
|
384
|
+
* @example
|
|
385
|
+
* mergeIntoStructure({ a: { b: { c: 1 } } }, 'a.b.c', 2);
|
|
386
|
+
* // { a: { b: { c: 2 } } }
|
|
387
|
+
*/
|
|
388
|
+
export const mergeIntoStructure = (target, selector, value) => {
|
|
389
|
+
const segments = parseSelector(selector);
|
|
390
|
+
let current = target;
|
|
391
|
+
for (let i = 0; i < segments.length; i++) {
|
|
392
|
+
const segment = segments[i];
|
|
393
|
+
const isLast = i === segments.length - 1;
|
|
394
|
+
switch (segment.type) {
|
|
395
|
+
case 'property':
|
|
396
|
+
if (isLast) {
|
|
397
|
+
current[String(segment.value)] = value;
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
if (!current[String(segment.value)]) {
|
|
401
|
+
const nextSegment = segments[i + 1];
|
|
402
|
+
current[String(segment.value)] =
|
|
403
|
+
nextSegment.type === 'index' ||
|
|
404
|
+
nextSegment.type === 'slice' ||
|
|
405
|
+
nextSegment.type === 'union' ||
|
|
406
|
+
nextSegment.type === 'wildcard'
|
|
407
|
+
? []
|
|
408
|
+
: {};
|
|
409
|
+
}
|
|
410
|
+
current = current[String(segment.value)];
|
|
411
|
+
}
|
|
412
|
+
break;
|
|
413
|
+
case 'index':
|
|
414
|
+
if (!Array.isArray(current)) {
|
|
415
|
+
current = [];
|
|
416
|
+
}
|
|
417
|
+
const index = segment.value;
|
|
418
|
+
if (isLast) {
|
|
419
|
+
if (index >= current.length) {
|
|
420
|
+
for (let j = current.length; j <= index; j++) {
|
|
421
|
+
current.push(undefined);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
current[index] = value;
|
|
425
|
+
}
|
|
426
|
+
else {
|
|
427
|
+
if (!current[index]) {
|
|
428
|
+
const nextSegment = segments[i + 1];
|
|
429
|
+
current[index] =
|
|
430
|
+
nextSegment.type === 'index' ||
|
|
431
|
+
nextSegment.type === 'slice' ||
|
|
432
|
+
nextSegment.type === 'union' ||
|
|
433
|
+
nextSegment.type === 'wildcard'
|
|
434
|
+
? []
|
|
435
|
+
: {};
|
|
436
|
+
}
|
|
437
|
+
current = current[index];
|
|
438
|
+
}
|
|
439
|
+
break;
|
|
440
|
+
case 'wildcard':
|
|
441
|
+
// For wildcards in get, we need to handle all elements
|
|
442
|
+
if (Array.isArray(current)) {
|
|
443
|
+
if (isLast) {
|
|
444
|
+
// Fill all positions with value
|
|
445
|
+
for (let j = 0; j < current.length; j++) {
|
|
446
|
+
current[j] = value;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
else {
|
|
450
|
+
// Ensure all elements have the structure
|
|
451
|
+
const nextSegment = segments[i + 1];
|
|
452
|
+
for (let j = 0; j < current.length; j++) {
|
|
453
|
+
if (!current[j]) {
|
|
454
|
+
current[j] =
|
|
455
|
+
nextSegment.type === 'index' ||
|
|
456
|
+
nextSegment.type === 'slice' ||
|
|
457
|
+
nextSegment.type === 'union' ||
|
|
458
|
+
nextSegment.type === 'wildcard'
|
|
459
|
+
? []
|
|
460
|
+
: {};
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
// Continue with first element (structure should be same for all)
|
|
464
|
+
if (current.length > 0) {
|
|
465
|
+
current = current[0];
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
break;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
};
|
|
473
|
+
// Export aliases for convenience
|
|
474
|
+
export { deepMergeKeepReference as deepMerge, deepMergeStrict as mergeStrict, deepMergeWithOptions as mergeWithOptions, };
|