@codady/utils 0.0.16 → 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/dist/utils.cjs.js +14 -14
- package/dist/utils.cjs.min.js +3 -3
- package/dist/utils.esm.js +14 -14
- package/dist/utils.esm.min.js +3 -3
- package/dist/utils.umd.js +14 -14
- package/dist/utils.umd.min.js +3 -3
- package/dist.zip +0 -0
- package/package.json +1 -1
- package/src/deepMerge.js +13 -13
- package/src/deepMerge.ts +20 -14
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}
|
|
@@ -527,10 +527,10 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
527
527
|
// Main helper function for recursive merging
|
|
528
528
|
// 递归合并的主辅助函数
|
|
529
529
|
smartMerger = (target, source, options) => {
|
|
530
|
-
let targetType = getDataType(target), sourceType = getDataType(source), flag = true,
|
|
530
|
+
let targetType = getDataType(target), sourceType = getDataType(source), flag = true, mergeType, result;
|
|
531
531
|
// Check interceptor - if it returns a value (not null/undefined), use it directly
|
|
532
532
|
if (options.interceptor && typeof options.interceptor === 'function') {
|
|
533
|
-
let interceptorResult = options.interceptor({ target, source, parent: options.parent });
|
|
533
|
+
let interceptorResult = options.interceptor({ target, source, targetType, sourceType, parent: options.parent });
|
|
534
534
|
if ((interceptorResult ?? false)) {
|
|
535
535
|
//如果不是返回{target,source},那么直接返回interceptorResult
|
|
536
536
|
if (interceptorResult?.target === null || interceptorResult?.source === null) {
|
|
@@ -544,31 +544,31 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
544
544
|
}
|
|
545
545
|
// If interceptor returns null/undefined, continue with normal cloning process
|
|
546
546
|
}
|
|
547
|
-
options?.onBeforeMerge?.({ target, source, parent: options.parent });
|
|
547
|
+
options?.onBeforeMerge?.({ target, source, targetType, sourceType, parent: options.parent });
|
|
548
548
|
// Determine the type and perform appropriate merging
|
|
549
549
|
// 确定类型并执行相应的合并
|
|
550
550
|
if (targetType === 'Object' && sourceType === 'Object') {
|
|
551
551
|
result = deepMergeObjects(target, source, options);
|
|
552
|
-
|
|
552
|
+
mergeType = 'Object';
|
|
553
553
|
}
|
|
554
554
|
else if (targetType === 'Array' && sourceType === 'Array') {
|
|
555
555
|
result = deepMergeArrays(target, source, options);
|
|
556
|
-
|
|
556
|
+
mergeType = 'Array';
|
|
557
557
|
}
|
|
558
558
|
else if (targetType === 'Set' && sourceType === 'Set') {
|
|
559
559
|
result = deepMergeSets(target, source, options);
|
|
560
|
-
|
|
560
|
+
mergeType = 'Set';
|
|
561
561
|
}
|
|
562
562
|
else if (targetType === 'Map' && sourceType === 'Map') {
|
|
563
563
|
result = deepMergeMaps(target, source, options);
|
|
564
|
-
|
|
564
|
+
mergeType = 'Map';
|
|
565
565
|
}
|
|
566
566
|
else {
|
|
567
567
|
flag = false;
|
|
568
568
|
result = target;
|
|
569
569
|
}
|
|
570
|
-
options?.onAfterMerge?.({ result, target, source,
|
|
571
|
-
return { result, flag,
|
|
570
|
+
options?.onAfterMerge?.({ result, target, source, targetType, sourceType, mergeType, parent: opts.parent });
|
|
571
|
+
return { result, flag, mergeType };
|
|
572
572
|
},
|
|
573
573
|
// Special handling for objects with enable property
|
|
574
574
|
// 对具有enable属性的对象进行特殊处理
|
|
@@ -618,8 +618,8 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
618
618
|
}
|
|
619
619
|
else {
|
|
620
620
|
//类型相同
|
|
621
|
-
if (resp.
|
|
622
|
-
if (resp.
|
|
621
|
+
if (resp.mergeType) {
|
|
622
|
+
if (resp.mergeType === 'Object') {
|
|
623
623
|
//如果遇上对象则深度复制
|
|
624
624
|
result[k] = resp.result;
|
|
625
625
|
}
|
|
@@ -699,7 +699,7 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
699
699
|
}
|
|
700
700
|
else {
|
|
701
701
|
// If both target and source are objects, merge them recursively
|
|
702
|
-
resp.
|
|
702
|
+
resp.mergeType === 'Object' && result.set(key, resp.result);
|
|
703
703
|
}
|
|
704
704
|
}
|
|
705
705
|
else {
|
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),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
|
|
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}
|
|
@@ -525,10 +525,10 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
525
525
|
// Main helper function for recursive merging
|
|
526
526
|
// 递归合并的主辅助函数
|
|
527
527
|
smartMerger = (target, source, options) => {
|
|
528
|
-
let targetType = getDataType(target), sourceType = getDataType(source), flag = true,
|
|
528
|
+
let targetType = getDataType(target), sourceType = getDataType(source), flag = true, mergeType, result;
|
|
529
529
|
// Check interceptor - if it returns a value (not null/undefined), use it directly
|
|
530
530
|
if (options.interceptor && typeof options.interceptor === 'function') {
|
|
531
|
-
let interceptorResult = options.interceptor({ target, source, parent: options.parent });
|
|
531
|
+
let interceptorResult = options.interceptor({ target, source, targetType, sourceType, parent: options.parent });
|
|
532
532
|
if ((interceptorResult ?? false)) {
|
|
533
533
|
//如果不是返回{target,source},那么直接返回interceptorResult
|
|
534
534
|
if (interceptorResult?.target === null || interceptorResult?.source === null) {
|
|
@@ -542,31 +542,31 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
542
542
|
}
|
|
543
543
|
// If interceptor returns null/undefined, continue with normal cloning process
|
|
544
544
|
}
|
|
545
|
-
options?.onBeforeMerge?.({ target, source, parent: options.parent });
|
|
545
|
+
options?.onBeforeMerge?.({ target, source, targetType, sourceType, parent: options.parent });
|
|
546
546
|
// Determine the type and perform appropriate merging
|
|
547
547
|
// 确定类型并执行相应的合并
|
|
548
548
|
if (targetType === 'Object' && sourceType === 'Object') {
|
|
549
549
|
result = deepMergeObjects(target, source, options);
|
|
550
|
-
|
|
550
|
+
mergeType = 'Object';
|
|
551
551
|
}
|
|
552
552
|
else if (targetType === 'Array' && sourceType === 'Array') {
|
|
553
553
|
result = deepMergeArrays(target, source, options);
|
|
554
|
-
|
|
554
|
+
mergeType = 'Array';
|
|
555
555
|
}
|
|
556
556
|
else if (targetType === 'Set' && sourceType === 'Set') {
|
|
557
557
|
result = deepMergeSets(target, source, options);
|
|
558
|
-
|
|
558
|
+
mergeType = 'Set';
|
|
559
559
|
}
|
|
560
560
|
else if (targetType === 'Map' && sourceType === 'Map') {
|
|
561
561
|
result = deepMergeMaps(target, source, options);
|
|
562
|
-
|
|
562
|
+
mergeType = 'Map';
|
|
563
563
|
}
|
|
564
564
|
else {
|
|
565
565
|
flag = false;
|
|
566
566
|
result = target;
|
|
567
567
|
}
|
|
568
|
-
options?.onAfterMerge?.({ result, target, source,
|
|
569
|
-
return { result, flag,
|
|
568
|
+
options?.onAfterMerge?.({ result, target, source, targetType, sourceType, mergeType, parent: opts.parent });
|
|
569
|
+
return { result, flag, mergeType };
|
|
570
570
|
},
|
|
571
571
|
// Special handling for objects with enable property
|
|
572
572
|
// 对具有enable属性的对象进行特殊处理
|
|
@@ -616,8 +616,8 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
616
616
|
}
|
|
617
617
|
else {
|
|
618
618
|
//类型相同
|
|
619
|
-
if (resp.
|
|
620
|
-
if (resp.
|
|
619
|
+
if (resp.mergeType) {
|
|
620
|
+
if (resp.mergeType === 'Object') {
|
|
621
621
|
//如果遇上对象则深度复制
|
|
622
622
|
result[k] = resp.result;
|
|
623
623
|
}
|
|
@@ -697,7 +697,7 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
697
697
|
}
|
|
698
698
|
else {
|
|
699
699
|
// If both target and source are objects, merge them recursively
|
|
700
|
-
resp.
|
|
700
|
+
resp.mergeType === 'Object' && result.set(key, resp.result);
|
|
701
701
|
}
|
|
702
702
|
}
|
|
703
703
|
else {
|
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({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
|
|
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};
|
package/dist/utils.umd.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}
|
|
@@ -531,10 +531,10 @@
|
|
|
531
531
|
// Main helper function for recursive merging
|
|
532
532
|
// 递归合并的主辅助函数
|
|
533
533
|
smartMerger = (target, source, options) => {
|
|
534
|
-
let targetType = getDataType(target), sourceType = getDataType(source), flag = true,
|
|
534
|
+
let targetType = getDataType(target), sourceType = getDataType(source), flag = true, mergeType, result;
|
|
535
535
|
// Check interceptor - if it returns a value (not null/undefined), use it directly
|
|
536
536
|
if (options.interceptor && typeof options.interceptor === 'function') {
|
|
537
|
-
let interceptorResult = options.interceptor({ target, source, parent: options.parent });
|
|
537
|
+
let interceptorResult = options.interceptor({ target, source, targetType, sourceType, parent: options.parent });
|
|
538
538
|
if ((interceptorResult ?? false)) {
|
|
539
539
|
//如果不是返回{target,source},那么直接返回interceptorResult
|
|
540
540
|
if (interceptorResult?.target === null || interceptorResult?.source === null) {
|
|
@@ -548,31 +548,31 @@
|
|
|
548
548
|
}
|
|
549
549
|
// If interceptor returns null/undefined, continue with normal cloning process
|
|
550
550
|
}
|
|
551
|
-
options?.onBeforeMerge?.({ target, source, parent: options.parent });
|
|
551
|
+
options?.onBeforeMerge?.({ target, source, targetType, sourceType, parent: options.parent });
|
|
552
552
|
// Determine the type and perform appropriate merging
|
|
553
553
|
// 确定类型并执行相应的合并
|
|
554
554
|
if (targetType === 'Object' && sourceType === 'Object') {
|
|
555
555
|
result = deepMergeObjects(target, source, options);
|
|
556
|
-
|
|
556
|
+
mergeType = 'Object';
|
|
557
557
|
}
|
|
558
558
|
else if (targetType === 'Array' && sourceType === 'Array') {
|
|
559
559
|
result = deepMergeArrays(target, source, options);
|
|
560
|
-
|
|
560
|
+
mergeType = 'Array';
|
|
561
561
|
}
|
|
562
562
|
else if (targetType === 'Set' && sourceType === 'Set') {
|
|
563
563
|
result = deepMergeSets(target, source, options);
|
|
564
|
-
|
|
564
|
+
mergeType = 'Set';
|
|
565
565
|
}
|
|
566
566
|
else if (targetType === 'Map' && sourceType === 'Map') {
|
|
567
567
|
result = deepMergeMaps(target, source, options);
|
|
568
|
-
|
|
568
|
+
mergeType = 'Map';
|
|
569
569
|
}
|
|
570
570
|
else {
|
|
571
571
|
flag = false;
|
|
572
572
|
result = target;
|
|
573
573
|
}
|
|
574
|
-
options?.onAfterMerge?.({ result, target, source,
|
|
575
|
-
return { result, flag,
|
|
574
|
+
options?.onAfterMerge?.({ result, target, source, targetType, sourceType, mergeType, parent: opts.parent });
|
|
575
|
+
return { result, flag, mergeType };
|
|
576
576
|
},
|
|
577
577
|
// Special handling for objects with enable property
|
|
578
578
|
// 对具有enable属性的对象进行特殊处理
|
|
@@ -622,8 +622,8 @@
|
|
|
622
622
|
}
|
|
623
623
|
else {
|
|
624
624
|
//类型相同
|
|
625
|
-
if (resp.
|
|
626
|
-
if (resp.
|
|
625
|
+
if (resp.mergeType) {
|
|
626
|
+
if (resp.mergeType === 'Object') {
|
|
627
627
|
//如果遇上对象则深度复制
|
|
628
628
|
result[k] = resp.result;
|
|
629
629
|
}
|
|
@@ -703,7 +703,7 @@
|
|
|
703
703
|
}
|
|
704
704
|
else {
|
|
705
705
|
// If both target and source are objects, merge them recursively
|
|
706
|
-
resp.
|
|
706
|
+
resp.mergeType === 'Object' && result.set(key, resp.result);
|
|
707
707
|
}
|
|
708
708
|
}
|
|
709
709
|
else {
|
package/dist/utils.umd.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
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).utils=t()}(this,function(){"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),n=Object.assign({cloneSet:!0,cloneMap:!0,cloneObject:!0,cloneArray:!0,cloneDate:!0,cloneRegex:!0},t);if(n.interceptor&&"function"==typeof n.interceptor){let t=n.interceptor({input:e,type:r,parent:n.parent});if(t)return t}n.onBeforeClone?.({input:e,type:r,parent:n.parent});let o,a=!0;if("Object"===r&&n.cloneObject){const t={},r=Object.getOwnPropertySymbols(e);for(const r in e)t[r]=deepClone(e[r],n);if(r.length>0)for(const o of r)t[o]=deepClone(e[o],{...n,parent:e});o=t}else if("Array"===r&&n.cloneArray)o=e.map(t=>deepClone(t,{...n,parent:e}));else if("Map"===r&&n.cloneMap){const t=new Map;for(const[r,o]of e)t.set(deepClone(r,n),deepClone(o,{...n,parent:e}));o=t}else if("Set"===r&&n.cloneSet){const t=new Set;for(const r of e)t.add(deepClone(r,{...n,parent:e}));o=t}else if("Date"===r&&n.cloneDate)o=new Date(e.getTime());else if("RegExp"===r&&n.cloneRegex){const t=e;o=new RegExp(t.source,t.flags)}else o=e,a=!1;return n.onAfterClone?.({output:o,input:e,type:r,cloned:a,parent:n.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},e=["push","pop","shift","unshift","splice","sort","reverse","copyWithin","fill"],t=["add","delete","clear"],r=["set","delete","clear"],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};return{getDataType:getDataType,requireTypes:(e,t,r)=>{let n=Array.isArray(t)?t:[t],o=getDataType(e),a=o.toLowerCase(),s=n.map(e=>e.toLowerCase()),i=a.includes("html")?"element":a;if(r)try{if(!s.includes(i))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${i}`)}catch(e){r(e,o)}else if(!s.includes(i))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${i}`);return o},deepClone:deepClone,deepCloneToJSON:deepCloneToJSON,wrapArrayMethods:({target:t,onBeforeMutate:r=()=>{},onAfterMutate:n=()=>{},allowList:o,props:a={}})=>{if(!Array.isArray(t))throw new TypeError("The 'target' parameter must be an array.");o&&!o?.length||(o=e);const s={};for(let e of o)s[e]=function(...o){const s={},i=t.length;switch(e){case"push":case"unshift":s.addedItems=[...o];break;case"pop":s.poppedItem=t[i-1];break;case"shift":s.shiftedItem=t[0];break;case"splice":const[e,r]=o,n=e<0?Math.max(i+e,0):Math.min(e,i),a=void 0===r?i-n:r;s.deletedItems=t.slice(n,n+a);break;case"sort":case"reverse":s.oldSnapshot=[...t];break;case"fill":case"copyWithin":const c=o[1]||0,l=void 0===o[2]?i:o[2];s.oldItems=t.slice(c,l),s.start=c,s.end=l}r?.(s);const c=Array.prototype[e].apply(t,o),l={value:c,key:e,args:o,context:s,target:t,...a};return n?.(l),c};return s},arrayMutableMethods:e,setMutableMethods:t,mapMutableMethods:r,wrapSetMethods:({target:e,onBeforeMutate:r=()=>{},onAfterMutate:n=()=>{},allowList:o=t,props:a={}})=>{if(!(e instanceof Set))throw new TypeError("The 'target' parameter must be a Set.");const s={},createWrappedMethod=t=>function(...o){const s={};switch(t){case"add":{const[t]=o;s.addedItem=t,s.existed=e.has(t);break}case"delete":{const[t]=o;s.existed=e.has(t),s.deletedItem=s.existed?t:void 0;break}case"clear":s.clearedItems=Array.from(e),s.previousSize=e.size}r(s);const i=e[t].apply(e,o),c={method:t,result:i,args:o,context:s,target:e,...a};return n(c),i};for(const e of o)t.includes(e)&&(s[e]=createWrappedMethod(e));return Object.defineProperty(s,"target",{get:()=>e,enumerable:!1,configurable:!1}),s},wrapMapMethods:({target:e,onBeforeMutate:t=()=>{},onAfterMutate:n=()=>{},allowList:o=r,props:a={}})=>{if(!(e instanceof Map))throw new TypeError("The 'target' parameter must be a Map.");const s={},createWrappedMethod=r=>function(...o){const s={};switch(r){case"set":{const[t,r]=o;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]=o;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 i=e[r].apply(e,o),c={method:r,result:i,args:o,context:s,target:e,...a};return n(c),i};for(const e of o)r.includes(e)&&(s[e]=createWrappedMethod(e));return Object.defineProperty(s,"target",{get:()=>e,enumerable:!1,configurable:!1}),s},getUniqueId:(e={})=>{const t=e.prefix,r=e.suffix,n=e.base10,o=e.base36;return`${t?t+"-":""}${Date.now()}${o?"-"+Math.random().toString(36).substring(2,11):""}${n?"-"+Math.floor(1e4*Math.random()).toString().padStart(4,"0"):""}${r?"-"+r:""}`},deepMerge:(e,t,r={})=>{const n=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0,useSymbol:!0,deepClone:{},onBeforeMerge:void 0,onAfterMerge:void 0},r),smartMerger=(e,t,n)=>{let o,a,s=getDataType(e),i=getDataType(t),c=!0;if(n.interceptor&&"function"==typeof n.interceptor){let r=n.interceptor({target:e,source:t,parent:n.parent});if(r){if(null===r?.target||null===r?.source)return r;e=r.target,t=r.source}}return n?.onBeforeMerge?.({target:e,source:t,parent:n.parent}),"Object"===s&&"Object"===i?(a=deepMergeObjects(e,t,n),o="Object"):"Array"===s&&"Array"===i?(a=deepMergeArrays(e,t,n),o="Array"):"Set"===s&&"Set"===i?(a=deepMergeSets(e,t,n),o="Set"):"Map"===s&&"Map"===i?(a=deepMergeMaps(e,t,n),o="Map"):(c=!1,a=e),n?.onAfterMerge?.({result:a,target:e,source:t,
|
|
15
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).utils=t()}(this,function(){"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),n=Object.assign({cloneSet:!0,cloneMap:!0,cloneObject:!0,cloneArray:!0,cloneDate:!0,cloneRegex:!0},t);if(n.interceptor&&"function"==typeof n.interceptor){let t=n.interceptor({input:e,type:r,parent:n.parent});if(t)return t}n.onBeforeClone?.({input:e,type:r,parent:n.parent});let o,a=!0;if("Object"===r&&n.cloneObject){const t={},r=Object.getOwnPropertySymbols(e);for(const r in e)t[r]=deepClone(e[r],n);if(r.length>0)for(const o of r)t[o]=deepClone(e[o],{...n,parent:e});o=t}else if("Array"===r&&n.cloneArray)o=e.map(t=>deepClone(t,{...n,parent:e}));else if("Map"===r&&n.cloneMap){const t=new Map;for(const[r,o]of e)t.set(deepClone(r,n),deepClone(o,{...n,parent:e}));o=t}else if("Set"===r&&n.cloneSet){const t=new Set;for(const r of e)t.add(deepClone(r,{...n,parent:e}));o=t}else if("Date"===r&&n.cloneDate)o=new Date(e.getTime());else if("RegExp"===r&&n.cloneRegex){const t=e;o=new RegExp(t.source,t.flags)}else o=e,a=!1;return n.onAfterClone?.({output:o,input:e,type:r,cloned:a,parent:n.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},e=["push","pop","shift","unshift","splice","sort","reverse","copyWithin","fill"],t=["add","delete","clear"],r=["set","delete","clear"],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};return{getDataType:getDataType,requireTypes:(e,t,r)=>{let n=Array.isArray(t)?t:[t],o=getDataType(e),a=o.toLowerCase(),s=n.map(e=>e.toLowerCase()),i=a.includes("html")?"element":a;if(r)try{if(!s.includes(i))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${i}`)}catch(e){r(e,o)}else if(!s.includes(i))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${i}`);return o},deepClone:deepClone,deepCloneToJSON:deepCloneToJSON,wrapArrayMethods:({target:t,onBeforeMutate:r=()=>{},onAfterMutate:n=()=>{},allowList:o,props:a={}})=>{if(!Array.isArray(t))throw new TypeError("The 'target' parameter must be an array.");o&&!o?.length||(o=e);const s={};for(let e of o)s[e]=function(...o){const s={},i=t.length;switch(e){case"push":case"unshift":s.addedItems=[...o];break;case"pop":s.poppedItem=t[i-1];break;case"shift":s.shiftedItem=t[0];break;case"splice":const[e,r]=o,n=e<0?Math.max(i+e,0):Math.min(e,i),a=void 0===r?i-n:r;s.deletedItems=t.slice(n,n+a);break;case"sort":case"reverse":s.oldSnapshot=[...t];break;case"fill":case"copyWithin":const c=o[1]||0,l=void 0===o[2]?i:o[2];s.oldItems=t.slice(c,l),s.start=c,s.end=l}r?.(s);const c=Array.prototype[e].apply(t,o),l={value:c,key:e,args:o,context:s,target:t,...a};return n?.(l),c};return s},arrayMutableMethods:e,setMutableMethods:t,mapMutableMethods:r,wrapSetMethods:({target:e,onBeforeMutate:r=()=>{},onAfterMutate:n=()=>{},allowList:o=t,props:a={}})=>{if(!(e instanceof Set))throw new TypeError("The 'target' parameter must be a Set.");const s={},createWrappedMethod=t=>function(...o){const s={};switch(t){case"add":{const[t]=o;s.addedItem=t,s.existed=e.has(t);break}case"delete":{const[t]=o;s.existed=e.has(t),s.deletedItem=s.existed?t:void 0;break}case"clear":s.clearedItems=Array.from(e),s.previousSize=e.size}r(s);const i=e[t].apply(e,o),c={method:t,result:i,args:o,context:s,target:e,...a};return n(c),i};for(const e of o)t.includes(e)&&(s[e]=createWrappedMethod(e));return Object.defineProperty(s,"target",{get:()=>e,enumerable:!1,configurable:!1}),s},wrapMapMethods:({target:e,onBeforeMutate:t=()=>{},onAfterMutate:n=()=>{},allowList:o=r,props:a={}})=>{if(!(e instanceof Map))throw new TypeError("The 'target' parameter must be a Map.");const s={},createWrappedMethod=r=>function(...o){const s={};switch(r){case"set":{const[t,r]=o;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]=o;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 i=e[r].apply(e,o),c={method:r,result:i,args:o,context:s,target:e,...a};return n(c),i};for(const e of o)r.includes(e)&&(s[e]=createWrappedMethod(e));return Object.defineProperty(s,"target",{get:()=>e,enumerable:!1,configurable:!1}),s},getUniqueId:(e={})=>{const t=e.prefix,r=e.suffix,n=e.base10,o=e.base36;return`${t?t+"-":""}${Date.now()}${o?"-"+Math.random().toString(36).substring(2,11):""}${n?"-"+Math.floor(1e4*Math.random()).toString().padStart(4,"0"):""}${r?"-"+r:""}`},deepMerge:(e,t,r={})=>{const n=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0,useSymbol:!0,deepClone:{},onBeforeMerge:void 0,onAfterMerge:void 0},r),smartMerger=(e,t,n)=>{let o,a,s=getDataType(e),i=getDataType(t),c=!0;if(n.interceptor&&"function"==typeof n.interceptor){let r=n.interceptor({target:e,source:t,targetType:s,sourceType:i,parent:n.parent});if(r){if(null===r?.target||null===r?.source)return r;e=r.target,t=r.source}}return n?.onBeforeMerge?.({target:e,source:t,targetType:s,sourceType:i,parent:n.parent}),"Object"===s&&"Object"===i?(a=deepMergeObjects(e,t,n),o="Object"):"Array"===s&&"Array"===i?(a=deepMergeArrays(e,t,n),o="Array"):"Set"===s&&"Set"===i?(a=deepMergeSets(e,t,n),o="Set"):"Map"===s&&"Map"===i?(a=deepMergeMaps(e,t,n),o="Map"):(c=!1,a=e),n?.onAfterMerge?.({result:a,target:e,source:t,targetType:s,sourceType:i,mergeType:o,parent:r.parent}),{result:a,flag:c,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 n=getDataType(e),o=getDataType(t);if("Object"!==n||"Object"!==o)return e;const a=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r);let s={};s=a.targetClone?shallowCopy(e):e;for(let e in t)if(t.hasOwnProperty(e)&&s.hasOwnProperty(e)){let n=smartMerger(s[e],t[e],{...r,parent:s});n.flag?n.mergeType?"Object"===n.mergeType&&(s[e]=n.result):s[e]=t[e]:a.useEnable?s[e]=mergeEnableObject(s[e],t[e]):s[e]=t[e]}else t.hasOwnProperty(e)&&!s.hasOwnProperty(e)&&a.inheritMissing&&(s[e]=t[e]);if(a.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 n=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1},r),o=n.targetClone?[...e]:e;if("replace"===n.dataMode)for(let e=0;e<t.length&&(n.inheritMissing||!(e>=o.length));e++){smartMerger(o[e],t[e],{...n,parent:o}).flag||(o[e]=t[e])}else"concat"===n.dataMode||(o.length=0),o.push(...t);return o},deepMergeMaps=(e,t,r={})=>{if(!(e instanceof Map&&t instanceof Map))return e;const n=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r),o=n.targetClone?new Map([...e]):e;for(const[e,a]of t.entries())if(o.has(e)){const t=o.get(e),r=a,s=smartMerger(t,r,n);s.flag?"Object"===s.mergeType&&o.set(e,s.result):o.set(e,r)}else r.inheritMissing&&o.set(e,a);return o},deepMergeSets=(e,t,r={})=>{if(!(e instanceof Set&&t instanceof Set))return e;const n=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0},r),o=n.targetClone?new Set(...e):e;if("replace"===n.dataMode){const e=[...o],r=[...t],a=smartMerger(e,r,n);o.clear();for(let e of a.result)o.add(e)}else if("concat"===n.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,n).result},shallowCopy:shallowCopy,copyObjectWithSymbol:copyObjectWithSymbol}});
|
package/dist.zip
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codady/utils",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.17",
|
|
4
4
|
"author": "AXUI Development Team",
|
|
5
5
|
"license": "MIT",
|
|
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.",
|
package/src/deepMerge.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @since Last modified: 2025/12/26
|
|
2
|
+
* @since Last modified: 2025/12/26 16:03:37
|
|
3
3
|
* @function deepMerge
|
|
4
4
|
* @description Deeply merges two data structures (Object, Array, Map, or Set) based on their types.
|
|
5
5
|
* This function recursively merges the properties or items of the target and source, depending on their types.
|
|
@@ -70,10 +70,10 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
70
70
|
// Main helper function for recursive merging
|
|
71
71
|
// 递归合并的主辅助函数
|
|
72
72
|
smartMerger = (target, source, options) => {
|
|
73
|
-
let targetType = getDataType(target), sourceType = getDataType(source), flag = true,
|
|
73
|
+
let targetType = getDataType(target), sourceType = getDataType(source), flag = true, mergeType, result;
|
|
74
74
|
// Check interceptor - if it returns a value (not null/undefined), use it directly
|
|
75
75
|
if (options.interceptor && typeof options.interceptor === 'function') {
|
|
76
|
-
let interceptorResult = options.interceptor({ target, source, parent: options.parent });
|
|
76
|
+
let interceptorResult = options.interceptor({ target, source, targetType, sourceType, parent: options.parent });
|
|
77
77
|
if ((interceptorResult ?? false)) {
|
|
78
78
|
//如果不是返回{target,source},那么直接返回interceptorResult
|
|
79
79
|
if (interceptorResult?.target === null || interceptorResult?.source === null) {
|
|
@@ -87,31 +87,31 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
87
87
|
}
|
|
88
88
|
// If interceptor returns null/undefined, continue with normal cloning process
|
|
89
89
|
}
|
|
90
|
-
options?.onBeforeMerge?.({ target, source, parent: options.parent });
|
|
90
|
+
options?.onBeforeMerge?.({ target, source, targetType, sourceType, parent: options.parent });
|
|
91
91
|
// Determine the type and perform appropriate merging
|
|
92
92
|
// 确定类型并执行相应的合并
|
|
93
93
|
if (targetType === 'Object' && sourceType === 'Object') {
|
|
94
94
|
result = deepMergeObjects(target, source, options);
|
|
95
|
-
|
|
95
|
+
mergeType = 'Object';
|
|
96
96
|
}
|
|
97
97
|
else if (targetType === 'Array' && sourceType === 'Array') {
|
|
98
98
|
result = deepMergeArrays(target, source, options);
|
|
99
|
-
|
|
99
|
+
mergeType = 'Array';
|
|
100
100
|
}
|
|
101
101
|
else if (targetType === 'Set' && sourceType === 'Set') {
|
|
102
102
|
result = deepMergeSets(target, source, options);
|
|
103
|
-
|
|
103
|
+
mergeType = 'Set';
|
|
104
104
|
}
|
|
105
105
|
else if (targetType === 'Map' && sourceType === 'Map') {
|
|
106
106
|
result = deepMergeMaps(target, source, options);
|
|
107
|
-
|
|
107
|
+
mergeType = 'Map';
|
|
108
108
|
}
|
|
109
109
|
else {
|
|
110
110
|
flag = false;
|
|
111
111
|
result = target;
|
|
112
112
|
}
|
|
113
|
-
options?.onAfterMerge?.({ result, target, source,
|
|
114
|
-
return { result, flag,
|
|
113
|
+
options?.onAfterMerge?.({ result, target, source, targetType, sourceType, mergeType, parent: opts.parent });
|
|
114
|
+
return { result, flag, mergeType };
|
|
115
115
|
},
|
|
116
116
|
// Special handling for objects with enable property
|
|
117
117
|
// 对具有enable属性的对象进行特殊处理
|
|
@@ -161,8 +161,8 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
161
161
|
}
|
|
162
162
|
else {
|
|
163
163
|
//类型相同
|
|
164
|
-
if (resp.
|
|
165
|
-
if (resp.
|
|
164
|
+
if (resp.mergeType) {
|
|
165
|
+
if (resp.mergeType === 'Object') {
|
|
166
166
|
//如果遇上对象则深度复制
|
|
167
167
|
result[k] = resp.result;
|
|
168
168
|
}
|
|
@@ -242,7 +242,7 @@ const deepMerge = (target, source, opts = {}) => {
|
|
|
242
242
|
}
|
|
243
243
|
else {
|
|
244
244
|
// If both target and source are objects, merge them recursively
|
|
245
|
-
resp.
|
|
245
|
+
resp.mergeType === 'Object' && result.set(key, resp.result);
|
|
246
246
|
}
|
|
247
247
|
}
|
|
248
248
|
else {
|
package/src/deepMerge.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @since Last modified: 2025/12/26
|
|
2
|
+
* @since Last modified: 2025/12/26 16:03:37
|
|
3
3
|
* @function deepMerge
|
|
4
4
|
* @description Deeply merges two data structures (Object, Array, Map, or Set) based on their types.
|
|
5
5
|
* This function recursively merges the properties or items of the target and source, depending on their types.
|
|
@@ -67,6 +67,8 @@ export interface DeepMergeOptions {
|
|
|
67
67
|
target: any;
|
|
68
68
|
source: any;
|
|
69
69
|
parent?: any;
|
|
70
|
+
targetType: string;
|
|
71
|
+
sourceType: string;
|
|
70
72
|
}) => any;
|
|
71
73
|
|
|
72
74
|
/**
|
|
@@ -77,6 +79,8 @@ export interface DeepMergeOptions {
|
|
|
77
79
|
target: any;
|
|
78
80
|
source: any;
|
|
79
81
|
parent?: any;
|
|
82
|
+
targetType: string;
|
|
83
|
+
sourceType: string;
|
|
80
84
|
}) => void;
|
|
81
85
|
|
|
82
86
|
/**
|
|
@@ -88,7 +92,9 @@ export interface DeepMergeOptions {
|
|
|
88
92
|
target: any;
|
|
89
93
|
source: any;
|
|
90
94
|
parent?: any;
|
|
91
|
-
|
|
95
|
+
targetType: string;
|
|
96
|
+
sourceType: string;
|
|
97
|
+
mergeType?: '' | 'Object' | 'Array' | 'Map' | 'Set';
|
|
92
98
|
}) => void;
|
|
93
99
|
|
|
94
100
|
/**
|
|
@@ -148,12 +154,12 @@ const deepMerge = (target: Object | Array<any> | Map<any, any> | Set<any>, sourc
|
|
|
148
154
|
let targetType = getDataType(target),
|
|
149
155
|
sourceType = getDataType(source),
|
|
150
156
|
flag = true,
|
|
151
|
-
|
|
157
|
+
mergeType: any,
|
|
152
158
|
result;
|
|
153
159
|
|
|
154
160
|
// Check interceptor - if it returns a value (not null/undefined), use it directly
|
|
155
161
|
if (options.interceptor && typeof options.interceptor === 'function') {
|
|
156
|
-
let interceptorResult = options.interceptor({ target, source, parent: options.parent });
|
|
162
|
+
let interceptorResult = options.interceptor({ target, source, targetType, sourceType, parent: options.parent });
|
|
157
163
|
if ((interceptorResult ?? false)) {
|
|
158
164
|
//如果不是返回{target,source},那么直接返回interceptorResult
|
|
159
165
|
if (interceptorResult?.target === null || interceptorResult?.source === null) {
|
|
@@ -167,28 +173,28 @@ const deepMerge = (target: Object | Array<any> | Map<any, any> | Set<any>, sourc
|
|
|
167
173
|
// If interceptor returns null/undefined, continue with normal cloning process
|
|
168
174
|
}
|
|
169
175
|
|
|
170
|
-
options?.onBeforeMerge?.({ target, source, parent: options.parent });
|
|
176
|
+
options?.onBeforeMerge?.({ target, source, targetType, sourceType, parent: options.parent });
|
|
171
177
|
|
|
172
178
|
// Determine the type and perform appropriate merging
|
|
173
179
|
// 确定类型并执行相应的合并
|
|
174
180
|
if (targetType === 'Object' && sourceType === 'Object') {
|
|
175
181
|
result = deepMergeObjects(target, source, options);
|
|
176
|
-
|
|
182
|
+
mergeType = 'Object';
|
|
177
183
|
} else if (targetType === 'Array' && sourceType === 'Array') {
|
|
178
184
|
result = deepMergeArrays(target, source, options);
|
|
179
|
-
|
|
185
|
+
mergeType = 'Array';
|
|
180
186
|
} else if (targetType === 'Set' && sourceType === 'Set') {
|
|
181
187
|
result = deepMergeSets(target, source, options);
|
|
182
|
-
|
|
188
|
+
mergeType = 'Set';
|
|
183
189
|
} else if (targetType === 'Map' && sourceType === 'Map') {
|
|
184
190
|
result = deepMergeMaps(target, source, options);
|
|
185
|
-
|
|
191
|
+
mergeType = 'Map';
|
|
186
192
|
} else {
|
|
187
193
|
flag = false;
|
|
188
194
|
result = target;
|
|
189
195
|
}
|
|
190
|
-
options?.onAfterMerge?.({ result, target, source,
|
|
191
|
-
return { result, flag,
|
|
196
|
+
options?.onAfterMerge?.({ result, target, source, targetType, sourceType, mergeType, parent: opts.parent });
|
|
197
|
+
return { result, flag, mergeType };
|
|
192
198
|
},
|
|
193
199
|
// Special handling for objects with enable property
|
|
194
200
|
// 对具有enable属性的对象进行特殊处理
|
|
@@ -239,8 +245,8 @@ const deepMerge = (target: Object | Array<any> | Map<any, any> | Set<any>, sourc
|
|
|
239
245
|
}
|
|
240
246
|
} else {
|
|
241
247
|
//类型相同
|
|
242
|
-
if (resp.
|
|
243
|
-
if (resp.
|
|
248
|
+
if (resp.mergeType) {
|
|
249
|
+
if (resp.mergeType === 'Object') {
|
|
244
250
|
//如果遇上对象则深度复制
|
|
245
251
|
(result as any)[k] = resp.result;
|
|
246
252
|
}
|
|
@@ -322,7 +328,7 @@ const deepMerge = (target: Object | Array<any> | Map<any, any> | Set<any>, sourc
|
|
|
322
328
|
result.set(key, _source);
|
|
323
329
|
} else {
|
|
324
330
|
// If both target and source are objects, merge them recursively
|
|
325
|
-
resp.
|
|
331
|
+
resp.mergeType === 'Object' && result.set(key, resp.result);
|
|
326
332
|
}
|
|
327
333
|
} else {
|
|
328
334
|
// If the key doesn't exist in the target, add the entry from the source Map
|