|
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) |
2 | 13 |
|
| 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 | + */ |
3 | 29 | function mergeConfigImpure (target, source) { |
4 | 30 | 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 |
8 | 34 | } else { |
9 | | - target[k] = source[k] // assign scalar value |
| 35 | + target[k] = deepCopy(source[k]) // assign scalar value |
10 | 36 | } |
11 | 37 | } |
12 | 38 | return target |
13 | 39 | } |
14 | 40 |
|
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] |
17 | 47 |
|
18 | 48 | const isEmptyObject = obj => |
19 | 49 | Object.keys(obj).length === 0 && obj.constructor === Object |
|
0 commit comments