relay-runtime 10.0.1 → 10.1.0
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/handlers/RelayDefaultHandlerProvider.js.flow +6 -0
- package/handlers/connection/MutationHandlers.js.flow +114 -3
- package/index.js +1 -1
- package/index.js.flow +16 -1
- package/lib/handlers/RelayDefaultHandlerProvider.js +9 -0
- package/lib/handlers/connection/MutationHandlers.js +138 -12
- package/lib/index.js +7 -0
- package/lib/mutations/RelayDeclarativeMutationConfig.js +2 -2
- package/lib/mutations/commitMutation.js +1 -4
- package/lib/mutations/validateMutation.js +27 -7
- package/lib/network/RelayQueryResponseCache.js +2 -2
- package/lib/query/GraphQLTag.js +2 -1
- package/lib/query/fetchQuery.js +2 -3
- package/lib/query/fetchQueryInternal.js +2 -3
- package/lib/store/DataChecker.js +82 -5
- package/lib/store/RelayModernEnvironment.js +18 -6
- package/lib/store/RelayModernFragmentSpecResolver.js +10 -1
- package/lib/store/RelayModernOperationDescriptor.js +6 -5
- package/lib/store/RelayModernQueryExecutor.js +44 -23
- package/lib/store/RelayModernStore.js +25 -14
- package/lib/store/RelayOperationTracker.js +2 -2
- package/lib/store/RelayPublishQueue.js +1 -1
- package/lib/store/RelayReader.js +196 -33
- package/lib/store/RelayRecordSourceMapImpl.js +2 -2
- package/lib/store/RelayReferenceMarker.js +89 -5
- package/lib/store/RelayResponseNormalizer.js +119 -19
- package/lib/store/RelayStoreReactFlightUtils.js +47 -0
- package/lib/store/defaultRequiredFieldLogger.js +18 -0
- package/lib/store/normalizeRelayPayload.js +1 -1
- package/lib/subscription/requestSubscription.js +2 -3
- package/lib/util/NormalizationNode.js +1 -5
- package/lib/util/RelayConcreteNode.js +2 -0
- package/lib/util/RelayFeatureFlags.js +5 -2
- package/lib/util/getFragmentIdentifier.js +12 -3
- package/lib/util/getOperation.js +33 -0
- package/lib/util/isEmptyObject.js +25 -0
- package/lib/util/recycleNodesInto.js +4 -1
- package/lib/util/reportMissingRequiredFields.js +48 -0
- package/mutations/commitMutation.js.flow +1 -2
- package/mutations/validateMutation.js.flow +34 -5
- package/network/RelayNetworkTypes.js.flow +22 -0
- package/package.json +2 -2
- package/query/GraphQLTag.js.flow +3 -1
- package/query/fetchQuery.js.flow +2 -2
- package/query/fetchQueryInternal.js.flow +0 -5
- package/relay-runtime.js +2 -2
- package/relay-runtime.min.js +2 -2
- package/store/DataChecker.js.flow +68 -2
- package/store/RelayModernEnvironment.js.flow +29 -9
- package/store/RelayModernFragmentSpecResolver.js.flow +13 -1
- package/store/RelayModernOperationDescriptor.js.flow +5 -1
- package/store/RelayModernQueryExecutor.js.flow +47 -23
- package/store/RelayModernStore.js.flow +31 -15
- package/store/RelayPublishQueue.js.flow +1 -1
- package/store/RelayReader.js.flow +180 -15
- package/store/RelayReferenceMarker.js.flow +72 -5
- package/store/RelayResponseNormalizer.js.flow +130 -19
- package/store/RelayStoreReactFlightUtils.js.flow +64 -0
- package/store/RelayStoreTypes.js.flow +90 -31
- package/store/defaultRequiredFieldLogger.js.flow +23 -0
- package/subscription/requestSubscription.js.flow +5 -2
- package/util/NormalizationNode.js.flow +17 -2
- package/util/ReaderNode.js.flow +20 -1
- package/util/RelayConcreteNode.js.flow +6 -0
- package/util/RelayFeatureFlags.js.flow +8 -1
- package/util/getFragmentIdentifier.js.flow +33 -9
- package/util/getOperation.js.flow +40 -0
- package/util/isEmptyObject.js.flow +25 -0
- package/util/recycleNodesInto.js.flow +11 -0
- package/util/reportMissingRequiredFields.js.flow +51 -0
|
@@ -26,10 +26,16 @@ function RelayDefaultHandlerProvider(handle: string): Handler {
|
|
|
26
26
|
return ConnectionHandler;
|
|
27
27
|
case 'deleteRecord':
|
|
28
28
|
return MutationHandlers.DeleteRecordHandler;
|
|
29
|
+
case 'deleteEdge':
|
|
30
|
+
return MutationHandlers.DeleteEdgeHandler;
|
|
29
31
|
case 'appendEdge':
|
|
30
32
|
return MutationHandlers.AppendEdgeHandler;
|
|
31
33
|
case 'prependEdge':
|
|
32
34
|
return MutationHandlers.PrependEdgeHandler;
|
|
35
|
+
case 'appendNode':
|
|
36
|
+
return MutationHandlers.AppendNodeHandler;
|
|
37
|
+
case 'prependNode':
|
|
38
|
+
return MutationHandlers.PrependNodeHandler;
|
|
33
39
|
}
|
|
34
40
|
invariant(
|
|
35
41
|
false,
|
|
@@ -27,15 +27,54 @@ import type {
|
|
|
27
27
|
const DeleteRecordHandler = {
|
|
28
28
|
update: (store: RecordSourceProxy, payload: HandleFieldPayload) => {
|
|
29
29
|
const record = store.get(payload.dataID);
|
|
30
|
+
|
|
30
31
|
if (record != null) {
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
const idOrIds = record.getValue(payload.fieldKey);
|
|
33
|
+
|
|
34
|
+
if (typeof idOrIds === 'string') {
|
|
35
|
+
store.delete(idOrIds);
|
|
36
|
+
} else if (Array.isArray(idOrIds)) {
|
|
37
|
+
idOrIds.forEach(id => {
|
|
38
|
+
if (typeof id === 'string') {
|
|
39
|
+
store.delete(id);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
34
42
|
}
|
|
35
43
|
}
|
|
36
44
|
},
|
|
37
45
|
};
|
|
38
46
|
|
|
47
|
+
const DeleteEdgeHandler = {
|
|
48
|
+
update: (store: RecordSourceProxy, payload: HandleFieldPayload) => {
|
|
49
|
+
const record = store.get(payload.dataID);
|
|
50
|
+
if (record == null) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const {connections} = payload.handleArgs;
|
|
54
|
+
invariant(
|
|
55
|
+
connections != null,
|
|
56
|
+
'MutationHandlers: Expected connection IDs to be specified.',
|
|
57
|
+
);
|
|
58
|
+
const idOrIds = record.getValue(payload.fieldKey);
|
|
59
|
+
const idList = Array.isArray(idOrIds) ? idOrIds : [idOrIds];
|
|
60
|
+
idList.forEach(id => {
|
|
61
|
+
if (typeof id === 'string') {
|
|
62
|
+
for (const connectionID of connections) {
|
|
63
|
+
const connection = store.get(connectionID);
|
|
64
|
+
if (connection == null) {
|
|
65
|
+
warning(
|
|
66
|
+
false,
|
|
67
|
+
`[Relay][Mutation] The connection with id '${connectionID}' doesn't exist.`,
|
|
68
|
+
);
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
ConnectionHandler.deleteNode(connection, id);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
|
|
39
78
|
const AppendEdgeHandler: Handler = {
|
|
40
79
|
update: edgeUpdater(ConnectionHandler.insertEdgeAfter),
|
|
41
80
|
};
|
|
@@ -44,6 +83,14 @@ const PrependEdgeHandler: Handler = {
|
|
|
44
83
|
update: edgeUpdater(ConnectionHandler.insertEdgeBefore),
|
|
45
84
|
};
|
|
46
85
|
|
|
86
|
+
const AppendNodeHandler: Handler = {
|
|
87
|
+
update: nodeUpdater(ConnectionHandler.insertEdgeAfter),
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const PrependNodeHandler: Handler = {
|
|
91
|
+
update: nodeUpdater(ConnectionHandler.insertEdgeBefore),
|
|
92
|
+
};
|
|
93
|
+
|
|
47
94
|
function edgeUpdater(
|
|
48
95
|
insertFn: (RecordProxy, RecordProxy, ?string) => void,
|
|
49
96
|
): (RecordSourceProxy, HandleFieldPayload) => void {
|
|
@@ -81,8 +128,72 @@ function edgeUpdater(
|
|
|
81
128
|
};
|
|
82
129
|
}
|
|
83
130
|
|
|
131
|
+
function nodeUpdater(
|
|
132
|
+
insertFn: (RecordProxy, RecordProxy, ?string) => void,
|
|
133
|
+
): (RecordSourceProxy, HandleFieldPayload) => void {
|
|
134
|
+
return (store: RecordSourceProxy, payload: HandleFieldPayload) => {
|
|
135
|
+
const record = store.get(payload.dataID);
|
|
136
|
+
if (record == null) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const {connections, edgeTypeName} = payload.handleArgs;
|
|
140
|
+
invariant(
|
|
141
|
+
connections != null,
|
|
142
|
+
'MutationHandlers: Expected connection IDs to be specified.',
|
|
143
|
+
);
|
|
144
|
+
invariant(
|
|
145
|
+
edgeTypeName != null,
|
|
146
|
+
'MutationHandlers: Expected edge typename to be specified.',
|
|
147
|
+
);
|
|
148
|
+
let singleServerNode;
|
|
149
|
+
let serverNodes;
|
|
150
|
+
try {
|
|
151
|
+
singleServerNode = record.getLinkedRecord(payload.fieldKey, payload.args);
|
|
152
|
+
} catch {}
|
|
153
|
+
if (!singleServerNode) {
|
|
154
|
+
try {
|
|
155
|
+
serverNodes = record.getLinkedRecords(payload.fieldKey, payload.args);
|
|
156
|
+
} catch {}
|
|
157
|
+
}
|
|
158
|
+
invariant(
|
|
159
|
+
singleServerNode != null || serverNodes != null,
|
|
160
|
+
'MutationHandlers: Expected target node to exist.',
|
|
161
|
+
);
|
|
162
|
+
const serverNodeList = serverNodes ?? [singleServerNode];
|
|
163
|
+
for (const serverNode of serverNodeList) {
|
|
164
|
+
if (serverNode == null) {
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
for (const connectionID of connections) {
|
|
168
|
+
const connection = store.get(connectionID);
|
|
169
|
+
if (connection == null) {
|
|
170
|
+
warning(
|
|
171
|
+
false,
|
|
172
|
+
`[Relay][Mutation] The connection with id '${connectionID}' doesn't exist.`,
|
|
173
|
+
);
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
const clientEdge = ConnectionHandler.createEdge(
|
|
177
|
+
store,
|
|
178
|
+
connection,
|
|
179
|
+
serverNode,
|
|
180
|
+
edgeTypeName,
|
|
181
|
+
);
|
|
182
|
+
invariant(
|
|
183
|
+
clientEdge != null,
|
|
184
|
+
'MutationHandlers: Failed to build the edge.',
|
|
185
|
+
);
|
|
186
|
+
insertFn(connection, clientEdge);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
84
192
|
module.exports = {
|
|
85
193
|
AppendEdgeHandler,
|
|
86
194
|
DeleteRecordHandler,
|
|
87
195
|
PrependEdgeHandler,
|
|
196
|
+
AppendNodeHandler,
|
|
197
|
+
PrependNodeHandler,
|
|
198
|
+
DeleteEdgeHandler,
|
|
88
199
|
};
|
package/index.js
CHANGED
package/index.js.flow
CHANGED
|
@@ -56,6 +56,7 @@ const isRelayModernEnvironment = require('./store/isRelayModernEnvironment');
|
|
|
56
56
|
const isScalarAndEqual = require('./util/isScalarAndEqual');
|
|
57
57
|
const readInlineData = require('./store/readInlineData');
|
|
58
58
|
const recycleNodesInto = require('./util/recycleNodesInto');
|
|
59
|
+
const reportMissingRequiredFields = require('./util/reportMissingRequiredFields');
|
|
59
60
|
const requestSubscription = require('./subscription/requestSubscription');
|
|
60
61
|
const stableCopy = require('./util/stableCopy');
|
|
61
62
|
|
|
@@ -93,6 +94,9 @@ export type {
|
|
|
93
94
|
LogRequestInfoFunction,
|
|
94
95
|
PayloadData,
|
|
95
96
|
PayloadError,
|
|
97
|
+
ReactFlightPayloadData,
|
|
98
|
+
ReactFlightPayloadQuery,
|
|
99
|
+
ReactFlightServerTree,
|
|
96
100
|
SubscribeFunction,
|
|
97
101
|
Uploadable,
|
|
98
102
|
UploadableMap,
|
|
@@ -109,7 +113,6 @@ export type {TaskScheduler} from './store/RelayModernQueryExecutor';
|
|
|
109
113
|
export type {RecordState} from './store/RelayRecordState';
|
|
110
114
|
export type {
|
|
111
115
|
FragmentMap,
|
|
112
|
-
FragmentPointer,
|
|
113
116
|
FragmentReference,
|
|
114
117
|
FragmentSpecResolver,
|
|
115
118
|
HandleFieldPayload,
|
|
@@ -118,6 +121,7 @@ export type {
|
|
|
118
121
|
LogEvent,
|
|
119
122
|
LogFunction,
|
|
120
123
|
MissingFieldHandler,
|
|
124
|
+
MissingRequiredFields,
|
|
121
125
|
ModuleImportPointer,
|
|
122
126
|
NormalizationSelector,
|
|
123
127
|
OperationAvailability,
|
|
@@ -130,6 +134,8 @@ export type {
|
|
|
130
134
|
PluralReaderSelector,
|
|
131
135
|
Props,
|
|
132
136
|
PublishQueue,
|
|
137
|
+
ReactFlightPayloadDeserializer,
|
|
138
|
+
ReactFlightClientResponse,
|
|
133
139
|
ReaderSelector,
|
|
134
140
|
ReadOnlyRecordProxy,
|
|
135
141
|
RecordProxy,
|
|
@@ -149,6 +155,7 @@ export type {
|
|
|
149
155
|
NormalizationArgument,
|
|
150
156
|
NormalizationDefer,
|
|
151
157
|
NormalizationField,
|
|
158
|
+
NormalizationFlightField,
|
|
152
159
|
NormalizationLinkedField,
|
|
153
160
|
NormalizationLinkedHandle,
|
|
154
161
|
NormalizationLocalArgumentDefinition,
|
|
@@ -164,6 +171,7 @@ export type {
|
|
|
164
171
|
ReaderArgument,
|
|
165
172
|
ReaderArgumentDefinition,
|
|
166
173
|
ReaderField,
|
|
174
|
+
ReaderFlightField,
|
|
167
175
|
ReaderFragment,
|
|
168
176
|
ReaderInlineDataFragment,
|
|
169
177
|
ReaderInlineDataFragmentSpread,
|
|
@@ -172,8 +180,10 @@ export type {
|
|
|
172
180
|
ReaderPaginationMetadata,
|
|
173
181
|
ReaderRefetchableFragment,
|
|
174
182
|
ReaderRefetchMetadata,
|
|
183
|
+
ReaderRequiredField,
|
|
175
184
|
ReaderScalarField,
|
|
176
185
|
ReaderSelection,
|
|
186
|
+
RequiredFieldAction,
|
|
177
187
|
} from './util/ReaderNode';
|
|
178
188
|
export type {
|
|
179
189
|
ConcreteRequest,
|
|
@@ -234,6 +244,7 @@ module.exports = {
|
|
|
234
244
|
RelayModernOperationDescriptor.createRequestDescriptor,
|
|
235
245
|
getDataIDsFromFragment: RelayModernSelector.getDataIDsFromFragment,
|
|
236
246
|
getDataIDsFromObject: RelayModernSelector.getDataIDsFromObject,
|
|
247
|
+
getNode: GraphQLTag.getNode,
|
|
237
248
|
getFragment: GraphQLTag.getFragment,
|
|
238
249
|
getInlineDataFragment: GraphQLTag.getInlineDataFragment,
|
|
239
250
|
getModuleComponentKey: RelayStoreUtils.getModuleComponentKey,
|
|
@@ -253,7 +264,11 @@ module.exports = {
|
|
|
253
264
|
RelayModernSelector.getVariablesFromPluralFragment,
|
|
254
265
|
getVariablesFromSingularFragment:
|
|
255
266
|
RelayModernSelector.getVariablesFromSingularFragment,
|
|
267
|
+
reportMissingRequiredFields,
|
|
256
268
|
graphql: GraphQLTag.graphql,
|
|
269
|
+
isFragment: GraphQLTag.isFragment,
|
|
270
|
+
isInlineDataFragment: GraphQLTag.isInlineDataFragment,
|
|
271
|
+
isRequest: GraphQLTag.isRequest,
|
|
257
272
|
readInlineData,
|
|
258
273
|
|
|
259
274
|
// Declarative mutation API
|
|
@@ -24,11 +24,20 @@ function RelayDefaultHandlerProvider(handle) {
|
|
|
24
24
|
case 'deleteRecord':
|
|
25
25
|
return MutationHandlers.DeleteRecordHandler;
|
|
26
26
|
|
|
27
|
+
case 'deleteEdge':
|
|
28
|
+
return MutationHandlers.DeleteEdgeHandler;
|
|
29
|
+
|
|
27
30
|
case 'appendEdge':
|
|
28
31
|
return MutationHandlers.AppendEdgeHandler;
|
|
29
32
|
|
|
30
33
|
case 'prependEdge':
|
|
31
34
|
return MutationHandlers.PrependEdgeHandler;
|
|
35
|
+
|
|
36
|
+
case 'appendNode':
|
|
37
|
+
return MutationHandlers.AppendNodeHandler;
|
|
38
|
+
|
|
39
|
+
case 'prependNode':
|
|
40
|
+
return MutationHandlers.PrependNodeHandler;
|
|
32
41
|
}
|
|
33
42
|
|
|
34
43
|
!false ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayDefaultHandlerProvider: No handler provided for `%s`.', handle) : invariant(false) : void 0;
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
// flowlint ambiguous-object-type:error
|
|
11
11
|
'use strict';
|
|
12
12
|
|
|
13
|
-
function _createForOfIteratorHelper(o) { if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (
|
|
13
|
+
function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
|
|
14
14
|
|
|
15
|
-
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(
|
|
15
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
16
16
|
|
|
17
17
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
18
18
|
|
|
@@ -27,12 +27,56 @@ var DeleteRecordHandler = {
|
|
|
27
27
|
var record = store.get(payload.dataID);
|
|
28
28
|
|
|
29
29
|
if (record != null) {
|
|
30
|
-
var
|
|
30
|
+
var idOrIds = record.getValue(payload.fieldKey);
|
|
31
|
+
|
|
32
|
+
if (typeof idOrIds === 'string') {
|
|
33
|
+
store["delete"](idOrIds);
|
|
34
|
+
} else if (Array.isArray(idOrIds)) {
|
|
35
|
+
idOrIds.forEach(function (id) {
|
|
36
|
+
if (typeof id === 'string') {
|
|
37
|
+
store["delete"](id);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
var DeleteEdgeHandler = {
|
|
45
|
+
update: function update(store, payload) {
|
|
46
|
+
var record = store.get(payload.dataID);
|
|
31
47
|
|
|
48
|
+
if (record == null) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
var connections = payload.handleArgs.connections;
|
|
53
|
+
!(connections != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'MutationHandlers: Expected connection IDs to be specified.') : invariant(false) : void 0;
|
|
54
|
+
var idOrIds = record.getValue(payload.fieldKey);
|
|
55
|
+
var idList = Array.isArray(idOrIds) ? idOrIds : [idOrIds];
|
|
56
|
+
idList.forEach(function (id) {
|
|
32
57
|
if (typeof id === 'string') {
|
|
33
|
-
|
|
58
|
+
var _iterator = _createForOfIteratorHelper(connections),
|
|
59
|
+
_step;
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
63
|
+
var connectionID = _step.value;
|
|
64
|
+
var connection = store.get(connectionID);
|
|
65
|
+
|
|
66
|
+
if (connection == null) {
|
|
67
|
+
process.env.NODE_ENV !== "production" ? warning(false, "[Relay][Mutation] The connection with id '".concat(connectionID, "' doesn't exist.")) : void 0;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
ConnectionHandler.deleteNode(connection, id);
|
|
72
|
+
}
|
|
73
|
+
} catch (err) {
|
|
74
|
+
_iterator.e(err);
|
|
75
|
+
} finally {
|
|
76
|
+
_iterator.f();
|
|
77
|
+
}
|
|
34
78
|
}
|
|
35
|
-
}
|
|
79
|
+
});
|
|
36
80
|
}
|
|
37
81
|
};
|
|
38
82
|
var AppendEdgeHandler = {
|
|
@@ -41,6 +85,12 @@ var AppendEdgeHandler = {
|
|
|
41
85
|
var PrependEdgeHandler = {
|
|
42
86
|
update: edgeUpdater(ConnectionHandler.insertEdgeBefore)
|
|
43
87
|
};
|
|
88
|
+
var AppendNodeHandler = {
|
|
89
|
+
update: nodeUpdater(ConnectionHandler.insertEdgeAfter)
|
|
90
|
+
};
|
|
91
|
+
var PrependNodeHandler = {
|
|
92
|
+
update: nodeUpdater(ConnectionHandler.insertEdgeBefore)
|
|
93
|
+
};
|
|
44
94
|
|
|
45
95
|
function edgeUpdater(insertFn) {
|
|
46
96
|
return function (store, payload) {
|
|
@@ -54,12 +104,12 @@ function edgeUpdater(insertFn) {
|
|
|
54
104
|
!(connections != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'MutationHandlers: Expected connection IDs to be specified.') : invariant(false) : void 0;
|
|
55
105
|
var serverEdge = record.getLinkedRecord(payload.fieldKey, payload.args);
|
|
56
106
|
|
|
57
|
-
var
|
|
58
|
-
|
|
107
|
+
var _iterator2 = _createForOfIteratorHelper(connections),
|
|
108
|
+
_step2;
|
|
59
109
|
|
|
60
110
|
try {
|
|
61
|
-
for (
|
|
62
|
-
var connectionID =
|
|
111
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
112
|
+
var connectionID = _step2.value;
|
|
63
113
|
var connection = store.get(connectionID);
|
|
64
114
|
|
|
65
115
|
if (connection == null) {
|
|
@@ -72,9 +122,82 @@ function edgeUpdater(insertFn) {
|
|
|
72
122
|
insertFn(connection, clientEdge);
|
|
73
123
|
}
|
|
74
124
|
} catch (err) {
|
|
75
|
-
|
|
125
|
+
_iterator2.e(err);
|
|
126
|
+
} finally {
|
|
127
|
+
_iterator2.f();
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function nodeUpdater(insertFn) {
|
|
133
|
+
return function (store, payload) {
|
|
134
|
+
var _serverNodes;
|
|
135
|
+
|
|
136
|
+
var record = store.get(payload.dataID);
|
|
137
|
+
|
|
138
|
+
if (record == null) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
var _payload$handleArgs = payload.handleArgs,
|
|
143
|
+
connections = _payload$handleArgs.connections,
|
|
144
|
+
edgeTypeName = _payload$handleArgs.edgeTypeName;
|
|
145
|
+
!(connections != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'MutationHandlers: Expected connection IDs to be specified.') : invariant(false) : void 0;
|
|
146
|
+
!(edgeTypeName != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'MutationHandlers: Expected edge typename to be specified.') : invariant(false) : void 0;
|
|
147
|
+
var singleServerNode;
|
|
148
|
+
var serverNodes;
|
|
149
|
+
|
|
150
|
+
try {
|
|
151
|
+
singleServerNode = record.getLinkedRecord(payload.fieldKey, payload.args);
|
|
152
|
+
} catch (_unused) {}
|
|
153
|
+
|
|
154
|
+
if (!singleServerNode) {
|
|
155
|
+
try {
|
|
156
|
+
serverNodes = record.getLinkedRecords(payload.fieldKey, payload.args);
|
|
157
|
+
} catch (_unused2) {}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
!(singleServerNode != null || serverNodes != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'MutationHandlers: Expected target node to exist.') : invariant(false) : void 0;
|
|
161
|
+
var serverNodeList = (_serverNodes = serverNodes) !== null && _serverNodes !== void 0 ? _serverNodes : [singleServerNode];
|
|
162
|
+
|
|
163
|
+
var _iterator3 = _createForOfIteratorHelper(serverNodeList),
|
|
164
|
+
_step3;
|
|
165
|
+
|
|
166
|
+
try {
|
|
167
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
168
|
+
var serverNode = _step3.value;
|
|
169
|
+
|
|
170
|
+
if (serverNode == null) {
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
var _iterator4 = _createForOfIteratorHelper(connections),
|
|
175
|
+
_step4;
|
|
176
|
+
|
|
177
|
+
try {
|
|
178
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
179
|
+
var connectionID = _step4.value;
|
|
180
|
+
var connection = store.get(connectionID);
|
|
181
|
+
|
|
182
|
+
if (connection == null) {
|
|
183
|
+
process.env.NODE_ENV !== "production" ? warning(false, "[Relay][Mutation] The connection with id '".concat(connectionID, "' doesn't exist.")) : void 0;
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
var clientEdge = ConnectionHandler.createEdge(store, connection, serverNode, edgeTypeName);
|
|
188
|
+
!(clientEdge != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'MutationHandlers: Failed to build the edge.') : invariant(false) : void 0;
|
|
189
|
+
insertFn(connection, clientEdge);
|
|
190
|
+
}
|
|
191
|
+
} catch (err) {
|
|
192
|
+
_iterator4.e(err);
|
|
193
|
+
} finally {
|
|
194
|
+
_iterator4.f();
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
} catch (err) {
|
|
198
|
+
_iterator3.e(err);
|
|
76
199
|
} finally {
|
|
77
|
-
|
|
200
|
+
_iterator3.f();
|
|
78
201
|
}
|
|
79
202
|
};
|
|
80
203
|
}
|
|
@@ -82,5 +205,8 @@ function edgeUpdater(insertFn) {
|
|
|
82
205
|
module.exports = {
|
|
83
206
|
AppendEdgeHandler: AppendEdgeHandler,
|
|
84
207
|
DeleteRecordHandler: DeleteRecordHandler,
|
|
85
|
-
PrependEdgeHandler: PrependEdgeHandler
|
|
208
|
+
PrependEdgeHandler: PrependEdgeHandler,
|
|
209
|
+
AppendNodeHandler: AppendNodeHandler,
|
|
210
|
+
PrependNodeHandler: PrependNodeHandler,
|
|
211
|
+
DeleteEdgeHandler: DeleteEdgeHandler
|
|
86
212
|
};
|
package/lib/index.js
CHANGED
|
@@ -96,6 +96,8 @@ var readInlineData = require('./store/readInlineData');
|
|
|
96
96
|
|
|
97
97
|
var recycleNodesInto = require('./util/recycleNodesInto');
|
|
98
98
|
|
|
99
|
+
var reportMissingRequiredFields = require('./util/reportMissingRequiredFields');
|
|
100
|
+
|
|
99
101
|
var requestSubscription = require('./subscription/requestSubscription');
|
|
100
102
|
|
|
101
103
|
var stableCopy = require('./util/stableCopy');
|
|
@@ -140,6 +142,7 @@ module.exports = {
|
|
|
140
142
|
createRequestDescriptor: RelayModernOperationDescriptor.createRequestDescriptor,
|
|
141
143
|
getDataIDsFromFragment: RelayModernSelector.getDataIDsFromFragment,
|
|
142
144
|
getDataIDsFromObject: RelayModernSelector.getDataIDsFromObject,
|
|
145
|
+
getNode: GraphQLTag.getNode,
|
|
143
146
|
getFragment: GraphQLTag.getFragment,
|
|
144
147
|
getInlineDataFragment: GraphQLTag.getInlineDataFragment,
|
|
145
148
|
getModuleComponentKey: RelayStoreUtils.getModuleComponentKey,
|
|
@@ -157,7 +160,11 @@ module.exports = {
|
|
|
157
160
|
getVariablesFromObject: RelayModernSelector.getVariablesFromObject,
|
|
158
161
|
getVariablesFromPluralFragment: RelayModernSelector.getVariablesFromPluralFragment,
|
|
159
162
|
getVariablesFromSingularFragment: RelayModernSelector.getVariablesFromSingularFragment,
|
|
163
|
+
reportMissingRequiredFields: reportMissingRequiredFields,
|
|
160
164
|
graphql: GraphQLTag.graphql,
|
|
165
|
+
isFragment: GraphQLTag.isFragment,
|
|
166
|
+
isInlineDataFragment: GraphQLTag.isInlineDataFragment,
|
|
167
|
+
isRequest: GraphQLTag.isRequest,
|
|
161
168
|
readInlineData: readInlineData,
|
|
162
169
|
// Declarative mutation API
|
|
163
170
|
MutationTypes: RelayDeclarativeMutationConfig.MutationTypes,
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
// flowlint ambiguous-object-type:error
|
|
11
11
|
'use strict';
|
|
12
12
|
|
|
13
|
-
function _createForOfIteratorHelper(o) { if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (
|
|
13
|
+
function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
|
|
14
14
|
|
|
15
|
-
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(
|
|
15
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
16
16
|
|
|
17
17
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
18
18
|
|
|
@@ -16,8 +16,6 @@ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers
|
|
|
16
16
|
|
|
17
17
|
var RelayDeclarativeMutationConfig = require('./RelayDeclarativeMutationConfig');
|
|
18
18
|
|
|
19
|
-
var RelayFeatureFlags = require('../util/RelayFeatureFlags');
|
|
20
|
-
|
|
21
19
|
var invariant = require("fbjs/lib/invariant");
|
|
22
20
|
|
|
23
21
|
var isRelayModernEnvironment = require('../store/isRelayModernEnvironment');
|
|
@@ -60,7 +58,7 @@ function commitMutation(environment, config) {
|
|
|
60
58
|
onUnsubscribe = config.onUnsubscribe,
|
|
61
59
|
variables = config.variables,
|
|
62
60
|
uploadables = config.uploadables;
|
|
63
|
-
var operation = createOperationDescriptor(mutation, variables, generateUniqueClientID()); // TODO: remove this check after we fix flow.
|
|
61
|
+
var operation = createOperationDescriptor(mutation, variables, cacheConfig, generateUniqueClientID()); // TODO: remove this check after we fix flow.
|
|
64
62
|
|
|
65
63
|
if (typeof optimisticResponse === 'function') {
|
|
66
64
|
optimisticResponse = optimisticResponse();
|
|
@@ -82,7 +80,6 @@ function commitMutation(environment, config) {
|
|
|
82
80
|
|
|
83
81
|
var errors = [];
|
|
84
82
|
var subscription = environment.executeMutation({
|
|
85
|
-
cacheConfig: cacheConfig,
|
|
86
83
|
operation: operation,
|
|
87
84
|
optimisticResponse: optimisticResponse,
|
|
88
85
|
optimisticUpdater: optimisticUpdater,
|
|
@@ -20,6 +20,8 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
20
20
|
|
|
21
21
|
var warning = require("fbjs/lib/warning");
|
|
22
22
|
|
|
23
|
+
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
24
|
+
|
|
23
25
|
var validateMutation = function validateMutation() {};
|
|
24
26
|
|
|
25
27
|
if (process.env.NODE_ENV !== "production") {
|
|
@@ -45,7 +47,8 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
45
47
|
visitedPaths: new Set(),
|
|
46
48
|
variables: variables || {},
|
|
47
49
|
missingDiff: {},
|
|
48
|
-
extraDiff: {}
|
|
50
|
+
extraDiff: {},
|
|
51
|
+
moduleImportPaths: new Set()
|
|
49
52
|
};
|
|
50
53
|
validateSelections(optimisticResponse, mutation.operation.selections, context);
|
|
51
54
|
validateOptimisticResponse(optimisticResponse, context);
|
|
@@ -67,6 +70,7 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
67
70
|
|
|
68
71
|
case 'ScalarField':
|
|
69
72
|
case 'LinkedField':
|
|
73
|
+
case 'FlightField':
|
|
70
74
|
return validateField(optimisticResponse, selection, context);
|
|
71
75
|
|
|
72
76
|
case 'InlineFragment':
|
|
@@ -88,6 +92,8 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
88
92
|
return;
|
|
89
93
|
|
|
90
94
|
case 'ModuleImport':
|
|
95
|
+
return validateModuleImport(context);
|
|
96
|
+
|
|
91
97
|
case 'LinkedHandle':
|
|
92
98
|
case 'ScalarHandle':
|
|
93
99
|
case 'Defer':
|
|
@@ -104,6 +110,10 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
104
110
|
}
|
|
105
111
|
};
|
|
106
112
|
|
|
113
|
+
var validateModuleImport = function validateModuleImport(context) {
|
|
114
|
+
context.moduleImportPaths.add(context.path);
|
|
115
|
+
};
|
|
116
|
+
|
|
107
117
|
var validateField = function validateField(optimisticResponse, field, context) {
|
|
108
118
|
var fieldName = field.alias || field.name;
|
|
109
119
|
var path = "".concat(context.path, ".").concat(fieldName);
|
|
@@ -111,7 +121,7 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
111
121
|
|
|
112
122
|
switch (field.kind) {
|
|
113
123
|
case 'ScalarField':
|
|
114
|
-
if (
|
|
124
|
+
if (hasOwnProperty.call(optimisticResponse, fieldName) === false) {
|
|
115
125
|
addFieldToDiff(path, context.missingDiff, true);
|
|
116
126
|
}
|
|
117
127
|
|
|
@@ -120,7 +130,7 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
120
130
|
case 'LinkedField':
|
|
121
131
|
var selections = field.selections;
|
|
122
132
|
|
|
123
|
-
if (optimisticResponse[fieldName] === null ||
|
|
133
|
+
if (optimisticResponse[fieldName] === null || hasOwnProperty.call(optimisticResponse, fieldName) && optimisticResponse[fieldName] === undefined) {
|
|
124
134
|
return;
|
|
125
135
|
}
|
|
126
136
|
|
|
@@ -128,7 +138,7 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
128
138
|
if (Array.isArray(optimisticResponse[fieldName])) {
|
|
129
139
|
optimisticResponse[fieldName].forEach(function (r) {
|
|
130
140
|
if (r !== null) {
|
|
131
|
-
validateSelections(r, selections, _objectSpread({}, context, {
|
|
141
|
+
validateSelections(r, selections, _objectSpread(_objectSpread({}, context), {}, {
|
|
132
142
|
path: path
|
|
133
143
|
}));
|
|
134
144
|
}
|
|
@@ -140,7 +150,7 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
140
150
|
}
|
|
141
151
|
} else {
|
|
142
152
|
if (optimisticResponse[fieldName] instanceof Object) {
|
|
143
|
-
validateSelections(optimisticResponse[fieldName], selections, _objectSpread({}, context, {
|
|
153
|
+
validateSelections(optimisticResponse[fieldName], selections, _objectSpread(_objectSpread({}, context), {}, {
|
|
144
154
|
path: path
|
|
145
155
|
}));
|
|
146
156
|
return;
|
|
@@ -150,6 +160,12 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
150
160
|
}
|
|
151
161
|
}
|
|
152
162
|
|
|
163
|
+
case 'FlightField':
|
|
164
|
+
if (optimisticResponse[fieldName] === null || hasOwnProperty.call(optimisticResponse, fieldName) && optimisticResponse[fieldName] === undefined) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
throw new Error('validateMutation: Flight fields are not compatible with ' + 'optimistic updates, as React does not have the component code ' + 'necessary to process new data on the client. Instead, you ' + 'should update your code to require a full refetch of the Flight ' + 'field so your UI can be updated.');
|
|
153
169
|
}
|
|
154
170
|
};
|
|
155
171
|
|
|
@@ -165,7 +181,11 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
165
181
|
|
|
166
182
|
Object.keys(optimisticResponse).forEach(function (key) {
|
|
167
183
|
var value = optimisticResponse[key];
|
|
168
|
-
var path = "".concat(context.path, ".").concat(key);
|
|
184
|
+
var path = "".concat(context.path, ".").concat(key); // if it's a module import path we don't have an ast so we cannot validate it
|
|
185
|
+
|
|
186
|
+
if (context.moduleImportPaths.has(path)) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
169
189
|
|
|
170
190
|
if (!context.visitedPaths.has(path)) {
|
|
171
191
|
addFieldToDiff(path, context.extraDiff);
|
|
@@ -173,7 +193,7 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
173
193
|
}
|
|
174
194
|
|
|
175
195
|
if (value instanceof Object) {
|
|
176
|
-
validateOptimisticResponse(value, _objectSpread({}, context, {
|
|
196
|
+
validateOptimisticResponse(value, _objectSpread(_objectSpread({}, context), {}, {
|
|
177
197
|
path: path
|
|
178
198
|
}));
|
|
179
199
|
}
|
|
@@ -57,8 +57,8 @@ var RelayQueryResponseCache = /*#__PURE__*/function () {
|
|
|
57
57
|
|
|
58
58
|
var response = this._responses.get(cacheKey);
|
|
59
59
|
|
|
60
|
-
return response != null ? _objectSpread({}, response.payload, {
|
|
61
|
-
extensions: _objectSpread({}, response.payload.extensions, {
|
|
60
|
+
return response != null ? _objectSpread(_objectSpread({}, response.payload), {}, {
|
|
61
|
+
extensions: _objectSpread(_objectSpread({}, response.payload.extensions), {}, {
|
|
62
62
|
cacheTimestamp: response.fetchTime
|
|
63
63
|
})
|
|
64
64
|
}) : null;
|