relay-runtime 13.0.3 → 13.2.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 (50) hide show
  1. package/index.js +1 -1
  2. package/index.js.flow +4 -2
  3. package/lib/index.js +3 -3
  4. package/lib/mutations/readUpdatableQuery_EXPERIMENTAL.js +3 -4
  5. package/lib/query/GraphQLTag.js +13 -0
  6. package/lib/query/fetchQuery.js +2 -5
  7. package/lib/store/RelayModernEnvironment.js +3 -3
  8. package/lib/store/RelayModernFragmentSpecResolver.js +6 -6
  9. package/lib/store/RelayModernSelector.js +16 -2
  10. package/lib/store/RelayReader.js +71 -6
  11. package/lib/store/RelayStoreSubscriptions.js +4 -2
  12. package/lib/store/RelayStoreUtils.js +1 -0
  13. package/lib/store/ResolverCache.js +25 -13
  14. package/lib/store/experimental-live-resolvers/LiveResolverCache.js +316 -0
  15. package/lib/store/experimental-live-resolvers/LiveResolverStore.js +787 -0
  16. package/lib/store/hasOverlappingIDs.js +1 -1
  17. package/lib/util/RelayConcreteNode.js +2 -0
  18. package/lib/util/RelayFeatureFlags.js +0 -3
  19. package/lib/util/handlePotentialSnapshotErrors.js +73 -0
  20. package/mutations/RelayRecordSourceProxy.js.flow +7 -3
  21. package/mutations/RelayRecordSourceSelectorProxy.js.flow +7 -3
  22. package/mutations/readUpdatableQuery_EXPERIMENTAL.js.flow +14 -12
  23. package/network/RelayNetworkTypes.js.flow +1 -1
  24. package/package.json +1 -1
  25. package/query/GraphQLTag.js.flow +38 -3
  26. package/query/fetchQuery.js.flow +6 -4
  27. package/relay-runtime.js +2 -2
  28. package/relay-runtime.min.js +2 -2
  29. package/store/RelayModernEnvironment.js.flow +3 -3
  30. package/store/RelayModernFragmentSpecResolver.js.flow +11 -7
  31. package/store/RelayModernSelector.js.flow +32 -8
  32. package/store/RelayReader.js.flow +65 -23
  33. package/store/RelayResponseNormalizer.js.flow +1 -1
  34. package/store/RelayStoreSubscriptions.js.flow +2 -0
  35. package/store/RelayStoreTypes.js.flow +22 -8
  36. package/store/RelayStoreUtils.js.flow +2 -1
  37. package/store/ResolverCache.js.flow +45 -10
  38. package/store/defaultGetDataID.js.flow +1 -1
  39. package/store/experimental-live-resolvers/LiveResolverCache.js.flow +410 -0
  40. package/store/experimental-live-resolvers/LiveResolverStore.js.flow +822 -0
  41. package/store/hasOverlappingIDs.js.flow +1 -1
  42. package/util/ReaderNode.js.flow +17 -1
  43. package/util/RelayConcreteNode.js.flow +9 -1
  44. package/util/RelayFeatureFlags.js.flow +0 -6
  45. package/util/RelayRuntimeTypes.js.flow +20 -1
  46. package/util/deepFreeze.js.flow +1 -1
  47. package/util/handlePotentialSnapshotErrors.js.flow +63 -0
  48. package/util/isEmptyObject.js.flow +1 -1
  49. package/lib/util/reportMissingRequiredFields.js +0 -48
  50. package/util/reportMissingRequiredFields.js.flow +0 -51
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Relay v13.0.3
2
+ * Relay v13.2.0
3
3
  *
4
4
  * Copyright (c) Meta Platforms, Inc. and affiliates.
5
5
  *
package/index.js.flow CHANGED
@@ -59,6 +59,7 @@ const getRefetchMetadata = require('./util/getRefetchMetadata');
59
59
  const getRelayHandleKey = require('./util/getRelayHandleKey');
60
60
  const getRequestIdentifier = require('./util/getRequestIdentifier');
61
61
  const getValueAtPath = require('./util/getValueAtPath');
62
+ const handlePotentialSnapshotErrors = require('./util/handlePotentialSnapshotErrors');
62
63
  const isPromise = require('./util/isPromise');
63
64
  const isScalarAndEqual = require('./util/isScalarAndEqual');
64
65
  const recycleNodesInto = require('./util/recycleNodesInto');
