@codady/utils 0.0.12 → 0.0.14

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
@@ -3,6 +3,42 @@
3
3
  All changes to Utils including new features, updates, and removals are documented here.
4
4
 
5
5
 
6
+ ## [v0.0.14] - 2025-12-26
7
+
8
+ ### Distribution Files
9
+ * **JS**: https://unpkg.com/@codady/utils@0.0.14/dist/js/utils.js
10
+ * **Zip**:https://unpkg.com/@codady/utils@0.0.14/dist.zip
11
+
12
+ ### Changes
13
+
14
+ #### Fixed
15
+ * Null
16
+
17
+ #### Added
18
+ * 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,可临时存储被拷贝的父对象。
19
+
20
+ #### Removed
21
+ * Null
22
+
23
+
24
+ ## [v0.0.13] - 2025-12-25
25
+
26
+ ### Distribution Files
27
+ * **JS**: https://unpkg.com/@codady/utils@0.0.13/dist/js/utils.js
28
+ * **Zip**:https://unpkg.com/@codady/utils@0.0.13/dist.zip
29
+
30
+ ### Changes
31
+
32
+ #### Fixed
33
+ * Modify the `shallowCopy` function to add support for data types such as Date, Regex, Error, Buffer, ArrayBuffer, WeakSet, and WeakMap.修改`shallowCopy`函数,增加对Date、Regex、Error、Buffer、ArrayBuffer、WeakSet、WeakMap数据类型的支持。
34
+
35
+ #### Added
36
+ * Added the following functions: `copyObjectWithSymbol`.新增`copyObjectWithSymbol`函数。
37
+
38
+ #### Removed
39
+ * Null
40
+
41
+
6
42
  ## [v0.0.12] - 2025-12-25
7
43
 
8
44
  ### Distribution Files
package/dist/utils.cjs.js CHANGED
@@ -1,8 +1,8 @@
1
1
 
