relay-runtime 8.0.0 → 10.0.1

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 (135) hide show
  1. package/handlers/RelayDefaultHandlerProvider.js.flow +41 -0
  2. package/handlers/connection/ConnectionHandler.js.flow +549 -0
  3. package/handlers/connection/ConnectionInterface.js.flow +92 -0
  4. package/handlers/connection/MutationHandlers.js.flow +88 -0
  5. package/index.js +1 -1
  6. package/index.js.flow +320 -0
  7. package/lib/handlers/RelayDefaultHandlerProvider.js +13 -2
  8. package/lib/handlers/connection/{RelayConnectionHandler.js → ConnectionHandler.js} +33 -35
  9. package/lib/handlers/connection/{RelayConnectionInterface.js → ConnectionInterface.js} +2 -2
  10. package/lib/handlers/connection/MutationHandlers.js +86 -0
  11. package/lib/index.js +15 -19
  12. package/lib/mutations/RelayDeclarativeMutationConfig.js +29 -52
  13. package/lib/mutations/RelayRecordProxy.js +1 -3
  14. package/lib/mutations/RelayRecordSourceMutator.js +2 -9
  15. package/lib/mutations/RelayRecordSourceProxy.js +2 -4
  16. package/lib/mutations/RelayRecordSourceSelectorProxy.js +1 -13
  17. package/lib/mutations/commitMutation.js +13 -3
  18. package/lib/mutations/validateMutation.js +16 -9
  19. package/lib/network/RelayObservable.js +9 -9
  20. package/lib/network/RelayQueryResponseCache.js +8 -6
  21. package/lib/query/PreloadableQueryRegistry.js +70 -0
  22. package/lib/query/fetchQueryInternal.js +31 -23
  23. package/lib/store/DataChecker.js +122 -110
  24. package/lib/store/RelayConcreteVariables.js +6 -2
  25. package/lib/store/RelayModernEnvironment.js +121 -67
  26. package/lib/store/RelayModernFragmentSpecResolver.js +12 -16
  27. package/lib/store/RelayModernQueryExecutor.js +389 -314
  28. package/lib/store/RelayModernRecord.js +14 -9
  29. package/lib/store/RelayModernSelector.js +7 -3
  30. package/lib/store/RelayModernStore.js +289 -484
  31. package/lib/store/RelayOperationTracker.js +35 -78
  32. package/lib/store/RelayOptimisticRecordSource.js +7 -5
  33. package/lib/store/RelayPublishQueue.js +6 -33
  34. package/lib/store/RelayReader.js +113 -45
  35. package/lib/store/RelayRecordSource.js +2 -9
  36. package/lib/store/RelayRecordSourceMapImpl.js +13 -18
  37. package/lib/store/RelayReferenceMarker.js +40 -60
  38. package/lib/store/RelayResponseNormalizer.js +158 -193
  39. package/lib/store/RelayStoreUtils.js +1 -0
  40. package/lib/store/StoreInspector.js +8 -8
  41. package/lib/store/TypeID.js +28 -0
  42. package/lib/store/cloneRelayScalarHandleSourceField.js +44 -0
  43. package/lib/store/normalizeRelayPayload.js +6 -2
  44. package/lib/store/readInlineData.js +1 -1
  45. package/lib/subscription/requestSubscription.js +5 -3
  46. package/lib/util/RelayConcreteNode.js +9 -6
  47. package/lib/util/RelayError.js +39 -9
  48. package/lib/util/RelayFeatureFlags.js +2 -5
  49. package/lib/util/RelayReplaySubject.js +3 -3
  50. package/lib/util/createPayloadFor3DField.js +7 -2
  51. package/lib/util/getRequestIdentifier.js +2 -2
  52. package/lib/util/recycleNodesInto.js +2 -6
  53. package/mutations/RelayDeclarativeMutationConfig.js.flow +380 -0
  54. package/mutations/RelayRecordProxy.js.flow +165 -0
  55. package/mutations/RelayRecordSourceMutator.js.flow +238 -0
  56. package/mutations/RelayRecordSourceProxy.js.flow +164 -0
  57. package/mutations/RelayRecordSourceSelectorProxy.js.flow +119 -0
  58. package/mutations/applyOptimisticMutation.js.flow +76 -0
  59. package/mutations/commitLocalUpdate.js.flow +24 -0
  60. package/mutations/commitMutation.js.flow +182 -0
  61. package/mutations/validateMutation.js.flow +213 -0
  62. package/network/ConvertToExecuteFunction.js.flow +49 -0
  63. package/network/RelayNetwork.js.flow +84 -0
  64. package/network/RelayNetworkTypes.js.flow +123 -0
  65. package/network/RelayObservable.js.flow +634 -0
  66. package/network/RelayQueryResponseCache.js.flow +111 -0
  67. package/package.json +1 -1
  68. package/query/GraphQLTag.js.flow +166 -0
  69. package/query/PreloadableQueryRegistry.js.flow +65 -0
  70. package/query/fetchQuery.js.flow +47 -0
  71. package/query/fetchQueryInternal.js.flow +348 -0
  72. package/relay-runtime.js +2 -2
  73. package/relay-runtime.min.js +2 -2
  74. package/store/ClientID.js.flow +43 -0
  75. package/store/DataChecker.js.flow +502 -0
  76. package/store/RelayConcreteVariables.js.flow +96 -0
  77. package/store/RelayModernEnvironment.js.flow +551 -0
  78. package/store/RelayModernFragmentSpecResolver.js.flow +426 -0
  79. package/store/RelayModernOperationDescriptor.js.flow +88 -0
  80. package/store/RelayModernQueryExecutor.js.flow +1321 -0
  81. package/store/RelayModernRecord.js.flow +403 -0
  82. package/store/RelayModernSelector.js.flow +455 -0
  83. package/store/RelayModernStore.js.flow +842 -0
  84. package/store/RelayOperationTracker.js.flow +164 -0
  85. package/store/RelayOptimisticRecordSource.js.flow +119 -0
  86. package/store/RelayPublishQueue.js.flow +401 -0
  87. package/store/RelayReader.js.flow +473 -0
  88. package/store/RelayRecordSource.js.flow +29 -0
  89. package/store/RelayRecordSourceMapImpl.js.flow +87 -0
  90. package/store/RelayRecordState.js.flow +37 -0
  91. package/store/RelayReferenceMarker.js.flow +257 -0
  92. package/store/RelayResponseNormalizer.js.flow +680 -0
  93. package/store/RelayStoreTypes.js.flow +899 -0
  94. package/store/RelayStoreUtils.js.flow +219 -0
  95. package/store/StoreInspector.js.flow +171 -0
  96. package/store/TypeID.js.flow +28 -0
  97. package/store/ViewerPattern.js.flow +26 -0
  98. package/store/cloneRelayHandleSourceField.js.flow +66 -0
  99. package/store/cloneRelayScalarHandleSourceField.js.flow +62 -0
  100. package/store/createFragmentSpecResolver.js.flow +55 -0
  101. package/store/createRelayContext.js.flow +44 -0
  102. package/store/defaultGetDataID.js.flow +27 -0
  103. package/store/hasOverlappingIDs.js.flow +34 -0
  104. package/store/isRelayModernEnvironment.js.flow +27 -0
  105. package/store/normalizeRelayPayload.js.flow +51 -0
  106. package/store/readInlineData.js.flow +75 -0
  107. package/subscription/requestSubscription.js.flow +100 -0
  108. package/util/JSResourceTypes.flow.js.flow +20 -0
  109. package/util/NormalizationNode.js.flow +198 -0
  110. package/util/ReaderNode.js.flow +208 -0
  111. package/util/RelayConcreteNode.js.flow +93 -0
  112. package/util/RelayDefaultHandleKey.js.flow +17 -0
  113. package/util/RelayError.js.flow +62 -0
  114. package/util/RelayFeatureFlags.js.flow +30 -0
  115. package/util/RelayProfiler.js.flow +284 -0
  116. package/util/RelayReplaySubject.js.flow +135 -0
  117. package/util/RelayRuntimeTypes.js.flow +72 -0
  118. package/util/createPayloadFor3DField.js.flow +43 -0
  119. package/util/deepFreeze.js.flow +36 -0
  120. package/util/generateID.js.flow +21 -0
  121. package/util/getFragmentIdentifier.js.flow +52 -0
  122. package/util/getRelayHandleKey.js.flow +41 -0
  123. package/util/getRequestIdentifier.js.flow +42 -0
  124. package/util/isPromise.js.flow +21 -0
  125. package/util/isScalarAndEqual.js.flow +26 -0
  126. package/util/recycleNodesInto.js.flow +76 -0
  127. package/util/resolveImmediate.js.flow +30 -0
  128. package/util/stableCopy.js.flow +35 -0
  129. package/lib/handlers/RelayDefaultMissingFieldHandlers.js +0 -26
  130. package/lib/handlers/getRelayDefaultMissingFieldHandlers.js +0 -36
  131. package/lib/query/RelayModernGraphQLTag.js +0 -104
  132. package/lib/store/RelayConnection.js +0 -37
  133. package/lib/store/RelayConnectionResolver.js +0 -178
  134. package/lib/store/RelayRecordSourceObjectImpl.js +0 -79
  135. package/lib/util/getFragmentSpecIdentifier.js +0 -27
