react-relay 2.0.0-rc.2 → 5.0.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.
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);