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.
Files changed (166) hide show
  1. package/index.js +2 -2
  2. package/lib/ReactRelayContext.js +6 -3
  3. package/lib/ReactRelayFragmentContainer.js +48 -46
  4. package/lib/ReactRelayFragmentMockRenderer.js +5 -1
  5. package/lib/ReactRelayPaginationContainer.js +102 -68
  6. package/lib/ReactRelayQueryFetcher.js +54 -28
  7. package/lib/ReactRelayQueryRenderer.js +28 -20
  8. package/lib/ReactRelayRefetchContainer.js +70 -58
  9. package/lib/ReactRelayTestMocker.js +56 -43
  10. package/lib/ReactRelayTypes.js +1 -1
  11. package/lib/RelayContext.js +8 -2
  12. package/lib/assertFragmentMap.js +9 -7
  13. package/lib/buildReactRelayContainer.js +32 -23
  14. package/lib/index.js +41 -0
  15. package/lib/isRelayEnvironment.js +1 -1
  16. package/lib/isRelayVariables.js +1 -1
  17. package/lib/readContext.js +7 -4
  18. package/package.json +4 -4
  19. package/react-relay.js +2 -2
  20. package/react-relay.min.js +2 -2
  21. package/classic.js +0 -10
  22. package/compat.js +0 -10
  23. package/lib/ConcreteQuery.js +0 -10
  24. package/lib/GraphQLQueryRunner.js +0 -264
  25. package/lib/GraphQLRange.js +0 -1124
  26. package/lib/GraphQLSegment.js +0 -743
  27. package/lib/GraphQLStoreChangeEmitter.js +0 -141
  28. package/lib/GraphQLStoreQueryResolver.js +0 -288
  29. package/lib/GraphQLStoreRangeUtils.js +0 -126
  30. package/lib/QueryBuilder.js +0 -228
  31. package/lib/ReactRelayClassicExports.js +0 -29
  32. package/lib/ReactRelayCompatContainerBuilder.js +0 -175
  33. package/lib/ReactRelayCompatPublic.js +0 -28
  34. package/lib/ReactRelayContainerProfiler.js +0 -30
  35. package/lib/ReactRelayFragmentContainer-flowtest.js +0 -201
  36. package/lib/ReactRelayPaginationContainer-flowtest.js +0 -213
  37. package/lib/ReactRelayPublic.js +0 -29
  38. package/lib/ReactRelayRefetchContainer-flowtest.js +0 -191
  39. package/lib/RelayCacheProcessor.js +0 -196
  40. package/lib/RelayChangeTracker.js +0 -83
  41. package/lib/RelayClassicContainerUtils.js +0 -49
  42. package/lib/RelayClassicCore.js +0 -34
  43. package/lib/RelayClassicRecordState.js +0 -31
  44. package/lib/RelayCompatContainer.js +0 -25
  45. package/lib/RelayCompatEnvironment.js +0 -27
  46. package/lib/RelayCompatMutations.js +0 -133
  47. package/lib/RelayCompatPaginationContainer.js +0 -27
  48. package/lib/RelayCompatRefetchContainer.js +0 -27
  49. package/lib/RelayCompatTypes.js +0 -10
  50. package/lib/RelayContainer.js +0 -889
  51. package/lib/RelayContainerComparators.js +0 -75
  52. package/lib/RelayContainerProxy.js +0 -21
  53. package/lib/RelayDefaultNetworkLayer.js +0 -192
  54. package/lib/RelayEnvironment.js +0 -449
  55. package/lib/RelayEnvironmentTypes.js +0 -10
  56. package/lib/RelayFetchMode.js +0 -17
  57. package/lib/RelayFragmentPointer.js +0 -161
  58. package/lib/RelayFragmentReference.js +0 -249
  59. package/lib/RelayFragmentSpecResolver.js +0 -305
  60. package/lib/RelayGraphQLMutation.js +0 -288
  61. package/lib/RelayGraphQLTag.js +0 -42
  62. package/lib/RelayInternalTypes.js +0 -15
  63. package/lib/RelayInternals.js +0 -24
  64. package/lib/RelayMetaRoute.js +0 -35
  65. package/lib/RelayMockRenderer.js +0 -71
  66. package/lib/RelayModern-flowtest.js +0 -342
  67. package/lib/RelayModernFlowtest_badref.graphql.js +0 -10
  68. package/lib/RelayModernFlowtest_notref.graphql.js +0 -10
  69. package/lib/RelayModernFlowtest_user.graphql.js +0 -10
  70. package/lib/RelayModernFlowtest_users.graphql.js +0 -10
  71. package/lib/RelayMutation.js +0 -322
  72. package/lib/RelayMutationDebugPrinter.js +0 -47
  73. package/lib/RelayMutationQuery.js +0 -558
  74. package/lib/RelayMutationQueue.js +0 -530
  75. package/lib/RelayMutationRequest.js +0 -103
  76. package/lib/RelayMutationTracker.js +0 -113
  77. package/lib/RelayMutationTransaction.js +0 -92
  78. package/lib/RelayMutationTransactionStatus.js +0 -55
  79. package/lib/RelayNetworkDebug.js +0 -131
  80. package/lib/RelayNetworkLayer.js +0 -185
  81. package/lib/RelayNodeInterface.js +0 -104
  82. package/lib/RelayOperationDescriptor.js +0 -40
  83. package/lib/RelayOptimisticMutationUtils.js +0 -208
  84. package/lib/RelayPendingQueryTracker.js +0 -166
  85. package/lib/RelayPropTypes.js +0 -57
  86. package/lib/RelayPublic.js +0 -44
  87. package/lib/RelayQL.js +0 -128
  88. package/lib/RelayQuery.js +0 -1584
  89. package/lib/RelayQueryCaching.js +0 -33
  90. package/lib/RelayQueryConfig.js +0 -58
  91. package/lib/RelayQueryPath.js +0 -204
  92. package/lib/RelayQueryRequest.js +0 -103
  93. package/lib/RelayQueryTracker.js +0 -86
  94. package/lib/RelayQueryTransform.js +0 -91
  95. package/lib/RelayQueryVisitor.js +0 -93
  96. package/lib/RelayQueryWriter.js +0 -573
  97. package/lib/RelayReadyState.js +0 -83
  98. package/lib/RelayReadyStateRenderer.js +0 -145
  99. package/lib/RelayRecord.js +0 -75
  100. package/lib/RelayRecordStatusMap.js +0 -57
  101. package/lib/RelayRecordStore.js +0 -433
  102. package/lib/RelayRecordWriter.js +0 -601
  103. package/lib/RelayRefQueryDescriptor.js +0 -27
  104. package/lib/RelayRenderer.js +0 -268
  105. package/lib/RelayRootContainer.js +0 -125
  106. package/lib/RelayRoute.js +0 -92
  107. package/lib/RelayRouteFragment.js +0 -44
  108. package/lib/RelaySelector.js +0 -201
  109. package/lib/RelayShallowMock.js +0 -69
  110. package/lib/RelayStaticContainer.js +0 -38
  111. package/lib/RelayStore.js +0 -12
  112. package/lib/RelayStoreConstants.js +0 -20
  113. package/lib/RelayStoreData.js +0 -660
  114. package/lib/RelayTaskQueue.js +0 -189
  115. package/lib/RelayTypes.js +0 -13
  116. package/lib/RelayVariable.js +0 -32
  117. package/lib/RelayVariables.js +0 -92
  118. package/lib/buildRQL.js +0 -160
  119. package/lib/callsFromGraphQL.js +0 -74
  120. package/lib/callsToGraphQL.js +0 -34
  121. package/lib/checkRelayQueryData.js +0 -250
  122. package/lib/createRelayQuery.js +0 -17
  123. package/lib/dedent.js +0 -49
  124. package/lib/diffRelayQuery.js +0 -757
  125. package/lib/directivesToGraphQL.js +0 -39
  126. package/lib/filterRelayQuery.js +0 -29
  127. package/lib/findRelayQueryLeaves.js +0 -293
  128. package/lib/flattenRelayQuery.js +0 -121
  129. package/lib/flattenSplitRelayQueries.js +0 -44
  130. package/lib/forEachRootCallArg.js +0 -40
  131. package/lib/fromGraphQL.js +0 -48
  132. package/lib/generateClientEdgeID.js +0 -22
  133. package/lib/generateClientID.js +0 -27
  134. package/lib/generateConcreteFragmentID.js +0 -30
  135. package/lib/generateForceIndex.js +0 -24
  136. package/lib/generateRQLFieldAlias.js +0 -39
  137. package/lib/getRangeBehavior.js +0 -58
  138. package/lib/getRelayQueries.js +0 -83
  139. package/lib/intersectRelayQuery.js +0 -149
  140. package/lib/isClassicRelayContext.js +0 -20
  141. package/lib/isClassicRelayEnvironment.js +0 -20
  142. package/lib/isCompatibleRelayFragmentType.js +0 -27
  143. package/lib/isRelayContainer.js +0 -16
  144. package/lib/makeLegacyStringishComponentRef.js +0 -52
  145. package/lib/printRelayOSSQuery.js +0 -329
  146. package/lib/printRelayQuery.js +0 -26
  147. package/lib/rangeOperationToMetadataKey.js +0 -25
  148. package/lib/readRelayQueryData.js +0 -551
  149. package/lib/relayUnstableBatchedUpdates.js +0 -12
  150. package/lib/relayUnstableBatchedUpdates.native.js +0 -11
  151. package/lib/restoreRelayCacheData.js +0 -188
  152. package/lib/serializeRelayQueryCall.js +0 -42
  153. package/lib/splitDeferredRelayQueries.js +0 -298
  154. package/lib/stableStringify.js +0 -85
  155. package/lib/testEditDistance.js +0 -112
  156. package/lib/throwFailedPromise.js +0 -26
  157. package/lib/toGraphQL.js +0 -94
  158. package/lib/transformRelayQueryPayload.js +0 -145
  159. package/lib/validateMutationConfig.js +0 -117
  160. package/lib/validateRelayReadQuery.js +0 -112
  161. package/lib/writeRelayQueryPayload.js +0 -44
  162. package/lib/writeRelayUpdatePayload.js +0 -513
  163. package/react-relay-classic.js +0 -4
  164. package/react-relay-classic.min.js +0 -9
  165. package/react-relay-compat.js +0 -4
  166. package/react-relay-compat.min.js +0 -9
@@ -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);