@jsopen/objects 1.4.0 → 1.4.1

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
@@ -1,6 +1,6 @@
1
- # v1.4.0
2
- [2024-11-22]
1
+ # v1.4.1
2
+ [2024-11-23]
3
3
 
4
4
  ### Changes
5
5
 
6
- * feat: Added "full" option to "deep" config ([`3d2a51a`](https://github.com/panates/jsopen-objects/commit/3d2a51adff14d2ac67f3ec0c8760ae167febc4d7))
6
+ * refactor: Optimized generated merge script ([`600e29d`](https://github.com/panates/jsopen-objects/commit/600e29db05ed0d6712d8f9623d632537efe756c4))
package/cjs/merge.js CHANGED
@@ -13,7 +13,7 @@ function merge(target, source, options) {
13
13
  throw new TypeError('"target" argument must be an object');
14
14
  }
15
15
  const fn = getMergeFunction(options);
16
- return fn(target, source, '', options, fn, type_guards_js_1.isBuiltIn, is_object_js_1.isObject, is_object_js_1.isPlainObject, arrayClone);
16
+ return fn(target, source, '', options, fn, is_object_js_1.isObject, is_object_js_1.isPlainObject, arrayClone);
17
17
  }
18
18
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
19
19
  const functionCache = new Map();
@@ -46,21 +46,10 @@ function getMergeFunction(options) {
46
46
  return fn;
47
47
  }
48
48
  function buildMerge(options) {
49
- const args = [
50
- 'target',
51
- 'source',
52
- 'curPath',
53
- 'options',
54
- 'mergeFunction',
55
- 'isBuiltIn',
56
- 'isObject',
57
- 'isPlainObject',
58
- 'arrayClone',
59
- ];
60
49
  const scriptL0 = [
61
50
  `
62
- const _merge = (_trgVal, _srcVal, _curPath) =>
63
- mergeFunction(_trgVal, _srcVal, _curPath, options, mergeFunction, isBuiltIn, isObject, isPlainObject, arrayClone);
51
+ const { options, merge, isObject, isPlainObject, deepTest, arrayClone } = context;
52
+ const hasOwnProperty = Object.prototype.hasOwnProperty;
64
53
  const keys = Object.getOwnPropertyNames(source);
65
54
  keys.push(...Object.getOwnPropertySymbols(source));
66
55
  let key;
@@ -69,7 +58,19 @@ let srcVal;
69
58
  let trgVal;
70
59
  `,
71
60
  ];
61
+ // noinspection JSUnusedGlobalSymbols
62
+ const context = {
63
+ options,
64
+ deepTest: is_object_js_1.isPlainObject,
65
+ isPlainObject: is_object_js_1.isPlainObject,
66
+ isObject: is_object_js_1.isObject,
67
+ arrayClone,
68
+ merge: null,
69
+ };
72
70
  if (options?.deep) {
71
+ if (options.deep === 'full') {
72
+ context.deepTest = v => typeof v === 'object' && !(0, type_guards_js_1.isBuiltIn)(v);
73
+ }
73
74
  scriptL0.push(`let subPath;`, `let _isArray;`);
74
75
  if (typeof options?.deep === 'function') {
75
76
  scriptL0.push(`const deepCallback = options.deep;`);
@@ -111,14 +112,11 @@ if (!filterCallback(key, source, target, curPath)) {
111
112
  if (typeof options?.ignore === 'function') {
112
113
  scriptL1For.push(`
113
114
  if (
114
- Object.prototype.hasOwnProperty.call(target, key) &&
115
+ hasOwnProperty.call(target, key) &&
115
116
  ignoreCallback(key, source, target, curPath)
116
117
  ) continue;
117
118
  `);
118
119
  }
119
- // scriptL1For.push(
120
- // `descriptor = { ...Object.getOwnPropertyDescriptor(source, key) };`,
121
- // );
122
120
  /** ************* copyDescriptors *****************/
123
121
  if (options?.copyDescriptors) {
124
122
  let scriptL2Descriptors = scriptL1For;
@@ -155,17 +153,14 @@ if (
155
153
  const deepArray = !options?.moveArrays || typeof options?.moveArrays === 'function';
156
154
  /** ************* deep *****************/
157
155
  if (options?.deep) {
158
- const deepCondition = options.deep === 'full'
159
- ? `typeof srcVal === 'object' && !isBuiltIn(srcVal)`
160
- : `isPlainObject(srcVal)`;
161
156
  if (deepArray) {
162
157
  scriptL1For.push(`
163
158
  _isArray = Array.isArray(srcVal);
164
- if (typeof key !== 'symbol' && (_isArray || (${deepCondition}))) {`);
159
+ if (typeof key !== 'symbol' && (_isArray || deepTest(srcVal))) {`);
165
160
  }
166
161
  else {
167
162
  scriptL1For.push(`
168
- if (typeof key !== 'symbol' && ${deepCondition}) {
163
+ if (typeof key !== 'symbol' && deepTest(srcVal)) {
169
164
  subPath = curPath + (curPath ? '.' : '') + key;`);
170
165
  }
171
166
  scriptL1For.push(`subPath = curPath + (curPath ? '.' : '') + key;`);
@@ -199,7 +194,7 @@ if (moveArraysCallback(key, subPath, target, source)) {
199
194
  scriptL4IsArray.push('}');
200
195
  }
201
196
  scriptL5CloneArrays.push(`
202
- descriptor.value = arrayClone(srcVal, _merge, subPath);
197
+ descriptor.value = arrayClone(srcVal, merge, subPath);
203
198
  Object.defineProperty(target, key, descriptor);
204
199
  continue;
205
200
  `);
@@ -211,7 +206,7 @@ if (!isObject(trgVal)) {
211
206
  descriptor.value = trgVal = {};
212
207
  Object.defineProperty(target, key, descriptor);
213
208
  }
214
- _merge(trgVal, srcVal, subPath, options);
209
+ merge(trgVal, srcVal, subPath, options);
215
210
  continue;`);
216
211
  }
217
212
  /** ************* finalize *****************/
@@ -221,7 +216,9 @@ Object.defineProperty(target, key, descriptor);`);
221
216
  scriptL0.push('return target;');
222
217
  const script = _flattenText(scriptL0);
223
218
  // eslint-disable-next-line @typescript-eslint/no-implied-eval,prefer-const
224
- return Function(...args, script);
219
+ const fn = Function('target', 'source', 'curPath', 'context', script);
220
+ context.merge = (target, source, curPath) => fn(target, source, curPath, context);
221
+ return context.merge;
225
222
  }
226
223
  function arrayClone(arr, _merge, curPath) {
227
224
  return arr.map((x) => {
package/esm/merge.js CHANGED
@@ -9,7 +9,7 @@ export function merge(target, source, options) {
9
9
  throw new TypeError('"target" argument must be an object');
10
10
  }
11
11
  const fn = getMergeFunction(options);
12
- return fn(target, source, '', options, fn, isBuiltIn, isObject, isPlainObject, arrayClone);
12
+ return fn(target, source, '', options, fn, isObject, isPlainObject, arrayClone);
13
13
  }
14
14
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
15
15
  const functionCache = new Map();
@@ -42,21 +42,10 @@ export function getMergeFunction(options) {
42
42
  return fn;
43
43
  }
44
44
  function buildMerge(options) {
45
- const args = [
46
- 'target',
47
- 'source',
48
- 'curPath',
49
- 'options',
50
- 'mergeFunction',
51
- 'isBuiltIn',
52
- 'isObject',
53
- 'isPlainObject',
54
- 'arrayClone',
55
- ];
56
45
  const scriptL0 = [
57
46
  `
58
- const _merge = (_trgVal, _srcVal, _curPath) =>
59
- mergeFunction(_trgVal, _srcVal, _curPath, options, mergeFunction, isBuiltIn, isObject, isPlainObject, arrayClone);
47
+ const { options, merge, isObject, isPlainObject, deepTest, arrayClone } = context;
48
+ const hasOwnProperty = Object.prototype.hasOwnProperty;
60
49
  const keys = Object.getOwnPropertyNames(source);
61
50
  keys.push(...Object.getOwnPropertySymbols(source));
62
51
  let key;
@@ -65,7 +54,19 @@ let srcVal;
65
54
  let trgVal;
66
55
  `,
67
56
  ];
57
+ // noinspection JSUnusedGlobalSymbols
58
+ const context = {
59
+ options,
60
+ deepTest: isPlainObject,
61
+ isPlainObject,
62
+ isObject,
63
+ arrayClone,
64
+ merge: null,
65
+ };
68
66
  if (options?.deep) {
67
+ if (options.deep === 'full') {
68
+ context.deepTest = v => typeof v === 'object' && !isBuiltIn(v);
69
+ }
69
70
  scriptL0.push(`let subPath;`, `let _isArray;`);
70
71
  if (typeof options?.deep === 'function') {
71
72
  scriptL0.push(`const deepCallback = options.deep;`);
@@ -107,14 +108,11 @@ if (!filterCallback(key, source, target, curPath)) {
107
108
  if (typeof options?.ignore === 'function') {
108
109
  scriptL1For.push(`
109
110
  if (
110
- Object.prototype.hasOwnProperty.call(target, key) &&
111
+ hasOwnProperty.call(target, key) &&
111
112
  ignoreCallback(key, source, target, curPath)
112
113
  ) continue;
113
114
  `);
114
115
  }
115
- // scriptL1For.push(
116
- // `descriptor = { ...Object.getOwnPropertyDescriptor(source, key) };`,
117
- // );
118
116
  /** ************* copyDescriptors *****************/
119
117
  if (options?.copyDescriptors) {
120
118
  let scriptL2Descriptors = scriptL1For;
@@ -151,17 +149,14 @@ if (
151
149
  const deepArray = !options?.moveArrays || typeof options?.moveArrays === 'function';
152
150
  /** ************* deep *****************/
153
151
  if (options?.deep) {
154
- const deepCondition = options.deep === 'full'
155
- ? `typeof srcVal === 'object' && !isBuiltIn(srcVal)`
156
- : `isPlainObject(srcVal)`;
157
152
  if (deepArray) {
158
153
  scriptL1For.push(`
159
154
  _isArray = Array.isArray(srcVal);
160
- if (typeof key !== 'symbol' && (_isArray || (${deepCondition}))) {`);
155
+ if (typeof key !== 'symbol' && (_isArray || deepTest(srcVal))) {`);
161
156
  }
162
157
  else {
163
158
  scriptL1For.push(`
164
- if (typeof key !== 'symbol' && ${deepCondition}) {
159
+ if (typeof key !== 'symbol' && deepTest(srcVal)) {
165
160
  subPath = curPath + (curPath ? '.' : '') + key;`);
166
161
  }
167
162
  scriptL1For.push(`subPath = curPath + (curPath ? '.' : '') + key;`);
@@ -195,7 +190,7 @@ if (moveArraysCallback(key, subPath, target, source)) {
195
190
  scriptL4IsArray.push('}');
196
191
  }
197
192
  scriptL5CloneArrays.push(`
198
- descriptor.value = arrayClone(srcVal, _merge, subPath);
193
+ descriptor.value = arrayClone(srcVal, merge, subPath);
199
194
  Object.defineProperty(target, key, descriptor);
200
195
  continue;
201
196
  `);
@@ -207,7 +202,7 @@ if (!isObject(trgVal)) {
207
202
  descriptor.value = trgVal = {};
208
203
  Object.defineProperty(target, key, descriptor);
209
204
  }
210
- _merge(trgVal, srcVal, subPath, options);
205
+ merge(trgVal, srcVal, subPath, options);
211
206
  continue;`);
212
207
  }
213
208
  /** ************* finalize *****************/
@@ -217,7 +212,9 @@ Object.defineProperty(target, key, descriptor);`);
217
212
  scriptL0.push('return target;');
218
213
  const script = _flattenText(scriptL0);
219
214
  // eslint-disable-next-line @typescript-eslint/no-implied-eval,prefer-const
220
- return Function(...args, script);
215
+ const fn = Function('target', 'source', 'curPath', 'context', script);
216
+ context.merge = (target, source, curPath) => fn(target, source, curPath, context);
217
+ return context.merge;
221
218
  }
222
219
  function arrayClone(arr, _merge, curPath) {
223
220
  return arr.map((x) => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jsopen/objects",
3
3
  "description": "Helper utilities for working with JavaScript objects and arrays",
4
- "version": "1.4.0",
4
+ "version": "1.4.1",
5
5
  "author": "Panates",
6
6
  "license": "MIT",
7
7
  "dependencies": {