react-relay 2.0.0-rc.2 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- package/index.js +2 -2
- package/lib/ReactRelayContext.js +6 -3
- package/lib/ReactRelayFragmentContainer.js +48 -46
- package/lib/ReactRelayFragmentMockRenderer.js +5 -1
- package/lib/ReactRelayPaginationContainer.js +102 -68
- package/lib/ReactRelayQueryFetcher.js +54 -28
- package/lib/ReactRelayQueryRenderer.js +28 -20
- package/lib/ReactRelayRefetchContainer.js +70 -58
- package/lib/ReactRelayTestMocker.js +56 -43
- package/lib/ReactRelayTypes.js +1 -1
- package/lib/RelayContext.js +8 -2
- package/lib/assertFragmentMap.js +9 -7
- package/lib/buildReactRelayContainer.js +32 -23
- package/lib/index.js +41 -0
- package/lib/isRelayEnvironment.js +1 -1
- package/lib/isRelayVariables.js +1 -1
- package/lib/readContext.js +7 -4
- package/package.json +4 -4
- package/react-relay.js +2 -2
- package/react-relay.min.js +2 -2
- package/classic.js +0 -10
- package/compat.js +0 -10
- package/lib/ConcreteQuery.js +0 -10
- package/lib/GraphQLQueryRunner.js +0 -264
- package/lib/GraphQLRange.js +0 -1124
- package/lib/GraphQLSegment.js +0 -743
- package/lib/GraphQLStoreChangeEmitter.js +0 -141
- package/lib/GraphQLStoreQueryResolver.js +0 -288
- package/lib/GraphQLStoreRangeUtils.js +0 -126
- package/lib/QueryBuilder.js +0 -228
- package/lib/ReactRelayClassicExports.js +0 -29
- package/lib/ReactRelayCompatContainerBuilder.js +0 -175
- package/lib/ReactRelayCompatPublic.js +0 -28
- package/lib/ReactRelayContainerProfiler.js +0 -30
- package/lib/ReactRelayFragmentContainer-flowtest.js +0 -201
- package/lib/ReactRelayPaginationContainer-flowtest.js +0 -213
- package/lib/ReactRelayPublic.js +0 -29
- package/lib/ReactRelayRefetchContainer-flowtest.js +0 -191
- package/lib/RelayCacheProcessor.js +0 -196
- package/lib/RelayChangeTracker.js +0 -83
- package/lib/RelayClassicContainerUtils.js +0 -49
- package/lib/RelayClassicCore.js +0 -34
- package/lib/RelayClassicRecordState.js +0 -31
- package/lib/RelayCompatContainer.js +0 -25
- package/lib/RelayCompatEnvironment.js +0 -27
- package/lib/RelayCompatMutations.js +0 -133
- package/lib/RelayCompatPaginationContainer.js +0 -27
- package/lib/RelayCompatRefetchContainer.js +0 -27
- package/lib/RelayCompatTypes.js +0 -10
- package/lib/RelayContainer.js +0 -889
- package/lib/RelayContainerComparators.js +0 -75
- package/lib/RelayContainerProxy.js +0 -21
- package/lib/RelayDefaultNetworkLayer.js +0 -192
- package/lib/RelayEnvironment.js +0 -449
- package/lib/RelayEnvironmentTypes.js +0 -10
- package/lib/RelayFetchMode.js +0 -17
- package/lib/RelayFragmentPointer.js +0 -161
- package/lib/RelayFragmentReference.js +0 -249
- package/lib/RelayFragmentSpecResolver.js +0 -305
- package/lib/RelayGraphQLMutation.js +0 -288
- package/lib/RelayGraphQLTag.js +0 -42
- package/lib/RelayInternalTypes.js +0 -15
- package/lib/RelayInternals.js +0 -24
- package/lib/RelayMetaRoute.js +0 -35
- package/lib/RelayMockRenderer.js +0 -71
- package/lib/RelayModern-flowtest.js +0 -342
- package/lib/RelayModernFlowtest_badref.graphql.js +0 -10
- package/lib/RelayModernFlowtest_notref.graphql.js +0 -10
- package/lib/RelayModernFlowtest_user.graphql.js +0 -10
- package/lib/RelayModernFlowtest_users.graphql.js +0 -10
- package/lib/RelayMutation.js +0 -322
- package/lib/RelayMutationDebugPrinter.js +0 -47
- package/lib/RelayMutationQuery.js +0 -558
- package/lib/RelayMutationQueue.js +0 -530
- package/lib/RelayMutationRequest.js +0 -103
- package/lib/RelayMutationTracker.js +0 -113
- package/lib/RelayMutationTransaction.js +0 -92
- package/lib/RelayMutationTransactionStatus.js +0 -55
- package/lib/RelayNetworkDebug.js +0 -131
- package/lib/RelayNetworkLayer.js +0 -185
- package/lib/RelayNodeInterface.js +0 -104
- package/lib/RelayOperationDescriptor.js +0 -40
- package/lib/RelayOptimisticMutationUtils.js +0 -208
- package/lib/RelayPendingQueryTracker.js +0 -166
- package/lib/RelayPropTypes.js +0 -57
- package/lib/RelayPublic.js +0 -44
- package/lib/RelayQL.js +0 -128
- package/lib/RelayQuery.js +0 -1584
- package/lib/RelayQueryCaching.js +0 -33
- package/lib/RelayQueryConfig.js +0 -58
- package/lib/RelayQueryPath.js +0 -204
- package/lib/RelayQueryRequest.js +0 -103
- package/lib/RelayQueryTracker.js +0 -86
- package/lib/RelayQueryTransform.js +0 -91
- package/lib/RelayQueryVisitor.js +0 -93
- package/lib/RelayQueryWriter.js +0 -573
- package/lib/RelayReadyState.js +0 -83
- package/lib/RelayReadyStateRenderer.js +0 -145
- package/lib/RelayRecord.js +0 -75
- package/lib/RelayRecordStatusMap.js +0 -57
- package/lib/RelayRecordStore.js +0 -433
- package/lib/RelayRecordWriter.js +0 -601
- package/lib/RelayRefQueryDescriptor.js +0 -27
- package/lib/RelayRenderer.js +0 -268
- package/lib/RelayRootContainer.js +0 -125
- package/lib/RelayRoute.js +0 -92
- package/lib/RelayRouteFragment.js +0 -44
- package/lib/RelaySelector.js +0 -201
- package/lib/RelayShallowMock.js +0 -69
- package/lib/RelayStaticContainer.js +0 -38
- package/lib/RelayStore.js +0 -12
- package/lib/RelayStoreConstants.js +0 -20
- package/lib/RelayStoreData.js +0 -660
- package/lib/RelayTaskQueue.js +0 -189
- package/lib/RelayTypes.js +0 -13
- package/lib/RelayVariable.js +0 -32
- package/lib/RelayVariables.js +0 -92
- package/lib/buildRQL.js +0 -160
- package/lib/callsFromGraphQL.js +0 -74
- package/lib/callsToGraphQL.js +0 -34
- package/lib/checkRelayQueryData.js +0 -250
- package/lib/createRelayQuery.js +0 -17
- package/lib/dedent.js +0 -49
- package/lib/diffRelayQuery.js +0 -757
- package/lib/directivesToGraphQL.js +0 -39
- package/lib/filterRelayQuery.js +0 -29
- package/lib/findRelayQueryLeaves.js +0 -293
- package/lib/flattenRelayQuery.js +0 -121
- package/lib/flattenSplitRelayQueries.js +0 -44
- package/lib/forEachRootCallArg.js +0 -40
- package/lib/fromGraphQL.js +0 -48
- package/lib/generateClientEdgeID.js +0 -22
- package/lib/generateClientID.js +0 -27
- package/lib/generateConcreteFragmentID.js +0 -30
- package/lib/generateForceIndex.js +0 -24
- package/lib/generateRQLFieldAlias.js +0 -39
- package/lib/getRangeBehavior.js +0 -58
- package/lib/getRelayQueries.js +0 -83
- package/lib/intersectRelayQuery.js +0 -149
- package/lib/isClassicRelayContext.js +0 -20
- package/lib/isClassicRelayEnvironment.js +0 -20
- package/lib/isCompatibleRelayFragmentType.js +0 -27
- package/lib/isRelayContainer.js +0 -16
- package/lib/makeLegacyStringishComponentRef.js +0 -52
- package/lib/printRelayOSSQuery.js +0 -329
- package/lib/printRelayQuery.js +0 -26
- package/lib/rangeOperationToMetadataKey.js +0 -25
- package/lib/readRelayQueryData.js +0 -551
- package/lib/relayUnstableBatchedUpdates.js +0 -12
- package/lib/relayUnstableBatchedUpdates.native.js +0 -11
- package/lib/restoreRelayCacheData.js +0 -188
- package/lib/serializeRelayQueryCall.js +0 -42
- package/lib/splitDeferredRelayQueries.js +0 -298
- package/lib/stableStringify.js +0 -85
- package/lib/testEditDistance.js +0 -112
- package/lib/throwFailedPromise.js +0 -26
- package/lib/toGraphQL.js +0 -94
- package/lib/transformRelayQueryPayload.js +0 -145
- package/lib/validateMutationConfig.js +0 -117
- package/lib/validateRelayReadQuery.js +0 -112
- package/lib/writeRelayQueryPayload.js +0 -44
- package/lib/writeRelayUpdatePayload.js +0 -513
- package/react-relay-classic.js +0 -4
- package/react-relay-classic.min.js +0 -9
- package/react-relay-compat.js +0 -4
- package/react-relay-compat.min.js +0 -9
package/lib/diffRelayQuery.js
DELETED
@@ -1,757 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* Copyright (c) Facebook, Inc. and its affiliates.
|
3
|
-
*
|
4
|
-
* This source code is licensed under the MIT license found in the
|
5
|
-
* LICENSE file in the root directory of this source tree.
|
6
|
-
*
|
7
|
-
*
|
8
|
-
* @format
|
9
|
-
*/
|
10
|
-
'use strict';
|
11
|
-
|
12
|
-
var idField = require("./RelayQuery").Field.build({
|
13
|
-
fieldName: require("./RelayNodeInterface").ID,
|
14
|
-
metadata: {
|
15
|
-
isRequisite: true
|
16
|
-
},
|
17
|
-
type: 'String'
|
18
|
-
});
|
19
|
-
|
20
|
-
var typeField = require("./RelayQuery").Field.build({
|
21
|
-
fieldName: require("./RelayNodeInterface").TYPENAME,
|
22
|
-
metadata: {
|
23
|
-
isRequisite: true
|
24
|
-
},
|
25
|
-
type: 'String'
|
26
|
-
});
|
27
|
-
|
28
|
-
var nodeWithID = require("./RelayQuery").Field.build({
|
29
|
-
fieldName: require("./RelayNodeInterface").NODE,
|
30
|
-
children: [idField, typeField],
|
31
|
-
metadata: {
|
32
|
-
canHaveSubselections: true
|
33
|
-
},
|
34
|
-
type: require("./RelayNodeInterface").NODE_TYPE
|
35
|
-
});
|
36
|
-
|
37
|
-
/**
|
38
|
-
* @internal
|
39
|
-
*
|
40
|
-
* Computes the difference between the data requested in `root` and the data
|
41
|
-
* available in `store`. It returns a minimal set of queries that will fulfill
|
42
|
-
* the difference, or an empty array if the query can be resolved locally.
|
43
|
-
*/
|
44
|
-
function diffRelayQuery(root, store, queryTracker) {
|
45
|
-
var path = require("./RelayQueryPath").create(root);
|
46
|
-
|
47
|
-
var queries = [];
|
48
|
-
var visitor = new RelayDiffQueryBuilder(store, queryTracker);
|
49
|
-
var rootIdentifyingArg = root.getIdentifyingArg();
|
50
|
-
var rootIdentifyingArgValue = rootIdentifyingArg && rootIdentifyingArg.value || null;
|
51
|
-
var isPluralCall = Array.isArray(rootIdentifyingArgValue) && rootIdentifyingArgValue.length > 1;
|
52
|
-
var metadata;
|
53
|
-
|
54
|
-
if (rootIdentifyingArg != null) {
|
55
|
-
metadata = {
|
56
|
-
identifyingArgName: rootIdentifyingArg.name,
|
57
|
-
identifyingArgType: rootIdentifyingArg.type != null ? rootIdentifyingArg.type : require("./RelayNodeInterface").ID_TYPE,
|
58
|
-
isAbstract: root.isAbstract(),
|
59
|
-
isDeferred: false,
|
60
|
-
isPlural: false
|
61
|
-
};
|
62
|
-
}
|
63
|
-
|
64
|
-
var fieldName = root.getFieldName();
|
65
|
-
var storageKey = root.getStorageKey();
|
66
|
-
|
67
|
-
require("./forEachRootCallArg")(root, function (_ref) {
|
68
|
-
var identifyingArgValue = _ref.identifyingArgValue,
|
69
|
-
identifyingArgKey = _ref.identifyingArgKey;
|
70
|
-
var nodeRoot;
|
71
|
-
|
72
|
-
if (isPluralCall) {
|
73
|
-
!(identifyingArgValue != null) ? process.env.NODE_ENV !== "production" ? require("fbjs/lib/invariant")(false, 'diffRelayQuery(): Unexpected null or undefined value in root call ' + 'argument array for query, `%s(...).', fieldName) : require("fbjs/lib/invariant")(false) : void 0;
|
74
|
-
nodeRoot = require("./RelayQuery").Root.build(root.getName(), fieldName, [identifyingArgValue], root.getChildren(), metadata, root.getType());
|
75
|
-
} else {
|
76
|
-
// Reuse `root` if it only maps to one result.
|
77
|
-
nodeRoot = root;
|
78
|
-
} // The whole query must be fetched if the root dataID is unknown.
|
79
|
-
|
80
|
-
|
81
|
-
var dataID = store.getDataID(storageKey, identifyingArgKey);
|
82
|
-
|
83
|
-
if (dataID == null) {
|
84
|
-
queries.push(nodeRoot);
|
85
|
-
return;
|
86
|
-
} // Diff the current dataID
|
87
|
-
|
88
|
-
|
89
|
-
var scope = makeScope(dataID);
|
90
|
-
var diffOutput = visitor.visit(nodeRoot, path, scope);
|
91
|
-
var diffNode = diffOutput ? diffOutput.diffNode : null;
|
92
|
-
|
93
|
-
if (diffNode) {
|
94
|
-
!(diffNode instanceof require("./RelayQuery").Root) ? process.env.NODE_ENV !== "production" ? require("fbjs/lib/invariant")(false, 'diffRelayQuery(): Expected result to be a root query.') : require("fbjs/lib/invariant")(false) : void 0;
|
95
|
-
queries.push(diffNode);
|
96
|
-
}
|
97
|
-
});
|
98
|
-
|
99
|
-
return queries.concat(visitor.getSplitQueries());
|
100
|
-
}
|
101
|
-
/**
|
102
|
-
* @internal
|
103
|
-
*
|
104
|
-
* A transform for (node + store) -> (diff + tracked queries). It is analagous
|
105
|
-
* to `RelayQueryTransform` with the main differences as follows:
|
106
|
-
* - there is no `state` (which allowed for passing data up and down the tree).
|
107
|
-
* - data is passed down via `scope`, which flows from a parent field down
|
108
|
-
* through intermediary fragments to the nearest child field.
|
109
|
-
* - data is passed up via the return type `{diffNode, trackedNode}`, where:
|
110
|
-
* - `diffNode`: subset of the input that could not diffed out
|
111
|
-
* - `trackedNode`: subset of the input that must be tracked
|
112
|
-
*
|
113
|
-
* The provided `queryTracker`, if any, is updated whenever the traversal of a
|
114
|
-
* node results in a `trackedNode` being created. New top-level queries are not
|
115
|
-
* returned up the tree, and instead are available via `getSplitQueries()`.
|
116
|
-
*
|
117
|
-
* @note If no `queryTracker` is provided, all tracking-related functionality is
|
118
|
-
* skipped.
|
119
|
-
*/
|
120
|
-
|
121
|
-
|
122
|
-
var RelayDiffQueryBuilder =
|
123
|
-
/*#__PURE__*/
|
124
|
-
function () {
|
125
|
-
function RelayDiffQueryBuilder(store, queryTracker) {
|
126
|
-
this._store = store;
|
127
|
-
this._splitQueries = [];
|
128
|
-
this._queryTracker = queryTracker;
|
129
|
-
}
|
130
|
-
|
131
|
-
var _proto = RelayDiffQueryBuilder.prototype;
|
132
|
-
|
133
|
-
_proto.splitQuery = function splitQuery(root) {
|
134
|
-
this._splitQueries.push(root);
|
135
|
-
};
|
136
|
-
|
137
|
-
_proto.getSplitQueries = function getSplitQueries() {
|
138
|
-
return this._splitQueries;
|
139
|
-
};
|
140
|
-
|
141
|
-
_proto.visit = function visit(node, path, scope) {
|
142
|
-
if (node instanceof require("./RelayQuery").Field) {
|
143
|
-
return this.visitField(node, path, scope);
|
144
|
-
} else if (node instanceof require("./RelayQuery").Fragment) {
|
145
|
-
return this.visitFragment(node, path, scope);
|
146
|
-
} else if (node instanceof require("./RelayQuery").Root) {
|
147
|
-
return this.visitRoot(node, path, scope);
|
148
|
-
}
|
149
|
-
};
|
150
|
-
|
151
|
-
_proto.visitRoot = function visitRoot(node, path, scope) {
|
152
|
-
return this.traverse(node, path, scope);
|
153
|
-
};
|
154
|
-
|
155
|
-
_proto.visitFragment = function visitFragment(node, path, scope) {
|
156
|
-
return this.traverse(node, path, scope);
|
157
|
-
};
|
158
|
-
/**
|
159
|
-
* Diffs the field conditionally based on the `scope` from the nearest
|
160
|
-
* ancestor field.
|
161
|
-
*/
|
162
|
-
|
163
|
-
|
164
|
-
_proto.visitField = function visitField(node, path, _ref2) {
|
165
|
-
var connectionField = _ref2.connectionField,
|
166
|
-
dataID = _ref2.dataID,
|
167
|
-
edgeID = _ref2.edgeID,
|
168
|
-
rangeInfo = _ref2.rangeInfo;
|
169
|
-
|
170
|
-
// special case when inside a connection traversal
|
171
|
-
if (connectionField && rangeInfo) {
|
172
|
-
var _ConnectionInterface$ = require("relay-runtime").ConnectionInterface.get(),
|
173
|
-
EDGES = _ConnectionInterface$.EDGES,
|
174
|
-
PAGE_INFO = _ConnectionInterface$.PAGE_INFO;
|
175
|
-
|
176
|
-
if (edgeID) {
|
177
|
-
// When traversing a specific connection edge only look at `edges`
|
178
|
-
if (node.getSchemaName() === EDGES) {
|
179
|
-
return this.diffConnectionEdge(connectionField, node, // edge field
|
180
|
-
require("./RelayQueryPath").getPath(path, node, edgeID), edgeID, rangeInfo);
|
181
|
-
} else {
|
182
|
-
return null;
|
183
|
-
}
|
184
|
-
} else {
|
185
|
-
// When traversing connection metadata fields, edges/page_info are
|
186
|
-
// only kept if there are range extension calls. Other fields fall
|
187
|
-
// through to regular diffing.
|
188
|
-
if (node.getSchemaName() === EDGES || node.getSchemaName() === PAGE_INFO) {
|
189
|
-
return rangeInfo.diffCalls.length > 0 ? {
|
190
|
-
diffNode: node,
|
191
|
-
trackedNode: null
|
192
|
-
} : null;
|
193
|
-
}
|
194
|
-
}
|
195
|
-
} // default field diffing algorithm
|
196
|
-
|
197
|
-
|
198
|
-
if (!node.canHaveSubselections()) {
|
199
|
-
return this.diffScalar(node, dataID);
|
200
|
-
} else if (node.isGenerated()) {
|
201
|
-
return {
|
202
|
-
diffNode: node,
|
203
|
-
trackedNode: null
|
204
|
-
};
|
205
|
-
} else if (node.isConnection()) {
|
206
|
-
return this.diffConnection(node, path, dataID);
|
207
|
-
} else if (node.isPlural()) {
|
208
|
-
return this.diffPluralLink(node, path, dataID);
|
209
|
-
} else {
|
210
|
-
return this.diffLink(node, path, dataID);
|
211
|
-
}
|
212
|
-
};
|
213
|
-
/**
|
214
|
-
* Visit all the children of the given `node` and merge their results.
|
215
|
-
*/
|
216
|
-
|
217
|
-
|
218
|
-
_proto.traverse = function traverse(node, path, scope) {
|
219
|
-
var _this = this;
|
220
|
-
|
221
|
-
var diffNode;
|
222
|
-
var diffChildren;
|
223
|
-
var trackedNode;
|
224
|
-
var trackedChildren;
|
225
|
-
var hasDiffField = false;
|
226
|
-
var hasTrackedField = false;
|
227
|
-
node.getChildren().forEach(function (child) {
|
228
|
-
if (child instanceof require("./RelayQuery").Field) {
|
229
|
-
var diffOutput = _this.visitField(child, path, scope);
|
230
|
-
|
231
|
-
var diffChild = diffOutput ? diffOutput.diffNode : null;
|
232
|
-
var trackedChild = diffOutput && _this._queryTracker ? diffOutput.trackedNode : null; // Diff uses child nodes and keeps requisite fields
|
233
|
-
|
234
|
-
if (diffChild) {
|
235
|
-
diffChildren = diffChildren || [];
|
236
|
-
diffChildren.push(diffChild);
|
237
|
-
hasDiffField = hasDiffField || !diffChild.isGenerated();
|
238
|
-
} else if (child.isRequisite() && !scope.rangeInfo) {
|
239
|
-
// The presence of `rangeInfo` indicates that we are traversing
|
240
|
-
// connection metadata fields, in which case `visitField` will ensure
|
241
|
-
// that `edges` and `page_info` are kept when necessary. The requisite
|
242
|
-
// check alone could cause these fields to be added back when not
|
243
|
-
// needed.
|
244
|
-
//
|
245
|
-
// Example: `friends.first(3) {count, edges {...}, page_info {...} }
|
246
|
-
// If all `edges` were fetched but `count` is unfetched, the diff
|
247
|
-
// should be `friends.first(3) {count}` and not include `page_info`.
|
248
|
-
diffChildren = diffChildren || [];
|
249
|
-
diffChildren.push(child);
|
250
|
-
}
|
251
|
-
|
252
|
-
if (_this._queryTracker) {
|
253
|
-
// Tracker uses tracked children and keeps requisite fields
|
254
|
-
if (trackedChild) {
|
255
|
-
trackedChildren = trackedChildren || [];
|
256
|
-
trackedChildren.push(trackedChild);
|
257
|
-
hasTrackedField = hasTrackedField || !trackedChild.isGenerated();
|
258
|
-
} else if (child.isRequisite()) {
|
259
|
-
trackedChildren = trackedChildren || [];
|
260
|
-
trackedChildren.push(child);
|
261
|
-
}
|
262
|
-
}
|
263
|
-
} else if (child instanceof require("./RelayQuery").Fragment) {
|
264
|
-
var isCompatibleType = require("./isCompatibleRelayFragmentType")(child, _this._store.getType(scope.dataID));
|
265
|
-
|
266
|
-
if (isCompatibleType) {
|
267
|
-
if (child.isTrackingEnabled()) {
|
268
|
-
var hash = child.getCompositeHash();
|
269
|
-
|
270
|
-
if (_this._store.hasFragmentData(scope.dataID, hash)) {
|
271
|
-
return {
|
272
|
-
diffNode: null,
|
273
|
-
trackedNode: null
|
274
|
-
};
|
275
|
-
}
|
276
|
-
}
|
277
|
-
|
278
|
-
var _diffOutput = _this.traverse(child, path, scope);
|
279
|
-
|
280
|
-
var _diffChild = _diffOutput ? _diffOutput.diffNode : null;
|
281
|
-
|
282
|
-
var _trackedChild = _diffOutput ? _diffOutput.trackedNode : null;
|
283
|
-
|
284
|
-
if (_diffChild) {
|
285
|
-
diffChildren = diffChildren || [];
|
286
|
-
diffChildren.push(_diffChild);
|
287
|
-
hasDiffField = true;
|
288
|
-
}
|
289
|
-
|
290
|
-
if (_trackedChild) {
|
291
|
-
trackedChildren = trackedChildren || [];
|
292
|
-
trackedChildren.push(_trackedChild);
|
293
|
-
hasTrackedField = true;
|
294
|
-
}
|
295
|
-
} else {
|
296
|
-
// Non-matching fragment types are similar to requisite fields:
|
297
|
-
// they don't need to be diffed against and should only be included
|
298
|
-
// if something *else* is missing from the node.
|
299
|
-
diffChildren = diffChildren || [];
|
300
|
-
diffChildren.push(child);
|
301
|
-
}
|
302
|
-
}
|
303
|
-
}); // Only return diff/tracked node if there are non-generated fields
|
304
|
-
|
305
|
-
if (diffChildren && hasDiffField) {
|
306
|
-
diffNode = node.clone(diffChildren);
|
307
|
-
}
|
308
|
-
|
309
|
-
if (trackedChildren && hasTrackedField) {
|
310
|
-
trackedNode = node.clone(trackedChildren);
|
311
|
-
} // Record tracked nodes. Fragments can be skipped because these will
|
312
|
-
// always be composed into, and therefore tracked by, their nearest
|
313
|
-
// non-fragment parent.
|
314
|
-
|
315
|
-
|
316
|
-
if (this._queryTracker && trackedNode && !(trackedNode instanceof require("./RelayQuery").Fragment)) {
|
317
|
-
this._queryTracker.trackNodeForID(trackedNode, scope.dataID);
|
318
|
-
}
|
319
|
-
|
320
|
-
return {
|
321
|
-
diffNode: diffNode,
|
322
|
-
trackedNode: trackedNode
|
323
|
-
};
|
324
|
-
};
|
325
|
-
/**
|
326
|
-
* Diff a scalar field such as `name` or `id`.
|
327
|
-
*/
|
328
|
-
|
329
|
-
|
330
|
-
_proto.diffScalar = function diffScalar(field, dataID) {
|
331
|
-
if (this._store.getField(dataID, field.getStorageKey()) === undefined) {
|
332
|
-
return {
|
333
|
-
diffNode: field,
|
334
|
-
trackedNode: null
|
335
|
-
};
|
336
|
-
}
|
337
|
-
|
338
|
-
return null;
|
339
|
-
};
|
340
|
-
/**
|
341
|
-
* Diff a field-of-fields such as `profile_picture {...}`. Returns early if
|
342
|
-
* the field has not been fetched, otherwise the result of traversal.
|
343
|
-
*/
|
344
|
-
|
345
|
-
|
346
|
-
_proto.diffLink = function diffLink(field, path, dataID) {
|
347
|
-
var nextDataID = this._store.getLinkedRecordID(dataID, field.getStorageKey());
|
348
|
-
|
349
|
-
if (nextDataID === undefined) {
|
350
|
-
return {
|
351
|
-
diffNode: field,
|
352
|
-
trackedNode: null
|
353
|
-
};
|
354
|
-
}
|
355
|
-
|
356
|
-
if (nextDataID === null) {
|
357
|
-
return {
|
358
|
-
diffNode: null,
|
359
|
-
trackedNode: this._queryTracker ? field : null
|
360
|
-
};
|
361
|
-
}
|
362
|
-
|
363
|
-
return this.traverse(field, require("./RelayQueryPath").getPath(path, field, nextDataID), makeScope(nextDataID));
|
364
|
-
};
|
365
|
-
/**
|
366
|
-
* Diffs a non-connection plural field against each of the fetched items.
|
367
|
-
* Note that scalar plural fields are handled by `_diffScalar`.
|
368
|
-
*/
|
369
|
-
|
370
|
-
|
371
|
-
_proto.diffPluralLink = function diffPluralLink(field, path, dataID) {
|
372
|
-
var _this2 = this;
|
373
|
-
|
374
|
-
var _ConnectionInterface$2 = require("relay-runtime").ConnectionInterface.get(),
|
375
|
-
NODE = _ConnectionInterface$2.NODE;
|
376
|
-
|
377
|
-
var linkedIDs = this._store.getLinkedRecordIDs(dataID, field.getStorageKey());
|
378
|
-
|
379
|
-
if (linkedIDs === undefined) {
|
380
|
-
// not fetched
|
381
|
-
return {
|
382
|
-
diffNode: field,
|
383
|
-
trackedNode: null
|
384
|
-
};
|
385
|
-
} else if (linkedIDs === null || linkedIDs.length === 0) {
|
386
|
-
// Don't fetch if array is null or empty, but still track the fragment
|
387
|
-
return {
|
388
|
-
diffNode: null,
|
389
|
-
trackedNode: this._queryTracker ? field : null
|
390
|
-
};
|
391
|
-
} else if (field.getInferredRootCallName() === NODE) {
|
392
|
-
// The items in this array are fetchable and may have been filled in
|
393
|
-
// from other sources, so check them all. For example, `Story{actors}`
|
394
|
-
// is an array (but not a range), and the Actors in that array likely
|
395
|
-
// had data fetched for them elsewhere (like `viewer(){actor}`).
|
396
|
-
var hasSplitQueries = false;
|
397
|
-
linkedIDs.forEach(function (itemID) {
|
398
|
-
var itemState = _this2.traverse(field, require("./RelayQueryPath").getPath(path, field, itemID), makeScope(itemID));
|
399
|
-
|
400
|
-
if (itemState) {
|
401
|
-
// If any child was tracked then `field` will also be tracked
|
402
|
-
hasSplitQueries = hasSplitQueries || !!itemState.trackedNode || !!itemState.diffNode; // split diff nodes into root queries
|
403
|
-
|
404
|
-
if (itemState.diffNode) {
|
405
|
-
_this2.splitQuery(buildRoot(itemID, itemState.diffNode.getChildren(), require("./RelayQueryPath").getName(path), field.getType(), field.isAbstract()));
|
406
|
-
}
|
407
|
-
}
|
408
|
-
}); // if sub-queries are split then this *entire* field will be tracked,
|
409
|
-
// therefore we don't need to merge the `trackedNode` from each item
|
410
|
-
|
411
|
-
if (hasSplitQueries) {
|
412
|
-
return {
|
413
|
-
diffNode: null,
|
414
|
-
trackedNode: this._queryTracker ? field : null
|
415
|
-
};
|
416
|
-
}
|
417
|
-
} else {
|
418
|
-
// The items in this array are not fetchable by ID, so nothing else could
|
419
|
-
// have fetched additional data for individual items. If any item in this
|
420
|
-
// list is missing data, refetch the whole field.
|
421
|
-
var atLeastOneItemHasMissingData = false;
|
422
|
-
var atLeastOneItemHasTrackedData = false;
|
423
|
-
linkedIDs.some(function (itemID) {
|
424
|
-
var itemState = _this2.traverse(field, require("./RelayQueryPath").getPath(path, field, itemID), makeScope(itemID));
|
425
|
-
|
426
|
-
if (itemState && itemState.diffNode) {
|
427
|
-
atLeastOneItemHasMissingData = true;
|
428
|
-
}
|
429
|
-
|
430
|
-
if (itemState && itemState.trackedNode) {
|
431
|
-
atLeastOneItemHasTrackedData = true;
|
432
|
-
} // Exit early if possible
|
433
|
-
|
434
|
-
|
435
|
-
return atLeastOneItemHasMissingData && atLeastOneItemHasTrackedData;
|
436
|
-
});
|
437
|
-
|
438
|
-
if (atLeastOneItemHasMissingData || atLeastOneItemHasTrackedData) {
|
439
|
-
return {
|
440
|
-
diffNode: atLeastOneItemHasMissingData ? field : null,
|
441
|
-
trackedNode: atLeastOneItemHasTrackedData ? field : null
|
442
|
-
};
|
443
|
-
}
|
444
|
-
}
|
445
|
-
|
446
|
-
return null;
|
447
|
-
};
|
448
|
-
/**
|
449
|
-
* Diff a connection field such as `news_feed.first(3)`. Returns early if
|
450
|
-
* the range has not been fetched or the entire range has already been
|
451
|
-
* fetched. Otherwise the diff output is a clone of `field` with updated
|
452
|
-
* after/first and before/last calls.
|
453
|
-
*/
|
454
|
-
|
455
|
-
|
456
|
-
_proto.diffConnection = function diffConnection(field, path, dataID) {
|
457
|
-
var _this3 = this;
|
458
|
-
|
459
|
-
var store = this._store;
|
460
|
-
var connectionID = store.getLinkedRecordID(dataID, field.getStorageKey());
|
461
|
-
var rangeInfo = store.getRangeMetadata(connectionID, field.getCallsWithValues()); // Keep the field if the connection is unfetched
|
462
|
-
|
463
|
-
if (connectionID === undefined) {
|
464
|
-
return {
|
465
|
-
diffNode: field,
|
466
|
-
trackedNode: null
|
467
|
-
};
|
468
|
-
} // Don't fetch if connection is null, but continue to track the fragment if
|
469
|
-
// appropriate.
|
470
|
-
|
471
|
-
|
472
|
-
if (connectionID === null) {
|
473
|
-
return this._queryTracker ? {
|
474
|
-
diffNode: null,
|
475
|
-
trackedNode: field
|
476
|
-
} : null;
|
477
|
-
} // If metadata fields but not edges are fetched, diff as a normal field.
|
478
|
-
// In practice, `rangeInfo` is `undefined` if unfetched, `null` if the
|
479
|
-
// connection was deleted (in which case `connectionID` is null too).
|
480
|
-
|
481
|
-
|
482
|
-
if (rangeInfo == null) {
|
483
|
-
return this.traverse(field, require("./RelayQueryPath").getPath(path, field, connectionID), makeScope(connectionID));
|
484
|
-
}
|
485
|
-
|
486
|
-
var diffCalls = rangeInfo.diffCalls,
|
487
|
-
filteredEdges = rangeInfo.filteredEdges; // check existing edges for missing fields
|
488
|
-
|
489
|
-
var hasSplitQueries = false;
|
490
|
-
filteredEdges.forEach(function (edge) {
|
491
|
-
var scope = {
|
492
|
-
connectionField: field,
|
493
|
-
dataID: connectionID,
|
494
|
-
edgeID: edge.edgeID,
|
495
|
-
rangeInfo: rangeInfo
|
496
|
-
};
|
497
|
-
|
498
|
-
var diffOutput = _this3.traverse(field, require("./RelayQueryPath").getPath(path, field, edge.edgeID), scope); // If any edges were missing data (resulting in a split query),
|
499
|
-
// then the entire original connection field must be tracked.
|
500
|
-
|
501
|
-
|
502
|
-
if (diffOutput) {
|
503
|
-
hasSplitQueries = hasSplitQueries || !!diffOutput.trackedNode;
|
504
|
-
}
|
505
|
-
}); // Scope has null `edgeID` to skip looking at `edges` fields.
|
506
|
-
|
507
|
-
var scope = {
|
508
|
-
connectionField: field,
|
509
|
-
dataID: connectionID,
|
510
|
-
edgeID: null,
|
511
|
-
rangeInfo: rangeInfo
|
512
|
-
}; // diff non-`edges` fields such as `count`
|
513
|
-
|
514
|
-
var diffOutput = this.traverse(field, require("./RelayQueryPath").getPath(path, field, connectionID), scope);
|
515
|
-
var diffNode = diffOutput ? diffOutput.diffNode : null;
|
516
|
-
var trackedNode = diffOutput ? diffOutput.trackedNode : null;
|
517
|
-
|
518
|
-
if (diffCalls.length && diffNode instanceof require("./RelayQuery").Field) {
|
519
|
-
diffNode = diffNode.cloneFieldWithCalls(diffNode.getChildren(), diffCalls);
|
520
|
-
} // if a sub-query was split, then we must track the entire field, which will
|
521
|
-
// be a superset of the `trackedNode` from traversing any metadata fields.
|
522
|
-
// Example:
|
523
|
-
// dataID: `4`
|
524
|
-
// node: `friends.first(3)`
|
525
|
-
// diffNode: null
|
526
|
-
// splitQueries: `node(friend1) {...}`, `node(friend2) {...}`
|
527
|
-
//
|
528
|
-
// In this case the two fetched `node` queries do not reflect the fact that
|
529
|
-
// `friends.first(3)` were fetched for item `4`, so `friends.first(3)` has
|
530
|
-
// to be tracked as-is.
|
531
|
-
|
532
|
-
|
533
|
-
if (hasSplitQueries) {
|
534
|
-
trackedNode = field;
|
535
|
-
}
|
536
|
-
|
537
|
-
return {
|
538
|
-
diffNode: diffNode,
|
539
|
-
trackedNode: this._queryTracker ? trackedNode : null
|
540
|
-
};
|
541
|
-
};
|
542
|
-
/**
|
543
|
-
* Diff an `edges` field for the edge rooted at `edgeID`, splitting a new
|
544
|
-
* root query to fetch any missing data (via a `node(id)` root if the
|
545
|
-
* field is refetchable or a `...{connection.find(id){}}` query if the
|
546
|
-
* field is not refetchable).
|
547
|
-
*/
|
548
|
-
|
549
|
-
|
550
|
-
_proto.diffConnectionEdge = function diffConnectionEdge(connectionField, edgeField, path, edgeID, rangeInfo) {
|
551
|
-
var _ConnectionInterface$3 = require("relay-runtime").ConnectionInterface.get(),
|
552
|
-
NODE = _ConnectionInterface$3.NODE;
|
553
|
-
|
554
|
-
var hasSplitQueries = false;
|
555
|
-
var diffOutput = this.traverse(edgeField, require("./RelayQueryPath").getPath(path, edgeField, edgeID), makeScope(edgeID));
|
556
|
-
var diffNode = diffOutput ? diffOutput.diffNode : null;
|
557
|
-
var trackedNode = diffOutput ? diffOutput.trackedNode : null;
|
558
|
-
|
559
|
-
var nodeID = this._store.getLinkedRecordID(edgeID, NODE);
|
560
|
-
|
561
|
-
if (diffNode) {
|
562
|
-
if (!nodeID || require("./RelayRecord").isClientID(nodeID)) {
|
563
|
-
process.env.NODE_ENV !== "production" ? require("fbjs/lib/warning")(connectionField.isConnectionWithoutNodeID(), 'RelayDiffQueryBuilder: Field `node` on connection `%s` cannot be ' + 'retrieved if it does not have an `id` field. If you expect fields ' + 'to be retrieved on this field, add an `id` field in the schema. ' + 'If you choose to ignore this warning, you can silence it by ' + 'adding `@relay(isConnectionWithoutNodeID: true)` to the ' + 'connection field.', connectionField.getStorageKey()) : void 0;
|
564
|
-
} else {
|
565
|
-
var _splitNodeAndEdgesFie = splitNodeAndEdgesFields(diffNode),
|
566
|
-
diffEdgesField = _splitNodeAndEdgesFie.edges,
|
567
|
-
diffNodeField = _splitNodeAndEdgesFie.node; // split missing `node` fields into a `node(id)` root query
|
568
|
-
|
569
|
-
|
570
|
-
if (diffNodeField) {
|
571
|
-
hasSplitQueries = true;
|
572
|
-
var nodeField = edgeField.getFieldByStorageKey('node');
|
573
|
-
!nodeField ? process.env.NODE_ENV !== "production" ? require("fbjs/lib/invariant")(false, 'RelayDiffQueryBuilder: Expected connection `%s` to have a ' + '`node` field.', connectionField.getSchemaName()) : require("fbjs/lib/invariant")(false) : void 0;
|
574
|
-
this.splitQuery(buildRoot(nodeID, diffNodeField.getChildren(), require("./RelayQueryPath").getName(path), nodeField.getType(), nodeField.isAbstract()));
|
575
|
-
} // split missing `edges` fields into a `connection.find(id)` query
|
576
|
-
// if `find` is supported, otherwise warn
|
577
|
-
|
578
|
-
|
579
|
-
if (diffEdgesField) {
|
580
|
-
if (connectionField.isFindable()) {
|
581
|
-
diffEdgesField = diffEdgesField.clone(diffEdgesField.getChildren().concat(nodeWithID));
|
582
|
-
var connectionFind = connectionField.cloneFieldWithCalls([diffEdgesField], rangeInfo.filterCalls.concat({
|
583
|
-
name: 'find',
|
584
|
-
value: nodeID
|
585
|
-
}));
|
586
|
-
|
587
|
-
if (connectionFind) {
|
588
|
-
hasSplitQueries = true; // current path has `parent`, `connection`, `edges`; pop to parent
|
589
|
-
|
590
|
-
var connectionParent = require("./RelayQueryPath").getParent(require("./RelayQueryPath").getParent(path));
|
591
|
-
|
592
|
-
var connectionQuery = require("./RelayQueryPath").getQuery(this._store, connectionParent, connectionFind);
|
593
|
-
|
594
|
-
this.splitQuery(connectionQuery);
|
595
|
-
}
|
596
|
-
} else {
|
597
|
-
process.env.NODE_ENV !== "production" ? require("fbjs/lib/warning")(false, 'RelayDiffQueryBuilder: connection `edges{*}` fields can only ' + 'be refetched if the connection supports the `find` call. ' + 'Cannot refetch data for field `%s`.', connectionField.getStorageKey()) : void 0;
|
598
|
-
}
|
599
|
-
}
|
600
|
-
}
|
601
|
-
} // Connection edges will never return diff nodes; instead missing fields
|
602
|
-
// are fetched by new root queries. Tracked nodes are returned if either
|
603
|
-
// a child field was tracked or missing fields were split into a new query.
|
604
|
-
// The returned `trackedNode` is never tracked directly: instead it serves
|
605
|
-
// as an indicator to `diffConnection` that the entire connection field must
|
606
|
-
// be tracked.
|
607
|
-
|
608
|
-
|
609
|
-
return this._queryTracker ? {
|
610
|
-
diffNode: null,
|
611
|
-
trackedNode: hasSplitQueries ? edgeField : trackedNode
|
612
|
-
} : null;
|
613
|
-
};
|
614
|
-
|
615
|
-
return RelayDiffQueryBuilder;
|
616
|
-
}();
|
617
|
-
/**
|
618
|
-
* Helper to construct a plain scope for the given `dataID`.
|
619
|
-
*/
|
620
|
-
|
621
|
-
|
622
|
-
function makeScope(dataID) {
|
623
|
-
return {
|
624
|
-
connectionField: null,
|
625
|
-
dataID: dataID,
|
626
|
-
edgeID: null,
|
627
|
-
rangeInfo: null
|
628
|
-
};
|
629
|
-
}
|
630
|
-
/**
|
631
|
-
* Returns a clone of the input with `edges` and `node` sub-fields split into
|
632
|
-
* separate `edges` and `node` roots. Example:
|
633
|
-
*
|
634
|
-
* Input:
|
635
|
-
* edges {
|
636
|
-
* edge_field,
|
637
|
-
* node {
|
638
|
-
* a,
|
639
|
-
* b
|
640
|
-
* },
|
641
|
-
* ${
|
642
|
-
* Fragment {
|
643
|
-
* edge_field_2,
|
644
|
-
* node {
|
645
|
-
* c
|
646
|
-
* }
|
647
|
-
* }
|
648
|
-
* }
|
649
|
-
* }
|
650
|
-
*
|
651
|
-
* Output:
|
652
|
-
* node:
|
653
|
-
* edges {
|
654
|
-
* a, // flattened
|
655
|
-
* b, // flattend
|
656
|
-
* ${
|
657
|
-
* Fragment {
|
658
|
-
* c // flattened
|
659
|
-
* }
|
660
|
-
* }
|
661
|
-
* }
|
662
|
-
* edges:
|
663
|
-
* edges {
|
664
|
-
* edge_field,
|
665
|
-
* ${
|
666
|
-
* Fragment {
|
667
|
-
* edge_field_2
|
668
|
-
* }
|
669
|
-
* }
|
670
|
-
* }
|
671
|
-
*/
|
672
|
-
|
673
|
-
|
674
|
-
function splitNodeAndEdgesFields(edgeOrFragment) {
|
675
|
-
var _ConnectionInterface$4 = require("relay-runtime").ConnectionInterface.get(),
|
676
|
-
NODE = _ConnectionInterface$4.NODE;
|
677
|
-
|
678
|
-
var children = edgeOrFragment.getChildren();
|
679
|
-
var edgeChildren = [];
|
680
|
-
var nodeChild = null;
|
681
|
-
var nodeChildren = [];
|
682
|
-
var hasEdgeChild = false;
|
683
|
-
|
684
|
-
for (var ii = 0; ii < children.length; ii++) {
|
685
|
-
var child = children[ii];
|
686
|
-
|
687
|
-
if (child instanceof require("./RelayQuery").Field) {
|
688
|
-
if (child.getSchemaName() === NODE) {
|
689
|
-
var subFields = child.getChildren();
|
690
|
-
nodeChildren = nodeChildren.concat(subFields); // can skip if `node` only has an `id` field
|
691
|
-
|
692
|
-
if (!nodeChild) {
|
693
|
-
if (subFields.length === 1) {
|
694
|
-
var subField = subFields[0];
|
695
|
-
|
696
|
-
if (!(subField instanceof require("./RelayQuery").Field) || subField.getSchemaName() !== require("./RelayNodeInterface").ID) {
|
697
|
-
nodeChild = child;
|
698
|
-
}
|
699
|
-
} else {
|
700
|
-
nodeChild = child;
|
701
|
-
}
|
702
|
-
}
|
703
|
-
} else {
|
704
|
-
edgeChildren.push(child);
|
705
|
-
hasEdgeChild = hasEdgeChild || !child.isRequisite();
|
706
|
-
}
|
707
|
-
} else if (child instanceof require("./RelayQuery").Fragment) {
|
708
|
-
var _splitNodeAndEdgesFie2 = splitNodeAndEdgesFields(child),
|
709
|
-
edges = _splitNodeAndEdgesFie2.edges,
|
710
|
-
node = _splitNodeAndEdgesFie2.node;
|
711
|
-
|
712
|
-
if (edges) {
|
713
|
-
edgeChildren.push(edges);
|
714
|
-
hasEdgeChild = true;
|
715
|
-
}
|
716
|
-
|
717
|
-
if (node) {
|
718
|
-
nodeChildren.push(node);
|
719
|
-
nodeChild = node;
|
720
|
-
}
|
721
|
-
}
|
722
|
-
}
|
723
|
-
|
724
|
-
return {
|
725
|
-
edges: hasEdgeChild ? edgeOrFragment.clone(edgeChildren) : null,
|
726
|
-
node: nodeChild && require("./RelayQuery").Fragment.build('diffRelayQuery', nodeChild.getType(), nodeChildren, {
|
727
|
-
isAbstract: nodeChild.isAbstract()
|
728
|
-
})
|
729
|
-
};
|
730
|
-
}
|
731
|
-
|
732
|
-
function buildRoot(rootID, nodes, name, type, isAbstract) {
|
733
|
-
var _ConnectionInterface$5 = require("relay-runtime").ConnectionInterface.get(),
|
734
|
-
NODE = _ConnectionInterface$5.NODE;
|
735
|
-
|
736
|
-
var children = [idField, typeField];
|
737
|
-
var fields = [];
|
738
|
-
nodes.forEach(function (node) {
|
739
|
-
if (node instanceof require("./RelayQuery").Field) {
|
740
|
-
fields.push(node);
|
741
|
-
} else {
|
742
|
-
children.push(node);
|
743
|
-
}
|
744
|
-
});
|
745
|
-
children.push(require("./RelayQuery").Fragment.build('diffRelayQuery', type, fields, {
|
746
|
-
isAbstract: isAbstract
|
747
|
-
}));
|
748
|
-
return require("./RelayQuery").Root.build(name, NODE, rootID, children, {
|
749
|
-
identifyingArgName: require("./RelayNodeInterface").ID,
|
750
|
-
identifyingArgType: require("./RelayNodeInterface").ID_TYPE,
|
751
|
-
isAbstract: true,
|
752
|
-
isDeferred: false,
|
753
|
-
isPlural: false
|
754
|
-
}, require("./RelayNodeInterface").NODE_TYPE);
|
755
|
-
}
|
756
|
-
|
757
|
-
module.exports = require("relay-runtime").RelayProfiler.instrument('diffRelayQuery', diffRelayQuery);
|