@codady/utils 0.0.15 → 0.0.17
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/CHANGELOG.md +19 -0
- package/dist/utils.cjs.js +37 -33
- package/dist/utils.cjs.min.js +3 -3
- package/dist/utils.esm.js +37 -33
- package/dist/utils.esm.min.js +3 -3
- package/dist/utils.umd.js +37 -33
- package/dist/utils.umd.min.js +3 -3
- package/dist.zip +0 -0
- package/package.json +1 -1
- package/src/deepClone.js +9 -9
- package/src/deepClone.ts +5 -5
- package/src/deepMerge.js +34 -24
- package/src/deepMerge.ts +84 -39
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
All changes to Utils including new features, updates, and removals are documented here.
|
|
4
4
|
|
|
5
|
+
## [v0.0.16] - 2025-12-26
|
|
6
|
+
|
|
7
|
+
### Distribution Files
|
|
8
|
+
* **JS**: https://unpkg.com/@codady/utils@0.0.16/dist/js/utils.js
|
|
9
|
+
* **Zip**:https://unpkg.com/@codady/utils@0.0.16/dist.zip
|
|
10
|
+
|
|
11
|
+
### Changes
|
|
12
|
+
|
|
13
|
+
#### Fixed
|
|
14
|
+
* Null
|
|
15
|
+
|
|
16
|
+
#### Added
|
|
17
|
+
* Modified the `deepMerge` function to include an `interceptor` parameter, which can be used to intercept the merging process and handle it manually when needed.修改了`deepMerge`函数,对参数增加`interceptor`属性,用来拦截合并,当需要手动处理合并时可使用该参数。
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
#### Removed
|
|
21
|
+
* Null
|
|
5
22
|
|
|
6
23
|
## [v0.0.14] - 2025-12-26
|
|
7
24
|
|
|
@@ -16,6 +33,8 @@ All changes to Utils including new features, updates, and removals are documente
|
|
|
16
33
|
|
|
17
34
|
#### Added
|
|
18
35
|
* The `onBeforeClone` and `onAfterClone` callbacks of the `deepClone` function now include a new `parent` property, which can temporarily store the parent object being cloned. deepClone函数的onBeforeClone和onAfterClone新增属性parent,可临时存储被拷贝的父对象。
|
|
36
|
+
* Modified the `deepMerge` function to include an `interceptor` parameter, which can be used to intercept the merging process and handle it manually when needed.修改了`deepMerge`函数,对参数增加`interceptor`属性,用来拦截合并,当需要手动处理合并时可使用该参数。
|
|
37
|
+
|
|
19
38
|
|
|
20
39
|
#### Removed
|
|
21
40
|
* Null
|
package/dist/utils.cjs.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
/*!
|
|
3
|
-
* @since Last modified: 2025-12-26
|
|
3
|
+
* @since Last modified: 2025-12-26 16:3:51
|
|
4
4
|
* @name Utils for web front-end.
|
|
5
|
-
* @version 0.0.
|
|
5
|
+
* @version 0.0.17
|
|
6
6
|
* @author AXUI development team <3217728223@qq.com>
|
|
7
7
|
* @description This is a set of general-purpose JavaScript utility functions developed by the AXUI team. All functions are pure and do not involve CSS or other third-party libraries. They are suitable for any web front-end environment.
|
|
8
8
|
* @see {@link https://www.axui.cn|Official website}
|
|
@@ -61,16 +61,10 @@ const deepClone = (data, options = {}) => {
|
|
|
61
61
|
}, options);
|
|
62
62
|
// Check interceptor - if it returns a value (not null/undefined), use it directly
|
|
63
63
|
if (opts.interceptor && typeof opts.interceptor === 'function') {
|
|
64
|
-
let result = opts.interceptor(data, dataType);
|
|
64
|
+
let result = opts.interceptor({ input: data, type: dataType, parent: opts.parent });
|
|
65
65
|
if ((result ?? false)) {
|
|
66
66
|
// Call onAfterClone if set
|
|
67
|
-
|
|
68
|
-
output: result,
|
|
69
|
-
input: data,
|
|
70
|
-
type: dataType,
|
|
71
|
-
cloned: result !== data,
|
|
72
|
-
parent: opts.parent
|
|
73
|
-
});
|
|
67
|
+
|
|
74
68
|
return result;
|
|
75
69
|
}
|
|
76
70
|
// If interceptor returns null/undefined, continue with normal cloning process
|
|
@@ -532,31 +526,49 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
532
526
|
}, opts),
|
|
533
527
|
// Main helper function for recursive merging
|
|
534
528
|
// 递归合并的主辅助函数
|
|
535
|
-
|
|
536
|
-
let targetType = getDataType(target), sourceType = getDataType(source), flag = true,
|
|
529
|
+
smartMerger = (target, source, options) => {
|
|
530
|
+
let targetType = getDataType(target), sourceType = getDataType(source), flag = true, mergeType, result;
|
|
531
|
+
// Check interceptor - if it returns a value (not null/undefined), use it directly
|
|
532
|
+
if (options.interceptor && typeof options.interceptor === 'function') {
|
|
533
|
+
let interceptorResult = options.interceptor({ target, source, targetType, sourceType, parent: options.parent });
|
|
534
|
+
if ((interceptorResult ?? false)) {
|
|
535
|
+
//如果不是返回{target,source},那么直接返回interceptorResult
|
|
536
|
+
if (interceptorResult?.target === null || interceptorResult?.source === null) {
|
|
537
|
+
return interceptorResult;
|
|
538
|
+
}
|
|
539
|
+
else {
|
|
540
|
+
//interceptorResult={target,source}
|
|
541
|
+
target = interceptorResult.target;
|
|
542
|
+
source = interceptorResult.source;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
// If interceptor returns null/undefined, continue with normal cloning process
|
|
546
|
+
}
|
|
547
|
+
options?.onBeforeMerge?.({ target, source, targetType, sourceType, parent: options.parent });
|
|
537
548
|
// Determine the type and perform appropriate merging
|
|
538
549
|
// 确定类型并执行相应的合并
|
|
539
550
|
if (targetType === 'Object' && sourceType === 'Object') {
|
|
540
551
|
result = deepMergeObjects(target, source, options);
|
|
541
|
-
|
|
552
|
+
mergeType = 'Object';
|
|
542
553
|
}
|
|
543
554
|
else if (targetType === 'Array' && sourceType === 'Array') {
|
|
544
555
|
result = deepMergeArrays(target, source, options);
|
|
545
|
-
|
|
556
|
+
mergeType = 'Array';
|
|
546
557
|
}
|
|
547
558
|
else if (targetType === 'Set' && sourceType === 'Set') {
|
|
548
559
|
result = deepMergeSets(target, source, options);
|
|
549
|
-
|
|
560
|
+
mergeType = 'Set';
|
|
550
561
|
}
|
|
551
562
|
else if (targetType === 'Map' && sourceType === 'Map') {
|
|
552
563
|
result = deepMergeMaps(target, source, options);
|
|
553
|
-
|
|
564
|
+
mergeType = 'Map';
|
|
554
565
|
}
|
|
555
566
|
else {
|
|
556
567
|
flag = false;
|
|
557
568
|
result = target;
|
|
558
569
|
}
|
|
559
|
-
|
|
570
|
+
options?.onAfterMerge?.({ result, target, source, targetType, sourceType, mergeType, parent: opts.parent });
|
|
571
|
+
return { result, flag, mergeType };
|
|
560
572
|
},
|
|
561
573
|
// Special handling for objects with enable property
|
|
562
574
|
// 对具有enable属性的对象进行特殊处理
|
|
@@ -584,7 +596,6 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
584
596
|
if (targetType !== 'Object' || sourceType !== 'Object') {
|
|
585
597
|
return target;
|
|
586
598
|
}
|
|
587
|
-
opts?.onBeforeMerge?.(target, source);
|
|
588
599
|
const options = Object.assign({ inheritMissing: true, targetClone: false, useEnable: true }, opts);
|
|
589
600
|
let result = {};
|
|
590
601
|
// If cloning is enabled, clone the target first
|
|
@@ -592,7 +603,7 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
592
603
|
result = options.targetClone ? shallowCopy(target) : target;
|
|
593
604
|
for (let k in source) {
|
|
594
605
|
if (source.hasOwnProperty(k) && result.hasOwnProperty(k)) {
|
|
595
|
-
let resp =
|
|
606
|
+
let resp = smartMerger(result[k], source[k], { ...opts, parent: result });
|
|
596
607
|
//resp={result,flag,type}
|
|
597
608
|
//flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
|
|
598
609
|
if (!resp.flag) {
|
|
@@ -607,8 +618,8 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
607
618
|
}
|
|
608
619
|
else {
|
|
609
620
|
//类型相同
|
|
610
|
-
if (resp.
|
|
611
|
-
if (resp.
|
|
621
|
+
if (resp.mergeType) {
|
|
622
|
+
if (resp.mergeType === 'Object') {
|
|
612
623
|
//如果遇上对象则深度复制
|
|
613
624
|
result[k] = resp.result;
|
|
614
625
|
}
|
|
@@ -632,13 +643,11 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
632
643
|
result[k] = source[k];
|
|
633
644
|
}
|
|
634
645
|
}
|
|
635
|
-
options?.onAfterMerge?.(result, target, source);
|
|
636
646
|
return result;
|
|
637
647
|
}, deepMergeArrays = (target, source, options = {}) => {
|
|
638
648
|
// Ensure both target and source are arrays
|
|
639
649
|
if (!Array.isArray(target) || !Array.isArray(source))
|
|
640
650
|
return target;
|
|
641
|
-
options?.onBeforeMerge?.(target, source);
|
|
642
651
|
// Merge options, with default values
|
|
643
652
|
const opts = Object.assign({ dataMode: 'clear', inheritMissing: true, targetClone: false }, options),
|
|
644
653
|
// If cloning is enabled, create a deep copy of the target array
|
|
@@ -651,7 +660,7 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
651
660
|
// 如果不允许添加超过长度
|
|
652
661
|
if (!opts.inheritMissing && i >= result.length)
|
|
653
662
|
break;
|
|
654
|
-
let resp =
|
|
663
|
+
let resp = smartMerger(result[i], source[i], { ...opts, parent: result });
|
|
655
664
|
//resp={result,flag,type}
|
|
656
665
|
//flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
|
|
657
666
|
if (!resp.flag) {
|
|
@@ -668,13 +677,11 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
668
677
|
result.length = 0;
|
|
669
678
|
result.push(...source);
|
|
670
679
|
}
|
|
671
|
-
options?.onAfterMerge?.(result, target, source);
|
|
672
680
|
return result;
|
|
673
681
|
}, deepMergeMaps = (target, source, options = {}) => {
|
|
674
682
|
// Ensure both target and source are Maps
|
|
675
683
|
if (!(target instanceof Map) || !(source instanceof Map))
|
|
676
684
|
return target;
|
|
677
|
-
options?.onBeforeMerge?.(target, source);
|
|
678
685
|
// Merge options, with default values
|
|
679
686
|
const opts = Object.assign({ inheritMissing: true, targetClone: false, useEnable: true }, options),
|
|
680
687
|
// If cloning is enabled, create a deep copy of the target Map
|
|
@@ -683,7 +690,7 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
683
690
|
for (const [key, value] of source.entries())
|
|
684
691
|
// Check if the key already exists in the target Map
|
|
685
692
|
if (result.has(key)) {
|
|
686
|
-
const _target = result.get(key), _source = value, resp =
|
|
693
|
+
const _target = result.get(key), _source = value, resp = smartMerger(_target, _source, opts);
|
|
687
694
|
//resp={result,flag,type}
|
|
688
695
|
//flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
|
|
689
696
|
if (!resp.flag) {
|
|
@@ -692,20 +699,18 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
692
699
|
}
|
|
693
700
|
else {
|
|
694
701
|
// If both target and source are objects, merge them recursively
|
|
695
|
-
resp.
|
|
702
|
+
resp.mergeType === 'Object' && result.set(key, resp.result);
|
|
696
703
|
}
|
|
697
704
|
}
|
|
698
705
|
else {
|
|
699
706
|
// If the key doesn't exist in the target, add the entry from the source Map
|
|
700
707
|
options.inheritMissing && result.set(key, value);
|
|
701
708
|
}
|
|
702
|
-
options?.onAfterMerge?.(result, target, source);
|
|
703
709
|
return result;
|
|
704
710
|
}, deepMergeSets = (target, source, options = {}) => {
|
|
705
711
|
// Ensure both target and source are Sets
|
|
706
712
|
if (!(target instanceof Set) || !(source instanceof Set))
|
|
707
713
|
return target;
|
|
708
|
-
options?.onBeforeMerge?.(target, source);
|
|
709
714
|
// Merge options, with default values
|
|
710
715
|
const opts = Object.assign({ dataMode: 'clear', inheritMissing: true, targetClone: false, useEnable: true }, options),
|
|
711
716
|
// If cloning is enabled, create a deep copy of the target Set
|
|
@@ -713,7 +718,7 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
713
718
|
// Handle different merge strategies based on dataMode
|
|
714
719
|
if (opts.dataMode === 'replace') {
|
|
715
720
|
// Replace mode: recursively merge items in the Sets
|
|
716
|
-
const _result = [...result], _source = [...source], resp =
|
|
721
|
+
const _result = [...result], _source = [...source], resp = smartMerger(_result, _source, opts);
|
|
717
722
|
result.clear();
|
|
718
723
|
for (let item of resp.result)
|
|
719
724
|
result.add(item);
|
|
@@ -729,10 +734,9 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
729
734
|
for (let item of source)
|
|
730
735
|
result.add(item);
|
|
731
736
|
}
|
|
732
|
-
options?.onAfterMerge?.(result, target, source);
|
|
733
737
|
return result;
|
|
734
738
|
};
|
|
735
|
-
return
|
|
739
|
+
return smartMerger(target, source, options).result;
|
|
736
740
|
};
|
|
737
741
|
|
|
738
742
|
const utils = {
|
package/dist/utils.cjs.min.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @since Last modified: 2025-12-26
|
|
2
|
+
* @since Last modified: 2025-12-26 16:3:51
|
|
3
3
|
* @name Utils for web front-end.
|
|
4
|
-
* @version 0.0.
|
|
4
|
+
* @version 0.0.17
|
|
5
5
|
* @author AXUI development team <3217728223@qq.com>
|
|
6
6
|
* @description This is a set of general-purpose JavaScript utility functions developed by the AXUI team. All functions are pure and do not involve CSS or other third-party libraries. They are suitable for any web front-end environment.
|
|
7
7
|
* @see {@link https://www.axui.cn|Official website}
|
|
@@ -12,4 +12,4 @@
|
|
|
12
12
|
* @copyright This software supports the MIT License, allowing free learning and commercial use, but please retain the terms 'ax,' 'axui,' 'AX,' and 'AXUI' within the software.
|
|
13
13
|
* @license MIT license
|
|
14
14
|
*/
|
|
15
|
-
"use strict";const getDataType=e=>{let t,r=Object.prototype.toString.call(e).slice(8,-1);return t="Function"===r&&/^\s*class\s+/.test(e.toString())?"Class":"Object"===r&&Object.getPrototypeOf(e)!==Object.prototype?"Instance":r,t},deepClone=(e,t={})=>{const r=getDataType(e),
|
|
15
|
+
"use strict";const getDataType=e=>{let t,r=Object.prototype.toString.call(e).slice(8,-1);return t="Function"===r&&/^\s*class\s+/.test(e.toString())?"Class":"Object"===r&&Object.getPrototypeOf(e)!==Object.prototype?"Instance":r,t},deepClone=(e,t={})=>{const r=getDataType(e),a=Object.assign({cloneSet:!0,cloneMap:!0,cloneObject:!0,cloneArray:!0,cloneDate:!0,cloneRegex:!0},t);if(a.interceptor&&"function"==typeof a.interceptor){let t=a.interceptor({input:e,type:r,parent:a.parent});if(t)return t}a.onBeforeClone?.({input:e,type:r,parent:a.parent});let o,n=!0;if("Object"===r&&a.cloneObject){const t={},r=Object.getOwnPropertySymbols(e);for(const r in e)t[r]=deepClone(e[r],a);if(r.length>0)for(const o of r)t[o]=deepClone(e[o],{...a,parent:e});o=t}else if("Array"===r&&a.cloneArray)o=e.map(t=>deepClone(t,{...a,parent:e}));else if("Map"===r&&a.cloneMap){const t=new Map;for(const[r,o]of e)t.set(deepClone(r,a),deepClone(o,{...a,parent:e}));o=t}else if("Set"===r&&a.cloneSet){const t=new Set;for(const r of e)t.add(deepClone(r,{...a,parent:e}));o=t}else if("Date"===r&&a.cloneDate)o=new Date(e.getTime());else if("RegExp"===r&&a.cloneRegex){const t=e;o=new RegExp(t.source,t.flags)}else o=e,n=!1;return a.onAfterClone?.({output:o,input:e,type:r,cloned:n,parent:a.parent}),o},deepCloneToJSON=e=>{const t=getDataType(e);if("Object"===t){const t={};for(const r in e)t[r]=deepCloneToJSON(e[r]);for(const e in t)void 0===t[e]&&Reflect.deleteProperty(t,e);return t}if("Array"===t){return e.map((e,t)=>deepCloneToJSON(e)).filter(e=>void 0!==e)}return["Number","String","Boolean","Null"].includes(t)?e:void 0},arrayMutableMethods=["push","pop","shift","unshift","splice","sort","reverse","copyWithin","fill"],wrapArrayMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a,props:o={}})=>{if(!Array.isArray(e))throw new TypeError("The 'target' parameter must be an array.");a&&!a?.length||(a=arrayMutableMethods);const n={};for(let s of a)n[s]=function(...a){const n={},l=e.length;switch(s){case"push":case"unshift":n.addedItems=[...a];break;case"pop":n.poppedItem=e[l-1];break;case"shift":n.shiftedItem=e[0];break;case"splice":const[t,r]=a,o=t<0?Math.max(l+t,0):Math.min(t,l),s=void 0===r?l-o:r;n.deletedItems=e.slice(o,o+s);break;case"sort":case"reverse":n.oldSnapshot=[...e];break;case"fill":case"copyWithin":const p=a[1]||0,i=void 0===a[2]?l:a[2];n.oldItems=e.slice(p,i),n.start=p,n.end=i}t?.(n);const p=Array.prototype[s].apply(e,a),i={value:p,key:s,args:a,context:n,target:e,...o};return r?.(i),p};return n},requireTypes=(e,t,r)=>{let a=Array.isArray(t)?t:[t],o=getDataType(e),n=o.toLowerCase(),s=a.map(e=>e.toLowerCase()),l=n.includes("html")?"element":n;if(r)try{if(!s.includes(l))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${l}`)}catch(e){r(e,o)}else if(!s.includes(l))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${l}`);return o},getUniqueId=(e={})=>{const t=e.prefix,r=e.suffix,a=e.base10,o=e.base36;return`${t?t+"-":""}${Date.now()}${o?"-"+Math.random().toString(36).substring(2,11):""}${a?"-"+Math.floor(1e4*Math.random()).toString().padStart(4,"0"):""}${r?"-"+r:""}`},setMutableMethods=["add","delete","clear"],mapMutableMethods=["set","delete","clear"],wrapSetMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a=setMutableMethods,props:o={}})=>{if(!(e instanceof Set))throw new TypeError("The 'target' parameter must be a Set.");const n={},createWrappedMethod=a=>function(...n){const s={};switch(a){case"add":{const[t]=n;s.addedItem=t,s.existed=e.has(t);break}case"delete":{const[t]=n;s.existed=e.has(t),s.deletedItem=s.existed?t:void 0;break}case"clear":s.clearedItems=Array.from(e),s.previousSize=e.size}t(s);const l=e[a].apply(e,n),p={method:a,result:l,args:n,context:s,target:e,...o};return r(p),l};for(const e of a)setMutableMethods.includes(e)&&(n[e]=createWrappedMethod(e));return Object.defineProperty(n,"target",{get:()=>e,enumerable:!1,configurable:!1}),n},wrapMapMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a=mapMutableMethods,props:o={}})=>{if(!(e instanceof Map))throw new TypeError("The 'target' parameter must be a Map.");const n={},createWrappedMethod=a=>function(...n){const s={};switch(a){case"set":{const[t,r]=n;s.key=t,s.newValue=r,s.existed=e.has(t),s.oldValue=s.existed?e.get(t):void 0;break}case"delete":{const[t]=n;s.key=t,s.existed=e.has(t),s.value=s.existed?e.get(t):void 0;break}case"clear":s.clearedItems=Array.from(e.entries()),s.previousSize=e.size}t(s);const l=e[a].apply(e,n),p={method:a,result:l,args:n,context:s,target:e,...o};return r(p),l};for(const e of a)mapMutableMethods.includes(e)&&(n[e]=createWrappedMethod(e));return Object.defineProperty(n,"target",{get:()=>e,enumerable:!1,configurable:!1}),n},copyObjectWithSymbol=e=>{if(!e||"object"!=typeof e)return e;const t=e,r=Object.getOwnPropertySymbols(t).reduce((e,r)=>(e[r]=t[r],e),{});return{...t,...r}},shallowCopy=(e,t={})=>{const r=getDataType(e);return"Set"===r?new Set([...e]):"Map"===r?new Map([...e]):Array.isArray(e)?[...e]:"object"===r?copyObjectWithSymbol(e):"Date"===r?new Date(e.getTime()):"RegExp"===r?new RegExp(e.source,e.flags):"Buffer"===r?Buffer.from(e):"ArrayBuffer"===r||ArrayBuffer.isView(e)?e.slice(0):"WeakSet"===r?new WeakSet([...e]):"WeakMap"===r?new WeakMap([...e]):"Error"===r?new Error(e.message):e},deepMerge=(e,t,r={})=>{const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0,useSymbol:!0,deepClone:{},onBeforeMerge:void 0,onAfterMerge:void 0},r),smartMerger=(e,t,a)=>{let o,n,s=getDataType(e),l=getDataType(t),p=!0;if(a.interceptor&&"function"==typeof a.interceptor){let r=a.interceptor({target:e,source:t,targetType:s,sourceType:l,parent:a.parent});if(r){if(null===r?.target||null===r?.source)return r;e=r.target,t=r.source}}return a?.onBeforeMerge?.({target:e,source:t,targetType:s,sourceType:l,parent:a.parent}),"Object"===s&&"Object"===l?(n=deepMergeObjects(e,t,a),o="Object"):"Array"===s&&"Array"===l?(n=deepMergeArrays(e,t,a),o="Array"):"Set"===s&&"Set"===l?(n=deepMergeSets(e,t,a),o="Set"):"Map"===s&&"Map"===l?(n=deepMergeMaps(e,t,a),o="Map"):(p=!1,n=e),a?.onAfterMerge?.({result:n,target:e,source:t,targetType:s,sourceType:l,mergeType:o,parent:r.parent}),{result:n,flag:p,mergeType:o}},mergeEnableObject=(e,t)=>e?.hasOwnProperty("enable")&&"boolean"==typeof t?(e.enable=t,e):t?.hasOwnProperty("enable")&&"boolean"==typeof e?Object.assign({enable:e},t):t,deepMergeObjects=(e,t,r={})=>{let a=getDataType(e),o=getDataType(t);if("Object"!==a||"Object"!==o)return e;const n=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r);let s={};s=n.targetClone?shallowCopy(e):e;for(let e in t)if(t.hasOwnProperty(e)&&s.hasOwnProperty(e)){let a=smartMerger(s[e],t[e],{...r,parent:s});a.flag?a.mergeType?"Object"===a.mergeType&&(s[e]=a.result):s[e]=t[e]:n.useEnable?s[e]=mergeEnableObject(s[e],t[e]):s[e]=t[e]}else t.hasOwnProperty(e)&&!s.hasOwnProperty(e)&&n.inheritMissing&&(s[e]=t[e]);if(n.useSymbol){let e=Object.getOwnPropertySymbols(t);if(e.length)for(let r of e)s[r]=t[r]}return s},deepMergeArrays=(e,t,r={})=>{if(!Array.isArray(e)||!Array.isArray(t))return e;const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1},r),o=a.targetClone?[...e]:e;if("replace"===a.dataMode)for(let e=0;e<t.length&&(a.inheritMissing||!(e>=o.length));e++){smartMerger(o[e],t[e],{...a,parent:o}).flag||(o[e]=t[e])}else"concat"===a.dataMode||(o.length=0),o.push(...t);return o},deepMergeMaps=(e,t,r={})=>{if(!(e instanceof Map&&t instanceof Map))return e;const a=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r),o=a.targetClone?new Map([...e]):e;for(const[e,n]of t.entries())if(o.has(e)){const t=o.get(e),r=n,s=smartMerger(t,r,a);s.flag?"Object"===s.mergeType&&o.set(e,s.result):o.set(e,r)}else r.inheritMissing&&o.set(e,n);return o},deepMergeSets=(e,t,r={})=>{if(!(e instanceof Set&&t instanceof Set))return e;const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0},r),o=a.targetClone?new Set(...e):e;if("replace"===a.dataMode){const e=[...o],r=[...t],n=smartMerger(e,r,a);o.clear();for(let e of n.result)o.add(e)}else if("concat"===a.dataMode)for(let e of t)o.add(e);else{o.clear();for(let e of t)o.add(e)}return o};return smartMerger(e,t,a).result},utils={getDataType:getDataType,requireTypes:requireTypes,deepClone:deepClone,deepCloneToJSON:deepCloneToJSON,wrapArrayMethods:wrapArrayMethods,arrayMutableMethods:arrayMutableMethods,setMutableMethods:setMutableMethods,mapMutableMethods:mapMutableMethods,wrapSetMethods:wrapSetMethods,wrapMapMethods:wrapMapMethods,getUniqueId:getUniqueId,deepMerge:deepMerge,shallowCopy:shallowCopy,copyObjectWithSymbol:copyObjectWithSymbol};module.exports=utils;
|
package/dist/utils.esm.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
/*!
|
|
3
|
-
* @since Last modified: 2025-12-26
|
|
3
|
+
* @since Last modified: 2025-12-26 16:3:51
|
|
4
4
|
* @name Utils for web front-end.
|
|
5
|
-
* @version 0.0.
|
|
5
|
+
* @version 0.0.17
|
|
6
6
|
* @author AXUI development team <3217728223@qq.com>
|
|
7
7
|
* @description This is a set of general-purpose JavaScript utility functions developed by the AXUI team. All functions are pure and do not involve CSS or other third-party libraries. They are suitable for any web front-end environment.
|
|
8
8
|
* @see {@link https://www.axui.cn|Official website}
|
|
@@ -59,16 +59,10 @@ const deepClone = (data, options = {}) => {
|
|
|
59
59
|
}, options);
|
|
60
60
|
// Check interceptor - if it returns a value (not null/undefined), use it directly
|
|
61
61
|
if (opts.interceptor && typeof opts.interceptor === 'function') {
|
|
62
|
-
let result = opts.interceptor(data, dataType);
|
|
62
|
+
let result = opts.interceptor({ input: data, type: dataType, parent: opts.parent });
|
|
63
63
|
if ((result ?? false)) {
|
|
64
64
|
// Call onAfterClone if set
|
|
65
|
-
|
|
66
|
-
output: result,
|
|
67
|
-
input: data,
|
|
68
|
-
type: dataType,
|
|
69
|
-
cloned: result !== data,
|
|
70
|
-
parent: opts.parent
|
|
71
|
-
});
|
|
65
|
+
|
|
72
66
|
return result;
|
|
73
67
|
}
|
|
74
68
|
// If interceptor returns null/undefined, continue with normal cloning process
|
|
@@ -530,31 +524,49 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
530
524
|
}, opts),
|
|
531
525
|
// Main helper function for recursive merging
|
|
532
526
|
// 递归合并的主辅助函数
|
|
533
|
-
|
|
534
|
-
let targetType = getDataType(target), sourceType = getDataType(source), flag = true,
|
|
527
|
+
smartMerger = (target, source, options) => {
|
|
528
|
+
let targetType = getDataType(target), sourceType = getDataType(source), flag = true, mergeType, result;
|
|
529
|
+
// Check interceptor - if it returns a value (not null/undefined), use it directly
|
|
530
|
+
if (options.interceptor && typeof options.interceptor === 'function') {
|
|
531
|
+
let interceptorResult = options.interceptor({ target, source, targetType, sourceType, parent: options.parent });
|
|
532
|
+
if ((interceptorResult ?? false)) {
|
|
533
|
+
//如果不是返回{target,source},那么直接返回interceptorResult
|
|
534
|
+
if (interceptorResult?.target === null || interceptorResult?.source === null) {
|
|
535
|
+
return interceptorResult;
|
|
536
|
+
}
|
|
537
|
+
else {
|
|
538
|
+
//interceptorResult={target,source}
|
|
539
|
+
target = interceptorResult.target;
|
|
540
|
+
source = interceptorResult.source;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
// If interceptor returns null/undefined, continue with normal cloning process
|
|
544
|
+
}
|
|
545
|
+
options?.onBeforeMerge?.({ target, source, targetType, sourceType, parent: options.parent });
|
|
535
546
|
// Determine the type and perform appropriate merging
|
|
536
547
|
// 确定类型并执行相应的合并
|
|
537
548
|
if (targetType === 'Object' && sourceType === 'Object') {
|
|
538
549
|
result = deepMergeObjects(target, source, options);
|
|
539
|
-
|
|
550
|
+
mergeType = 'Object';
|
|
540
551
|
}
|
|
541
552
|
else if (targetType === 'Array' && sourceType === 'Array') {
|
|
542
553
|
result = deepMergeArrays(target, source, options);
|
|
543
|
-
|
|
554
|
+
mergeType = 'Array';
|
|
544
555
|
}
|
|
545
556
|
else if (targetType === 'Set' && sourceType === 'Set') {
|
|
546
557
|
result = deepMergeSets(target, source, options);
|
|
547
|
-
|
|
558
|
+
mergeType = 'Set';
|
|
548
559
|
}
|
|
549
560
|
else if (targetType === 'Map' && sourceType === 'Map') {
|
|
550
561
|
result = deepMergeMaps(target, source, options);
|
|
551
|
-
|
|
562
|
+
mergeType = 'Map';
|
|
552
563
|
}
|
|
553
564
|
else {
|
|
554
565
|
flag = false;
|
|
555
566
|
result = target;
|
|
556
567
|
}
|
|
557
|
-
|
|
568
|
+
options?.onAfterMerge?.({ result, target, source, targetType, sourceType, mergeType, parent: opts.parent });
|
|
569
|
+
return { result, flag, mergeType };
|
|
558
570
|
},
|
|
559
571
|
// Special handling for objects with enable property
|
|
560
572
|
// 对具有enable属性的对象进行特殊处理
|
|
@@ -582,7 +594,6 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
582
594
|
if (targetType !== 'Object' || sourceType !== 'Object') {
|
|
583
595
|
return target;
|
|
584
596
|
}
|
|
585
|
-
opts?.onBeforeMerge?.(target, source);
|
|
586
597
|
const options = Object.assign({ inheritMissing: true, targetClone: false, useEnable: true }, opts);
|
|
587
598
|
let result = {};
|
|
588
599
|
// If cloning is enabled, clone the target first
|
|
@@ -590,7 +601,7 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
590
601
|
result = options.targetClone ? shallowCopy(target) : target;
|
|
591
602
|
for (let k in source) {
|
|
592
603
|
if (source.hasOwnProperty(k) && result.hasOwnProperty(k)) {
|
|
593
|
-
let resp =
|
|
604
|
+
let resp = smartMerger(result[k], source[k], { ...opts, parent: result });
|
|
594
605
|
//resp={result,flag,type}
|
|
595
606
|
//flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
|
|
596
607
|
if (!resp.flag) {
|
|
@@ -605,8 +616,8 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
605
616
|
}
|
|
606
617
|
else {
|
|
607
618
|
//类型相同
|
|
608
|
-
if (resp.
|
|
609
|
-
if (resp.
|
|
619
|
+
if (resp.mergeType) {
|
|
620
|
+
if (resp.mergeType === 'Object') {
|
|
610
621
|
//如果遇上对象则深度复制
|
|
611
622
|
result[k] = resp.result;
|
|
612
623
|
}
|
|
@@ -630,13 +641,11 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
630
641
|
result[k] = source[k];
|
|
631
642
|
}
|
|
632
643
|
}
|
|
633
|
-
options?.onAfterMerge?.(result, target, source);
|
|
634
644
|
return result;
|
|
635
645
|
}, deepMergeArrays = (target, source, options = {}) => {
|
|
636
646
|
// Ensure both target and source are arrays
|
|
637
647
|
if (!Array.isArray(target) || !Array.isArray(source))
|
|
638
648
|
return target;
|
|
639
|
-
options?.onBeforeMerge?.(target, source);
|
|
640
649
|
// Merge options, with default values
|
|
641
650
|
const opts = Object.assign({ dataMode: 'clear', inheritMissing: true, targetClone: false }, options),
|
|
642
651
|
// If cloning is enabled, create a deep copy of the target array
|
|
@@ -649,7 +658,7 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
649
658
|
// 如果不允许添加超过长度
|
|
650
659
|
if (!opts.inheritMissing && i >= result.length)
|
|
651
660
|
break;
|
|
652
|
-
let resp =
|
|
661
|
+
let resp = smartMerger(result[i], source[i], { ...opts, parent: result });
|
|
653
662
|
//resp={result,flag,type}
|
|
654
663
|
//flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
|
|
655
664
|
if (!resp.flag) {
|
|
@@ -666,13 +675,11 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
666
675
|
result.length = 0;
|
|
667
676
|
result.push(...source);
|
|
668
677
|
}
|
|
669
|
-
options?.onAfterMerge?.(result, target, source);
|
|
670
678
|
return result;
|
|
671
679
|
}, deepMergeMaps = (target, source, options = {}) => {
|
|
672
680
|
// Ensure both target and source are Maps
|
|
673
681
|
if (!(target instanceof Map) || !(source instanceof Map))
|
|
674
682
|
return target;
|
|
675
|
-
options?.onBeforeMerge?.(target, source);
|
|
676
683
|
// Merge options, with default values
|
|
677
684
|
const opts = Object.assign({ inheritMissing: true, targetClone: false, useEnable: true }, options),
|
|
678
685
|
// If cloning is enabled, create a deep copy of the target Map
|
|
@@ -681,7 +688,7 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
681
688
|
for (const [key, value] of source.entries())
|
|
682
689
|
// Check if the key already exists in the target Map
|
|
683
690
|
if (result.has(key)) {
|
|
684
|
-
const _target = result.get(key), _source = value, resp =
|
|
691
|
+
const _target = result.get(key), _source = value, resp = smartMerger(_target, _source, opts);
|
|
685
692
|
//resp={result,flag,type}
|
|
686
693
|
//flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
|
|
687
694
|
if (!resp.flag) {
|
|
@@ -690,20 +697,18 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
690
697
|
}
|
|
691
698
|
else {
|
|
692
699
|
// If both target and source are objects, merge them recursively
|
|
693
|
-
resp.
|
|
700
|
+
resp.mergeType === 'Object' && result.set(key, resp.result);
|
|
694
701
|
}
|
|
695
702
|
}
|
|
696
703
|
else {
|
|
697
704
|
// If the key doesn't exist in the target, add the entry from the source Map
|
|
698
705
|
options.inheritMissing && result.set(key, value);
|
|
699
706
|
}
|
|
700
|
-
options?.onAfterMerge?.(result, target, source);
|
|
701
707
|
return result;
|
|
702
708
|
}, deepMergeSets = (target, source, options = {}) => {
|
|
703
709
|
// Ensure both target and source are Sets
|
|
704
710
|
if (!(target instanceof Set) || !(source instanceof Set))
|
|
705
711
|
return target;
|
|
706
|
-
options?.onBeforeMerge?.(target, source);
|
|
707
712
|
// Merge options, with default values
|
|
708
713
|
const opts = Object.assign({ dataMode: 'clear', inheritMissing: true, targetClone: false, useEnable: true }, options),
|
|
709
714
|
// If cloning is enabled, create a deep copy of the target Set
|
|
@@ -711,7 +716,7 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
711
716
|
// Handle different merge strategies based on dataMode
|
|
712
717
|
if (opts.dataMode === 'replace') {
|
|
713
718
|
// Replace mode: recursively merge items in the Sets
|
|
714
|
-
const _result = [...result], _source = [...source], resp =
|
|
719
|
+
const _result = [...result], _source = [...source], resp = smartMerger(_result, _source, opts);
|
|
715
720
|
result.clear();
|
|
716
721
|
for (let item of resp.result)
|
|
717
722
|
result.add(item);
|
|
@@ -727,10 +732,9 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
727
732
|
for (let item of source)
|
|
728
733
|
result.add(item);
|
|
729
734
|
}
|
|
730
|
-
options?.onAfterMerge?.(result, target, source);
|
|
731
735
|
return result;
|
|
732
736
|
};
|
|
733
|
-
return
|
|
737
|
+
return smartMerger(target, source, options).result;
|
|
734
738
|
};
|
|
735
739
|
|
|
736
740
|
const utils = {
|
package/dist/utils.esm.min.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @since Last modified: 2025-12-26
|
|
2
|
+
* @since Last modified: 2025-12-26 16:3:51
|
|
3
3
|
* @name Utils for web front-end.
|
|
4
|
-
* @version 0.0.
|
|
4
|
+
* @version 0.0.17
|
|
5
5
|
* @author AXUI development team <3217728223@qq.com>
|
|
6
6
|
* @description This is a set of general-purpose JavaScript utility functions developed by the AXUI team. All functions are pure and do not involve CSS or other third-party libraries. They are suitable for any web front-end environment.
|
|
7
7
|
* @see {@link https://www.axui.cn|Official website}
|
|
@@ -12,4 +12,4 @@
|
|
|
12
12
|
* @copyright This software supports the MIT License, allowing free learning and commercial use, but please retain the terms 'ax,' 'axui,' 'AX,' and 'AXUI' within the software.
|
|
13
13
|
* @license MIT license
|
|
14
14
|
*/
|
|
15
|
-
const getDataType=e=>{let t,r=Object.prototype.toString.call(e).slice(8,-1);return t="Function"===r&&/^\s*class\s+/.test(e.toString())?"Class":"Object"===r&&Object.getPrototypeOf(e)!==Object.prototype?"Instance":r,t},deepClone=(e,t={})=>{const r=getDataType(e),a=Object.assign({cloneSet:!0,cloneMap:!0,cloneObject:!0,cloneArray:!0,cloneDate:!0,cloneRegex:!0},t);if(a.interceptor&&"function"==typeof a.interceptor){let t=a.interceptor(
|
|
15
|
+
const getDataType=e=>{let t,r=Object.prototype.toString.call(e).slice(8,-1);return t="Function"===r&&/^\s*class\s+/.test(e.toString())?"Class":"Object"===r&&Object.getPrototypeOf(e)!==Object.prototype?"Instance":r,t},deepClone=(e,t={})=>{const r=getDataType(e),a=Object.assign({cloneSet:!0,cloneMap:!0,cloneObject:!0,cloneArray:!0,cloneDate:!0,cloneRegex:!0},t);if(a.interceptor&&"function"==typeof a.interceptor){let t=a.interceptor({input:e,type:r,parent:a.parent});if(t)return t}a.onBeforeClone?.({input:e,type:r,parent:a.parent});let o,n=!0;if("Object"===r&&a.cloneObject){const t={},r=Object.getOwnPropertySymbols(e);for(const r in e)t[r]=deepClone(e[r],a);if(r.length>0)for(const o of r)t[o]=deepClone(e[o],{...a,parent:e});o=t}else if("Array"===r&&a.cloneArray)o=e.map(t=>deepClone(t,{...a,parent:e}));else if("Map"===r&&a.cloneMap){const t=new Map;for(const[r,o]of e)t.set(deepClone(r,a),deepClone(o,{...a,parent:e}));o=t}else if("Set"===r&&a.cloneSet){const t=new Set;for(const r of e)t.add(deepClone(r,{...a,parent:e}));o=t}else if("Date"===r&&a.cloneDate)o=new Date(e.getTime());else if("RegExp"===r&&a.cloneRegex){const t=e;o=new RegExp(t.source,t.flags)}else o=e,n=!1;return a.onAfterClone?.({output:o,input:e,type:r,cloned:n,parent:a.parent}),o},deepCloneToJSON=e=>{const t=getDataType(e);if("Object"===t){const t={};for(const r in e)t[r]=deepCloneToJSON(e[r]);for(const e in t)void 0===t[e]&&Reflect.deleteProperty(t,e);return t}if("Array"===t){return e.map((e,t)=>deepCloneToJSON(e)).filter(e=>void 0!==e)}return["Number","String","Boolean","Null"].includes(t)?e:void 0},arrayMutableMethods=["push","pop","shift","unshift","splice","sort","reverse","copyWithin","fill"],wrapArrayMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a,props:o={}})=>{if(!Array.isArray(e))throw new TypeError("The 'target' parameter must be an array.");a&&!a?.length||(a=arrayMutableMethods);const n={};for(let s of a)n[s]=function(...a){const n={},l=e.length;switch(s){case"push":case"unshift":n.addedItems=[...a];break;case"pop":n.poppedItem=e[l-1];break;case"shift":n.shiftedItem=e[0];break;case"splice":const[t,r]=a,o=t<0?Math.max(l+t,0):Math.min(t,l),s=void 0===r?l-o:r;n.deletedItems=e.slice(o,o+s);break;case"sort":case"reverse":n.oldSnapshot=[...e];break;case"fill":case"copyWithin":const p=a[1]||0,i=void 0===a[2]?l:a[2];n.oldItems=e.slice(p,i),n.start=p,n.end=i}t?.(n);const p=Array.prototype[s].apply(e,a),i={value:p,key:s,args:a,context:n,target:e,...o};return r?.(i),p};return n},requireTypes=(e,t,r)=>{let a=Array.isArray(t)?t:[t],o=getDataType(e),n=o.toLowerCase(),s=a.map(e=>e.toLowerCase()),l=n.includes("html")?"element":n;if(r)try{if(!s.includes(l))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${l}`)}catch(e){r(e,o)}else if(!s.includes(l))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${l}`);return o},getUniqueId=(e={})=>{const t=e.prefix,r=e.suffix,a=e.base10,o=e.base36;return`${t?t+"-":""}${Date.now()}${o?"-"+Math.random().toString(36).substring(2,11):""}${a?"-"+Math.floor(1e4*Math.random()).toString().padStart(4,"0"):""}${r?"-"+r:""}`},setMutableMethods=["add","delete","clear"],mapMutableMethods=["set","delete","clear"],wrapSetMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a=setMutableMethods,props:o={}})=>{if(!(e instanceof Set))throw new TypeError("The 'target' parameter must be a Set.");const n={},createWrappedMethod=a=>function(...n){const s={};switch(a){case"add":{const[t]=n;s.addedItem=t,s.existed=e.has(t);break}case"delete":{const[t]=n;s.existed=e.has(t),s.deletedItem=s.existed?t:void 0;break}case"clear":s.clearedItems=Array.from(e),s.previousSize=e.size}t(s);const l=e[a].apply(e,n),p={method:a,result:l,args:n,context:s,target:e,...o};return r(p),l};for(const e of a)setMutableMethods.includes(e)&&(n[e]=createWrappedMethod(e));return Object.defineProperty(n,"target",{get:()=>e,enumerable:!1,configurable:!1}),n},wrapMapMethods=({target:e,onBeforeMutate:t=()=>{},onAfterMutate:r=()=>{},allowList:a=mapMutableMethods,props:o={}})=>{if(!(e instanceof Map))throw new TypeError("The 'target' parameter must be a Map.");const n={},createWrappedMethod=a=>function(...n){const s={};switch(a){case"set":{const[t,r]=n;s.key=t,s.newValue=r,s.existed=e.has(t),s.oldValue=s.existed?e.get(t):void 0;break}case"delete":{const[t]=n;s.key=t,s.existed=e.has(t),s.value=s.existed?e.get(t):void 0;break}case"clear":s.clearedItems=Array.from(e.entries()),s.previousSize=e.size}t(s);const l=e[a].apply(e,n),p={method:a,result:l,args:n,context:s,target:e,...o};return r(p),l};for(const e of a)mapMutableMethods.includes(e)&&(n[e]=createWrappedMethod(e));return Object.defineProperty(n,"target",{get:()=>e,enumerable:!1,configurable:!1}),n},copyObjectWithSymbol=e=>{if(!e||"object"!=typeof e)return e;const t=e,r=Object.getOwnPropertySymbols(t).reduce((e,r)=>(e[r]=t[r],e),{});return{...t,...r}},shallowCopy=(e,t={})=>{const r=getDataType(e);return"Set"===r?new Set([...e]):"Map"===r?new Map([...e]):Array.isArray(e)?[...e]:"object"===r?copyObjectWithSymbol(e):"Date"===r?new Date(e.getTime()):"RegExp"===r?new RegExp(e.source,e.flags):"Buffer"===r?Buffer.from(e):"ArrayBuffer"===r||ArrayBuffer.isView(e)?e.slice(0):"WeakSet"===r?new WeakSet([...e]):"WeakMap"===r?new WeakMap([...e]):"Error"===r?new Error(e.message):e},deepMerge=(e,t,r={})=>{const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0,useSymbol:!0,deepClone:{},onBeforeMerge:void 0,onAfterMerge:void 0},r),smartMerger=(e,t,a)=>{let o,n,s=getDataType(e),l=getDataType(t),p=!0;if(a.interceptor&&"function"==typeof a.interceptor){let r=a.interceptor({target:e,source:t,targetType:s,sourceType:l,parent:a.parent});if(r){if(null===r?.target||null===r?.source)return r;e=r.target,t=r.source}}return a?.onBeforeMerge?.({target:e,source:t,targetType:s,sourceType:l,parent:a.parent}),"Object"===s&&"Object"===l?(n=deepMergeObjects(e,t,a),o="Object"):"Array"===s&&"Array"===l?(n=deepMergeArrays(e,t,a),o="Array"):"Set"===s&&"Set"===l?(n=deepMergeSets(e,t,a),o="Set"):"Map"===s&&"Map"===l?(n=deepMergeMaps(e,t,a),o="Map"):(p=!1,n=e),a?.onAfterMerge?.({result:n,target:e,source:t,targetType:s,sourceType:l,mergeType:o,parent:r.parent}),{result:n,flag:p,mergeType:o}},mergeEnableObject=(e,t)=>e?.hasOwnProperty("enable")&&"boolean"==typeof t?(e.enable=t,e):t?.hasOwnProperty("enable")&&"boolean"==typeof e?Object.assign({enable:e},t):t,deepMergeObjects=(e,t,r={})=>{let a=getDataType(e),o=getDataType(t);if("Object"!==a||"Object"!==o)return e;const n=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r);let s={};s=n.targetClone?shallowCopy(e):e;for(let e in t)if(t.hasOwnProperty(e)&&s.hasOwnProperty(e)){let a=smartMerger(s[e],t[e],{...r,parent:s});a.flag?a.mergeType?"Object"===a.mergeType&&(s[e]=a.result):s[e]=t[e]:n.useEnable?s[e]=mergeEnableObject(s[e],t[e]):s[e]=t[e]}else t.hasOwnProperty(e)&&!s.hasOwnProperty(e)&&n.inheritMissing&&(s[e]=t[e]);if(n.useSymbol){let e=Object.getOwnPropertySymbols(t);if(e.length)for(let r of e)s[r]=t[r]}return s},deepMergeArrays=(e,t,r={})=>{if(!Array.isArray(e)||!Array.isArray(t))return e;const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1},r),o=a.targetClone?[...e]:e;if("replace"===a.dataMode)for(let e=0;e<t.length&&(a.inheritMissing||!(e>=o.length));e++){smartMerger(o[e],t[e],{...a,parent:o}).flag||(o[e]=t[e])}else"concat"===a.dataMode||(o.length=0),o.push(...t);return o},deepMergeMaps=(e,t,r={})=>{if(!(e instanceof Map&&t instanceof Map))return e;const a=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r),o=a.targetClone?new Map([...e]):e;for(const[e,n]of t.entries())if(o.has(e)){const t=o.get(e),r=n,s=smartMerger(t,r,a);s.flag?"Object"===s.mergeType&&o.set(e,s.result):o.set(e,r)}else r.inheritMissing&&o.set(e,n);return o},deepMergeSets=(e,t,r={})=>{if(!(e instanceof Set&&t instanceof Set))return e;const a=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0},r),o=a.targetClone?new Set(...e):e;if("replace"===a.dataMode){const e=[...o],r=[...t],n=smartMerger(e,r,a);o.clear();for(let e of n.result)o.add(e)}else if("concat"===a.dataMode)for(let e of t)o.add(e);else{o.clear();for(let e of t)o.add(e)}return o};return smartMerger(e,t,a).result},utils={getDataType:getDataType,requireTypes:requireTypes,deepClone:deepClone,deepCloneToJSON:deepCloneToJSON,wrapArrayMethods:wrapArrayMethods,arrayMutableMethods:arrayMutableMethods,setMutableMethods:setMutableMethods,mapMutableMethods:mapMutableMethods,wrapSetMethods:wrapSetMethods,wrapMapMethods:wrapMapMethods,getUniqueId:getUniqueId,deepMerge:deepMerge,shallowCopy:shallowCopy,copyObjectWithSymbol:copyObjectWithSymbol};export{utils as default};
|