@@ -0,0 +1,70 @@
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
+ * @emails oncall+relay
8
+ *
9
+ * @format
10
+ */
11
+ 'use strict';
12
+
13
+ var PreloadableQueryRegistry = /*#__PURE__*/function () {
14
+ function PreloadableQueryRegistry() {
15
+ this._preloadableQueries = new Map();
16
+ this._callbacks = new Map();
17
+ }
18
+
19
+ var _proto = PreloadableQueryRegistry.prototype;
20
+
21
+ _proto.set = function set(key, value) {
22
+ this._preloadableQueries.set(key, value);
23
+
24
+ var callbacks = this._callbacks.get(key);
25
+
26
+ if (callbacks != null) {
27
+ callbacks.forEach(function (cb) {
28
+ try {
29
+ cb(value);
30
+ } catch (e) {
31
+ // We do *not* want to throw in this tick, as this callback is executed
32
+ // while a query is required for the very first time.
33
+ setTimeout(function () {
34
+ throw e;
35
+ }, 0);
36
+ }
37
+ });
38
+ }
39
+ };
40
+
41
+ _proto.get = function get(key) {
42
+ return this._preloadableQueries.get(key);
43
+ };
44
+
45
+ _proto.onLoad = function onLoad(key, callback) {
46
+ var _this$_callbacks$get;
47
+
48
+ var callbacks = (_this$_callbacks$get = this._callbacks.get(key)) !== null && _this$_callbacks$get !== void 0 ? _this$_callbacks$get : new Set();
49
+ callbacks.add(callback);
50
+
51
+ var dispose = function dispose() {
52
+ callbacks["delete"](callback);
53
+ };
54
+
55
+ this._callbacks.set(key, callbacks);
56
+
57
+ return {
58
+ dispose: dispose
59
+ };
60
+ };
61
+
62
+ _proto.clear = function clear() {
63
+ this._preloadableQueries.clear();
64
+ };
65
+
66
+ return PreloadableQueryRegistry;
67
+ }();
68
+
69
+ var preloadableQueryRegistry = new PreloadableQueryRegistry();
70
+ module.exports = preloadableQueryRegistry;
@@ -16,7 +16,8 @@ var RelayReplaySubject = require('../util/RelayReplaySubject');
16
16
 
