@codady/utils 0.0.14 → 0.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/deepMerge.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @since Last modified: 2025/12/25 12:10:30
2
+ * @since Last modified: 2025/12/26 15:40:50
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.
@@ -59,20 +59,42 @@ export interface DeepMergeOptions {
59
59
  // 启用克隆时传递给deepClone函数的选项
60
60
  deepClone?: Record<string, any>;
61
61
 
62
- // Callback function executed before merging each data structure
63
- // 在每个数据结构合并前执行的回调函数
64
- onBeforeMerge?: (
65
- target: Object | Array<any> | Map<any, any> | Set<any>,
66
- source: Object | Array<any> | Map<any, any> | Set<any> | any
67
- ) => void;
68
-
69
- // Callback function executed after merging each data structure
70
- // 在每个数据结构合并后执行的回调函数
71
- onAfterMerge?: (
72
- result: Object | Array<any> | Map<any, any> | Set<any>,
73
- originalTarget: Object | Array<any> | Map<any, any> | Set<any>,
74
- source: Object | Array<any> | Map<any, any> | Set<any> | any
75
- ) => void;
62
+ /**
63
+ * Interceptor function. If returns a non-null value, use it as the merging result.
64
+ * 拦截器函数。如果返回非null值,则将其用作合并结果。
65
+ */
66
+ interceptor?: (params: {
67
+ target: any;
68
+ source: any;
69
+ parent?: any;
70
+ }) => any;
71
+
72
+ /**
73
+ * Callback function executed before merging each data structure
74
+ * 在每个数据结构合并前执行的回调函数
75
+ */
76
+ onBeforeMerge?: (params: {
77
+ target: any;
78
+ source: any;
79
+ parent?: any;
80
+ }) => void;
81
+
82
+ /**
83
+ * Callback function executed after merging each data structure
84
+ * 在每个数据结构合并后执行的回调函数
85
+ */
86
+ onAfterMerge?: (params: {
87
+ result: any;
88
+ target: any;
89
+ source: any;
90
+ parent?: any;
91
+ type?: '' | 'Object' | 'Array' | 'Map' | 'Set';
92
+ }) => void;
93
+
94
+ /**
95
+ * 深度合并时的临时保存的父对象
96
+ */
97
+ parent?: any;
76
98
  }
77
99
  export type EnableObject = {
78
100
  enable: boolean;
@@ -122,12 +144,31 @@ const deepMerge = (target: Object | Array<any> | Map<any, any> | Set<any>, sourc
122
144
  }, opts),
123
145
  // Main helper function for recursive merging
124
146
  // 递归合并的主辅助函数