2
2
  /*!
3
- * @since Last modified: 2025-12-25 12:10:38
3
+ * @since Last modified: 2025-12-26 9:45:49
4
4
  * @name Utils for web front-end.
5
- * @version 0.0.12
5
+ * @version 0.0.14
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}
@@ -69,18 +69,26 @@ const deepClone = (data, options = {}) => {
69
69
  input: data,
70
70
  type: dataType,
71
71
  cloned: result !== data,
72
+ parent: opts.parent
72
73
  });
73
74
  return result;
74
75
  }
75
76
  // If interceptor returns null/undefined, continue with normal cloning process
76
77
  }
77
78
  // Callback before cloning
78
- opts.onBeforeClone?.(data, dataType);
79
+ opts.onBeforeClone?.({
80
+ input: data,
81
+ type: dataType,
82
+ parent: opts.parent
83
+ });
79
84
  let newData, cloned = true;
80
85
  if (dataType === 'Object' && opts.cloneObject) {
81
86
  const newObj = {}, symbols = Object.getOwnPropertySymbols(data);
87
+ //存储parent对象,在下一次深复制时使用
88
+ opts.parent = data;
82
89
  // Clone regular properties
83
90
  for (const key in data) {
91
+ //临时保存父对象
84
92
  newObj[key] = deepClone(data[key], opts);
85
93
  }
86
94
  // Clone Symbol properties
@@ -92,10 +100,12 @@ const deepClone = (data, options = {}) => {
92
100
  newData = newObj;
93
101
  }
94
102
  else if (dataType === 'Array' && opts.cloneArray) {
103
+ opts.parent = data;
95
104
  newData = data.map(item => deepClone(item, opts));
96
105
  }
97
106
  else if (dataType === 'Map' && opts.cloneMap) {
98
107
  const newMap = new Map();
108
+ opts.parent = data;
99
109
  for (const [key, value] of data) {
100
110
  // Both Map keys and values need deep cloning
101
111
  newMap.set(deepClone(key, opts), deepClone(value, opts));
@@ -104,6 +114,7 @@ const deepClone = (data, options = {}) => {
104
114
  }
105
115
  else if (dataType === 'Set' && opts.cloneSet) {
106
116
  const newSet = new Set();
117
+ opts.parent = data;
107
118
  for (const value of data) {
108
119
  // Set values need deep cloning
109
120
  newSet.add(deepClone(value, opts));
@@ -133,6 +144,7 @@ const deepClone = (data, options = {}) => {
133
144
  input: data,
134
145
  type: dataType,
135
146
  cloned,
147
+ parent: opts.parent
136
148
  });
137
149
  return newData;
138
150
  };
@@ -422,7 +434,20 @@ const wrapMapMethods = ({ target, onBeforeMutate = () => { }, onAfterMutate = ()
422
434
  return methods;
423
435
  };
424
436
 
425
- const shallowCopy = (data) => {
437
+ const copyObjectWithSymbol = (data) => {
438
+ if (!data || typeof data !== 'object') {
439
+ return data;
440
+ }
441
+ // Ensure the object type includes string and symbol keys
442
+ const obj = data, symbolProperties = Object.getOwnPropertySymbols(obj).reduce((acc, sym) => {
443
+ acc[sym] = obj[sym];
444
+ return acc;
445
+ }, {});
446
+ // Shallow copy the object and include the Symbol properties
447
+ return { ...obj, ...symbolProperties };
448
+ };
449
+
450
+ const shallowCopy = (data, options = {}) => {
426
451
  const dataType = getDataType(data);
427
452
  // Check if data is a Set
428
453
  if (dataType === 'Set') {
@@ -441,13 +466,37 @@ const shallowCopy = (data) => {
441
466
  }
442
467
  // Check if data is a Plain Object (including Symbol keys)
443
468
  if (dataType === 'object') {
444
- const obj = data; // Ensure the object type includes string and symbol keys
445
- const symbolProperties = Object.getOwnPropertySymbols(obj).reduce((acc, sym) => {
446
- acc[sym] = obj[sym];
447
- return acc;
448
- }, {});
469
+ // Ensure the object type includes string and symbol keys
449
470
  // Shallow copy the object and include the Symbol properties
450
- return { ...obj, ...symbolProperties };
471
+ return copyObjectWithSymbol(data);
472
+ }
473
+ // Check if data is a Date
474
+ if (dataType === 'Date') {
475
+ return new Date(data.getTime());
476
+ }
477
+ // Check if data is a RegExp
478
+ if (dataType === 'RegExp') {
479
+ return new RegExp(data.source, data.flags);
480
+ }
481
+ // Check if data is a Buffer (for Node.js)
482
+ if (dataType === 'Buffer') {
483
+ return Buffer.from(data);
484
+ }
485
+ // Check if data is an ArrayBuffer or TypedArray
486
+ if (dataType === 'ArrayBuffer' || ArrayBuffer.isView(data)) {
487
+ return data.slice(0);
488
+ }
489
+ // Check if data is a WeakSet
490
+ if (dataType === 'WeakSet') {
491
+ return new WeakSet([...data]);
492
+ }
493
+ // Check if data is a WeakMap
494
+ if (dataType === 'WeakMap') {
495
+ return new WeakMap([...data]);
496
+ }
497
+ // Check if data is an Error
498
+ if (dataType === 'Error') {
499
+ return new Error(data.message);
451
500
  }
452
501
  // For other types (such as numbers, strings, booleans, etc.), return the original value
453
502
  return data;
@@ -708,6 +757,7 @@ const utils = {
708
757
  getUniqueId,
709
758
  deepMerge,
710
759
  shallowCopy,
760
+ copyObjectWithSymbol,
711
761
  };
712
762
 
713
763
  module.exports = utils;
@@ -1,7 +1,7 @@
1
1
  /*!
2
- * @since Last modified: 2025-12-25 12:10:38
2
+ * @since Last modified: 2025-12-26 9:45:49
3
3
  * @name Utils for web front-end.
4
- * @version 0.0.12
4
+ * @version 0.0.14
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}),t}o.onBeforeClone?.(e,r);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);a=t}else if("Array"===r&&o.cloneArray)a=e.map(e=>deepClone(e,o));else if("Map"===r&&o.cloneMap){const t=new Map;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;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}),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,c=void 0===o[2]?l:o[2];n.oldItems=e.slice(i,c),n.start=i,n.end=c}t?.(n);const i=Array.prototype[s].apply(e,o),c={value:i,key:s,args:o,context:n,target:e,...a};return r?.(c),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},shallowCopy=e=>{const t=getDataType(e);if("Set"===t)return new Set([...e]);if("Map"===t)return new Map([...e]);if(Array.isArray(e))return[...e];if("object"===t){const t=e,r=Object.getOwnPropertySymbols(t).reduce((e,r)=>(e[r]=t[r],e),{});return{...t,...r}}return 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};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),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;
package/dist/utils.esm.js CHANGED
@@ -1,8 +1,8 @@
1
1
 
2
2
  /*!
3
- * @since Last modified: 2025-12-25 12:10:38
3
+ * @since Last modified: 2025-12-26 9:45:49
4
4
  * @name Utils for web front-end.
5
- * @version 0.0.12
5
+ * @version 0.0.14
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}
@@ -67,18 +67,26 @@ const deepClone = (data, options = {}) => {
67
67
  input: data,
68
68
  type: dataType,
69
69
  cloned: result !== data,
70
+ parent: opts.parent
70
71
  });
71
72
  return result;
72
73
  }
73
74
  // If interceptor returns null/undefined, continue with normal cloning process
74
75
  }
75
76
  // Callback before cloning
76
- opts.onBeforeClone?.(data, dataType);
77
+ opts.onBeforeClone?.({
78
+ input: data,
79
+ type: dataType,
80
+ parent: opts.parent
81
+ });
77
82
  let newData, cloned = true;
78
83
  if (dataType === 'Object' && opts.cloneObject) {
79
84
  const newObj = {}, symbols = Object.getOwnPropertySymbols(data);
85
+ //存储parent对象,在下一次深复制时使用
86
+ opts.parent = data;
80
87
  // Clone regular properties
81
88
  for (const key in data) {
89
+ //临时保存父对象
82
90
  newObj[key] = deepClone(data[key], opts);
83
91
  }
84
92
  // Clone Symbol properties
@@ -90,10 +98,12 @@ const deepClone = (data, options = {}) => {
90
98
  newData = newObj;
91
99
  }
92
100
  else if (dataType === 'Array' && opts.cloneArray) {
101
+ opts.parent = data;
93
102
  newData = data.map(item => deepClone(item, opts));
94
103
  }
95
104
  else if (dataType === 'Map' && opts.cloneMap) {
96
105
  const newMap = new Map();
106
+ opts.parent = data;
97
107
  for (const [key, value] of data) {
98
108
  // Both Map keys and values need deep cloning
99
109
  newMap.set(deepClone(key, opts), deepClone(value, opts));
@@ -102,6 +112,7 @@ const deepClone = (data, options = {}) => {
102
112
  }
103
113
  else if (dataType === 'Set' && opts.cloneSet) {
104
114
  const newSet = new Set();
115
+ opts.parent = data;
105
116
  for (const value of data) {
106
117
  // Set values need deep cloning
107
118
  newSet.add(deepClone(value, opts));
@@ -131,6 +142,7 @@ const deepClone = (data, options = {}) => {
131
142
  input: data,
132
143
  type: dataType,
133
144
  cloned,
145
+ parent: opts.parent
134
146
  });
135
147
  return newData;
136
148
  };
@@ -420,7 +432,20 @@ const wrapMapMethods = ({ target, onBeforeMutate = () => { }, onAfterMutate = ()
420
432
  return methods;
421
433
  };
422
434
 
423
- const shallowCopy = (data) => {
435
+ const copyObjectWithSymbol = (data) => {
436
+ if (!data || typeof data !== 'object') {
437
+ return data;
438
+ }
439
+ // Ensure the object type includes string and symbol keys
440
+ const obj = data, symbolProperties = Object.getOwnPropertySymbols(obj).reduce((acc, sym) => {
441
+ acc[sym] = obj[sym];
442
+ return acc;
443
+ }, {});
444
+ // Shallow copy the object and include the Symbol properties
445
+ return { ...obj, ...symbolProperties };
446
+ };
447
+
448
+ const shallowCopy = (data, options = {}) => {
424
449
  const dataType = getDataType(data);
425
450
  // Check if data is a Set
426
451
  if (dataType === 'Set') {
@@ -439,13 +464,37 @@ const shallowCopy = (data) => {
439
464
  }
440
465
  // Check if data is a Plain Object (including Symbol keys)
441
466
  if (dataType === 'object') {
442
- const obj = data; // Ensure the object type includes string and symbol keys
443
- const symbolProperties = Object.getOwnPropertySymbols(obj).reduce((acc, sym) => {
444
- acc[sym] = obj[sym];
445
- return acc;
446
- }, {});
467
+ // Ensure the object type includes string and symbol keys
447
468
  // Shallow copy the object and include the Symbol properties
448
- return { ...obj, ...symbolProperties };
469
+ return copyObjectWithSymbol(data);
470
+ }
471
+ // Check if data is a Date
472
+ if (dataType === 'Date') {
473
+ return new Date(data.getTime());
474
+ }
475
+ // Check if data is a RegExp
476
+ if (dataType === 'RegExp') {
477
+ return new RegExp(data.source, data.flags);
478
+ }
479
+ // Check if data is a Buffer (for Node.js)
480
+ if (dataType === 'Buffer') {
481
+ return Buffer.from(data);
482
+ }
483
+ // Check if data is an ArrayBuffer or TypedArray
484
+ if (dataType === 'ArrayBuffer' || ArrayBuffer.isView(data)) {
485
+ return data.slice(0);
486
+ }
487
+ // Check if data is a WeakSet
488
+ if (dataType === 'WeakSet') {
489
+ return new WeakSet([...data]);
490
+ }
491
+ // Check if data is a WeakMap
492
+ if (dataType === 'WeakMap') {
493
+ return new WeakMap([...data]);
494
+ }
495
+ // Check if data is an Error
496
+ if (dataType === 'Error') {
497
+ return new Error(data.message);
449
498
  }
450
499
  // For other types (such as numbers, strings, booleans, etc.), return the original value
451
500
  return data;
@@ -706,6 +755,7 @@ const utils = {
706
755
  getUniqueId,
707
756
  deepMerge,
708
757
  shallowCopy,
758
+ copyObjectWithSymbol,
709
759
  };
710
760
 
711
761
  export { utils as default };
@@ -1,7 +1,7 @@
1
1
  /*!
2
- * @since Last modified: 2025-12-25 12:10:38
2
+ * @since Last modified: 2025-12-26 9:45:49
3
3
  * @name Utils for web front-end.
4
- * @version 0.0.12
4
+ * @version 0.0.14
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),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}),t}o.onBeforeClone?.(e,r);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);a=t}else if("Array"===r&&o.cloneArray)a=e.map(e=>deepClone(e,o));else if("Map"===r&&o.cloneMap){const t=new Map;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;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}),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,c=void 0===o[2]?l:o[2];n.oldItems=e.slice(i,c),n.start=i,n.end=c}t?.(n);const i=Array.prototype[s].apply(e,o),c={value:i,key:s,args:o,context:n,target:e,...a};return r?.(c),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},shallowCopy=e=>{const t=getDataType(e);if("Set"===t)return new Set([...e]);if("Map"===t)return new Map([...e]);if(Array.isArray(e))return[...e];if("object"===t){const t=e,r=Object.getOwnPropertySymbols(t).reduce((e,r)=>(e[r]=t[r],e),{});return{...t,...r}}return 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};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(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};
package/dist/utils.umd.js CHANGED
@@ -1,8 +1,8 @@
1
1
 
2
2
  /*!
3
- * @since Last modified: 2025-12-25 12:10:38
3
+ * @since Last modified: 2025-12-26 9:45:49
4
4
  * @name Utils for web front-end.
5
- * @version 0.0.12
5
+ * @version 0.0.14
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}
@@ -73,18 +73,26 @@
73
73
  input: data,
74
74
  type: dataType,
75
75
  cloned: result !== data,
76
+ parent: opts.parent
76
77
  });
77
78
  return result;
78
79
  }
79
80
  // If interceptor returns null/undefined, continue with normal cloning process
80
81
  }
81
82
  // Callback before cloning
82
- opts.onBeforeClone?.(data, dataType);
83
+ opts.onBeforeClone?.({
84
+ input: data,
85
+ type: dataType,
86
+ parent: opts.parent
87
+ });
83
88
  let newData, cloned = true;
84
89
  if (dataType === 'Object' && opts.cloneObject) {
85
90
  const newObj = {}, symbols = Object.getOwnPropertySymbols(data);
91
+ //存储parent对象,在下一次深复制时使用
92
+ opts.parent = data;
86
93
  // Clone regular properties
87
94
  for (const key in data) {
95
+ //临时保存父对象
88
96
  newObj[key] = deepClone(data[key], opts);
89
97
  }
90
98
  // Clone Symbol properties
@@ -96,10 +104,12 @@
96
104
  newData = newObj;
97
105
  }
98
106
  else if (dataType === 'Array' && opts.cloneArray) {
107
+ opts.parent = data;
99
108
  newData = data.map(item => deepClone(item, opts));
100
109
  }
101
110
  else if (dataType === 'Map' && opts.cloneMap) {
102
111
  const newMap = new Map();
112
+ opts.parent = data;
103
113
  for (const [key, value] of data) {
104
114
  // Both Map keys and values need deep cloning
105
115
  newMap.set(deepClone(key, opts), deepClone(value, opts));
@@ -108,6 +118,7 @@
108
118
  }
109
119
  else if (dataType === 'Set' && opts.cloneSet) {
110
120
  const newSet = new Set();
121
+ opts.parent = data;
111
122
  for (const value of data) {
112
123
  // Set values need deep cloning
113
124
  newSet.add(deepClone(value, opts));
@@ -137,6 +148,7 @@
137
148
  input: data,
138
149
  type: dataType,
139
150
  cloned,
151
+ parent: opts.parent
140
152
  });
141
153
  return newData;
142
154
  };
@@ -426,7 +438,20 @@
426
438
  return methods;
427
439
  };
428
440
 
429
- const shallowCopy = (data) => {
441
+ const copyObjectWithSymbol = (data) => {
442
+ if (!data || typeof data !== 'object') {
443
+ return data;
444
+ }
445
+ // Ensure the object type includes string and symbol keys
446
+ const obj = data, symbolProperties = Object.getOwnPropertySymbols(obj).reduce((acc, sym) => {
447
+ acc[sym] = obj[sym];
448
+ return acc;
449
+ }, {});
450
+ // Shallow copy the object and include the Symbol properties
451
+ return { ...obj, ...symbolProperties };
452
+ };
453
+
454
+ const shallowCopy = (data, options = {}) => {
430
455
  const dataType = getDataType(data);
431
456
  // Check if data is a Set
432
457
  if (dataType === 'Set') {
@@ -445,13 +470,37 @@
445
470
  }
446
471
  // Check if data is a Plain Object (including Symbol keys)
447
472
  if (dataType === 'object') {
448
- const obj = data; // Ensure the object type includes string and symbol keys
449
- const symbolProperties = Object.getOwnPropertySymbols(obj).reduce((acc, sym) => {
450
- acc[sym] = obj[sym];
451
- return acc;
452
- }, {});
473
+ // Ensure the object type includes string and symbol keys
453
474
  // Shallow copy the object and include the Symbol properties
454
- return { ...obj, ...symbolProperties };
475
+ return copyObjectWithSymbol(data);
476
+ }
477
+ // Check if data is a Date
478
+ if (dataType === 'Date') {
479
+ return new Date(data.getTime());
480
+ }
481
+ // Check if data is a RegExp
482
+ if (dataType === 'RegExp') {
483
+ return new RegExp(data.source, data.flags);
484
+ }
485
+ // Check if data is a Buffer (for Node.js)
486
+ if (dataType === 'Buffer') {
487
+ return Buffer.from(data);
488
+ }
489
+ // Check if data is an ArrayBuffer or TypedArray
490
+ if (dataType === 'ArrayBuffer' || ArrayBuffer.isView(data)) {
491
+ return data.slice(0);
492
+ }
493
+ // Check if data is a WeakSet
494
+ if (dataType === 'WeakSet') {
495
+ return new WeakSet([...data]);
496
+ }
497
+ // Check if data is a WeakMap
498
+ if (dataType === 'WeakMap') {
499
+ return new WeakMap([...data]);
500
+ }
501
+ // Check if data is an Error
502
+ if (dataType === 'Error') {
503
+ return new Error(data.message);
455
504
  }
456
505
  // For other types (such as numbers, strings, booleans, etc.), return the original value
457
506
  return data;
@@ -712,6 +761,7 @@
712
761
  getUniqueId,
713
762
  deepMerge,
714
763
  shallowCopy,
764
+ copyObjectWithSymbol,
715
765
  };
716
766
 
717
767
  return utils;
@@ -1,7 +1,7 @@
1
1
  /*!
2
- * @since Last modified: 2025-12-25 12:10:38
2
+ * @since Last modified: 2025-12-26 9:45:49
3
3
  * @name Utils for web front-end.
4
- * @version 0.0.12
4
+ * @version 0.0.14
5
5
  * @author AXUI development team <3217728223@qq.com>
6
6
  * @description This is a set of general-purpose JavaScript utility functions developed by the AXUI team. All functions are pure and do not involve CSS or other third-party libraries. They are suitable for any web front-end environment.
7
7
  * @see {@link https://www.axui.cn|Official website}
@@ -12,4 +12,4 @@
12
12
  * @copyright This software supports the MIT License, allowing free learning and commercial use, but please retain the terms 'ax,' 'axui,' 'AX,' and 'AXUI' within the software.
13
13
  * @license MIT license
14
14
  */