17
17
  var invariant = require("fbjs/lib/invariant");
18
18
 
19
- var requestCachesByEnvironment = new Map();
19
+ var WEAKMAP_SUPPORTED = typeof WeakMap === 'function';
20
+ var requestCachesByEnvironment = WEAKMAP_SUPPORTED ? new WeakMap() : new Map();
20
21
  /**
21
22
  * Fetches the given query and variables on the provided environment,
22
23
  * and de-dupes identical in-flight requests.
@@ -82,7 +83,7 @@ var requestCachesByEnvironment = new Map();
82
83
  */
83
84
 
84
85
  function fetchQuery(environment, operation, options) {
85
- return fetchQueryDeduped(environment, operation.request, function () {
86
+ return fetchQueryDeduped(environment, operation.request.identifier, function () {
86
87
  return environment.execute({
87
88
  operation: operation,
88
89
  cacheConfig: options === null || options === void 0 ? void 0 : options.networkCacheConfig
@@ -98,10 +99,9 @@ function fetchQuery(environment, operation, options) {
98
99
  */
99
100
 
100
101
 
101
- function fetchQueryDeduped(environment, request, fetchFn) {
102
+ function fetchQueryDeduped(environment, identifier, fetchFn) {
102
103
  return Observable.create(function (sink) {
103
104
  var requestCache = getRequestCache(environment);
104
- var identifier = request.identifier;
105
105
  var cachedRequest = requestCache.get(identifier);
106
106
 
107
107
  if (!cachedRequest) {
@@ -172,15 +172,20 @@ function getObservableForCachedRequest(requestCache, cachedRequest) {
172
172
  */
173
173
 
174
174
 
175
- function getInFlightStatusObservableForCachedRequest(requestCache, cachedRequest) {
175
+ function getActiveStatusObservableForCachedRequest(environment, requestCache, cachedRequest) {
176
176
  return Observable.create(function (sink) {
177
177
  var subscription = cachedRequest.subjectForInFlightStatus.subscribe({
178
178
  error: sink.error,
179
- next: sink.next,
179
+ next: function next(response) {
180
+ if (!environment.isRequestActive(cachedRequest.identifier)) {
181
+ sink.complete();
182
+ return;
183
+ }
184
+
185
+ sink.next();
186
+ },
180
187
  complete: sink.complete,
181
- unsubscribe: function unsubscribe() {
182
- sink.complete();
183
- }
188
+ unsubscribe: sink.complete
184
189
  });
185
190
  return function () {
186
191
  subscription.unsubscribe();
@@ -188,14 +193,15 @@ function getInFlightStatusObservableForCachedRequest(requestCache, cachedRequest
188
193
  });
189
194
  }
190
195
  /**
191
- * If a request is in flight for the given query, variables and environment,
196
+ * If a request is active for the given query, variables and environment,
192
197
  * this function will return a Promise that will resolve when that request has
193
- * completed and the data has been saved to the store.
194
- * If no request is in flight, null will be returned
198
+ * stops being active (receives a final payload), and the data has been saved
199
+ * to the store.
200
+ * If no request is active, null will be returned
195
201
  */
196
202
 
197
203
 
198
- function getPromiseForRequestInFlight(environment, request) {
204
+ function getPromiseForActiveRequest(environment, request) {
199
205
  var requestCache = getRequestCache(environment);
200
206
  var cachedRequest = requestCache.get(request.identifier);
201
207
 
@@ -203,9 +209,13 @@ function getPromiseForRequestInFlight(environment, request) {
203
209
  return null;
204
210
  }
205
211
 
212
+ if (!environment.isRequestActive(cachedRequest.identifier)) {
213
+ return null;
214
+ }
215
+
206
216
  return new Promise(function (resolve, reject) {
207
217
  var resolveOnNext = false;
208
- getInFlightStatusObservableForCachedRequest(requestCache, cachedRequest).subscribe({
218
+ getActiveStatusObservableForCachedRequest(environment, requestCache, cachedRequest).subscribe({
209
219
  complete: resolve,
210
220
  error: reject,
211
221
  next: function next(response) {
@@ -231,7 +241,7 @@ function getPromiseForRequestInFlight(environment, request) {
231
241
  */
232
242
 
233
243
 
234
- function getObservableForRequestInFlight(environment, request) {
244
+ function getObservableForActiveRequest(environment, request) {
235
245
  var requestCache = getRequestCache(environment);
236
246
  var cachedRequest = requestCache.get(request.identifier);
237
247
 
@@ -239,12 +249,11 @@ function getObservableForRequestInFlight(environment, request) {
239
249
  return null;
240
250
  }
241
251
 
242
- return getInFlightStatusObservableForCachedRequest(requestCache, cachedRequest);
243
- }
252
+ if (!environment.isRequestActive(cachedRequest.identifier)) {
253
+ return null;
254
+ }
244
255
 
245
- function hasRequestInFlight(environment, request) {
246
- var requestCache = getRequestCache(environment);
247
- return requestCache.has(request.identifier);
256
+ return getActiveStatusObservableForCachedRequest(environment, requestCache, cachedRequest);
248
257
  }
249
258
  /**
250
259
  * @private
@@ -276,7 +285,6 @@ function getCachedRequest(requestCache, identifier) {
276
285
  module.exports = {
277
286
  fetchQuery: fetchQuery,
278
287
  fetchQueryDeduped: fetchQueryDeduped,
279
- getPromiseForRequestInFlight: getPromiseForRequestInFlight,
280
- getObservableForRequestInFlight: getObservableForRequestInFlight,
281
- hasRequestInFlight: hasRequestInFlight
288
+ getPromiseForActiveRequest: getPromiseForActiveRequest,
289
+ getObservableForActiveRequest: getObservableForActiveRequest
282
290
  };
@@ -11,9 +11,15 @@
11
11
  // flowlint ambiguous-object-type:error
12
12
  'use strict';
13
13
 
14
+ function _createForOfIteratorHelper(o) { if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (o = _unsupportedIterableToArray(o))) { var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var it, normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
15
+
16
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(n); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
17
+
18
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
19
+
14
20
  var RelayConcreteNode = require('../util/RelayConcreteNode');
15
21
 
16
- var RelayConnection = require('./RelayConnection');
22
+ var RelayFeatureFlags = require('../util/RelayFeatureFlags');
17
23
 
18
24
  var RelayModernRecord = require('./RelayModernRecord');
19
25
 
@@ -25,6 +31,8 @@ var RelayStoreUtils = require('./RelayStoreUtils');
25
31
 
26
32
  var cloneRelayHandleSourceField = require('./cloneRelayHandleSourceField');
27
33
 
34
+ var cloneRelayScalarHandleSourceField = require('./cloneRelayScalarHandleSourceField');
35
+
28
36
  var invariant = require("fbjs/lib/invariant");
29
37
 
30
38
  var _require = require('./ClientID'),
@@ -34,10 +42,12 @@ var _require2 = require('./RelayRecordState'),
34
42
  EXISTENT = _require2.EXISTENT,
35
43
  UNKNOWN = _require2.UNKNOWN;
36
44
 
45
+ var _require3 = require('./TypeID'),
46
+ generateTypeID = _require3.generateTypeID;
47
+
37
48
  var CONDITION = RelayConcreteNode.CONDITION,
38
49
  CLIENT_EXTENSION = RelayConcreteNode.CLIENT_EXTENSION,
39
50
  DEFER = RelayConcreteNode.DEFER,
40
- CONNECTION = RelayConcreteNode.CONNECTION,
41
51
  FRAGMENT_SPREAD = RelayConcreteNode.FRAGMENT_SPREAD,
42
52
  INLINE_FRAGMENT = RelayConcreteNode.INLINE_FRAGMENT,
43
53
  LINKED_FIELD = RelayConcreteNode.LINKED_FIELD,
@@ -45,7 +55,8 @@ var CONDITION = RelayConcreteNode.CONDITION,
45
55
  MODULE_IMPORT = RelayConcreteNode.MODULE_IMPORT,
46
56
  SCALAR_FIELD = RelayConcreteNode.SCALAR_FIELD,
47
57
  SCALAR_HANDLE = RelayConcreteNode.SCALAR_HANDLE,
48
- STREAM = RelayConcreteNode.STREAM;
58
+ STREAM = RelayConcreteNode.STREAM,
59
+ TYPE_DISCRIMINATOR = RelayConcreteNode.TYPE_DISCRIMINATOR;
49
60
  var getModuleOperationKey = RelayStoreUtils.getModuleOperationKey,
50
61
  getStorageKey = RelayStoreUtils.getStorageKey,
51
62
  getArgumentValues = RelayStoreUtils.getArgumentValues;
@@ -60,11 +71,11 @@ var getModuleOperationKey = RelayStoreUtils.getModuleOperationKey,
60
71
  * If all records are present, returns `true`, otherwise `false`.
61
72
  */
62
73
 
63
- function check(source, target, selector, handlers, operationLoader, getDataID, getConnectionEvents) {
74
+ function check(source, target, selector, handlers, operationLoader, getDataID) {
64
75
  var dataID = selector.dataID,
65
76
  node = selector.node,
66
77
  variables = selector.variables;
67
- var checker = new DataChecker(source, target, variables, handlers, operationLoader, getDataID, getConnectionEvents);
78
+ var checker = new DataChecker(source, target, variables, handlers, operationLoader, getDataID);
68
79
  return checker.check(node, dataID);
69
80
  }
70
81
  /**
@@ -72,19 +83,13 @@ function check(source, target, selector, handlers, operationLoader, getDataID, g
72
83
  */
73
84
 
74
85
 
75
- var DataChecker =
76
- /*#__PURE__*/
77
- function () {
78
- function DataChecker(source, target, variables, handlers, operationLoader, getDataID, getConnectionEvents) {
79
- var _operationLoader;
80
-
81
- var newConnectionEvents = [];
82
- var mutator = new RelayRecordSourceMutator(source, target, newConnectionEvents);
86
+ var DataChecker = /*#__PURE__*/function () {
87
+ function DataChecker(source, target, variables, handlers, operationLoader, getDataID) {
88
+ var mutator = new RelayRecordSourceMutator(source, target);
83
89
  this._mostRecentlyInvalidatedAt = null;
84
- this._getConnectionEvents = getConnectionEvents;
85
90
  this._handlers = handlers;
86
91
  this._mutator = mutator;
87
- this._operationLoader = (_operationLoader = operationLoader) !== null && _operationLoader !== void 0 ? _operationLoader : null;
92
+ this._operationLoader = operationLoader !== null && operationLoader !== void 0 ? operationLoader : null;
88
93
  this._recordSourceProxy = new RelayRecordSourceProxy(mutator, getDataID);
89
94
  this._recordWasMissing = false;
90
95
  this._source = source;
@@ -136,12 +141,11 @@ function () {
136
141
  args = _this$_getDataForHand.args,
137
142
  record = _this$_getDataForHand.record;
138
143
 
139
- var _iteratorNormalCompletion = true;
140
- var _didIteratorError = false;
141
- var _iteratorError = undefined;
144
+ var _iterator = _createForOfIteratorHelper(this._handlers),
145
+ _step;
142
146
 
143
147
  try {
144
- for (var _iterator = this._handlers[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
148
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
145
149
  var handler = _step.value;
146
150
 
147
151
  if (handler.kind === 'scalar') {
@@ -153,18 +157,9 @@ function () {
153
157
  }
154
158
  }
155
159
  } catch (err) {
156
- _didIteratorError = true;
157
- _iteratorError = err;
160
+ _iterator.e(err);
158
161
  } finally {
159
- try {
160
- if (!_iteratorNormalCompletion && _iterator["return"] != null) {
161
- _iterator["return"]();
162
- }
163
- } finally {
164
- if (_didIteratorError) {
165
- throw _iteratorError;
166
- }
167
- }
162
+ _iterator.f();
168
163
  }
169
164
 
170
165
  this._handleMissing();
@@ -175,35 +170,25 @@ function () {
175
170
  args = _this$_getDataForHand2.args,
176
171
  record = _this$_getDataForHand2.record;
177
172
 
178
- var _iteratorNormalCompletion2 = true;
179
- var _didIteratorError2 = false;
180
- var _iteratorError2 = undefined;
173
+ var _iterator2 = _createForOfIteratorHelper(this._handlers),
174
+ _step2;
181
175
 
182
176
  try {
183
- for (var _iterator2 = this._handlers[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
177
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
184
178
  var handler = _step2.value;
185
179
 
186
180
  if (handler.kind === 'linked') {
187
181
  var newValue = handler.handle(field, record, args, this._recordSourceProxy);
188
182
 
189
- if (newValue != null && this._mutator.getStatus(newValue) === EXISTENT) {
183
+ if (newValue !== undefined && (newValue === null || this._mutator.getStatus(newValue) === EXISTENT)) {
190
184
  return newValue;
191
185
  }
192
186
  }
193
187
  }
194
188
  } catch (err) {
195
- _didIteratorError2 = true;
196
- _iteratorError2 = err;
189
+ _iterator2.e(err);
197
190
  } finally {
198
- try {
199
- if (!_iteratorNormalCompletion2 && _iterator2["return"] != null) {
200
- _iterator2["return"]();
201
- }
202
- } finally {
203
- if (_didIteratorError2) {
204
- throw _iteratorError2;
205
- }
206
- }
191
+ _iterator2.f();
207
192
  }
208
193
 
209
194
  this._handleMissing();
@@ -216,12 +201,11 @@ function () {
216
201
  args = _this$_getDataForHand3.args,
217
202
  record = _this$_getDataForHand3.record;
218
203
 
219
- var _iteratorNormalCompletion3 = true;
220
- var _didIteratorError3 = false;
221
- var _iteratorError3 = undefined;
204
+ var _iterator3 = _createForOfIteratorHelper(this._handlers),
205
+ _step3;
222
206
 
223
207
  try {
224
- for (var _iterator3 = this._handlers[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
208
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
225
209
  var handler = _step3.value;
226
210
 
227
211
  if (handler.kind === 'pluralLinked') {
@@ -235,22 +219,15 @@ function () {
235
219
  if (allItemsKnown) {
236
220
  return newValue;
237
221
  }
222
+ } else if (newValue === null) {
223
+ return null;
238
224
  }
239
225
  }
240
226
  }
241
227
  } catch (err) {
242
- _didIteratorError3 = true;
243
- _iteratorError3 = err;
228
+ _iterator3.e(err);
244
229
  } finally {
245
- try {
246
- if (!_iteratorNormalCompletion3 && _iterator3["return"] != null) {
247
- _iterator3["return"]();
248
- }
249
- } finally {
250
- if (_didIteratorError3) {
251
- throw _iteratorError3;
252
- }
253
- }
230
+ _iterator3.f();
254
231
  }
255
232
 
256
233
  this._handleMissing();
@@ -305,26 +282,71 @@ function () {
305
282
  break;
306
283
 
307
284
  case INLINE_FRAGMENT:
308
- var typeName = _this2._mutator.getType(dataID);
285
+ {
286
+ var abstractKey = selection.abstractKey;
287
+
288
+ if (abstractKey == null) {
289
+ // concrete type refinement: only check data if the type exactly matches
290
+ var typeName = _this2._mutator.getType(dataID);
291
+
292
+ if (typeName === selection.type) {
293
+ _this2._traverseSelections(selection.selections, dataID);
294
+ }
295
+ } else if (RelayFeatureFlags.ENABLE_PRECISE_TYPE_REFINEMENT) {
296
+ // Abstract refinement: check data depending on whether the type
297
+ // conforms to the interface/union or not:
298
+ // - Type known to _not_ implement the interface: don't check the selections.
299
+ // - Type is known _to_ implement the interface: check selections.
300
+ // - Unknown whether the type implements the interface: don't check the selections
301
+ // and treat the data as missing; we do this because the Relay Compiler
302
+ // guarantees that the type discriminator will always be fetched.
303
+ var recordType = _this2._mutator.getType(dataID);
304
+
305
+ !(recordType != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'DataChecker: Expected record `%s` to have a known type', dataID) : invariant(false) : void 0;
306
+ var typeID = generateTypeID(recordType);
307
+
308
+ var implementsInterface = _this2._mutator.getValue(typeID, abstractKey);
309
+
310
+ if (implementsInterface === true) {
311
+ _this2._traverseSelections(selection.selections, dataID);
312
+ } else if (implementsInterface == null) {
313
+ // unsure if the type implements the interface: data is
314
+ // missing so don't bother reading the fragment
315
+ _this2._handleMissing();
316
+ } // else false: known to not implement the interface
317
+
318
+ } else {
319
+ // legacy behavior for abstract refinements: always check even
320
+ // if the type doesn't conform
321
+ _this2._traverseSelections(selection.selections, dataID);
322
+ }
309
323
 
310
- if (typeName != null && typeName === selection.type) {
311
- _this2._traverseSelections(selection.selections, dataID);
324
+ break;
312
325
  }
313
326
 
314
- break;
315
-
316
327
  case LINKED_HANDLE:
317
- // Handles have no selections themselves; traverse the original field
318
- // where the handle was set-up instead.
319
- var handleField = cloneRelayHandleSourceField(selection, selections, _this2._variables);
328
+ {
329
+ // Handles have no selections themselves; traverse the original field
330
+ // where the handle was set-up instead.
331
+ var handleField = cloneRelayHandleSourceField(selection, selections, _this2._variables);
332
+
333
+ if (handleField.plural) {
334
+ _this2._checkPluralLink(handleField, dataID);
335
+ } else {
336
+ _this2._checkLink(handleField, dataID);
337
+ }
320
338
 
321
- if (handleField.plural) {
322
- _this2._checkPluralLink(handleField, dataID);
323
- } else {
324
- _this2._checkLink(handleField, dataID);
339
+ break;
325
340
  }
326
341
 
327
- break;
342
+ case SCALAR_HANDLE:
343
+ {
344
+ var _handleField = cloneRelayScalarHandleSourceField(selection, selections, _this2._variables);
345
+
346
+ _this2._checkScalar(_handleField, dataID);
347
+
348
+ break;
349
+ }
328
350
 
329
351
  case MODULE_IMPORT:
330
352
  _this2._checkModuleImport(selection, dataID);
@@ -337,9 +359,8 @@ function () {
337
359
 
338
360
  break;
339
361
 
340
- case SCALAR_HANDLE:
341
362
  case FRAGMENT_SPREAD:
342
- !false ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayAsyncLoader(): Unexpected ast kind `%s`.', selection.kind) : invariant(false) : void 0; // $FlowExpectedError - we need the break; for OSS linter
363
+ !false ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayAsyncLoader(): Unexpected ast kind `%s`.', selection.kind) : invariant(false) : void 0; // $FlowExpectedError[unreachable-code] - we need the break; for OSS linter
343
364
 
344
365
  break;
345
366
 
@@ -351,8 +372,25 @@ function () {
351
372
  _this2._recordWasMissing = recordWasMissing;
352
373
  break;
353
374
 
354
- case CONNECTION:
355
- _this2._checkConnection(selection, dataID);
375
+ case TYPE_DISCRIMINATOR:
376
+ if (RelayFeatureFlags.ENABLE_PRECISE_TYPE_REFINEMENT) {
377
+ var _abstractKey = selection.abstractKey;
378
+
379
+ var _recordType = _this2._mutator.getType(dataID);
380
+
381
+ !(_recordType != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'DataChecker: Expected record `%s` to have a known type', dataID) : invariant(false) : void 0;
382
+
383
+ var _typeID = generateTypeID(_recordType);
384
+
385
+ var _implementsInterface = _this2._mutator.getValue(_typeID, _abstractKey);
386
+
387
+ if (_implementsInterface == null) {
388
+ // unsure if the type implements the interface: data is
389
+ // missing
390
+ _this2._handleMissing();
391
+ } // else: if it does or doesn't implement, we don't need to check or skip anything else
392
+
393
+ }
356
394
 
357
395
  break;
358
396
 
@@ -389,36 +427,6 @@ function () {
389
427
  }
390
428
  };
391
429
 
392
- _proto._checkConnection = function _checkConnection(connection, dataID) {
393
- var _this3 = this;
394
-
395
- var connectionID = RelayConnection.createConnectionID(dataID, connection.label);
396
-
397
- var connectionEvents = this._getConnectionEvents(connectionID);
398
-
399
- if (connectionEvents == null || connectionEvents.length === 0) {
400
- return;
401
- }
402
-
403
- connectionEvents.forEach(function (event) {
404
- if (event.kind === 'fetch') {
405
- event.edgeIDs.forEach(function (edgeID) {
406
- if (edgeID != null) {
407
- _this3._traverse(connection.edges, edgeID);
408
- }
409
- });
410
- } else if (event.kind === 'insert') {
411
- _this3._traverse(connection.edges, event.edgeID);
412
- } else if (event.kind === 'stream.edge') {
413
- _this3._traverse(connection.edges, event.edgeID);
414
- } else if (event.kind === 'stream.pageInfo') {// no-op
415
- } else {
416
- event;
417
- !false ? process.env.NODE_ENV !== "production" ? invariant(false, 'DataChecker: Unexpected connection event kind `%s`.', event.kind) : invariant(false) : void 0;
418
- }
419
- });
420
- };
421
-
422
430
  _proto._checkScalar = function _checkScalar(field, dataID) {
423
431
  var storageKey = getStorageKey(field, this._variables);
424
432
 
@@ -443,6 +451,8 @@ function () {
443
451
 
444
452
  if (linkedID != null) {
445
453
  this._mutator.setLinkedRecordID(dataID, storageKey, linkedID);
454
+ } else if (linkedID === null) {
455
+ this._mutator.setValue(dataID, storageKey, null);
446
456
  }
447
457
  }
448
458
 
@@ -452,7 +462,7 @@ function () {
452
462
  };
453
463
 
454
464
  _proto._checkPluralLink = function _checkPluralLink(field, dataID) {
455
- var _this4 = this;
465
+ var _this3 = this;
456
466
 
457
467
  var storageKey = getStorageKey(field, this._variables);
458
468
 
@@ -463,13 +473,15 @@ function () {
463
473
 
464
474
  if (linkedIDs != null) {
465
475
  this._mutator.setLinkedRecordIDs(dataID, storageKey, linkedIDs);
476
+ } else if (linkedIDs === null) {
477
+ this._mutator.setValue(dataID, storageKey, null);
466
478
  }
467
479
  }
468
480
 
469
481
  if (linkedIDs) {
470
482
  linkedIDs.forEach(function (linkedID) {
471
483
  if (linkedID != null) {
472
- _this4._traverse(field, linkedID);
484
+ _this3._traverse(field, linkedID);
473
485
  }
474
486
  });
475
487
  }
@@ -12,7 +12,11 @@
12
12
 
13
13
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
14
14
 
15
- var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));
15
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
16
+
17
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
18
+
19
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
16
20
 
17
21
  var invariant = require("fbjs/lib/invariant");
18
22
 
@@ -30,7 +34,7 @@ function getFragmentVariables(fragment, rootVariables, argumentVariables) {
30
34
  return;
31
35
  }
32
36
 
33
- variables = variables || (0, _objectSpread2["default"])({}, argumentVariables);
37
+ variables = variables || _objectSpread({}, argumentVariables);
34
38
 
35
39
  switch (definition.kind) {
36
40
  case 'LocalArgument':