@codady/utils 0.0.14 → 0.0.16

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 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 9:45:49
3
+ * @since Last modified: 2025-12-26 15:47:37
4
4
  * @name Utils for web front-end.
5
- * @version 0.0.14
5
+ * @version 0.0.16
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
- opts.onAfterClone?.({
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
@@ -84,8 +78,6 @@ const deepClone = (data, options = {}) => {
84
78
  let newData, cloned = true;
85
79
  if (dataType === 'Object' && opts.cloneObject) {
86
80
  const newObj = {}, symbols = Object.getOwnPropertySymbols(data);
87
- //存储parent对象,在下一次深复制时使用
88
- opts.parent = data;
89
81
  // Clone regular properties
90
82
  for (const key in data) {
91
83
  //临时保存父对象
@@ -94,30 +86,27 @@ const deepClone = (data, options = {}) => {
94
86
  // Clone Symbol properties
95
87
  if (symbols.length > 0) {
96
88
  for (const symbol of symbols) {
97
- newObj[symbol] = deepClone(data[symbol], opts);
89
+ newObj[symbol] = deepClone(data[symbol], { ...opts, parent: data });
98
90
  }
99
91
  }
100
92
  newData = newObj;
101
93
  }
102
94
  else if (dataType === 'Array' && opts.cloneArray) {
103
- opts.parent = data;
104
- newData = data.map(item => deepClone(item, opts));
95
+ newData = data.map(item => deepClone(item, { ...opts, parent: data }));
105
96
  }
106
97
  else if (dataType === 'Map' && opts.cloneMap) {
107
98
  const newMap = new Map();
108
- opts.parent = data;
109
99
  for (const [key, value] of data) {
110
100
  // Both Map keys and values need deep cloning
111
- newMap.set(deepClone(key, opts), deepClone(value, opts));
101
+ newMap.set(deepClone(key, opts), deepClone(value, { ...opts, parent: data }));
112
102
  }
113
103
  newData = newMap;
114
104
  }
115
105
  else if (dataType === 'Set' && opts.cloneSet) {
116
106
  const newSet = new Set();
117
- opts.parent = data;
118
107
  for (const value of data) {
119
108
  // Set values need deep cloning
120
- newSet.add(deepClone(value, opts));
109
+ newSet.add(deepClone(value, { ...opts, parent: data }));
121
110
  }
122
111
  newData = newSet;
123
112
  }
@@ -537,8 +526,25 @@ const deepMerge = (target, source, opts = {}) => {
537
526
  }, opts),
538
527
  // Main helper function for recursive merging
539
528
  // 递归合并的主辅助函数
540
- deepMergeHelper = (target, source, options) => {
529
+ smartMerger = (target, source, options) => {
541
530
  let targetType = getDataType(target), sourceType = getDataType(source), flag = true, type, 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, 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, parent: options.parent });
542
548
  // Determine the type and perform appropriate merging
543
549
  // 确定类型并执行相应的合并
544
550
  if (targetType === 'Object' && sourceType === 'Object') {
@@ -561,6 +567,7 @@ const deepMerge = (target, source, opts = {}) => {
561
567
  flag = false;
562
568
  result = target;
563
569
  }
570
+ options?.onAfterMerge?.({ result, target, source, type, parent: opts.parent });
564
571
  return { result, flag, type };
565
572
  },
566
573
  // Special handling for objects with enable property
@@ -589,7 +596,6 @@ const deepMerge = (target, source, opts = {}) => {
589
596
  if (targetType !== 'Object' || sourceType !== 'Object') {
590
597
  return target;
591
598
  }
592
- opts?.onBeforeMerge?.(target, source);
593
599
  const options = Object.assign({ inheritMissing: true, targetClone: false, useEnable: true }, opts);
594
600
  let result = {};
595
601
  // If cloning is enabled, clone the target first
@@ -597,7 +603,7 @@ const deepMerge = (target, source, opts = {}) => {
597
603
  result = options.targetClone ? shallowCopy(target) : target;
598
604
  for (let k in source) {
599
605
  if (source.hasOwnProperty(k) && result.hasOwnProperty(k)) {
600
- let resp = deepMergeHelper(result[k], source[k], opts);
606
+ let resp = smartMerger(result[k], source[k], { ...opts, parent: result });
601
607
  //resp={result,flag,type}
602
608
  //flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
603
609
  if (!resp.flag) {
@@ -637,13 +643,11 @@ const deepMerge = (target, source, opts = {}) => {
637
643
  result[k] = source[k];
638
644
  }
639
645
  }
640
- options?.onAfterMerge?.(result, target, source);
641
646
  return result;
642
647
  }, deepMergeArrays = (target, source, options = {}) => {
643
648
  // Ensure both target and source are arrays
644
649
  if (!Array.isArray(target) || !Array.isArray(source))
645
650
  return target;
646
- options?.onBeforeMerge?.(target, source);
647
651
  // Merge options, with default values
648
652
  const opts = Object.assign({ dataMode: 'clear', inheritMissing: true, targetClone: false }, options),
649
653
  // If cloning is enabled, create a deep copy of the target array
@@ -656,7 +660,7 @@ const deepMerge = (target, source, opts = {}) => {
656
660
  // 如果不允许添加超过长度
657
661
  if (!opts.inheritMissing && i >= result.length)
658
662
  break;
659
- let resp = deepMergeHelper(result[i], source[i], opts);
663
+ let resp = smartMerger(result[i], source[i], { ...opts, parent: result });
660
664
  //resp={result,flag,type}
661
665
  //flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
662
666
  if (!resp.flag) {
@@ -673,13 +677,11 @@ const deepMerge = (target, source, opts = {}) => {
673
677
  result.length = 0;
674
678
  result.push(...source);
675
679
  }
676
- options?.onAfterMerge?.(result, target, source);
677
680
  return result;
678
681
  }, deepMergeMaps = (target, source, options = {}) => {
679
682
  // Ensure both target and source are Maps
680
683
  if (!(target instanceof Map) || !(source instanceof Map))
681
684
  return target;
682
- options?.onBeforeMerge?.(target, source);
683
685
  // Merge options, with default values
684
686
  const opts = Object.assign({ inheritMissing: true, targetClone: false, useEnable: true }, options),
685
687
  // If cloning is enabled, create a deep copy of the target Map
@@ -688,7 +690,7 @@ const deepMerge = (target, source, opts = {}) => {
688
690
  for (const [key, value] of source.entries())
689
691
  // Check if the key already exists in the target Map
690
692
  if (result.has(key)) {
691
- const _target = result.get(key), _source = value, resp = deepMergeHelper(_target, _source, opts);
693
+ const _target = result.get(key), _source = value, resp = smartMerger(_target, _source, opts);
692
694
  //resp={result,flag,type}
693
695
  //flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
694
696
  if (!resp.flag) {
@@ -704,13 +706,11 @@ const deepMerge = (target, source, opts = {}) => {
704
706
  // If the key doesn't exist in the target, add the entry from the source Map
705
707
  options.inheritMissing && result.set(key, value);
706
708
  }
707
- options?.onAfterMerge?.(result, target, source);
708
709
  return result;
709
710
  }, deepMergeSets = (target, source, options = {}) => {
710
711
  // Ensure both target and source are Sets
711
712
  if (!(target instanceof Set) || !(source instanceof Set))
712
713
  return target;
713
- options?.onBeforeMerge?.(target, source);
714
714
  // Merge options, with default values
715
715
  const opts = Object.assign({ dataMode: 'clear', inheritMissing: true, targetClone: false, useEnable: true }, options),
716
716
  // If cloning is enabled, create a deep copy of the target Set
@@ -718,7 +718,7 @@ const deepMerge = (target, source, opts = {}) => {
718
718
  // Handle different merge strategies based on dataMode
719
719
  if (opts.dataMode === 'replace') {
720
720
  // Replace mode: recursively merge items in the Sets
721
- const _result = [...result], _source = [...source], resp = deepMergeHelper(_result, _source, opts);
721
+ const _result = [...result], _source = [...source], resp = smartMerger(_result, _source, opts);
722
722
  result.clear();
723
723
  for (let item of resp.result)
724
724
  result.add(item);
@@ -734,10 +734,9 @@ const deepMerge = (target, source, opts = {}) => {
734
734
  for (let item of source)
735
735
  result.add(item);
736
736
  }
737
- options?.onAfterMerge?.(result, target, source);
738
737
  return result;
739
738
  };
740
- return deepMergeHelper(target, source, options).result;
739
+ return smartMerger(target, source, options).result;
741
740
  };
742
741
 
743
742
  const utils = {
@@ -1,7 +1,7 @@
1
1
  /*!
2
- * @since Last modified: 2025-12-26 9:45:49
2
+ * @since Last modified: 2025-12-26 15:47:37
3
3
  * @name Utils for web front-end.
4
- * @version 0.0.14
4
+ * @version 0.0.16
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),o=Object.assign({cloneSet:!0,cloneMap:!0,cloneObject:!0,cloneArray:!0,cloneDate:!0,cloneRegex:!0},t);if(o.interceptor&&"function"==typeof o.interceptor){let t=o.interceptor(e,r);if(t)return o.onAfterClone?.({output:t,input:e,type:r,cloned:t!==e,parent:o.parent}),t}o.onBeforeClone?.({input:e,type:r,parent:o.parent});let a,n=!0;if("Object"===r&&o.cloneObject){const t={},r=Object.getOwnPropertySymbols(e);o.parent=e;for(const r in e)t[r]=deepClone(e[r],o);if(r.length>0)for(const a of r)t[a]=deepClone(e[a],o);a=t}else if("Array"===r&&o.cloneArray)o.parent=e,a=e.map(e=>deepClone(e,o));else if("Map"===r&&o.cloneMap){const t=new Map;o.parent=e;for(const[r,a]of e)t.set(deepClone(r,o),deepClone(a,o));a=t}else if("Set"===r&&o.cloneSet){const t=new Set;o.parent=e;for(const r of e)t.add(deepClone(r,o));a=t}else if("Date"===r&&o.cloneDate)a=new Date(e.getTime());else if("RegExp"===r&&o.cloneRegex){const t=e;a=new RegExp(t.source,t.flags)}else a=e,n=!1;return o.onAfterClone?.({output:a,input:e,type:r,cloned:n,parent:o.parent}),a},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:o,props:a={}})=>{if(!Array.isArray(e))throw new TypeError("The 'target' parameter must be an array.");o&&!o?.length||(o=arrayMutableMethods);const n={};for(let s of o)n[s]=function(...o){const n={},l=e.length;switch(s){case"push":case"unshift":n.addedItems=[...o];break;case"pop":n.poppedItem=e[l-1];break;case"shift":n.shiftedItem=e[0];break;case"splice":const[t,r]=o,a=t<0?Math.max(l+t,0):Math.min(t,l),s=void 0===r?l-a:r;n.deletedItems=e.slice(a,a+s);break;case"sort":case"reverse":n.oldSnapshot=[...e];break;case"fill":case"copyWithin":const i=o[1]||0,p=void 0===o[2]?l:o[2];n.oldItems=e.slice(i,p),n.start=i,n.end=p}t?.(n);const i=Array.prototype[s].apply(e,o),p={value:i,key:s,args:o,context:n,target:e,...a};return r?.(p),i};return n},requireTypes=(e,t,r)=>{let o=Array.isArray(t)?t:[t],a=getDataType(e),n=a.toLowerCase(),s=o.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,a)}else if(!s.includes(l))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${l}`);return a},getUniqueId=(e={})=>{const t=e.prefix,r=e.suffix,o=e.base10,a=e.base36;return`${t?t+"-":""}${Date.now()}${a?"-"+Math.random().toString(36).substring(2,11):""}${o?"-"+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:o=setMutableMethods,props:a={}})=>{if(!(e instanceof Set))throw new TypeError("The 'target' parameter must be a Set.");const n={},createWrappedMethod=o=>function(...n){const s={};switch(o){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[o].apply(e,n),i={method:o,result:l,args:n,context:s,target:e,...a};return r(i),l};for(const e of o)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:o=mapMutableMethods,props:a={}})=>{if(!(e instanceof Map))throw new TypeError("The 'target' parameter must be a Map.");const n={},createWrappedMethod=o=>function(...n){const s={};switch(o){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[o].apply(e,n),i={method:o,result:l,args:n,context:s,target:e,...a};return r(i),l};for(const e of o)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 o=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0,useSymbol:!0,deepClone:{},onBeforeMerge:void 0,onAfterMerge:void 0},r),deepMergeHelper=(e,t,r)=>{let o,a,n=getDataType(e),s=getDataType(t),l=!0;return"Object"===n&&"Object"===s?(a=deepMergeObjects(e,t,r),o="Object"):"Array"===n&&"Array"===s?(a=deepMergeArrays(e,t,r),o="Array"):"Set"===n&&"Set"===s?(a=deepMergeSets(e,t,r),o="Set"):"Map"===n&&"Map"===s?(a=deepMergeMaps(e,t,r),o="Map"):(l=!1,a=e),{result:a,flag:l,type: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 o=getDataType(e),a=getDataType(t);if("Object"!==o||"Object"!==a)return e;r?.onBeforeMerge?.(e,t);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 o=deepMergeHelper(s[e],t[e],r);o.flag?o.type?"Object"===o.type&&(s[e]=o.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 n?.onAfterMerge?.(s,e,t),s},deepMergeArrays=(e,t,r={})=>{if(!Array.isArray(e)||!Array.isArray(t))return e;r?.onBeforeMerge?.(e,t);const o=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1},r),a=o.targetClone?[...e]:e;if("replace"===o.dataMode)for(let e=0;e<t.length&&(o.inheritMissing||!(e>=a.length));e++){deepMergeHelper(a[e],t[e],o).flag||(a[e]=t[e])}else"concat"===o.dataMode||(a.length=0),a.push(...t);return r?.onAfterMerge?.(a,e,t),a},deepMergeMaps=(e,t,r={})=>{if(!(e instanceof Map&&t instanceof Map))return e;r?.onBeforeMerge?.(e,t);const o=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r),a=o.targetClone?new Map([...e]):e;for(const[e,n]of t.entries())if(a.has(e)){const t=a.get(e),r=n,s=deepMergeHelper(t,r,o);s.flag?"Object"===s.type&&a.set(e,s.result):a.set(e,r)}else r.inheritMissing&&a.set(e,n);return r?.onAfterMerge?.(a,e,t),a},deepMergeSets=(e,t,r={})=>{if(!(e instanceof Set&&t instanceof Set))return e;r?.onBeforeMerge?.(e,t);const o=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0},r),a=o.targetClone?new Set(...e):e;if("replace"===o.dataMode){const e=[...a],r=[...t],n=deepMergeHelper(e,r,o);a.clear();for(let e of n.result)a.add(e)}else if("concat"===o.dataMode)for(let e of t)a.add(e);else{a.clear();for(let e of t)a.add(e)}return r?.onAfterMerge?.(a,e,t),a};return deepMergeHelper(e,t,o).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;
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 i=a[1]||0,p=void 0===a[2]?l:a[2];n.oldItems=e.slice(i,p),n.start=i,n.end=p}t?.(n);const i=Array.prototype[s].apply(e,a),p={value:i,key:s,args:a,context:n,target:e,...o};return r?.(p),i};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),i={method:a,result:l,args:n,context:s,target:e,...o};return r(i),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),i={method:a,result:l,args:n,context:s,target:e,...o};return r(i),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),i=!0;if(a.interceptor&&"function"==typeof a.interceptor){let r=a.interceptor({target:e,source:t,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,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"):(i=!1,n=e),a?.onAfterMerge?.({result:n,target:e,source:t,type:o,parent:r.parent}),{result:n,flag:i,type: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.type?"Object"===a.type&&(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.type&&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 9:45:49
3
+ * @since Last modified: 2025-12-26 15:47:37
4
4
  * @name Utils for web front-end.
5
- * @version 0.0.14
5
+ * @version 0.0.16
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
- opts.onAfterClone?.({
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
@@ -82,8 +76,6 @@ const deepClone = (data, options = {}) => {
82
76
  let newData, cloned = true;
83
77
  if (dataType === 'Object' && opts.cloneObject) {
84
78
  const newObj = {}, symbols = Object.getOwnPropertySymbols(data);
85
- //存储parent对象,在下一次深复制时使用
86
- opts.parent = data;
87
79
  // Clone regular properties
88
80
  for (const key in data) {
89
81
  //临时保存父对象
@@ -92,30 +84,27 @@ const deepClone = (data, options = {}) => {
92
84
  // Clone Symbol properties
93
85
  if (symbols.length > 0) {
94
86
  for (const symbol of symbols) {
95
- newObj[symbol] = deepClone(data[symbol], opts);
87
+ newObj[symbol] = deepClone(data[symbol], { ...opts, parent: data });
96
88
  }
97
89
  }
98
90
  newData = newObj;
99
91
  }
100
92
  else if (dataType === 'Array' && opts.cloneArray) {
101
- opts.parent = data;
102
- newData = data.map(item => deepClone(item, opts));
93
+ newData = data.map(item => deepClone(item, { ...opts, parent: data }));
103
94
  }
104
95
  else if (dataType === 'Map' && opts.cloneMap) {
105
96
  const newMap = new Map();
106
- opts.parent = data;
107
97
  for (const [key, value] of data) {
108
98
  // Both Map keys and values need deep cloning
109
- newMap.set(deepClone(key, opts), deepClone(value, opts));
99
+ newMap.set(deepClone(key, opts), deepClone(value, { ...opts, parent: data }));
110
100
  }
111
101
  newData = newMap;
112
102
  }
113
103
  else if (dataType === 'Set' && opts.cloneSet) {
114
104
  const newSet = new Set();
115
- opts.parent = data;
116
105
  for (const value of data) {
117
106
  // Set values need deep cloning
118
- newSet.add(deepClone(value, opts));
107
+ newSet.add(deepClone(value, { ...opts, parent: data }));
119
108
  }
120
109
  newData = newSet;
121
110
  }
@@ -535,8 +524,25 @@ const deepMerge = (target, source, opts = {}) => {
535
524
  }, opts),
536
525
  // Main helper function for recursive merging
537
526
  // 递归合并的主辅助函数
538
- deepMergeHelper = (target, source, options) => {
527
+ smartMerger = (target, source, options) => {
539
528
  let targetType = getDataType(target), sourceType = getDataType(source), flag = true, type, 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, 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, parent: options.parent });
540
546
  // Determine the type and perform appropriate merging
541
547
  // 确定类型并执行相应的合并
542
548
  if (targetType === 'Object' && sourceType === 'Object') {
@@ -559,6 +565,7 @@ const deepMerge = (target, source, opts = {}) => {
559
565
  flag = false;
560
566
  result = target;
561
567
  }
568
+ options?.onAfterMerge?.({ result, target, source, type, parent: opts.parent });
562
569
  return { result, flag, type };
563
570
  },
564
571
  // Special handling for objects with enable property
@@ -587,7 +594,6 @@ const deepMerge = (target, source, opts = {}) => {
587
594
  if (targetType !== 'Object' || sourceType !== 'Object') {
588
595
  return target;
589
596
  }
590
- opts?.onBeforeMerge?.(target, source);
591
597
  const options = Object.assign({ inheritMissing: true, targetClone: false, useEnable: true }, opts);
592
598
  let result = {};
593
599
  // If cloning is enabled, clone the target first
@@ -595,7 +601,7 @@ const deepMerge = (target, source, opts = {}) => {
595
601
  result = options.targetClone ? shallowCopy(target) : target;
596
602
  for (let k in source) {
597
603
  if (source.hasOwnProperty(k) && result.hasOwnProperty(k)) {
598
- let resp = deepMergeHelper(result[k], source[k], opts);
604
+ let resp = smartMerger(result[k], source[k], { ...opts, parent: result });
599
605
  //resp={result,flag,type}
600
606
  //flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
601
607
  if (!resp.flag) {
@@ -635,13 +641,11 @@ const deepMerge = (target, source, opts = {}) => {
635
641
  result[k] = source[k];
636
642
  }
637
643
  }
638
- options?.onAfterMerge?.(result, target, source);
639
644
  return result;
640
645
  }, deepMergeArrays = (target, source, options = {}) => {
641
646
  // Ensure both target and source are arrays
642
647
  if (!Array.isArray(target) || !Array.isArray(source))
643
648
  return target;
644
- options?.onBeforeMerge?.(target, source);
645
649
  // Merge options, with default values
646
650
  const opts = Object.assign({ dataMode: 'clear', inheritMissing: true, targetClone: false }, options),
647
651
  // If cloning is enabled, create a deep copy of the target array
@@ -654,7 +658,7 @@ const deepMerge = (target, source, opts = {}) => {
654
658
  // 如果不允许添加超过长度
655
659
  if (!opts.inheritMissing && i >= result.length)
656
660
  break;
657
- let resp = deepMergeHelper(result[i], source[i], opts);
661
+ let resp = smartMerger(result[i], source[i], { ...opts, parent: result });
658
662
  //resp={result,flag,type}
659
663
  //flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
660
664
  if (!resp.flag) {
@@ -671,13 +675,11 @@ const deepMerge = (target, source, opts = {}) => {
671
675
  result.length = 0;
672
676
  result.push(...source);
673
677
  }
674
- options?.onAfterMerge?.(result, target, source);
675
678
  return result;
676
679
  }, deepMergeMaps = (target, source, options = {}) => {
677
680
  // Ensure both target and source are Maps
678
681
  if (!(target instanceof Map) || !(source instanceof Map))
679
682
  return target;
680
- options?.onBeforeMerge?.(target, source);
681
683
  // Merge options, with default values
682
684
  const opts = Object.assign({ inheritMissing: true, targetClone: false, useEnable: true }, options),
683
685
  // If cloning is enabled, create a deep copy of the target Map
@@ -686,7 +688,7 @@ const deepMerge = (target, source, opts = {}) => {
686
688
  for (const [key, value] of source.entries())
687
689
  // Check if the key already exists in the target Map
688
690
  if (result.has(key)) {
689
- const _target = result.get(key), _source = value, resp = deepMergeHelper(_target, _source, opts);
691
+ const _target = result.get(key), _source = value, resp = smartMerger(_target, _source, opts);
690
692
  //resp={result,flag,type}
691
693
  //flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
692
694
  if (!resp.flag) {
@@ -702,13 +704,11 @@ const deepMerge = (target, source, opts = {}) => {
702
704
  // If the key doesn't exist in the target, add the entry from the source Map
703
705
  options.inheritMissing && result.set(key, value);
704
706
  }
705
- options?.onAfterMerge?.(result, target, source);
706
707
  return result;
707
708
  }, deepMergeSets = (target, source, options = {}) => {
708
709
  // Ensure both target and source are Sets
709
710
  if (!(target instanceof Set) || !(source instanceof Set))
710
711
  return target;
711
- options?.onBeforeMerge?.(target, source);
712
712
  // Merge options, with default values
713
713
  const opts = Object.assign({ dataMode: 'clear', inheritMissing: true, targetClone: false, useEnable: true }, options),
714
714
  // If cloning is enabled, create a deep copy of the target Set
@@ -716,7 +716,7 @@ const deepMerge = (target, source, opts = {}) => {
716
716
  // Handle different merge strategies based on dataMode
717
717
  if (opts.dataMode === 'replace') {
718
718
  // Replace mode: recursively merge items in the Sets
719
- const _result = [...result], _source = [...source], resp = deepMergeHelper(_result, _source, opts);
719
+ const _result = [...result], _source = [...source], resp = smartMerger(_result, _source, opts);
720
720
  result.clear();
721
721
  for (let item of resp.result)
722
722
  result.add(item);
@@ -732,10 +732,9 @@ const deepMerge = (target, source, opts = {}) => {
732
732
  for (let item of source)
733
733
  result.add(item);
734
734
  }
735
- options?.onAfterMerge?.(result, target, source);
736
735
  return result;
737
736
  };
738
- return deepMergeHelper(target, source, options).result;
737
+ return smartMerger(target, source, options).result;
739
738
  };
740
739
 
741
740
  const utils = {
@@ -1,7 +1,7 @@
1
1
  /*!
2
- * @since Last modified: 2025-12-26 9:45:49
2
+ * @since Last modified: 2025-12-26 15:47:37
3
3
  * @name Utils for web front-end.
4
- * @version 0.0.14
4
+ * @version 0.0.16
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(e,r);if(t)return a.onAfterClone?.({output:t,input:e,type:r,cloned:t!==e,parent:a.parent}),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);a.parent=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);o=t}else if("Array"===r&&a.cloneArray)a.parent=e,o=e.map(e=>deepClone(e,a));else if("Map"===r&&a.cloneMap){const t=new Map;a.parent=e;for(const[r,o]of e)t.set(deepClone(r,a),deepClone(o,a));o=t}else if("Set"===r&&a.cloneSet){const t=new Set;a.parent=e;for(const r of e)t.add(deepClone(r,a));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 i=a[1]||0,p=void 0===a[2]?l:a[2];n.oldItems=e.slice(i,p),n.start=i,n.end=p}t?.(n);const i=Array.prototype[s].apply(e,a),p={value:i,key:s,args:a,context:n,target:e,...o};return r?.(p),i};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),i={method:a,result:l,args:n,context:s,target:e,...o};return r(i),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),i={method:a,result:l,args:n,context:s,target:e,...o};return r(i),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),deepMergeHelper=(e,t,r)=>{let a,o,n=getDataType(e),s=getDataType(t),l=!0;return"Object"===n&&"Object"===s?(o=deepMergeObjects(e,t,r),a="Object"):"Array"===n&&"Array"===s?(o=deepMergeArrays(e,t,r),a="Array"):"Set"===n&&"Set"===s?(o=deepMergeSets(e,t,r),a="Set"):"Map"===n&&"Map"===s?(o=deepMergeMaps(e,t,r),a="Map"):(l=!1,o=e),{result:o,flag:l,type:a}},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;r?.onBeforeMerge?.(e,t);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=deepMergeHelper(s[e],t[e],r);a.flag?a.type?"Object"===a.type&&(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 n?.onAfterMerge?.(s,e,t),s},deepMergeArrays=(e,t,r={})=>{if(!Array.isArray(e)||!Array.isArray(t))return e;r?.onBeforeMerge?.(e,t);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++){deepMergeHelper(o[e],t[e],a).flag||(o[e]=t[e])}else"concat"===a.dataMode||(o.length=0),o.push(...t);return r?.onAfterMerge?.(o,e,t),o},deepMergeMaps=(e,t,r={})=>{if(!(e instanceof Map&&t instanceof Map))return e;r?.onBeforeMerge?.(e,t);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=deepMergeHelper(t,r,a);s.flag?"Object"===s.type&&o.set(e,s.result):o.set(e,r)}else r.inheritMissing&&o.set(e,n);return r?.onAfterMerge?.(o,e,t),o},deepMergeSets=(e,t,r={})=>{if(!(e instanceof Set&&t instanceof Set))return e;r?.onBeforeMerge?.(e,t);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=deepMergeHelper(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 r?.onAfterMerge?.(o,e,t),o};return deepMergeHelper(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};
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 i=a[1]||0,p=void 0===a[2]?l:a[2];n.oldItems=e.slice(i,p),n.start=i,n.end=p}t?.(n);const i=Array.prototype[s].apply(e,a),p={value:i,key:s,args:a,context:n,target:e,...o};return r?.(p),i};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),i={method:a,result:l,args:n,context:s,target:e,...o};return r(i),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),i={method:a,result:l,args:n,context:s,target:e,...o};return r(i),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),i=!0;if(a.interceptor&&"function"==typeof a.interceptor){let r=a.interceptor({target:e,source:t,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,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"):(i=!1,n=e),a?.onAfterMerge?.({result:n,target:e,source:t,type:o,parent:r.parent}),{result:n,flag:i,type: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.type?"Object"===a.type&&(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.type&&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};