Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81158 views
1
/**
2
* Copyright 2013-2014, Facebook, Inc.
3
* All rights reserved.
4
*
5
* This source code is licensed under the BSD-style license found in the
6
* LICENSE file in the root directory of this source tree. An additional grant
7
* of patent rights can be found in the PATENTS file in the same directory.
8
*
9
* @providesModule mergeHelpers
10
*
11
* requiresPolyfills: Array.isArray
12
*/
13
14
"use strict";
15
16
var invariant = require('invariant');
17
var keyMirror = require('keyMirror');
18
19
/**
20
* Maximum number of levels to traverse. Will catch circular structures.
21
* @const
22
*/
23
var MAX_MERGE_DEPTH = 36;
24
25
/**
26
* We won't worry about edge cases like new String('x') or new Boolean(true).
27
* Functions are considered terminals, and arrays are not.
28
* @param {*} o The item/object/value to test.
29
* @return {boolean} true iff the argument is a terminal.
30
*/
31
var isTerminal = function(o) {
32
return typeof o !== 'object' || o === null;
33
};
34
35
var mergeHelpers = {
36
37
MAX_MERGE_DEPTH: MAX_MERGE_DEPTH,
38
39
isTerminal: isTerminal,
40
41
/**
42
* Converts null/undefined values into empty object.
43
*
44
* @param {?Object=} arg Argument to be normalized (nullable optional)
45
* @return {!Object}
46
*/
47
normalizeMergeArg: function(arg) {
48
return arg === undefined || arg === null ? {} : arg;
49
},
50
51
/**
52
* If merging Arrays, a merge strategy *must* be supplied. If not, it is
53
* likely the caller's fault. If this function is ever called with anything
54
* but `one` and `two` being `Array`s, it is the fault of the merge utilities.
55
*
56
* @param {*} one Array to merge into.
57
* @param {*} two Array to merge from.
58
*/
59
checkMergeArrayArgs: function(one, two) {
60
invariant(
61
Array.isArray(one) && Array.isArray(two),
62
'Tried to merge arrays, instead got %s and %s.',
63
one,
64
two
65
);
66
},
67
68
/**
69
* @param {*} one Object to merge into.
70
* @param {*} two Object to merge from.
71
*/
72
checkMergeObjectArgs: function(one, two) {
73
mergeHelpers.checkMergeObjectArg(one);
74
mergeHelpers.checkMergeObjectArg(two);
75
},
76
77
/**
78
* @param {*} arg
79
*/
80
checkMergeObjectArg: function(arg) {
81
invariant(
82
!isTerminal(arg) && !Array.isArray(arg),
83
'Tried to merge an object, instead got %s.',
84
arg
85
);
86
},
87
88
/**
89
* @param {*} arg
90
*/
91
checkMergeIntoObjectArg: function(arg) {
92
invariant(
93
(!isTerminal(arg) || typeof arg === 'function') && !Array.isArray(arg),
94
'Tried to merge into an object, instead got %s.',
95
arg
96
);
97
},
98
99
/**
100
* Checks that a merge was not given a circular object or an object that had
101
* too great of depth.
102
*
103
* @param {number} Level of recursion to validate against maximum.
104
*/
105
checkMergeLevel: function(level) {
106
invariant(
107
level < MAX_MERGE_DEPTH,
108
'Maximum deep merge depth exceeded. You may be attempting to merge ' +
109
'circular structures in an unsupported way.'
110
);
111
},
112
113
/**
114
* Checks that the supplied merge strategy is valid.
115
*
116
* @param {string} Array merge strategy.
117
*/
118
checkArrayStrategy: function(strategy) {
119
invariant(
120
strategy === undefined || strategy in mergeHelpers.ArrayStrategies,
121
'You must provide an array strategy to deep merge functions to ' +
122
'instruct the deep merge how to resolve merging two arrays.'
123
);
124
},
125
126
/**
127
* Set of possible behaviors of merge algorithms when encountering two Arrays
128
* that must be merged together.
129
* - `clobber`: The left `Array` is ignored.
130
* - `indexByIndex`: The result is achieved by recursively deep merging at
131
* each index. (not yet supported.)
132
*/
133
ArrayStrategies: keyMirror({
134
Clobber: true,
135
IndexByIndex: true
136
})
137
138
};
139
140
module.exports = mergeHelpers;
141
142