Skip to content

Commit c240ad3

Browse files
committed
fix: function mergeConfig now uses deepCopy through JSON serdes.
Before we created only a shallow copy using the spread operator and we also passed arrays by reference.
1 parent 34d19fb commit c240ad3

1 file changed

Lines changed: 37 additions & 7 deletions

File tree

src/utils.js

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,49 @@
1-
const mergeConfig = (a, b) => mergeConfigImpure({ ...a }, b)
1+
// @ts-check
2+
/**
3+
* Merges `b` configuration structure to `a` by creating
4+
* a deep copy of `a`.
5+
* - Note: The configuration structure `a` must be serializable to JSON.
6+
* - This function is pure
7+
*
8+
* @template T
9+
* @param {T} a
10+
* @param {T} b
11+
*/
12+
const mergeConfig = (a, b) => mergeConfigImpure(deepCopy(a), b)
213

14+
/**
15+
* Creates a deep copy of an object using JSON seriazlie/deserialize.
16+
* This function is pure
17+
* @template T
18+
* @param {T} x Must be serializable to JSON!
19+
* @return {T}
20+
*/
21+
const deepCopy = x => JSON.parse(JSON.stringify(x))
22+
23+
/**
24+
* Merges `b` to `a` by altering `a`.
25+
* @template T
26+
* @param {T} target
27+
* @param {T} source
28+
*/
329
function mergeConfigImpure (target, source) {
430
for (let k in source) {
5-
const objOrScalar = target[k]
6-
if (objOrScalar != null && objOrScalar.constructor === Object) {
7-
mergeConfigImpure(objOrScalar, source[k]) // recurse on objects
31+
const maybeObject = target[k]
32+
if (maybeObject != null && maybeObject.constructor === Object) {
33+
mergeConfigImpure(maybeObject, source[k]) // recurse on objects
834
} else {
9-
target[k] = source[k] // assign scalar value
35+
target[k] = deepCopy(source[k]) // assign scalar value
1036
}
1137
}
1238
return target
1339
}
1440

15-
/** @type {(x:object) => object|object[]} */
16-
const ensureArray = x => (Object(x) instanceof Array ? x : [x])
41+
/**
42+
* @template T
43+
* @param {T | T[]} x
44+
* @return {T[]}
45+
*/
46+
const ensureArray = x => x instanceof Array ? x : [x]
1747

1848
const isEmptyObject = obj =>
1949
Object.keys(obj).length === 0 && obj.constructor === Object

0 commit comments

Comments
 (0)