125
- deepMergeHelper = (target: any, source: any, options: DeepMergeOptions): any => {
147
+ smartMerger = (target: any, source: any, options: DeepMergeOptions): any => {
126
148
  let targetType = getDataType(target),
127
149
  sourceType = getDataType(source),
128
150
  flag = true,
129
- type,
151
+ type: any,
130
152
  result;
153
+
154
+ // Check interceptor - if it returns a value (not null/undefined), use it directly
155
+ if (options.interceptor && typeof options.interceptor === 'function') {
156
+ let interceptorResult = options.interceptor({ target, source, parent: options.parent });
157
+ if ((interceptorResult ?? false)) {
158
+ //如果不是返回{target,source},那么直接返回interceptorResult
159
+ if (interceptorResult?.target === null || interceptorResult?.source === null) {
160
+ return interceptorResult;
161
+ } else {
162
+ //interceptorResult={target,source}
163
+ target = interceptorResult.target;
164
+ source = interceptorResult.source;
165
+ }
166
+ }
167
+ // If interceptor returns null/undefined, continue with normal cloning process
168
+ }
169
+
170
+ options?.onBeforeMerge?.({ target, source, parent: options.parent });
171
+
131
172
  // Determine the type and perform appropriate merging
132
173
  // 确定类型并执行相应的合并
133
174
  if (targetType === 'Object' && sourceType === 'Object') {
@@ -146,6 +187,7 @@ const deepMerge = (target: Object | Array<any> | Map<any, any> | Set<any>, sourc
146
187
  flag = false;
147
188
  result = target;
148
189
  }
190
+ options?.onAfterMerge?.({ result, target, source, type, parent: opts.parent });
149
191
  return { result, flag, type };
150
192
  },
151
193
  // Special handling for objects with enable property
@@ -174,7 +216,6 @@ const deepMerge = (target: Object | Array<any> | Map<any, any> | Set<any>, sourc
174
216
  if (targetType !== 'Object' || sourceType !== 'Object') {
175
217
  return target;
176
218
  }
177
- opts?.onBeforeMerge?.(target, source);
178
219
 
179
220
  const options = Object.assign({ inheritMissing: true, targetClone: false, useEnable: true }, opts);
180
221
  let result: any = {};
@@ -185,7 +226,7 @@ const deepMerge = (target: Object | Array<any> | Map<any, any> | Set<any>, sourc
185
226
  for (let k in source) {
186
227
  if (source.hasOwnProperty(k) && result.hasOwnProperty(k)) {
187
228
 
188
- let resp = deepMergeHelper((result as any)[k], source[k], opts);
229
+ let resp = smartMerger((result as any)[k], source[k], { ...opts, parent: result });
189
230
  //resp={result,flag,type}
190
231
  //flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
191
232
  if (!resp.flag) {
@@ -221,13 +262,12 @@ const deepMerge = (target: Object | Array<any> | Map<any, any> | Set<any>, sourc
221
262
  for (let k of symbols) (result as any)[k] = source[k];
222
263
  }
223
264
  }
224
- options?.onAfterMerge?.(result, target, source);
225
265
  return result;
226
266
  },
227
267
  deepMergeArrays = (target: any[], source: any[], options: DeepMergeOptions = {}): any[] => {
228
268
  // Ensure both target and source are arrays
229
269
  if (!Array.isArray(target) || !Array.isArray(source)) return target;
230
- options?.onBeforeMerge?.(target, source);
270
+
231
271
  // Merge options, with default values
232
272
  const opts = Object.assign({ dataMode: 'clear', inheritMissing: true, targetClone: false }, options),
233
273
 
@@ -241,7 +281,7 @@ const deepMerge = (target: Object | Array<any> | Map<any, any> | Set<any>, sourc
241
281
  // If not allowed to add beyond length
242
282
  // 如果不允许添加超过长度
243
283
  if (!opts.inheritMissing && i >= result.length) break;
244
- let resp = deepMergeHelper(result[i], source[i], opts);
284
+ let resp = smartMerger(result[i], source[i], { ...opts, parent: result });
245
285
  //resp={result,flag,type}
246
286
  //flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
247
287
  if (!resp.flag) {
@@ -256,13 +296,12 @@ const deepMerge = (target: Object | Array<any> | Map<any, any> | Set<any>, sourc
256
296
  result.length = 0;
257
297
  result.push(...source);
258
298
  }
259
- options?.onAfterMerge?.(result, target, source);
260
299
  return result;
261
300
  },
262
301
  deepMergeMaps = (target: Map<any, any>, source: Map<any, any>, options: DeepMergeOptions = {}): Map<any, any> => {
263
302
  // Ensure both target and source are Maps
264
303
  if (!(target instanceof Map) || !(source instanceof Map)) return target;
265
- options?.onBeforeMerge?.(target, source);
304
+
266
305
  // Merge options, with default values
267
306
  const opts = Object.assign({ inheritMissing: true, targetClone: false, useEnable: true }, options),
268
307
 
@@ -275,7 +314,7 @@ const deepMerge = (target: Object | Array<any> | Map<any, any> | Set<any>, sourc
275
314
  if (result.has(key)) {
276
315
  const _target = result.get(key),
277
316
  _source = value,
278
- resp = deepMergeHelper(_target, _source, opts);
317
+ resp = smartMerger(_target, _source, opts);
279
318
  //resp={result,flag,type}
280
319
  //flag=true表示类型一致并完成了合并,false表示并没有合并需要直接赋值
281
320
  if (!resp.flag) {
@@ -289,13 +328,12 @@ const deepMerge = (target: Object | Array<any> | Map<any, any> | Set<any>, sourc
289
328
  // If the key doesn't exist in the target, add the entry from the source Map
290
329
  options.inheritMissing && result.set(key, value);
291
330
  }
292
- options?.onAfterMerge?.(result, target, source);
293
331
  return result;
294
332
  },
295
333
  deepMergeSets = (target: Set<any>, source: Set<any>, options: DeepMergeOptions = {}): Set<any> => {
296
334
  // Ensure both target and source are Sets
297
335
  if (!(target instanceof Set) || !(source instanceof Set)) return target;
298
- options?.onBeforeMerge?.(target, source);
336
+
299
337
  // Merge options, with default values
300
338
  const opts = Object.assign({ dataMode: 'clear', inheritMissing: true, targetClone: false, useEnable: true }, options),
301
339
 
@@ -307,11 +345,10 @@ const deepMerge = (target: Object | Array<any> | Map<any, any> | Set<any>, sourc
307
345
  // Replace mode: recursively merge items in the Sets
308
346
  const _result = [...result],
309
347
  _source = [...source],
310
- resp = deepMergeHelper(_result, _source, opts);
348
+ resp = smartMerger(_result, _source, opts);
311
349
  result.clear();
312
350
  for (let item of resp.result) result.add(item);
313
351
 
314
-
315
352
  } else if (opts.dataMode === 'concat') {
316
353
  // Concatenate mode: add all items from the source Set to the target Set
317
354
  for (let item of source) result.add(item);
@@ -320,9 +357,11 @@ const deepMerge = (target: Object | Array<any> | Map<any, any> | Set<any>, sourc
320
357
  result.clear();
321
358
  for (let item of source) result.add(item);
322
359
  }
323
- options?.onAfterMerge?.(result, target, source);
360
+
324
361
  return result;
325
362
  };
326
- return deepMergeHelper(target, source, options).result;
363
+
364
+
365
+ return smartMerger(target, source, options).result;
327
366
  }
328
367
  export default deepMerge;