@codady/utils 0.0.15 → 0.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md 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 11:26:20
3
+ * @since Last modified: 2025-12-26 16:3:51
4
4
  * @name Utils for web front-end.
5
- * @version 0.0.15
5
+ * @version 0.0.17
6
6
  * @author AXUI development team <3217728223@qq.com>
7
7
  * @description This is a set of general-purpose JavaScript utility functions developed by the AXUI team. All functions are pure and do not involve CSS or other third-party libraries. They are suitable for any web front-end environment.
8
8
  * @see {@link https://www.axui.cn|Official website}
@@ -61,16 +61,10 @@ const deepClone = (data, options = {}) => {
61
61
  }, options);
62
62
  // Check interceptor - if it returns a value (not null/undefined), use it directly
63
63
  if (opts.interceptor && typeof opts.interceptor === 'function') {
64
- let result = opts.interceptor(data, dataType);
64
+ let result = opts.interceptor({ input: data, type: dataType, parent: opts.parent });
65
65
  if ((result ?? false)) {
66
66
  // Call onAfterClone if set
67
- 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
@@ -532,31 +526,49 @@ const deepMerge = (target, source, opts = {}) => {
532
526
  }, opts),
533
527
  // Main helper function for recursive merging
534
528
  // 递归合并的主辅助函数
535
- deepMergeHelper = (target, source, options) => {
536
- let targetType = getDataType(target), sourceType = getDataType(source), flag = true, type, result;
529
+ smartMerger = (target, source, options) => {
530
+ let targetType = getDataType(target), sourceType = getDataType(source), flag = true, mergeType, result;
531
+ // Check interceptor - if it returns a value (not null/undefined), use it directly
532
+ if (options.interceptor && typeof options.interceptor === 'function') {
533
+ let interceptorResult = options.interceptor({ target, source, targetType, sourceType, parent: options.parent });
534
+ if ((interceptorResult ?? false)) {
535
+ //如果不是返回{target,source},那么直接返回interceptorResult
536
+ if (interceptorResult?.target === null || interceptorResult?.source === null) {
537
+ return interceptorResult;
538
+ }
539
+ else {
540
+ //interceptorResult={target,source}
541
+ target = interceptorResult.target;
542
+ source = interceptorResult.source;
543
+ }
544
+ }
545
+ // If interceptor returns null/undefined, continue with normal cloning process
546
+ }
547
+ options?.onBeforeMerge?.({ target, source, targetType, sourceType, parent: options.parent });
537
548
  // Determine the type and perform appropriate merging
538
549
  // 确定类型并执行相应的合并
539
550
  if (targetType === 'Object' && sourceType === 'Object') {
540
551
  result = deepMergeObjects(target, source, options);
541
- type = 'Object';
552
+ mergeType = 'Object';
542
553
  }
543
554
  else if (targetType === 'Array' && sourceType === 'Array') {
544
555
  result = deepMergeArrays(target, source, options);
545
- type = 'Array';
556
+ mergeType = 'Array';
546
557
  }
547
558
  else if (targetType === 'Set' && sourceType === 'Set') {
548
559
  result = deepMergeSets(target, source, options);
549
- type = 'Set';
560
+ mergeType = 'Set';
550
561
  }
551
562
  else if (targetType === 'Map' && sourceType === 'Map') {
552
563
  result = deepMergeMaps(target, source, options);
553
- type = 'Map';
564
+ mergeType = 'Map';
554
565
  }
555
566
  else {
556
567
  flag = false;
557
568
  result = target;
558
569
  }
559
- return { result, flag, type };
570
+ options?.onAfterMerge?.({ result, target, source, targetType, sourceType, mergeType, parent: opts.parent });
571
+ return { result, flag, mergeType };
560
572
  },
561
573
  // Special handling for objects with enable property
562
574
  // 对具有enable属性的对象进行特殊处理
@@ -584,7 +596,6 @@ const deepMerge = (target, source, opts = {}) => {
584
596
  if (targetType !== 'Object' || sourceType !== 'Object') {
585
597
  return target;
586
598
  }
587
- opts?.onBeforeMerge?.(target, source);
588
599
  const options = Object.assign({ inheritMissing: true, targetClone: false, useEnable: true }, opts);
589
600
  let result = {};
590
601
  // If cloning is enabled, clone the target first
@@ -592,7 +603,7 @@ const deepMerge = (target, source, opts = {}) => {
592
603
  result = options.targetClone ? shallowCopy(target) : target;
593
604
  for (let k in source) {
594
605
  if (source.hasOwnProperty(k) && result.hasOwnProperty(k)) {
595
- let resp = deepMergeHelper(result[k], source[k], opts);
606
+ let resp = smartMerger(result[k], source[k], { ...opts, parent: result });
596
607
  //resp={result,flag,type}
597
608
  //flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
598
609
  if (!resp.flag) {
@@ -607,8 +618,8 @@ const deepMerge = (target, source, opts = {}) => {
607
618
  }
608
619
  else {
609
620
  //类型相同
610
- if (resp.type) {
611
- if (resp.type === 'Object') {
621
+ if (resp.mergeType) {
622
+ if (resp.mergeType === 'Object') {
612
623
  //如果遇上对象则深度复制
613
624
  result[k] = resp.result;
614
625
  }
@@ -632,13 +643,11 @@ const deepMerge = (target, source, opts = {}) => {
632
643
  result[k] = source[k];
633
644
  }
634
645
  }
635
- options?.onAfterMerge?.(result, target, source);
636
646
  return result;
637
647
  }, deepMergeArrays = (target, source, options = {}) => {
638
648
  // Ensure both target and source are arrays
639
649
  if (!Array.isArray(target) || !Array.isArray(source))
640
650
  return target;
641
- options?.onBeforeMerge?.(target, source);
642
651
  // Merge options, with default values
643
652
  const opts = Object.assign({ dataMode: 'clear', inheritMissing: true, targetClone: false }, options),
644
653
  // If cloning is enabled, create a deep copy of the target array
@@ -651,7 +660,7 @@ const deepMerge = (target, source, opts = {}) => {
651
660
  // 如果不允许添加超过长度
652
661
  if (!opts.inheritMissing && i >= result.length)
653
662
  break;
654
- let resp = deepMergeHelper(result[i], source[i], opts);
663
+ let resp = smartMerger(result[i], source[i], { ...opts, parent: result });
655
664
  //resp={result,flag,type}
656
665
  //flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
657
666
  if (!resp.flag) {
@@ -668,13 +677,11 @@ const deepMerge = (target, source, opts = {}) => {
668
677
  result.length = 0;
669
678
  result.push(...source);
670
679
  }
671
- options?.onAfterMerge?.(result, target, source);
672
680
  return result;
673
681
  }, deepMergeMaps = (target, source, options = {}) => {
674
682
  // Ensure both target and source are Maps
675
683
  if (!(target instanceof Map) || !(source instanceof Map))
676
684
  return target;
677
- options?.onBeforeMerge?.(target, source);
678
685
  // Merge options, with default values
679
686
  const opts = Object.assign({ inheritMissing: true, targetClone: false, useEnable: true }, options),
680
687
  // If cloning is enabled, create a deep copy of the target Map
@@ -683,7 +690,7 @@ const deepMerge = (target, source, opts = {}) => {
683
690
  for (const [key, value] of source.entries())
684
691
  // Check if the key already exists in the target Map
685
692
  if (result.has(key)) {
686
- const _target = result.get(key), _source = value, resp = deepMergeHelper(_target, _source, opts);
693
+ const _target = result.get(key), _source = value, resp = smartMerger(_target, _source, opts);
687
694
  //resp={result,flag,type}
688
695
  //flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
689
696
  if (!resp.flag) {
@@ -692,20 +699,18 @@ const deepMerge = (target, source, opts = {}) => {
692
699
  }
693
700
  else {
694
701
  // If both target and source are objects, merge them recursively
695
- resp.type === 'Object' && result.set(key, resp.result);
702
+ resp.mergeType === 'Object' && result.set(key, resp.result);
696
703
  }
697
704
  }
698
705
  else {
699
706
  // If the key doesn't exist in the target, add the entry from the source Map
700
707
  options.inheritMissing && result.set(key, value);
701
708
  }
702
- options?.onAfterMerge?.(result, target, source);
703
709
  return result;
704
710
  }, deepMergeSets = (target, source, options = {}) => {
705
711
  // Ensure both target and source are Sets
706
712
  if (!(target instanceof Set) || !(source instanceof Set))
707
713
  return target;
708
- options?.onBeforeMerge?.(target, source);
709
714
  // Merge options, with default values
710
715
  const opts = Object.assign({ dataMode: 'clear', inheritMissing: true, targetClone: false, useEnable: true }, options),
711
716
  // If cloning is enabled, create a deep copy of the target Set
@@ -713,7 +718,7 @@ const deepMerge = (target, source, opts = {}) => {
713
718
  // Handle different merge strategies based on dataMode
714
719
  if (opts.dataMode === 'replace') {
715
720
  // Replace mode: recursively merge items in the Sets
716
- const _result = [...result], _source = [...source], resp = deepMergeHelper(_result, _source, opts);
721
+ const _result = [...result], _source = [...source], resp = smartMerger(_result, _source, opts);
717
722
  result.clear();
718
723
  for (let item of resp.result)
719
724
  result.add(item);
@@ -729,10 +734,9 @@ const deepMerge = (target, source, opts = {}) => {
729
734
  for (let item of source)
730
735
  result.add(item);
731
736
  }
732
- options?.onAfterMerge?.(result, target, source);
733
737
  return result;
734
738
  };
735
- return deepMergeHelper(target, source, options).result;
739
+ return smartMerger(target, source, options).result;
736
740
  };
737
741
 
738
742
  const utils = {
@@ -1,7 +1,7 @@
1
1
  /*!
2
- * @since Last modified: 2025-12-26 11:26:20
2
+ * @since Last modified: 2025-12-26 16:3:51
3
3
  * @name Utils for web front-end.
4
- * @version 0.0.15
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),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);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,parent:e});a=t}else if("Array"===r&&o.cloneArray)a=e.map(t=>deepClone(t,{...o,parent:e}));else if("Map"===r&&o.cloneMap){const t=new Map;for(const[r,a]of e)t.set(deepClone(r,o),deepClone(a,{...o,parent:e}));a=t}else if("Set"===r&&o.cloneSet){const t=new Set;for(const r of e)t.add(deepClone(r,{...o,parent:e}));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 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 11:26:20
3
+ * @since Last modified: 2025-12-26 16:3:51
4
4
  * @name Utils for web front-end.
5
- * @version 0.0.15
5
+ * @version 0.0.17
6
6
  * @author AXUI development team <3217728223@qq.com>
7
7
  * @description This is a set of general-purpose JavaScript utility functions developed by the AXUI team. All functions are pure and do not involve CSS or other third-party libraries. They are suitable for any web front-end environment.
8
8
  * @see {@link https://www.axui.cn|Official website}
@@ -59,16 +59,10 @@ const deepClone = (data, options = {}) => {
59
59
  }, options);
60
60
  // Check interceptor - if it returns a value (not null/undefined), use it directly
61
61
  if (opts.interceptor && typeof opts.interceptor === 'function') {
62
- let result = opts.interceptor(data, dataType);
62
+ let result = opts.interceptor({ input: data, type: dataType, parent: opts.parent });
63
63
  if ((result ?? false)) {
64
64
  // Call onAfterClone if set
65
- 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
@@ -530,31 +524,49 @@ const deepMerge = (target, source, opts = {}) => {
530
524
  }, opts),
531
525
  // Main helper function for recursive merging
532
526
  // 递归合并的主辅助函数
533
- deepMergeHelper = (target, source, options) => {
534
- let targetType = getDataType(target), sourceType = getDataType(source), flag = true, type, result;
527
+ smartMerger = (target, source, options) => {
528
+ let targetType = getDataType(target), sourceType = getDataType(source), flag = true, mergeType, result;
529
+ // Check interceptor - if it returns a value (not null/undefined), use it directly
530
+ if (options.interceptor && typeof options.interceptor === 'function') {
531
+ let interceptorResult = options.interceptor({ target, source, targetType, sourceType, parent: options.parent });
532
+ if ((interceptorResult ?? false)) {
533
+ //如果不是返回{target,source},那么直接返回interceptorResult
534
+ if (interceptorResult?.target === null || interceptorResult?.source === null) {
535
+ return interceptorResult;
536
+ }
537
+ else {
538
+ //interceptorResult={target,source}
539
+ target = interceptorResult.target;
540
+ source = interceptorResult.source;
541
+ }
542
+ }
543
+ // If interceptor returns null/undefined, continue with normal cloning process
544
+ }
545
+ options?.onBeforeMerge?.({ target, source, targetType, sourceType, parent: options.parent });
535
546
  // Determine the type and perform appropriate merging
536
547
  // 确定类型并执行相应的合并
537
548
  if (targetType === 'Object' && sourceType === 'Object') {
538
549
  result = deepMergeObjects(target, source, options);
539
- type = 'Object';
550
+ mergeType = 'Object';
540
551
  }
541
552
  else if (targetType === 'Array' && sourceType === 'Array') {
542
553
  result = deepMergeArrays(target, source, options);
543
- type = 'Array';
554
+ mergeType = 'Array';
544
555
  }
545
556
  else if (targetType === 'Set' && sourceType === 'Set') {
546
557
  result = deepMergeSets(target, source, options);
547
- type = 'Set';
558
+ mergeType = 'Set';
548
559
  }
549
560
  else if (targetType === 'Map' && sourceType === 'Map') {
550
561
  result = deepMergeMaps(target, source, options);
551
- type = 'Map';
562
+ mergeType = 'Map';
552
563
  }
553
564
  else {
554
565
  flag = false;
555
566
  result = target;
556
567
  }
557
- return { result, flag, type };
568
+ options?.onAfterMerge?.({ result, target, source, targetType, sourceType, mergeType, parent: opts.parent });
569
+ return { result, flag, mergeType };
558
570
  },
559
571
  // Special handling for objects with enable property
560
572
  // 对具有enable属性的对象进行特殊处理
@@ -582,7 +594,6 @@ const deepMerge = (target, source, opts = {}) => {
582
594
  if (targetType !== 'Object' || sourceType !== 'Object') {
583
595
  return target;
584
596
  }
585
- opts?.onBeforeMerge?.(target, source);
586
597
  const options = Object.assign({ inheritMissing: true, targetClone: false, useEnable: true }, opts);
587
598
  let result = {};
588
599
  // If cloning is enabled, clone the target first
@@ -590,7 +601,7 @@ const deepMerge = (target, source, opts = {}) => {
590
601
  result = options.targetClone ? shallowCopy(target) : target;
591
602
  for (let k in source) {
592
603
  if (source.hasOwnProperty(k) && result.hasOwnProperty(k)) {
593
- let resp = deepMergeHelper(result[k], source[k], opts);
604
+ let resp = smartMerger(result[k], source[k], { ...opts, parent: result });
594
605
  //resp={result,flag,type}
595
606
  //flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
596
607
  if (!resp.flag) {
@@ -605,8 +616,8 @@ const deepMerge = (target, source, opts = {}) => {
605
616
  }
606
617
  else {
607
618
  //类型相同
608
- if (resp.type) {
609
- if (resp.type === 'Object') {
619
+ if (resp.mergeType) {
620
+ if (resp.mergeType === 'Object') {
610
621
  //如果遇上对象则深度复制
611
622
  result[k] = resp.result;
612
623
  }
@@ -630,13 +641,11 @@ const deepMerge = (target, source, opts = {}) => {
630
641
  result[k] = source[k];
631
642
  }
632
643
  }
633
- options?.onAfterMerge?.(result, target, source);
634
644
  return result;
635
645
  }, deepMergeArrays = (target, source, options = {}) => {
636
646
  // Ensure both target and source are arrays
637
647
  if (!Array.isArray(target) || !Array.isArray(source))
638
648
  return target;
639
- options?.onBeforeMerge?.(target, source);
640
649
  // Merge options, with default values
641
650
  const opts = Object.assign({ dataMode: 'clear', inheritMissing: true, targetClone: false }, options),
642
651
  // If cloning is enabled, create a deep copy of the target array
@@ -649,7 +658,7 @@ const deepMerge = (target, source, opts = {}) => {
649
658
  // 如果不允许添加超过长度
650
659
  if (!opts.inheritMissing && i >= result.length)
651
660
  break;
652
- let resp = deepMergeHelper(result[i], source[i], opts);
661
+ let resp = smartMerger(result[i], source[i], { ...opts, parent: result });
653
662
  //resp={result,flag,type}
654
663
  //flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
655
664
  if (!resp.flag) {
@@ -666,13 +675,11 @@ const deepMerge = (target, source, opts = {}) => {
666
675
  result.length = 0;
667
676
  result.push(...source);
668
677
  }
669
- options?.onAfterMerge?.(result, target, source);
670
678
  return result;
671
679
  }, deepMergeMaps = (target, source, options = {}) => {
672
680
  // Ensure both target and source are Maps
673
681
  if (!(target instanceof Map) || !(source instanceof Map))
674
682
  return target;
675
- options?.onBeforeMerge?.(target, source);
676
683
  // Merge options, with default values
677
684
  const opts = Object.assign({ inheritMissing: true, targetClone: false, useEnable: true }, options),
678
685
  // If cloning is enabled, create a deep copy of the target Map
@@ -681,7 +688,7 @@ const deepMerge = (target, source, opts = {}) => {
681
688
  for (const [key, value] of source.entries())
682
689
  // Check if the key already exists in the target Map
683
690
  if (result.has(key)) {
684
- const _target = result.get(key), _source = value, resp = deepMergeHelper(_target, _source, opts);
691
+ const _target = result.get(key), _source = value, resp = smartMerger(_target, _source, opts);
685
692
  //resp={result,flag,type}
686
693
  //flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
687
694
  if (!resp.flag) {
@@ -690,20 +697,18 @@ const deepMerge = (target, source, opts = {}) => {
690
697
  }
691
698
  else {
692
699
  // If both target and source are objects, merge them recursively
693
- resp.type === 'Object' && result.set(key, resp.result);
700
+ resp.mergeType === 'Object' && result.set(key, resp.result);
694
701
  }
695
702
  }
696
703
  else {
697
704
  // If the key doesn't exist in the target, add the entry from the source Map
698
705
  options.inheritMissing && result.set(key, value);
699
706
  }
700
- options?.onAfterMerge?.(result, target, source);
701
707
  return result;
702
708
  }, deepMergeSets = (target, source, options = {}) => {
703
709
  // Ensure both target and source are Sets
704
710
  if (!(target instanceof Set) || !(source instanceof Set))
705
711
  return target;
706
- options?.onBeforeMerge?.(target, source);
707
712
  // Merge options, with default values
708
713
  const opts = Object.assign({ dataMode: 'clear', inheritMissing: true, targetClone: false, useEnable: true }, options),
709
714
  // If cloning is enabled, create a deep copy of the target Set
@@ -711,7 +716,7 @@ const deepMerge = (target, source, opts = {}) => {
711
716
  // Handle different merge strategies based on dataMode
712
717
  if (opts.dataMode === 'replace') {
713
718
  // Replace mode: recursively merge items in the Sets
714
- const _result = [...result], _source = [...source], resp = deepMergeHelper(_result, _source, opts);
719
+ const _result = [...result], _source = [...source], resp = smartMerger(_result, _source, opts);
715
720
  result.clear();
716
721
  for (let item of resp.result)
717
722
  result.add(item);
@@ -727,10 +732,9 @@ const deepMerge = (target, source, opts = {}) => {
727
732
  for (let item of source)
728
733
  result.add(item);
729
734
  }
730
- options?.onAfterMerge?.(result, target, source);
731
735
  return result;
732
736
  };
733
- return deepMergeHelper(target, source, options).result;
737
+ return smartMerger(target, source, options).result;
734
738
  };
735
739
 
736
740
  const utils = {
@@ -1,7 +1,7 @@
1
1
  /*!
2
- * @since Last modified: 2025-12-26 11:26:20
2
+ * @since Last modified: 2025-12-26 16:3:51
3
3
  * @name Utils for web front-end.
4
- * @version 0.0.15
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(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);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),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 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};