@jsopen/objects 1.4.0 → 1.4.2
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 +3 -3
- package/cjs/merge.js +23 -26
- package/esm/merge.js +23 -26
- package/package.json +1 -1
- package/types/merge.d.ts +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# v1.4.
|
|
2
|
-
[2024-11-
|
|
1
|
+
# v1.4.2
|
|
2
|
+
[2024-11-23]
|
|
3
3
|
|
|
4
4
|
### Changes
|
|
5
5
|
|
|
6
|
-
*
|
|
6
|
+
* refactor: Optimized typing ([`52b8f3a`](https://github.com/panates/jsopen-objects/commit/52b8f3a9ec0584c5afc77277b9b3269828cc7866))
|
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,
|
|
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
|
|
63
|
-
|
|
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
|
-
|
|
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 || (
|
|
159
|
+
if (typeof key !== 'symbol' && (_isArray || deepTest(srcVal))) {`);
|
|
165
160
|
}
|
|
166
161
|
else {
|
|
167
162
|
scriptL1For.push(`
|
|
168
|
-
if (typeof key !== 'symbol' &&
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
|
59
|
-
|
|
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
|
-
|
|
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 || (
|
|
155
|
+
if (typeof key !== 'symbol' && (_isArray || deepTest(srcVal))) {`);
|
|
161
156
|
}
|
|
162
157
|
else {
|
|
163
158
|
scriptL1For.push(`
|
|
164
|
-
if (typeof key !== 'symbol' &&
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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
package/types/merge.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export declare function merge<A, B>(target: A, source: B, options?: merge.Options): A & B;
|
|
2
|
+
export declare function getMergeFunction(options?: merge.Options): Function;
|
|
1
3
|
export declare namespace merge {
|
|
2
4
|
type NodeCallback = (key: string | symbol, source: any, target: any, path: string) => boolean;
|
|
3
5
|
interface Options {
|
|
@@ -35,5 +37,3 @@ export declare namespace merge {
|
|
|
35
37
|
filter?: NodeCallback;
|
|
36
38
|
}
|
|
37
39
|
}
|
|
38
|
-
export declare function merge<A, B>(target: A, source: B, options?: merge.Options): A & B;
|
|
39
|
-
export declare function getMergeFunction(options?: merge.Options): Function;
|