@codady/utils 0.0.17 → 0.0.19

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/src/deepMerge.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @since Last modified: 2025/12/26 16:03:37
2
+ * @since Last modified: 2025/12/27 14:35:01
3
3
  * @function deepMerge
4
4
  * @description Deeply merges two data structures (Object, Array, Map, or Set) based on their types.
5
5
  * This function recursively merges the properties or items of the target and source, depending on their types.
@@ -42,6 +42,10 @@ export interface DeepMergeOptions {
42
42
  // Mode for handling array items
43
43
  // 处理数组成员的模式
44
44
  dataMode?: 'clear' | 'replace' | 'concat';
45
+ //如果source值=null,target如何处理,ignore表示不理会null保持target;preserve将覆盖target,delete将删除target(key)
46
+ nullBehavior?: 'ignore' | 'preserve' | 'delete';
47
+ //如果source值=undefined,target如何处理,ignore表示不理会undefined保持target;preserve将覆盖target,delete将删除target(key)
48
+ undefinedBehavior?: 'ignore' | 'preserve' | 'delete';
45
49
  // Whether to append properties (for objects)
46
50
  // 是否追加属性(针对对象)
47
51
  inheritMissing?: boolean;
@@ -136,6 +140,10 @@ const deepMerge = (target: Object | Array<any> | Map<any, any> | Set<any>, sourc
136
140
  // target是{}类型时,是否允许合并key=symbol的键值对。
137
141
  useSymbol: true,
138
142
 
143
+ nullBehavior:'preserve',
144
+
145
+ undefinedBehavior:'preserve',
146
+
139
147
  // Options passed to the deepClone function when targetClone is true
140
148
  // 当targetClone为true时传递给deepClone函数的选项
141
149
  deepClone: {},
@@ -230,18 +238,38 @@ const deepMerge = (target: Object | Array<any> | Map<any, any> | Set<any>, sourc
230
238
  result = options.targetClone ? shallowCopy(target) : target;
231
239
 
232
240
  for (let k in source) {
241
+ const _result = (result as any)[k],
242
+ _source = source[k];
233
243
  if (source.hasOwnProperty(k) && result.hasOwnProperty(k)) {
234
244
 
235
- let resp = smartMerger((result as any)[k], source[k], { ...opts, parent: result });
245
+ const resp = smartMerger(_result, _source, { ...opts, parent: result });
236
246
  //resp={result,flag,type}
237
- //flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
247
+ //flag=true表示类型一致(object/array/map/set)并完成了合并,false表示并没有合并需要直接赋值
238
248
  if (!resp.flag) {
239
249
  //类型不同则直接覆盖
240
- if (options.useEnable) {
241
- (result as any)[k] = mergeEnableObject((result as any)[k], source[k]);
250
+ let tmp = options.useEnable ? mergeEnableObject(_result, _source) : _source;
251
+ if (_result !== tmp && tmp === null) {
252
+ if (options.nullBehavior === 'ignore') {
253
+ //不处理
254
+ } else if (options.nullBehavior === 'delete') {
255
+ //删除属性
256
+ Reflect.deleteProperty(result, k);
257
+ } else {
258
+ //替换
259
+ (result as any)[k] = tmp;
260
+ }
261
+ } else if (_result !== tmp && tmp === undefined) {
262
+ if (options.undefinedBehavior === 'ignore') {
263
+ //不处理
264
+ } else if (options.undefinedBehavior === 'delete') {
265
+ //删除属性
266
+ Reflect.deleteProperty(result, k);
267
+ } else {
268
+ //替换
269
+ (result as any)[k] = _source;
270
+ }
242
271
  } else {
243
- //完全替换
244
- (result as any)[k] = source[k];
272
+ (result as any)[k] = _source;
245
273
  }
246
274
  } else {
247
275
  //类型相同
@@ -252,13 +280,13 @@ const deepMerge = (target: Object | Array<any> | Map<any, any> | Set<any>, sourc
252
280
  }
253
281
  } else {
254
282
  //其他类型则直接覆盖
255
- (result as any)[k] = source[k];
283
+ (result as any)[k] = _source;
256
284
  }
257
285
  }
258
286
 
259
287
  } else if (source.hasOwnProperty(k) && !result.hasOwnProperty(k) && options.inheritMissing) {
260
288
  //如果source有属性,result没有该属性,但是options允许追加属性则直接赋值
261
- (result as any)[k] = source[k];
289
+ (result as any)[k] = _source;
262
290
  }
263
291
  }
264
292
  //Symbol键直接追加,因为Symbol是唯一,结果同Object.assign
package/src/getEl.js ADDED
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @since Last modified: 2026/01/05 10:28:14
3
+ * @function getEl
4
+ * @description Get a DOM node (real or virtual). Supports obtaining nodes from various types (not just HTMLElement).
5
+ * @param {string|Node} obj - Can be a node selector (e.g., #id, .classname, NODENAME, [attribute]) or any node type (HTMLElement, Node, DocumentFragment, etc.).
6
+ * @param {Node|string} wrap - Parent node (or selector) from which to get the sub-node. Defaults to document.body.
7
+ * @returns {Node|null} Returns the matching node or null if not found.
8
+ * @example
9
+ * ax.getEl('#demo');
10
+ * <!-- returns a DOM node -->
11
+ */
12
+ //简介:获得一个节点。支持获得一个真实节点或虚拟节点
13
+ //参数obj:可以是#id、.className、NODENAME、[attribute]等节点选择器或节点
14
+ //参数parent:父节点,从该节点获取子节点,默认document.body
15
+ //返回:一个节点或null
16
+ 'use strict';
17
+ import getDataType from './getDataType';
18
+ const getEl = (obj, wrap = document.body) => {
19
+ let objType = getDataType(obj), parType = getDataType(wrap), parent = parType.includes('HTML') ? wrap : document.querySelector(wrap),
20
+ //如果parent是template节点,需要通过node.content.querySelector取得子节点
21
+ root = parent && parent instanceof HTMLTemplateElement ? parent.content : parent, result = null;
22
+ if (obj) {
23
+ if (objType.includes('HTML')) {
24
+ result = obj;
25
+ }
26
+ else if (objType === 'String') {
27
+ try {
28
+ result = (root || document).querySelector(obj.trim());
29
+ //可能会报错,报错则返回null
30
+ }
31
+ catch {
32
+ result = null;
33
+ }
34
+ }
35
+ }
36
+ return result;
37
+ };
38
+ export default getEl;
package/src/getEl.ts ADDED
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @since Last modified: 2026/01/05 10:28:14
3
+ * @function getEl
4
+ * @description Get a DOM node (real or virtual). Supports obtaining nodes from various types (not just HTMLElement).
5
+ * @param {string|Node} obj - Can be a node selector (e.g., #id, .classname, NODENAME, [attribute]) or any node type (HTMLElement, Node, DocumentFragment, etc.).
6
+ * @param {Node|string} wrap - Parent node (or selector) from which to get the sub-node. Defaults to document.body.
7
+ * @returns {Node|null} Returns the matching node or null if not found.
8
+ * @example
9
+ * ax.getEl('#demo');
10
+ * <!-- returns a DOM node -->
11
+ */
12
+ //简介:获得一个节点。支持获得一个真实节点或虚拟节点
13
+ //参数obj:可以是#id、.className、NODENAME、[attribute]等节点选择器或节点
14
+ //参数parent:父节点,从该节点获取子节点,默认document.body
15
+ //返回:一个节点或null
16
+ 'use strict';
17
+ import getDataType from './getDataType';
18
+
19
+
20
+ const getEl = (obj: string | Node | null, wrap: Node | string | null = document.body): Node | null => {
21
+ let objType = getDataType(obj),
22
+ parType = getDataType(wrap),
23
+ parent = parType.includes('HTML') ? wrap : document.querySelector(wrap as string),
24
+ //如果parent是template节点,需要通过node.content.querySelector取得子节点
25
+ root = parent && parent instanceof HTMLTemplateElement ? parent.content : parent,
26
+ result: Node | null = null;
27
+ if (obj) {
28
+ if (objType.includes('HTML')) {
29
+ result = (obj as Node);
30
+ } else if (objType === 'String') {
31
+ try {
32
+ result = (((root as Node) || document) as any).querySelector((obj as string).trim());
33
+ //可能会报错,报错则返回null
34
+ } catch {
35
+ result = null;
36
+ }
37
+ }
38
+ }
39
+ return result;
40
+ }
41
+ export default getEl;
package/src/getEls.js ADDED
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @since Last modified: 2026/01/05 10:29:34
3
+ * @function getEls
4
+ * @description Get the node array.
5
+ * @param {*} data - It can be a single node selector or a node array.
6
+ * @param {HTMLElement} parent - Parent node, get sub-node from this node, default document.body
7
+ * @returns {array} Return a node array.
8
+ * @example
9
+ * ax.getEls('#demo');
10
+ * <!--return [node]-->
11
+ * ax.getEls('#demo1,#demo2,#demo3');
12
+ * <!--return [node1,node2,node3]-->
13
+ * ax.getEls(['#demo1','#demo2,'#demo3']);
14
+ * <!--return [node1,node2,node3]-->
15
+ */
16
+ //简介:获得节点数组。
17
+ //参数data:可以单个节点选择器,使用方法同getEl,也可以是以“,”分隔的多个选择器,也可以节点数组。
18
+ //参数parent:父节点,从该节点获取子节点,默认document。
19
+ //返回:一个节点数组。
20
+ 'use strict';
21
+ import getDataType from './getDataType';
22
+ import getEl from './getEl';
23
+ import isEmpty from './isEmpty';
24
+ const getEls = (data, parent = document.body) => {
25
+ let type = getDataType(data), parentEl = getEl(parent), root = parentEl && parentEl instanceof HTMLTemplateElement ? parentEl.content : (parentEl || document), result = [];
26
+ //data为空直接返回空数组
27
+ if (isEmpty(data)) {
28
+ return result;
29
+ }
30
+ if (type.includes('HTML')) {
31
+ //一个节点
32
+ result.push(data);
33
+ }
34
+ else if (type === 'String') {
35
+ data = data.trim();
36
+ //以英文逗号作为节点选择器分隔符
37
+ result = data.split(',').map((k) => {
38
+ return [...root.querySelectorAll(k)];
39
+ }).flat();
40
+ }
41
+ else if (type === 'Array') {
42
+ result = data.map((k) => {
43
+ return getEl(k, parentEl);
44
+ });
45
+ }
46
+ return result.filter(Boolean);
47
+ };
48
+ export default getEls;
package/src/getEls.ts ADDED
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @since Last modified: 2026/01/05 10:29:34
3
+ * @function getEls
4
+ * @description Get the node array.
5
+ * @param {*} data - It can be a single node selector or a node array.
6
+ * @param {HTMLElement} parent - Parent node, get sub-node from this node, default document.body
7
+ * @returns {array} Return a node array.
8
+ * @example
9
+ * ax.getEls('#demo');
10
+ * <!--return [node]-->
11
+ * ax.getEls('#demo1,#demo2,#demo3');
12
+ * <!--return [node1,node2,node3]-->
13
+ * ax.getEls(['#demo1','#demo2,'#demo3']);
14
+ * <!--return [node1,node2,node3]-->
15
+ */
16
+ //简介:获得节点数组。
17
+ //参数data:可以单个节点选择器,使用方法同getEl,也可以是以“,”分隔的多个选择器,也可以节点数组。
18
+ //参数parent:父节点,从该节点获取子节点,默认document。
19
+ //返回:一个节点数组。
20
+ 'use strict';
21
+ import getDataType from './getDataType';
22
+ import getEl from './getEl';
23
+ import isEmpty from './isEmpty';
24
+
25
+ const getEls = (data: Node | string | null | (Node | string)[], parent: Node | string | null = document.body): (Node | string)[] => {
26
+ let type = getDataType(data),
27
+ parentEl = getEl(parent),
28
+ root = parentEl && parentEl instanceof HTMLTemplateElement ? parentEl.content : (parentEl || document),
29
+ result: any[] = [];
30
+ //data为空直接返回空数组
31
+ if (isEmpty(data)) { return result; }
32
+ if (type.includes('HTML')) {
33
+ //一个节点
34
+ result.push(data);
35
+ } else if (type === 'String') {
36
+ data = (data as string).trim();
37
+ //以英文逗号作为节点选择器分隔符
38
+ result = data.split(',').map((k: any) => {
39
+ return [...(root as any).querySelectorAll(k)];
40
+ }).flat();
41
+ } else if (type === 'Array') {
42
+ result = (data as (Node | string)[]).map((k: any) => {
43
+ return getEl(k, parentEl);
44
+ });
45
+ }
46
+ return result.filter(Boolean);
47
+ }
48
+ export default getEls;