@@ -68,7 +69,6 @@ const RelayError = require('./util/RelayError');
68
69
  const RelayFeatureFlags = require('./util/RelayFeatureFlags');
69
70
  const RelayProfiler = require('./util/RelayProfiler');
70
71
  const RelayReplaySubject = require('./util/RelayReplaySubject');
71
- const reportMissingRequiredFields = require('./util/reportMissingRequiredFields');
72
72
  const stableCopy = require('./util/stableCopy');
73
73
  const withProvidedVariables = require('./util/withProvidedVariables');
74
74
 
@@ -203,6 +203,7 @@ export type {
203
203
  } from './util/ReaderNode';
204
204
  export type {
205
205
  ConcreteRequest,
206
+ ConcreteUpdatableQuery,
206
207
  GeneratedNode,
207
208
  RequestParameters,
208
209
  } from './util/RelayConcreteNode';
@@ -221,6 +222,7 @@ export type {
221
222
  Query,
222
223
  RefetchableFragment,
223
224
  RenderPolicy,
225
+ UpdatableQuery,
224
226
  Variables,
225
227
  VariablesOf,
226
228
  } from './util/RelayRuntimeTypes';
@@ -289,7 +291,7 @@ module.exports = {
289
291
  RelayModernSelector.getVariablesFromPluralFragment,
290
292
  getVariablesFromSingularFragment:
291
293
  RelayModernSelector.getVariablesFromSingularFragment,
292
- reportMissingRequiredFields,
294
+ handlePotentialSnapshotErrors,
293
295
  graphql: GraphQLTag.graphql,
294
296
  isFragment: GraphQLTag.isFragment,
295
297
  isInlineDataFragment: GraphQLTag.isInlineDataFragment,
package/lib/index.js CHANGED
@@ -99,6 +99,8 @@ var getRequestIdentifier = require('./util/getRequestIdentifier');
99
99
 
100
100
  var getValueAtPath = require('./util/getValueAtPath');
101
101
 
102
+ var handlePotentialSnapshotErrors = require('./util/handlePotentialSnapshotErrors');
103
+
102
104
  var isPromise = require('./util/isPromise');
103
105
 
104
106
  var isScalarAndEqual = require('./util/isScalarAndEqual');
@@ -117,8 +119,6 @@ var RelayProfiler = require('./util/RelayProfiler');
117
119
 
118
120
  var RelayReplaySubject = require('./util/RelayReplaySubject');
119
121
 
120
- var reportMissingRequiredFields = require('./util/reportMissingRequiredFields');
121
-
122
122
  var stableCopy = require('./util/stableCopy');
123
123
 
124
124
  var withProvidedVariables = require('./util/withProvidedVariables');
@@ -176,7 +176,7 @@ module.exports = {
176
176
  getVariablesFromObject: RelayModernSelector.getVariablesFromObject,
177
177
  getVariablesFromPluralFragment: RelayModernSelector.getVariablesFromPluralFragment,
178
178
  getVariablesFromSingularFragment: RelayModernSelector.getVariablesFromSingularFragment,
179
- reportMissingRequiredFields: reportMissingRequiredFields,
179
+ handlePotentialSnapshotErrors: handlePotentialSnapshotErrors,
180
180
  graphql: GraphQLTag.graphql,
181
181
  isFragment: GraphQLTag.isFragment,
182
182
  isInlineDataFragment: GraphQLTag.isInlineDataFragment,
@@ -16,7 +16,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
16
16
  var _createForOfIteratorHelper2 = _interopRequireDefault(require("@babel/runtime/helpers/createForOfIteratorHelper"));
17
17
 
18
18
  var _require = require('../query/GraphQLTag'),
19
- getRequest = _require.getRequest;
19
+ getUpdatableQuery = _require.getUpdatableQuery;
20
20
 
21
21
  var _require2 = require('../store/RelayStoreUtils'),
22
22
  getArgumentValues = _require2.getArgumentValues;
@@ -24,10 +24,9 @@ var _require2 = require('../store/RelayStoreUtils'),
24
24
  var nonUpdatableKeys = ['id', '__id', '__typename', 'js'];
25
25
 
26
26
  function readUpdatableQuery_EXPERIMENTAL(query, variables, proxy) {
27
- // TODO assert that the concrete request is an updatable query
28
- var request = getRequest(query);
27
+ var updatableQuery = getUpdatableQuery(query);
29
28
  var updatableProxy = {};
30
- updateProxyFromSelections(updatableProxy, proxy.getRoot(), variables, request.fragment.selections, proxy);
29
+ updateProxyFromSelections(updatableProxy, proxy.getRoot(), variables, updatableQuery.fragment.selections, proxy);
31
30
 
32
31
  if (process.env.NODE_ENV !== "production") {
33
32
  Object.freeze(updatableProxy);
@@ -49,6 +49,11 @@ function isRequest(node) {
49
49
  return typeof request === 'object' && request !== null && request.kind === RelayConcreteNode.REQUEST;
50
50
  }
51
51
 
52
+ function isUpdatableQuery(node) {
53
+ var updatableQuery = getNode(node);
54
+ return typeof updatableQuery === 'object' && updatableQuery !== null && updatableQuery.kind === RelayConcreteNode.UPDATABLE_QUERY;
55
+ }
56
+
52
57
  function isInlineDataFragment(node) {
53
58
  var fragment = getNode(node);
54
59
  return typeof fragment === 'object' && fragment !== null && fragment.kind === RelayConcreteNode.INLINE_DATA_FRAGMENT;
@@ -93,6 +98,12 @@ function getRequest(taggedNode) {
93
98
  return request;
94
99
  }
95
100
 
101
+ function getUpdatableQuery(taggedNode) {
102
+ var updatableQuery = getNode(taggedNode);
103
+ !isUpdatableQuery(updatableQuery) ? process.env.NODE_ENV !== "production" ? invariant(false, 'GraphQLTag: Expected a request, got `%s`.', JSON.stringify(updatableQuery)) : invariant(false) : void 0;
104
+ return updatableQuery;
105
+ }
106
+
96
107
  function getInlineDataFragment(taggedNode) {
97
108
  var fragment = getNode(taggedNode);
98
109
  !isInlineDataFragment(fragment) ? process.env.NODE_ENV !== "production" ? invariant(false, 'GraphQLTag: Expected an inline data fragment, got `%s`.', JSON.stringify(fragment)) : invariant(false) : void 0;
@@ -105,9 +116,11 @@ module.exports = {
105
116
  getPaginationFragment: getPaginationFragment,
106
117
  getRefetchableFragment: getRefetchableFragment,
107
118
  getRequest: getRequest,
119
+ getUpdatableQuery: getUpdatableQuery,
108
120
  getInlineDataFragment: getInlineDataFragment,
109
121
  graphql: graphql,
110
122
  isFragment: isFragment,
111
123
  isRequest: isRequest,
124
+ isUpdatableQuery: isUpdatableQuery,
112
125
  isInlineDataFragment: isInlineDataFragment
113
126
  };
@@ -20,7 +20,7 @@ var RelayObservable = require('../network/RelayObservable');
20
20
  var _require = require('../store/RelayModernOperationDescriptor'),
21
21
  createOperationDescriptor = _require.createOperationDescriptor;
22
22
 
23
- var reportMissingRequiredFields = require('../util/reportMissingRequiredFields');
23
+ var handlePotentialSnapshotErrors = require('../util/handlePotentialSnapshotErrors');
24
24
 
25
25
  var fetchQueryInternal = require('./fetchQueryInternal');
26
26
 
@@ -119,13 +119,10 @@ function fetchQuery(environment, query, variables, options) {
119
119
  var fetchPolicy = (_options$fetchPolicy = options === null || options === void 0 ? void 0 : options.fetchPolicy) !== null && _options$fetchPolicy !== void 0 ? _options$fetchPolicy : 'network-only';
120
120
 
121
121
  function readData(snapshot) {
122
- if (snapshot.missingRequiredFields != null) {
123
- reportMissingRequiredFields(environment, snapshot.missingRequiredFields);
124
- }
122
+ handlePotentialSnapshotErrors(environment, snapshot.missingRequiredFields, snapshot.relayResolverErrors);
125
123
  /* $FlowFixMe[incompatible-return] we assume readData returns the right
126
124
  * data just having written it from network or checked availability. */
127
125
 
128
-
129
126
  return snapshot.data;
130
127
  }
131
128
 
@@ -291,7 +291,7 @@ var RelayModernEnvironment = /*#__PURE__*/function () {
291
291
  var operation = _ref.operation;
292
292
  return this._execute({
293
293
  createSource: function createSource() {
294
- return _this7._network.execute(operation.request.node.params, operation.request.variables, operation.request.cacheConfig || {}, null);
294
+ return _this7.getNetwork().execute(operation.request.node.params, operation.request.variables, operation.request.cacheConfig || {}, null);
295
295
  },
296
296
  isClientPayload: false,
297
297
  operation: operation,
@@ -316,7 +316,7 @@ var RelayModernEnvironment = /*#__PURE__*/function () {
316
316
  updater = _ref2.updater;
317
317
  return this._execute({
318
318
  createSource: function createSource() {
319
- return _this8._network.execute(operation.request.node.params, operation.request.variables, operation.request.cacheConfig || {}, null);
319
+ return _this8.getNetwork().execute(operation.request.node.params, operation.request.variables, operation.request.cacheConfig || {}, null);
320
320
  },
321
321
  isClientPayload: false,
322
322
  operation: operation,
@@ -356,7 +356,7 @@ var RelayModernEnvironment = /*#__PURE__*/function () {
356
356
 
357
357
  return this._execute({
358
358
  createSource: function createSource() {
359
- return _this9._network.execute(operation.request.node.params, operation.request.variables, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, operation.request.cacheConfig), {}, {
359
+ return _this9.getNetwork().execute(operation.request.node.params, operation.request.variables, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, operation.request.cacheConfig), {}, {
360
360
  force: true
361
361
  }), uploadables);
362
362
  },
@@ -18,14 +18,14 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/de
18
18
 
19
19
  var getPendingOperationsForFragment = require('../util/getPendingOperationsForFragment');
20
20
 
21
+ var handlePotentialSnapshotErrors = require('../util/handlePotentialSnapshotErrors');
22
+
21
23
  var isScalarAndEqual = require('../util/isScalarAndEqual');
22
24
 
23
25
  var recycleNodesInto = require('../util/recycleNodesInto');
24
26
 
25
27
  var RelayFeatureFlags = require('../util/RelayFeatureFlags');
26
28
 
27
- var reportMissingRequiredFields = require('../util/reportMissingRequiredFields');
28
-
29
29
  var _require = require('./RelayModernOperationDescriptor'),
30
30
  createRequestDescriptor = _require.createRequestDescriptor;
31
31
 
@@ -206,6 +206,7 @@ var SelectorResolver = /*#__PURE__*/function () {
206
206
  _this2._data = snapshot.data;
207
207
  _this2._isMissingData = snapshot.isMissingData;
208
208
  _this2._missingRequiredFields = snapshot.missingRequiredFields;
209
+ _this2._relayResolverErrors = snapshot.relayResolverErrors;
209
210
 
210
211
  _this2._callback();
211
212
  });
@@ -216,6 +217,7 @@ var SelectorResolver = /*#__PURE__*/function () {
216
217
  this._data = _snapshot.data;
217
218
  this._isMissingData = _snapshot.isMissingData;
218
219
  this._missingRequiredFields = _snapshot.missingRequiredFields;
220
+ this._relayResolverErrors = _snapshot.relayResolverErrors;
219
221
  this._environment = environment;
220
222
  this._rootIsQueryRenderer = rootIsQueryRenderer;
221
223
  this._selector = selector;
@@ -289,10 +291,7 @@ var SelectorResolver = /*#__PURE__*/function () {
289
291
  }
290
292
  }
291
293
 
292
- if (this._missingRequiredFields != null) {
293
- reportMissingRequiredFields(this._environment, this._missingRequiredFields);
294
- }
295
-
294
+ handlePotentialSnapshotErrors(this._environment, this._missingRequiredFields, this._relayResolverErrors);
296
295
  return this._data;
297
296
  };
298
297
 
@@ -308,6 +307,7 @@ var SelectorResolver = /*#__PURE__*/function () {
308
307
  this._data = recycleNodesInto(this._data, snapshot.data);
309
308
  this._isMissingData = snapshot.isMissingData;
310
309
  this._missingRequiredFields = snapshot.missingRequiredFields;
310
+ this._relayResolverErrors = snapshot.relayResolverErrors;
311
311
  this._selector = selector;
312
312
  this._subscription = this._environment.subscribe(snapshot, this._onChange);
313
313
  };
@@ -284,6 +284,10 @@ function getVariablesFromPluralFragment(fragment, items) {
284
284
  });
285
285
  return variables;
286
286
  }
287
+
288
+ function areEqualSingularSelectors(thisSelector, thatSelector) {
289
+ return thisSelector.owner === thatSelector.owner && thisSelector.dataID === thatSelector.dataID && thisSelector.node === thatSelector.node && areEqual(thisSelector.variables, thatSelector.variables);
290
+ }
287
291
  /**
288
292
  * @public
289
293
  *
@@ -293,8 +297,18 @@ function getVariablesFromPluralFragment(fragment, items) {
293
297
  */
294
298
 
295
299
 
296
- function areEqualSelectors(thisSelector, thatSelector) {
297
- return thisSelector.owner === thatSelector.owner && thisSelector.dataID === thatSelector.dataID && thisSelector.node === thatSelector.node && areEqual(thisSelector.variables, thatSelector.variables);
300
+ function areEqualSelectors(a, b) {
301
+ if ((a === null || a === void 0 ? void 0 : a.kind) === 'SingularReaderSelector' && (b === null || b === void 0 ? void 0 : b.kind) === 'SingularReaderSelector') {
302
+ return areEqualSingularSelectors(a, b);
303
+ } else if ((a === null || a === void 0 ? void 0 : a.kind) === 'PluralReaderSelector' && (b === null || b === void 0 ? void 0 : b.kind) === 'PluralReaderSelector') {
304
+ return a.selectors.length === b.selectors.length && a.selectors.every(function (s, i) {
305
+ return areEqualSingularSelectors(s, b.selectors[i]);
306
+ });
307
+ } else if (a == null && b == null) {
308
+ return true;
309
+ } else {
310
+ return false;
311
+ }
298
312
  }
299
313
 
300
314
  function createReaderSelector(fragment, dataID, variables, request) {
@@ -12,6 +12,8 @@
12
12
 
13
13
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
14
14
 
15
+ var _createForOfIteratorHelper2 = _interopRequireDefault(require("@babel/runtime/helpers/createForOfIteratorHelper"));
16
+
15
17
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
16
18
 
17
19
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
@@ -28,6 +30,7 @@ var _require = require('../util/RelayConcreteNode'),
28
30
  INLINE_FRAGMENT = _require.INLINE_FRAGMENT,
29
31
  LINKED_FIELD = _require.LINKED_FIELD,
30
32
  MODULE_IMPORT = _require.MODULE_IMPORT,
33
+ RELAY_LIVE_RESOLVER = _require.RELAY_LIVE_RESOLVER,
31
34
  RELAY_RESOLVER = _require.RELAY_RESOLVER,
32
35
  REQUIRED_FIELD = _require.REQUIRED_FIELD,
33
36
  SCALAR_FIELD = _require.SCALAR_FIELD,
@@ -90,6 +93,7 @@ var RelayReader = /*#__PURE__*/function () {
90
93
  this._selector = selector;
91
94
  this._variables = selector.variables;
92
95
  this._resolverCache = resolverCache;
96
+ this._resolverErrors = [];
93
97
  this._fragmentName = selector.node.name;
94
98
  }
95
99
 
@@ -164,7 +168,8 @@ var RelayReader = /*#__PURE__*/function () {
164
168
  missingClientEdges: RelayFeatureFlags.ENABLE_CLIENT_EDGES && this._missingClientEdges.length ? this._missingClientEdges : null,
165
169
  seenRecords: this._seenRecords,
166
170
  selector: this._selector,
167
- missingRequiredFields: this._missingRequiredFields
171
+ missingRequiredFields: this._missingRequiredFields,
172
+ relayResolverErrors: this._resolverErrors
168
173
  };
169
174
  };
170
175
 
@@ -359,6 +364,17 @@ var RelayReader = /*#__PURE__*/function () {
359
364
  break;
360
365
  }
361
366
 
367
+ case RELAY_LIVE_RESOLVER:
368
+ {
369
+ if (!RelayFeatureFlags.ENABLE_RELAY_RESOLVERS) {
370
+ throw new Error('Relay Resolver fields are not yet supported.');
371
+ }
372
+
373
+ this._readResolverField(selection, record, data);
374
+
375
+ break;
376
+ }
377
+
362
378
  case RELAY_RESOLVER:
363
379
  {
364
380
  if (!RelayFeatureFlags.ENABLE_RELAY_RESOLVERS) {
@@ -475,6 +491,13 @@ var RelayReader = /*#__PURE__*/function () {
475
491
 
476
492
  return this._readResolverField(selection.field, record, data);
477
493
 
494
+ case RELAY_LIVE_RESOLVER:
495
+ if (!RelayFeatureFlags.ENABLE_RELAY_RESOLVERS) {
496
+ throw new Error('Relay Resolver fields are not yet supported.');
497
+ }
498
+
499
+ return this._readResolverField(selection.field, record, data);
500
+
478
501
  default:
479
502
  selection.field.kind;
480
503
  !false ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayReader(): Unexpected ast kind `%s`.', selection.kind) : invariant(false) : void 0;
@@ -497,6 +520,8 @@ var RelayReader = /*#__PURE__*/function () {
497
520
  var fragmentReaderSelector;
498
521
  var fragmentMissingRequiredFields;
499
522
  var previousMissingRequriedFields;
523
+ var currentResolverErrors;
524
+ var previousResolverErrors;
500
525
  var fragmentSeenRecordIDs = new Set();
501
526
 
502
527
  var getDataForResolverFragment = function getDataForResolverFragment(singularReaderSelector) {
@@ -517,16 +542,20 @@ var RelayReader = /*#__PURE__*/function () {
517
542
  var resolverFragmentData = {};
518
543
  previousMissingRequriedFields = _this._missingRequiredFields;
519
544
  _this._missingRequiredFields = null;
545
+ previousResolverErrors = _this._resolverErrors;
546
+ _this._resolverErrors = [];
520
547
 
521
548
  _this._createInlineDataOrResolverFragmentPointer(singularReaderSelector.node, record, resolverFragmentData);
522
549
 
523
550
  fragmentMissingRequiredFields = _this._missingRequiredFields;
551
+ currentResolverErrors = _this._resolverErrors;
524
552
  fragmentValue = (_resolverFragmentData = resolverFragmentData[FRAGMENTS_KEY]) === null || _resolverFragmentData === void 0 ? void 0 : _resolverFragmentData[fragment.name];
525
553
  !(typeof fragmentValue === 'object' && fragmentValue !== null) ? process.env.NODE_ENV !== "production" ? invariant(false, "Expected reader data to contain a __fragments property with a property for the fragment named ".concat(fragment.name, ", but it is missing.")) : invariant(false) : void 0;
526
554
  return fragmentValue;
527
555
  } finally {
528
556
  _this._seenRecords = existingSeenRecords;
529
557
  _this._missingRequiredFields = previousMissingRequriedFields;
558
+ _this._resolverErrors = previousResolverErrors;
530
559
  }
531
560
  };
532
561
 
@@ -534,17 +563,35 @@ var RelayReader = /*#__PURE__*/function () {
534
563
  getDataForResolverFragment: getDataForResolverFragment
535
564
  };
536
565
 
537
- var _this$_resolverCache$ = this._resolverCache.readFromCacheOrEvaluate(record, field, this._variables, function () {
566
+ var evaluate = function evaluate() {
538
567
  var key = {
539
568
  __id: RelayModernRecord.getDataID(record),
540
569
  __fragmentOwner: _this._owner,
541
570
  __fragments: (0, _defineProperty2["default"])({}, fragment.name, {})
542
571
  };
543
572
  return withResolverContext(resolverContext, function () {
544
- // $FlowFixMe[prop-missing] - resolver module's type signature is a lie
545
- var resolverResult = resolverModule(key);
573
+ var resolverResult = null;
574
+
575
+ try {
576
+ // $FlowFixMe[prop-missing] - resolver module's type signature is a lie
577
+ resolverResult = resolverModule(key);
578
+ } catch (e) {
579
+ var _field$path;
580
+
581
+ // `field.path` is typed as nullable while we rollout compiler changes.
582
+ var path = (_field$path = field.path) !== null && _field$path !== void 0 ? _field$path : '[UNKNOWN]';
583
+ currentResolverErrors.push({
584
+ field: {
585
+ path: path,
586
+ owner: _this._fragmentName
587
+ },
588
+ error: e
589
+ });
590
+ }
591
+
546
592
  return {
547
593
  resolverResult: resolverResult,
594
+ errors: currentResolverErrors,
548
595
  fragmentValue: fragmentValue,
549
596
  resolverID: resolverID,
550
597
  seenRecordIDs: fragmentSeenRecordIDs,
@@ -552,10 +599,28 @@ var RelayReader = /*#__PURE__*/function () {
552
599
  missingRequiredFields: fragmentMissingRequiredFields
553
600
  };
554
601
  });
555
- }, getDataForResolverFragment),
602
+ };
603
+
604
+ var _this$_resolverCache$ = this._resolverCache.readFromCacheOrEvaluate(record, field, this._variables, evaluate, getDataForResolverFragment),
556
605
  result = _this$_resolverCache$[0],
557
606
  seenRecord = _this$_resolverCache$[1],
558
- missingRequiredFields = _this$_resolverCache$[2];
607
+ resolverErrors = _this$_resolverCache$[2],
608
+ missingRequiredFields = _this$_resolverCache$[3];
609
+
610
+ var _iterator = (0, _createForOfIteratorHelper2["default"])(resolverErrors),
611
+ _step;
612
+
613
+ try {
614
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
615
+ var resolverError = _step.value;
616
+
617
+ this._resolverErrors.push(resolverError);
618
+ }
619
+ } catch (err) {
620
+ _iterator.e(err);
621
+ } finally {
622
+ _iterator.f();
623
+ }
559
624
 
560
625
  if (missingRequiredFields != null) {
561
626
  this._addMissingRequiredFields(missingRequiredFields);
@@ -96,7 +96,8 @@ var RelayStoreSubscriptions = /*#__PURE__*/function () {
96
96
  missingClientEdges: backup.missingClientEdges,
97
97
  seenRecords: backup.seenRecords,
98
98
  selector: backup.selector,
99
- missingRequiredFields: backup.missingRequiredFields
99
+ missingRequiredFields: backup.missingRequiredFields,
100
+ relayResolverErrors: backup.relayResolverErrors
100
101
  };
101
102
  } else {
102
103
  subscription.stale = true;
@@ -146,7 +147,8 @@ var RelayStoreSubscriptions = /*#__PURE__*/function () {
146
147
  missingClientEdges: nextSnapshot.missingClientEdges,
147
148
  seenRecords: nextSnapshot.seenRecords,
148
149
  selector: nextSnapshot.selector,
149
- missingRequiredFields: nextSnapshot.missingRequiredFields
150
+ missingRequiredFields: nextSnapshot.missingRequiredFields,
151
+ relayResolverErrors: nextSnapshot.relayResolverErrors
150
152
  };
151
153
 
152
154
  if (process.env.NODE_ENV !== "production") {
@@ -212,6 +212,7 @@ var RelayStoreUtils = {
212
212
  RELAY_RESOLVER_INPUTS_KEY: '__resolverInputValues',
213
213
  RELAY_RESOLVER_READER_SELECTOR_KEY: '__resolverReaderSelector',
214
214
  RELAY_RESOLVER_MISSING_REQUIRED_FIELDS_KEY: '__resolverMissingRequiredFields',
215
+ RELAY_RESOLVER_ERROR_KEY: '__resolverError',
215
216
  formatStorageKey: formatStorageKey,
216
217
  getArgumentValue: getArgumentValue,
217
218
  getArgumentValues: getArgumentValues,
@@ -16,18 +16,24 @@ var _createForOfIteratorHelper2 = _interopRequireDefault(require("@babel/runtime
16
16
 
17
17
  var recycleNodesInto = require('../util/recycleNodesInto');
18
18
 
19
- var _require = require('./ClientID'),
20
- generateClientID = _require.generateClientID;
19
+ var _require = require('../util/RelayConcreteNode'),
20
+ RELAY_LIVE_RESOLVER = _require.RELAY_LIVE_RESOLVER;
21
+
22
+ var _require2 = require('./ClientID'),
23
+ generateClientID = _require2.generateClientID;
21
24
 
22
25
  var RelayModernRecord = require('./RelayModernRecord');
23
26
 
24
- var _require2 = require('./RelayStoreUtils'),
25
- RELAY_RESOLVER_INPUTS_KEY = _require2.RELAY_RESOLVER_INPUTS_KEY,
26
- RELAY_RESOLVER_INVALIDATION_KEY = _require2.RELAY_RESOLVER_INVALIDATION_KEY,
27
- RELAY_RESOLVER_MISSING_REQUIRED_FIELDS_KEY = _require2.RELAY_RESOLVER_MISSING_REQUIRED_FIELDS_KEY,
28
- RELAY_RESOLVER_READER_SELECTOR_KEY = _require2.RELAY_RESOLVER_READER_SELECTOR_KEY,
29
- RELAY_RESOLVER_VALUE_KEY = _require2.RELAY_RESOLVER_VALUE_KEY,
30
- getStorageKey = _require2.getStorageKey;
27
+ var _require3 = require('./RelayStoreUtils'),
28
+ RELAY_RESOLVER_ERROR_KEY = _require3.RELAY_RESOLVER_ERROR_KEY,
29
+ RELAY_RESOLVER_INPUTS_KEY = _require3.RELAY_RESOLVER_INPUTS_KEY,
30
+ RELAY_RESOLVER_INVALIDATION_KEY = _require3.RELAY_RESOLVER_INVALIDATION_KEY,
31
+ RELAY_RESOLVER_MISSING_REQUIRED_FIELDS_KEY = _require3.RELAY_RESOLVER_MISSING_REQUIRED_FIELDS_KEY,
32
+ RELAY_RESOLVER_READER_SELECTOR_KEY = _require3.RELAY_RESOLVER_READER_SELECTOR_KEY,
33
+ RELAY_RESOLVER_VALUE_KEY = _require3.RELAY_RESOLVER_VALUE_KEY,
34
+ getStorageKey = _require3.getStorageKey;
35
+
36
+ var invariant = require('invariant');
31
37
 
32
38
  var warning = require("fbjs/lib/warning");
33
39
 
@@ -40,11 +46,14 @@ var NoopResolverCache = /*#__PURE__*/function () {
40
46
  var _proto = NoopResolverCache.prototype;
41
47
 
42
48
  _proto.readFromCacheOrEvaluate = function readFromCacheOrEvaluate(record, field, variables, evaluate, getDataForResolverFragment) {
49
+ !(field.kind !== RELAY_LIVE_RESOLVER) ? process.env.NODE_ENV !== "production" ? invariant(false, 'This store does not support Live Resolvers') : invariant(false) : void 0;
50
+
43
51
  var _evaluate = evaluate(),
44
52
  resolverResult = _evaluate.resolverResult,
45
- missingRequiredFields = _evaluate.missingRequiredFields;
53
+ missingRequiredFields = _evaluate.missingRequiredFields,
54
+ errors = _evaluate.errors;
46
55
 
47
- return [resolverResult, undefined, missingRequiredFields];
56
+ return [resolverResult, undefined, errors, missingRequiredFields];
48
57
  };
49
58
 
50
59
  _proto.invalidateDataIDs = function invalidateDataIDs(updatedDataIDs) {};
@@ -91,6 +100,7 @@ var RecordResolverCache = /*#__PURE__*/function () {
91
100
  RelayModernRecord.setValue(linkedRecord, RELAY_RESOLVER_INPUTS_KEY, evaluationResult.fragmentValue);
92
101
  RelayModernRecord.setValue(linkedRecord, RELAY_RESOLVER_READER_SELECTOR_KEY, evaluationResult.readerSelector);
93
102
  RelayModernRecord.setValue(linkedRecord, RELAY_RESOLVER_MISSING_REQUIRED_FIELDS_KEY, evaluationResult.missingRequiredFields);
103
+ RelayModernRecord.setValue(linkedRecord, RELAY_RESOLVER_ERROR_KEY, evaluationResult.errors);
94
104
  recordSource.set(linkedID, linkedRecord); // Link the resolver value record to the resolver field of the record being read:
95
105
 
96
106
  var nextRecord = RelayModernRecord.clone(record);
@@ -119,8 +129,10 @@ var RecordResolverCache = /*#__PURE__*/function () {
119
129
 
120
130
  var answer = linkedRecord[RELAY_RESOLVER_VALUE_KEY];
121
131
  var missingRequiredFields = // $FlowFixMe[incompatible-type] - casting mixed
122
- linkedRecord[RELAY_RESOLVER_MISSING_REQUIRED_FIELDS_KEY];
123
- return [answer, linkedID, missingRequiredFields];
132
+ linkedRecord[RELAY_RESOLVER_MISSING_REQUIRED_FIELDS_KEY]; // $FlowFixMe[incompatible-type] - casting mixed
133
+
134
+ var errors = linkedRecord[RELAY_RESOLVER_ERROR_KEY];
135
+ return [answer, linkedID, errors, missingRequiredFields];
124
136
  };
125
137
 
126
138
  _proto2.invalidateDataIDs = function invalidateDataIDs(updatedDataIDs) {