15
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).utils=t()}(this,function(){"use strict";const getDataType=e=>{let t,r=Object.prototype.toString.call(e).slice(8,-1);return t="Function"===r&&/^\s*class\s+/.test(e.toString())?"Class":"Object"===r&&Object.getPrototypeOf(e)!==Object.prototype?"Instance":r,t},deepClone=(e,t={})=>{const r=getDataType(e),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}),t}o.onBeforeClone?.(e,r);let n,a=!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 n of r)t[n]=deepClone(e[n],o);n=t}else if("Array"===r&&o.cloneArray)n=e.map(e=>deepClone(e,o));else if("Map"===r&&o.cloneMap){const t=new Map;for(const[r,n]of e)t.set(deepClone(r,o),deepClone(n,o));n=t}else if("Set"===r&&o.cloneSet){const t=new Set;for(const r of e)t.add(deepClone(r,o));n=t}else if("Date"===r&&o.cloneDate)n=new Date(e.getTime());else if("RegExp"===r&&o.cloneRegex){const t=e;n=new RegExp(t.source,t.flags)}else n=e,a=!1;return o.onAfterClone?.({output:n,input:e,type:r,cloned:a}),n},deepCloneToJSON=e=>{const t=getDataType(e);if("Object"===t){const t={};for(const r in e)t[r]=deepCloneToJSON(e[r]);for(const e in t)void 0===t[e]&&Reflect.deleteProperty(t,e);return t}if("Array"===t){return e.map((e,t)=>deepCloneToJSON(e)).filter(e=>void 0!==e)}return["Number","String","Boolean","Null"].includes(t)?e:void 0},e=["push","pop","shift","unshift","splice","sort","reverse","copyWithin","fill"],t=["add","delete","clear"],r=["set","delete","clear"],shallowCopy=e=>{const t=getDataType(e);if("Set"===t)return new Set([...e]);if("Map"===t)return new Map([...e]);if(Array.isArray(e))return[...e];if("object"===t){const t=e,r=Object.getOwnPropertySymbols(t).reduce((e,r)=>(e[r]=t[r],e),{});return{...t,...r}}return e};return{getDataType:getDataType,requireTypes:(e,t,r)=>{let o=Array.isArray(t)?t:[t],n=getDataType(e),a=n.toLowerCase(),s=o.map(e=>e.toLowerCase()),i=a.includes("html")?"element":a;if(r)try{if(!s.includes(i))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${i}`)}catch(e){r(e,n)}else if(!s.includes(i))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${i}`);return n},deepClone:deepClone,deepCloneToJSON:deepCloneToJSON,wrapArrayMethods:({target:t,onBeforeMutate:r=()=>{},onAfterMutate:o=()=>{},allowList:n,props:a={}})=>{if(!Array.isArray(t))throw new TypeError("The 'target' parameter must be an array.");n&&!n?.length||(n=e);const s={};for(let e of n)s[e]=function(...n){const s={},i=t.length;switch(e){case"push":case"unshift":s.addedItems=[...n];break;case"pop":s.poppedItem=t[i-1];break;case"shift":s.shiftedItem=t[0];break;case"splice":const[e,r]=n,o=e<0?Math.max(i+e,0):Math.min(e,i),a=void 0===r?i-o:r;s.deletedItems=t.slice(o,o+a);break;case"sort":case"reverse":s.oldSnapshot=[...t];break;case"fill":case"copyWithin":const l=n[1]||0,c=void 0===n[2]?i:n[2];s.oldItems=t.slice(l,c),s.start=l,s.end=c}r?.(s);const l=Array.prototype[e].apply(t,n),c={value:l,key:e,args:n,context:s,target:t,...a};return o?.(c),l};return s},arrayMutableMethods:e,setMutableMethods:t,mapMutableMethods:r,wrapSetMethods:({target:e,onBeforeMutate:r=()=>{},onAfterMutate:o=()=>{},allowList:n=t,props:a={}})=>{if(!(e instanceof Set))throw new TypeError("The 'target' parameter must be a Set.");const s={},createWrappedMethod=t=>function(...n){const s={};switch(t){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}r(s);const i=e[t].apply(e,n),l={method:t,result:i,args:n,context:s,target:e,...a};return o(l),i};for(const e of n)t.includes(e)&&(s[e]=createWrappedMethod(e));return Object.defineProperty(s,"target",{get:()=>e,enumerable:!1,configurable:!1}),s},wrapMapMethods:({target:e,onBeforeMutate:t=()=>{},onAfterMutate:o=()=>{},allowList:n=r,props:a={}})=>{if(!(e instanceof Map))throw new TypeError("The 'target' parameter must be a Map.");const s={},createWrappedMethod=r=>function(...n){const s={};switch(r){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 i=e[r].apply(e,n),l={method:r,result:i,args:n,context:s,target:e,...a};return o(l),i};for(const e of n)r.includes(e)&&(s[e]=createWrappedMethod(e));return Object.defineProperty(s,"target",{get:()=>e,enumerable:!1,configurable:!1}),s},getUniqueId:(e={})=>{const t=e.prefix,r=e.suffix,o=e.base10,n=e.base36;return`${t?t+"-":""}${Date.now()}${n?"-"+Math.random().toString(36).substring(2,11):""}${o?"-"+Math.floor(1e4*Math.random()).toString().padStart(4,"0"):""}${r?"-"+r:""}`},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,n,a=getDataType(e),s=getDataType(t),i=!0;return"Object"===a&&"Object"===s?(n=deepMergeObjects(e,t,r),o="Object"):"Array"===a&&"Array"===s?(n=deepMergeArrays(e,t,r),o="Array"):"Set"===a&&"Set"===s?(n=deepMergeSets(e,t,r),o="Set"):"Map"===a&&"Map"===s?(n=deepMergeMaps(e,t,r),o="Map"):(i=!1,n=e),{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 o=getDataType(e),n=getDataType(t);if("Object"!==o||"Object"!==n)return e;r?.onBeforeMerge?.(e,t);const a=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r);let s={};s=a.targetClone?shallowCopy(e):e;for(let e in t)if(t.hasOwnProperty(e)&&s.hasOwnProperty(e)){let o=deepMergeHelper(s[e],t[e],r);o.flag?o.type?"Object"===o.type&&(s[e]=o.result):s[e]=t[e]:a.useEnable?s[e]=mergeEnableObject(s[e],t[e]):s[e]=t[e]}else t.hasOwnProperty(e)&&!s.hasOwnProperty(e)&&a.inheritMissing&&(s[e]=t[e]);if(a.useSymbol){let e=Object.getOwnPropertySymbols(t);if(e.length)for(let r of e)s[r]=t[r]}return a?.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),n=o.targetClone?[...e]:e;if("replace"===o.dataMode)for(let e=0;e<t.length&&(o.inheritMissing||!(e>=n.length));e++){deepMergeHelper(n[e],t[e],o).flag||(n[e]=t[e])}else"concat"===o.dataMode||(n.length=0),n.push(...t);return r?.onAfterMerge?.(n,e,t),n},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),n=o.targetClone?new Map([...e]):e;for(const[e,a]of t.entries())if(n.has(e)){const t=n.get(e),r=a,s=deepMergeHelper(t,r,o);s.flag?"Object"===s.type&&n.set(e,s.result):n.set(e,r)}else r.inheritMissing&&n.set(e,a);return r?.onAfterMerge?.(n,e,t),n},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),n=o.targetClone?new Set(...e):e;if("replace"===o.dataMode){const e=[...n],r=[...t],a=deepMergeHelper(e,r,o);n.clear();for(let e of a.result)n.add(e)}else if("concat"===o.dataMode)for(let e of t)n.add(e);else{n.clear();for(let e of t)n.add(e)}return r?.onAfterMerge?.(n,e,t),n};return deepMergeHelper(e,t,o).result},shallowCopy:shallowCopy}});
15
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).utils=t()}(this,function(){"use strict";const getDataType=e=>{let t,r=Object.prototype.toString.call(e).slice(8,-1);return t="Function"===r&&/^\s*class\s+/.test(e.toString())?"Class":"Object"===r&&Object.getPrototypeOf(e)!==Object.prototype?"Instance":r,t},deepClone=(e,t={})=>{const r=getDataType(e),n=Object.assign({cloneSet:!0,cloneMap:!0,cloneObject:!0,cloneArray:!0,cloneDate:!0,cloneRegex:!0},t);if(n.interceptor&&"function"==typeof n.interceptor){let t=n.interceptor(e,r);if(t)return n.onAfterClone?.({output:t,input:e,type:r,cloned:t!==e,parent:n.parent}),t}n.onBeforeClone?.({input:e,type:r,parent:n.parent});let o,a=!0;if("Object"===r&&n.cloneObject){const t={},r=Object.getOwnPropertySymbols(e);n.parent=e;for(const r in e)t[r]=deepClone(e[r],n);if(r.length>0)for(const o of r)t[o]=deepClone(e[o],n);o=t}else if("Array"===r&&n.cloneArray)n.parent=e,o=e.map(e=>deepClone(e,n));else if("Map"===r&&n.cloneMap){const t=new Map;n.parent=e;for(const[r,o]of e)t.set(deepClone(r,n),deepClone(o,n));o=t}else if("Set"===r&&n.cloneSet){const t=new Set;n.parent=e;for(const r of e)t.add(deepClone(r,n));o=t}else if("Date"===r&&n.cloneDate)o=new Date(e.getTime());else if("RegExp"===r&&n.cloneRegex){const t=e;o=new RegExp(t.source,t.flags)}else o=e,a=!1;return n.onAfterClone?.({output:o,input:e,type:r,cloned:a,parent:n.parent}),o},deepCloneToJSON=e=>{const t=getDataType(e);if("Object"===t){const t={};for(const r in e)t[r]=deepCloneToJSON(e[r]);for(const e in t)void 0===t[e]&&Reflect.deleteProperty(t,e);return t}if("Array"===t){return e.map((e,t)=>deepCloneToJSON(e)).filter(e=>void 0!==e)}return["Number","String","Boolean","Null"].includes(t)?e:void 0},e=["push","pop","shift","unshift","splice","sort","reverse","copyWithin","fill"],t=["add","delete","clear"],r=["set","delete","clear"],copyObjectWithSymbol=e=>{if(!e||"object"!=typeof e)return e;const t=e,r=Object.getOwnPropertySymbols(t).reduce((e,r)=>(e[r]=t[r],e),{});return{...t,...r}},shallowCopy=(e,t={})=>{const r=getDataType(e);return"Set"===r?new Set([...e]):"Map"===r?new Map([...e]):Array.isArray(e)?[...e]:"object"===r?copyObjectWithSymbol(e):"Date"===r?new Date(e.getTime()):"RegExp"===r?new RegExp(e.source,e.flags):"Buffer"===r?Buffer.from(e):"ArrayBuffer"===r||ArrayBuffer.isView(e)?e.slice(0):"WeakSet"===r?new WeakSet([...e]):"WeakMap"===r?new WeakMap([...e]):"Error"===r?new Error(e.message):e};return{getDataType:getDataType,requireTypes:(e,t,r)=>{let n=Array.isArray(t)?t:[t],o=getDataType(e),a=o.toLowerCase(),s=n.map(e=>e.toLowerCase()),i=a.includes("html")?"element":a;if(r)try{if(!s.includes(i))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${i}`)}catch(e){r(e,o)}else if(!s.includes(i))throw new TypeError(`Expected data type(s): [${s.join(", ")}], but got: ${i}`);return o},deepClone:deepClone,deepCloneToJSON:deepCloneToJSON,wrapArrayMethods:({target:t,onBeforeMutate:r=()=>{},onAfterMutate:n=()=>{},allowList:o,props:a={}})=>{if(!Array.isArray(t))throw new TypeError("The 'target' parameter must be an array.");o&&!o?.length||(o=e);const s={};for(let e of o)s[e]=function(...o){const s={},i=t.length;switch(e){case"push":case"unshift":s.addedItems=[...o];break;case"pop":s.poppedItem=t[i-1];break;case"shift":s.shiftedItem=t[0];break;case"splice":const[e,r]=o,n=e<0?Math.max(i+e,0):Math.min(e,i),a=void 0===r?i-n:r;s.deletedItems=t.slice(n,n+a);break;case"sort":case"reverse":s.oldSnapshot=[...t];break;case"fill":case"copyWithin":const l=o[1]||0,c=void 0===o[2]?i:o[2];s.oldItems=t.slice(l,c),s.start=l,s.end=c}r?.(s);const l=Array.prototype[e].apply(t,o),c={value:l,key:e,args:o,context:s,target:t,...a};return n?.(c),l};return s},arrayMutableMethods:e,setMutableMethods:t,mapMutableMethods:r,wrapSetMethods:({target:e,onBeforeMutate:r=()=>{},onAfterMutate:n=()=>{},allowList:o=t,props:a={}})=>{if(!(e instanceof Set))throw new TypeError("The 'target' parameter must be a Set.");const s={},createWrappedMethod=t=>function(...o){const s={};switch(t){case"add":{const[t]=o;s.addedItem=t,s.existed=e.has(t);break}case"delete":{const[t]=o;s.existed=e.has(t),s.deletedItem=s.existed?t:void 0;break}case"clear":s.clearedItems=Array.from(e),s.previousSize=e.size}r(s);const i=e[t].apply(e,o),l={method:t,result:i,args:o,context:s,target:e,...a};return n(l),i};for(const e of o)t.includes(e)&&(s[e]=createWrappedMethod(e));return Object.defineProperty(s,"target",{get:()=>e,enumerable:!1,configurable:!1}),s},wrapMapMethods:({target:e,onBeforeMutate:t=()=>{},onAfterMutate:n=()=>{},allowList:o=r,props:a={}})=>{if(!(e instanceof Map))throw new TypeError("The 'target' parameter must be a Map.");const s={},createWrappedMethod=r=>function(...o){const s={};switch(r){case"set":{const[t,r]=o;s.key=t,s.newValue=r,s.existed=e.has(t),s.oldValue=s.existed?e.get(t):void 0;break}case"delete":{const[t]=o;s.key=t,s.existed=e.has(t),s.value=s.existed?e.get(t):void 0;break}case"clear":s.clearedItems=Array.from(e.entries()),s.previousSize=e.size}t(s);const i=e[r].apply(e,o),l={method:r,result:i,args:o,context:s,target:e,...a};return n(l),i};for(const e of o)r.includes(e)&&(s[e]=createWrappedMethod(e));return Object.defineProperty(s,"target",{get:()=>e,enumerable:!1,configurable:!1}),s},getUniqueId:(e={})=>{const t=e.prefix,r=e.suffix,n=e.base10,o=e.base36;return`${t?t+"-":""}${Date.now()}${o?"-"+Math.random().toString(36).substring(2,11):""}${n?"-"+Math.floor(1e4*Math.random()).toString().padStart(4,"0"):""}${r?"-"+r:""}`},deepMerge:(e,t,r={})=>{const n=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0,useSymbol:!0,deepClone:{},onBeforeMerge:void 0,onAfterMerge:void 0},r),deepMergeHelper=(e,t,r)=>{let n,o,a=getDataType(e),s=getDataType(t),i=!0;return"Object"===a&&"Object"===s?(o=deepMergeObjects(e,t,r),n="Object"):"Array"===a&&"Array"===s?(o=deepMergeArrays(e,t,r),n="Array"):"Set"===a&&"Set"===s?(o=deepMergeSets(e,t,r),n="Set"):"Map"===a&&"Map"===s?(o=deepMergeMaps(e,t,r),n="Map"):(i=!1,o=e),{result:o,flag:i,type:n}},mergeEnableObject=(e,t)=>e?.hasOwnProperty("enable")&&"boolean"==typeof t?(e.enable=t,e):t?.hasOwnProperty("enable")&&"boolean"==typeof e?Object.assign({enable:e},t):t,deepMergeObjects=(e,t,r={})=>{let n=getDataType(e),o=getDataType(t);if("Object"!==n||"Object"!==o)return e;r?.onBeforeMerge?.(e,t);const a=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r);let s={};s=a.targetClone?shallowCopy(e):e;for(let e in t)if(t.hasOwnProperty(e)&&s.hasOwnProperty(e)){let n=deepMergeHelper(s[e],t[e],r);n.flag?n.type?"Object"===n.type&&(s[e]=n.result):s[e]=t[e]:a.useEnable?s[e]=mergeEnableObject(s[e],t[e]):s[e]=t[e]}else t.hasOwnProperty(e)&&!s.hasOwnProperty(e)&&a.inheritMissing&&(s[e]=t[e]);if(a.useSymbol){let e=Object.getOwnPropertySymbols(t);if(e.length)for(let r of e)s[r]=t[r]}return a?.onAfterMerge?.(s,e,t),s},deepMergeArrays=(e,t,r={})=>{if(!Array.isArray(e)||!Array.isArray(t))return e;r?.onBeforeMerge?.(e,t);const n=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1},r),o=n.targetClone?[...e]:e;if("replace"===n.dataMode)for(let e=0;e<t.length&&(n.inheritMissing||!(e>=o.length));e++){deepMergeHelper(o[e],t[e],n).flag||(o[e]=t[e])}else"concat"===n.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 n=Object.assign({inheritMissing:!0,targetClone:!1,useEnable:!0},r),o=n.targetClone?new Map([...e]):e;for(const[e,a]of t.entries())if(o.has(e)){const t=o.get(e),r=a,s=deepMergeHelper(t,r,n);s.flag?"Object"===s.type&&o.set(e,s.result):o.set(e,r)}else r.inheritMissing&&o.set(e,a);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 n=Object.assign({dataMode:"clear",inheritMissing:!0,targetClone:!1,useEnable:!0},r),o=n.targetClone?new Set(...e):e;if("replace"===n.dataMode){const e=[...o],r=[...t],a=deepMergeHelper(e,r,n);o.clear();for(let e of a.result)o.add(e)}else if("concat"===n.dataMode)for(let e of t)o.add(e);else{o.clear();for(let e of t)o.add(e)}return r?.onAfterMerge?.(o,e,t),o};return deepMergeHelper(e,t,n).result},shallowCopy:shallowCopy,copyObjectWithSymbol:copyObjectWithSymbol}});
package/dist.zip CHANGED
Binary file