Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81152 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 update
10
*/
11
12
"use strict";
13
14
var assign = require('Object.assign');
15
var keyOf = require('keyOf');
16
var invariant = require('invariant');
17
18
function shallowCopy(x) {
19
if (Array.isArray(x)) {
20
return x.concat();
21
} else if (x && typeof x === 'object') {
22
return assign(new x.constructor(), x);
23
} else {
24
return x;
25
}
26
}
27
28
var COMMAND_PUSH = keyOf({$push: null});
29
var COMMAND_UNSHIFT = keyOf({$unshift: null});
30
var COMMAND_SPLICE = keyOf({$splice: null});
31
var COMMAND_SET = keyOf({$set: null});
32
var COMMAND_MERGE = keyOf({$merge: null});
33
var COMMAND_APPLY = keyOf({$apply: null});
34
35
var ALL_COMMANDS_LIST = [
36
COMMAND_PUSH,
37
COMMAND_UNSHIFT,
38
COMMAND_SPLICE,
39
COMMAND_SET,
40
COMMAND_MERGE,
41
COMMAND_APPLY
42
];
43
44
var ALL_COMMANDS_SET = {};
45
46
ALL_COMMANDS_LIST.forEach(function(command) {
47
ALL_COMMANDS_SET[command] = true;
48
});
49
50
function invariantArrayCase(value, spec, command) {
51
invariant(
52
Array.isArray(value),
53
'update(): expected target of %s to be an array; got %s.',
54
command,
55
value
56
);
57
var specValue = spec[command];
58
invariant(
59
Array.isArray(specValue),
60
'update(): expected spec of %s to be an array; got %s. ' +
61
'Did you forget to wrap your parameter in an array?',
62
command,
63
specValue
64
);
65
}
66
67
function update(value, spec) {
68
invariant(
69
typeof spec === 'object',
70
'update(): You provided a key path to update() that did not contain one ' +
71
'of %s. Did you forget to include {%s: ...}?',
72
ALL_COMMANDS_LIST.join(', '),
73
COMMAND_SET
74
);
75
76
if (spec.hasOwnProperty(COMMAND_SET)) {
77
invariant(
78
Object.keys(spec).length === 1,
79
'Cannot have more than one key in an object with %s',
80
COMMAND_SET
81
);
82
83
return spec[COMMAND_SET];
84
}
85
86
var nextValue = shallowCopy(value);
87
88
if (spec.hasOwnProperty(COMMAND_MERGE)) {
89
var mergeObj = spec[COMMAND_MERGE];
90
invariant(
91
mergeObj && typeof mergeObj === 'object',
92
'update(): %s expects a spec of type \'object\'; got %s',
93
COMMAND_MERGE,
94
mergeObj
95
);
96
invariant(
97
nextValue && typeof nextValue === 'object',
98
'update(): %s expects a target of type \'object\'; got %s',
99
COMMAND_MERGE,
100
nextValue
101
);
102
assign(nextValue, spec[COMMAND_MERGE]);
103
}
104
105
if (spec.hasOwnProperty(COMMAND_PUSH)) {
106
invariantArrayCase(value, spec, COMMAND_PUSH);
107
spec[COMMAND_PUSH].forEach(function(item) {
108
nextValue.push(item);
109
});
110
}
111
112
if (spec.hasOwnProperty(COMMAND_UNSHIFT)) {
113
invariantArrayCase(value, spec, COMMAND_UNSHIFT);
114
spec[COMMAND_UNSHIFT].forEach(function(item) {
115
nextValue.unshift(item);
116
});
117
}
118
119
if (spec.hasOwnProperty(COMMAND_SPLICE)) {
120
invariant(
121
Array.isArray(value),
122
'Expected %s target to be an array; got %s',
123
COMMAND_SPLICE,
124
value
125
);
126
invariant(
127
Array.isArray(spec[COMMAND_SPLICE]),
128
'update(): expected spec of %s to be an array of arrays; got %s. ' +
129
'Did you forget to wrap your parameters in an array?',
130
COMMAND_SPLICE,
131
spec[COMMAND_SPLICE]
132
);
133
spec[COMMAND_SPLICE].forEach(function(args) {
134
invariant(
135
Array.isArray(args),
136
'update(): expected spec of %s to be an array of arrays; got %s. ' +
137
'Did you forget to wrap your parameters in an array?',
138
COMMAND_SPLICE,
139
spec[COMMAND_SPLICE]
140
);
141
nextValue.splice.apply(nextValue, args);
142
});
143
}
144
145
if (spec.hasOwnProperty(COMMAND_APPLY)) {
146
invariant(
147
typeof spec[COMMAND_APPLY] === 'function',
148
'update(): expected spec of %s to be a function; got %s.',
149
COMMAND_APPLY,
150
spec[COMMAND_APPLY]
151
);
152
nextValue = spec[COMMAND_APPLY](nextValue);
153
}
154
155
for (var k in spec) {
156
if (!(ALL_COMMANDS_SET.hasOwnProperty(k) && ALL_COMMANDS_SET[k])) {
157
nextValue[k] = update(value[k], spec[k]);
158
}
159
}
160
161
return nextValue;
162
}
163
164
module.exports = update;
165
166