relay-runtime 18.1.0 → 19.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 (92) hide show
  1. package/experimental.js +1 -1
  2. package/experimental.js.flow +22 -9
  3. package/handlers/connection/ConnectionHandler.js.flow +6 -1
  4. package/index.js +1 -1
  5. package/index.js.flow +4 -0
  6. package/lib/experimental.js +5 -2
  7. package/lib/handlers/connection/ConnectionHandler.js +1 -1
  8. package/lib/index.js +3 -0
  9. package/lib/multi-actor-environment/ActorSpecificEnvironment.js +1 -1
  10. package/lib/mutations/RelayRecordProxy.js +14 -3
  11. package/lib/mutations/RelayRecordSourceMutator.js +17 -0
  12. package/lib/mutations/RelayRecordSourceProxy.js +2 -1
  13. package/lib/mutations/createUpdatableProxy.js +1 -1
  14. package/lib/mutations/validateMutation.js +2 -2
  15. package/lib/network/RelayObservable.js +1 -3
  16. package/lib/network/wrapNetworkWithLogObserver.js +2 -2
  17. package/lib/query/fetchQuery.js +1 -1
  18. package/lib/store/DataChecker.js +4 -5
  19. package/lib/store/OperationExecutor.js +11 -0
  20. package/lib/store/RelayModernEnvironment.js +13 -4
  21. package/lib/store/RelayModernFragmentSpecResolver.js +4 -4
  22. package/lib/store/RelayModernStore.js +43 -21
  23. package/lib/store/RelayPublishQueue.js +11 -15
  24. package/lib/store/RelayReader.js +244 -183
  25. package/lib/store/RelayReferenceMarker.js +3 -4
  26. package/lib/store/RelayResponseNormalizer.js +48 -26
  27. package/lib/store/RelayStoreSubscriptions.js +2 -2
  28. package/lib/store/RelayStoreUtils.js +8 -0
  29. package/lib/store/ResolverCache.js +1 -165
  30. package/lib/store/ResolverFragments.js +2 -2
  31. package/lib/store/createRelayLoggingContext.js +17 -0
  32. package/lib/store/generateTypenamePrefixedDataID.js +9 -0
  33. package/lib/store/live-resolvers/LiveResolverCache.js +5 -10
  34. package/lib/store/live-resolvers/resolverDataInjector.js +4 -4
  35. package/lib/store/observeFragmentExperimental.js +60 -13
  36. package/lib/store/observeQueryExperimental.js +21 -0
  37. package/lib/util/RelayFeatureFlags.js +7 -2
  38. package/lib/util/handlePotentialSnapshotErrors.js +12 -9
  39. package/multi-actor-environment/ActorSpecificEnvironment.js.flow +1 -0
  40. package/mutations/RelayRecordProxy.js.flow +30 -3
  41. package/mutations/RelayRecordSourceMutator.js.flow +27 -0
  42. package/mutations/RelayRecordSourceProxy.js.flow +4 -0
  43. package/mutations/createUpdatableProxy.js.flow +1 -1
  44. package/mutations/validateMutation.js.flow +3 -3
  45. package/network/RelayNetworkTypes.js.flow +3 -0
  46. package/network/RelayObservable.js.flow +1 -5
  47. package/network/wrapNetworkWithLogObserver.js.flow +19 -1
  48. package/package.json +1 -1
  49. package/query/fetchQuery.js.flow +1 -1
  50. package/store/DataChecker.js.flow +5 -2
  51. package/store/OperationExecutor.js.flow +12 -1
  52. package/store/RelayExperimentalGraphResponseTransform.js.flow +4 -4
  53. package/store/RelayModernEnvironment.js.flow +22 -6
  54. package/store/RelayModernFragmentSpecResolver.js.flow +6 -6
  55. package/store/RelayModernRecord.js.flow +1 -1
  56. package/store/RelayModernSelector.js.flow +2 -0
  57. package/store/RelayModernStore.js.flow +74 -27
  58. package/store/RelayOptimisticRecordSource.js.flow +2 -0
  59. package/store/RelayPublishQueue.js.flow +32 -21
  60. package/store/RelayReader.js.flow +400 -145
  61. package/store/RelayRecordState.js.flow +1 -1
  62. package/store/RelayReferenceMarker.js.flow +3 -4
  63. package/store/RelayResponseNormalizer.js.flow +94 -62
  64. package/store/RelayStoreSubscriptions.js.flow +2 -2
  65. package/store/RelayStoreTypes.js.flow +45 -15
  66. package/store/RelayStoreUtils.js.flow +30 -1
  67. package/store/ResolverCache.js.flow +2 -271
  68. package/store/ResolverFragments.js.flow +5 -3
  69. package/store/StoreInspector.js.flow +5 -0
  70. package/store/createRelayContext.js.flow +3 -2
  71. package/store/createRelayLoggingContext.js.flow +46 -0
  72. package/store/generateTypenamePrefixedDataID.js.flow +25 -0
  73. package/store/live-resolvers/LiveResolverCache.js.flow +5 -10
  74. package/store/live-resolvers/resolverDataInjector.js.flow +10 -6
  75. package/store/observeFragmentExperimental.js.flow +82 -28
  76. package/store/observeQueryExperimental.js.flow +61 -0
  77. package/store/waitForFragmentExperimental.js.flow +4 -3
  78. package/util/NormalizationNode.js.flow +10 -1
  79. package/util/ReaderNode.js.flow +9 -3
  80. package/util/RelayConcreteNode.js.flow +3 -1
  81. package/util/RelayError.js.flow +1 -0
  82. package/util/RelayFeatureFlags.js.flow +31 -7
  83. package/util/RelayRuntimeTypes.js.flow +17 -3
  84. package/util/getPaginationVariables.js.flow +2 -0
  85. package/util/handlePotentialSnapshotErrors.js.flow +24 -12
  86. package/util/registerEnvironmentWithDevTools.js.flow +4 -2
  87. package/util/withProvidedVariables.js.flow +1 -0
  88. package/util/withStartAndDuration.js.flow +3 -0
  89. package/relay-runtime-experimental.js +0 -4
  90. package/relay-runtime-experimental.min.js +0 -9
  91. package/relay-runtime.js +0 -4
  92. package/relay-runtime.min.js +0 -9
@@ -4,9 +4,9 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
5
5
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
6
6
  var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
7
- var _createForOfIteratorHelper2 = _interopRequireDefault(require("@babel/runtime/helpers/createForOfIteratorHelper"));
8
7
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
9
8
  var _excluded = ["message"];
9
+ var RelayFeatureFlags = require('../util/RelayFeatureFlags');
10
10
  var _require = require('./live-resolvers/LiveResolverSuspenseSentinel'),
11
11
  isSuspenseSentinel = _require.isSuspenseSentinel;
12
12
  var RelayConcreteVariables = require('./RelayConcreteVariables');
@@ -36,14 +36,15 @@ function read(recordSource, selector, resolverCache, resolverContext) {
36
36
  }
37
37
  var RelayReader = /*#__PURE__*/function () {
38
38
  function RelayReader(recordSource, selector, resolverCache, resolverContext) {
39
- var _selector$clientEdgeT;
39
+ var _selector$clientEdgeT, _ref, _this$_owner$node$ope, _this$_owner$node$ope2;
40
40
  this._clientEdgeTraversalPath = (_selector$clientEdgeT = selector.clientEdgeTraversalPath) !== null && _selector$clientEdgeT !== void 0 && _selector$clientEdgeT.length ? (0, _toConsumableArray2["default"])(selector.clientEdgeTraversalPath) : [];
41
41
  this._missingClientEdges = [];
42
42
  this._missingLiveResolverFields = [];
43
43
  this._isMissingData = false;
44
44
  this._isWithinUnmatchedTypeRefinement = false;
45
- this._errorResponseFields = null;
45
+ this._fieldErrors = null;
46
46
  this._owner = selector.owner;
47
+ this._useExecTimeResolvers = (_ref = (_this$_owner$node$ope = this._owner.node.operation.use_exec_time_resolvers) !== null && _this$_owner$node$ope !== void 0 ? _this$_owner$node$ope : ((_this$_owner$node$ope2 = this._owner.node.operation.exec_time_resolvers_enabled_provider) === null || _this$_owner$node$ope2 === void 0 ? void 0 : _this$_owner$node$ope2.get()) === true) !== null && _ref !== void 0 ? _ref : false;
47
48
  this._recordSource = recordSource;
48
49
  this._seenRecords = new Set();
49
50
  this._selector = selector;
@@ -55,6 +56,7 @@ var RelayReader = /*#__PURE__*/function () {
55
56
  }
56
57
  var _proto = RelayReader.prototype;
57
58
  _proto.read = function read() {
59
+ var _this$_selector$node$;
58
60
  var _this$_selector = this._selector,
59
61
  node = _this$_selector.node,
60
62
  dataID = _this$_selector.dataID,
@@ -75,6 +77,10 @@ var RelayReader = /*#__PURE__*/function () {
75
77
  }
76
78
  this._isWithinUnmatchedTypeRefinement = !isDataExpectedToBePresent;
77
79
  var data = this._traverse(node, dataID, null);
80
+ var catchTo = (_this$_selector$node$ = this._selector.node.metadata) === null || _this$_selector$node$ === void 0 ? void 0 : _this$_selector$node$.catchTo;
81
+ if (catchTo != null) {
82
+ data = this._catchErrors(data, catchTo, null);
83
+ }
78
84
  if (this._updatedDataIDs.size > 0) {
79
85
  this._resolverCache.notifyUpdatedSubscribers(this._updatedDataIDs);
80
86
  this._updatedDataIDs.clear();
@@ -86,58 +92,52 @@ var RelayReader = /*#__PURE__*/function () {
86
92
  missingLiveResolverFields: this._missingLiveResolverFields,
87
93
  seenRecords: this._seenRecords,
88
94
  selector: this._selector,
89
- errorResponseFields: this._errorResponseFields
95
+ fieldErrors: this._fieldErrors
90
96
  };
91
97
  };
92
- _proto._maybeAddErrorResponseFields = function _maybeAddErrorResponseFields(record, storageKey) {
98
+ _proto._maybeAddFieldErrors = function _maybeAddFieldErrors(record, storageKey) {
93
99
  var errors = RelayModernRecord.getErrors(record, storageKey);
94
100
  if (errors == null) {
95
101
  return;
96
102
  }
97
103
  var owner = this._fragmentName;
98
- if (this._errorResponseFields == null) {
99
- this._errorResponseFields = [];
100
- }
101
- var _iterator = (0, _createForOfIteratorHelper2["default"])(errors),
102
- _step;
103
- try {
104
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
105
- var _error$path, _this$_selector$node$, _this$_selector$node$2;
106
- var error = _step.value;
107
- this._errorResponseFields.push({
108
- kind: 'relay_field_payload.error',
109
- owner: owner,
110
- fieldPath: ((_error$path = error.path) !== null && _error$path !== void 0 ? _error$path : []).join('.'),
111
- error: error,
112
- shouldThrow: (_this$_selector$node$ = (_this$_selector$node$2 = this._selector.node.metadata) === null || _this$_selector$node$2 === void 0 ? void 0 : _this$_selector$node$2.throwOnFieldError) !== null && _this$_selector$node$ !== void 0 ? _this$_selector$node$ : false,
113
- handled: false
114
- });
115
- }
116
- } catch (err) {
117
- _iterator.e(err);
118
- } finally {
119
- _iterator.f();
104
+ if (this._fieldErrors == null) {
105
+ this._fieldErrors = [];
106
+ }
107
+ for (var i = 0; i < errors.length; i++) {
108
+ var _error$path, _this$_selector$node$2, _this$_selector$node$3;
109
+ var error = errors[i];
110
+ this._fieldErrors.push({
111
+ kind: 'relay_field_payload.error',
112
+ owner: owner,
113
+ fieldPath: ((_error$path = error.path) !== null && _error$path !== void 0 ? _error$path : []).join('.'),
114
+ error: error,
115
+ shouldThrow: (_this$_selector$node$2 = (_this$_selector$node$3 = this._selector.node.metadata) === null || _this$_selector$node$3 === void 0 ? void 0 : _this$_selector$node$3.throwOnFieldError) !== null && _this$_selector$node$2 !== void 0 ? _this$_selector$node$2 : false,
116
+ handled: false,
117
+ uiContext: undefined
118
+ });
120
119
  }
121
120
  };
122
- _proto._markDataAsMissing = function _markDataAsMissing() {
123
- var _this$_selector$node$3, _this$_selector$node$4;
121
+ _proto._markDataAsMissing = function _markDataAsMissing(fieldName) {
122
+ var _this$_selector$node$4, _this$_selector$node$5;
124
123
  if (this._isWithinUnmatchedTypeRefinement) {
125
124
  return;
126
125
  }
127
- if (this._errorResponseFields == null) {
128
- this._errorResponseFields = [];
126
+ if (this._fieldErrors == null) {
127
+ this._fieldErrors = [];
129
128
  }
130
- var fieldPath = '';
131
129
  var owner = this._fragmentName;
132
- this._errorResponseFields.push(((_this$_selector$node$3 = (_this$_selector$node$4 = this._selector.node.metadata) === null || _this$_selector$node$4 === void 0 ? void 0 : _this$_selector$node$4.throwOnFieldError) !== null && _this$_selector$node$3 !== void 0 ? _this$_selector$node$3 : false) ? {
130
+ this._fieldErrors.push(((_this$_selector$node$4 = (_this$_selector$node$5 = this._selector.node.metadata) === null || _this$_selector$node$5 === void 0 ? void 0 : _this$_selector$node$5.throwOnFieldError) !== null && _this$_selector$node$4 !== void 0 ? _this$_selector$node$4 : false) ? {
133
131
  kind: 'missing_expected_data.throw',
134
132
  owner: owner,
135
- fieldPath: fieldPath,
136
- handled: false
133
+ fieldPath: fieldName,
134
+ handled: false,
135
+ uiContext: undefined
137
136
  } : {
138
137
  kind: 'missing_expected_data.log',
139
138
  owner: owner,
140
- fieldPath: fieldPath
139
+ fieldPath: fieldName,
140
+ uiContext: undefined
141
141
  });
142
142
  this._isMissingData = true;
143
143
  if (this._clientEdgeTraversalPath.length) {
@@ -155,7 +155,7 @@ var RelayReader = /*#__PURE__*/function () {
155
155
  this._seenRecords.add(dataID);
156
156
  if (record == null) {
157
157
  if (record === undefined) {
158
- this._markDataAsMissing();
158
+ this._markDataAsMissing('<record>');
159
159
  }
160
160
  return record;
161
161
  }
@@ -167,37 +167,85 @@ var RelayReader = /*#__PURE__*/function () {
167
167
  !this._variables.hasOwnProperty(name) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayReader(): Undefined variable `%s`.', name) : invariant(false) : void 0;
168
168
  return this._variables[name];
169
169
  };
170
- _proto._maybeReportUnexpectedNull = function _maybeReportUnexpectedNull(fieldPath, action) {
170
+ _proto._maybeReportUnexpectedNull = function _maybeReportUnexpectedNull(selection) {
171
+ if (selection.action === 'NONE') {
172
+ return;
173
+ }
171
174
  var owner = this._fragmentName;
172
- if (this._errorResponseFields == null) {
173
- this._errorResponseFields = [];
175
+ if (this._fieldErrors == null) {
176
+ this._fieldErrors = [];
174
177
  }
175
- switch (action) {
178
+ var fieldName;
179
+ if (selection.field.linkedField != null) {
180
+ var _selection$field$link;
181
+ fieldName = (_selection$field$link = selection.field.linkedField.alias) !== null && _selection$field$link !== void 0 ? _selection$field$link : selection.field.linkedField.name;
182
+ } else {
183
+ var _selection$field$alia;
184
+ fieldName = (_selection$field$alia = selection.field.alias) !== null && _selection$field$alia !== void 0 ? _selection$field$alia : selection.field.name;
185
+ }
186
+ switch (selection.action) {
176
187
  case 'THROW':
177
- this._errorResponseFields.push({
188
+ this._fieldErrors.push({
178
189
  kind: 'missing_required_field.throw',
179
- fieldPath: fieldPath,
190
+ fieldPath: fieldName,
180
191
  owner: owner,
181
- handled: false
192
+ handled: false,
193
+ uiContext: undefined
182
194
  });
183
195
  return;
184
196
  case 'LOG':
185
- this._errorResponseFields.push({
197
+ this._fieldErrors.push({
186
198
  kind: 'missing_required_field.log',
187
- fieldPath: fieldPath,
188
- owner: owner
199
+ fieldPath: fieldName,
200
+ owner: owner,
201
+ uiContext: undefined
189
202
  });
190
203
  return;
191
204
  default:
192
- action;
205
+ selection.action;
193
206
  }
194
207
  };
195
- _proto._handleCatchToResult = function _handleCatchToResult(selection, record, data, value) {
196
- var _selection$field$back, _selection$field, _field$alias, _this$_errorResponseF;
197
- var field = (_selection$field$back = (_selection$field = selection.field) === null || _selection$field === void 0 ? void 0 : _selection$field.backingField) !== null && _selection$field$back !== void 0 ? _selection$field$back : selection.field;
198
- var fieldName = (_field$alias = field === null || field === void 0 ? void 0 : field.alias) !== null && _field$alias !== void 0 ? _field$alias : field === null || field === void 0 ? void 0 : field.name;
199
- !(fieldName != null) ? process.env.NODE_ENV !== "production" ? invariant(false, "Couldn't determine field name for this field. It might be a ReaderClientExtension - which is not yet supported.") : invariant(false) : void 0;
200
- var errors = (_this$_errorResponseF = this._errorResponseFields) === null || _this$_errorResponseF === void 0 ? void 0 : _this$_errorResponseF.map(function (error) {
208
+ _proto._handleRequiredFieldValue = function _handleRequiredFieldValue(selection, value) {
209
+ if (value == null) {
210
+ this._maybeReportUnexpectedNull(selection);
211
+ return false;
212
+ }
213
+ return true;
214
+ };
215
+ _proto._catchErrors = function _catchErrors(_value, to, previousResponseFields) {
216
+ var value = _value;
217
+ switch (to) {
218
+ case 'RESULT':
219
+ value = this._asResult(_value);
220
+ break;
221
+ case 'NULL':
222
+ if (this._fieldErrors != null && this._fieldErrors.length > 0) {
223
+ value = null;
224
+ }
225
+ break;
226
+ default:
227
+ to;
228
+ }
229
+ var childrenFieldErrors = this._fieldErrors;
230
+ this._fieldErrors = previousResponseFields;
231
+ if (childrenFieldErrors != null) {
232
+ if (this._fieldErrors == null) {
233
+ this._fieldErrors = [];
234
+ }
235
+ for (var i = 0; i < childrenFieldErrors.length; i++) {
236
+ this._fieldErrors.push(markFieldErrorHasHandled(childrenFieldErrors[i]));
237
+ }
238
+ }
239
+ return value;
240
+ };
241
+ _proto._asResult = function _asResult(value) {
242
+ if (this._fieldErrors == null || this._fieldErrors.length === 0) {
243
+ return {
244
+ ok: true,
245
+ value: value
246
+ };
247
+ }
248
+ var errors = this._fieldErrors.map(function (error) {
201
249
  switch (error.kind) {
202
250
  case 'relay_field_payload.error':
203
251
  var _error$error = error.error,
@@ -221,27 +269,14 @@ var RelayReader = /*#__PURE__*/function () {
221
269
  return null;
222
270
  default:
223
271
  error.kind;
224
- !false ? process.env.NODE_ENV !== "production" ? invariant(false, 'Unexpected error errorResponseField kind: %s', error.kind) : invariant(false) : void 0;
272
+ !false ? process.env.NODE_ENV !== "production" ? invariant(false, 'Unexpected error fieldError kind: %s', error.kind) : invariant(false) : void 0;
225
273
  }
226
274
  }).filter(Boolean);
227
- data[fieldName] = errors != null ? {
275
+ return {
228
276
  ok: false,
229
277
  errors: errors
230
- } : {
231
- ok: true,
232
- value: value
233
278
  };
234
279
  };
235
- _proto._handleRequiredFieldValue = function _handleRequiredFieldValue(selection, value) {
236
- if (value == null) {
237
- var action = selection.action;
238
- if (action !== 'NONE') {
239
- this._maybeReportUnexpectedNull(selection.path, action);
240
- }
241
- return false;
242
- }
243
- return true;
244
- };
245
280
  _proto._traverseSelections = function _traverseSelections(selections, record, data) {
246
281
  for (var i = 0; i < selections.length; i++) {
247
282
  var selection = selections[i];
@@ -254,22 +289,14 @@ var RelayReader = /*#__PURE__*/function () {
254
289
  break;
255
290
  case 'CatchField':
256
291
  {
257
- var previousResponseFields = this._errorResponseFields;
258
- this._errorResponseFields = null;
292
+ var _selection$field$back, _selection$field, _field$alias;
293
+ var previousResponseFields = this._fieldErrors;
294
+ this._fieldErrors = null;
259
295
  var catchFieldValue = this._readClientSideDirectiveField(selection, record, data);
260
- if (selection.to === 'RESULT') {
261
- this._handleCatchToResult(selection, record, data, catchFieldValue);
262
- }
263
- var childrenErrorResponseFields = this._errorResponseFields;
264
- this._errorResponseFields = previousResponseFields;
265
- if (childrenErrorResponseFields != null) {
266
- if (this._errorResponseFields == null) {
267
- this._errorResponseFields = [];
268
- }
269
- for (var _i = 0; _i < childrenErrorResponseFields.length; _i++) {
270
- this._errorResponseFields.push(markFieldErrorHasHandled(childrenErrorResponseFields[_i]));
271
- }
272
- }
296
+ var field = (_selection$field$back = (_selection$field = selection.field) === null || _selection$field === void 0 ? void 0 : _selection$field.backingField) !== null && _selection$field$back !== void 0 ? _selection$field$back : selection.field;
297
+ var fieldName = (_field$alias = field === null || field === void 0 ? void 0 : field.alias) !== null && _field$alias !== void 0 ? _field$alias : field === null || field === void 0 ? void 0 : field.name;
298
+ !(fieldName != null) ? process.env.NODE_ENV !== "production" ? invariant(false, "Couldn't determine field name for this field. It might be a ReaderClientExtension - which is not yet supported.") : invariant(false) : void 0;
299
+ data[fieldName] = this._catchErrors(catchFieldValue, selection.to, previousResponseFields);
273
300
  break;
274
301
  }
275
302
  case 'ScalarField':
@@ -302,7 +329,11 @@ var RelayReader = /*#__PURE__*/function () {
302
329
  case 'RelayLiveResolver':
303
330
  case 'RelayResolver':
304
331
  {
305
- this._readResolverField(selection, record, data);
332
+ if (this._useExecTimeResolvers) {
333
+ this._readScalar(selection, record, data);
334
+ } else {
335
+ this._readResolverField(selection, record, data);
336
+ }
306
337
  break;
307
338
  }
308
339
  case 'FragmentSpread':
@@ -310,11 +341,7 @@ var RelayReader = /*#__PURE__*/function () {
310
341
  break;
311
342
  case 'AliasedInlineFragmentSpread':
312
343
  {
313
- var fieldValue = this._readInlineFragment(selection.fragment, record, {}, true);
314
- if (fieldValue === false) {
315
- fieldValue = null;
316
- }
317
- data[selection.name] = fieldValue;
344
+ this._readAliasedInlineFragment(selection, record, data);
318
345
  break;
319
346
  }
320
347
  case 'ModuleImport':
@@ -350,7 +377,16 @@ var RelayReader = /*#__PURE__*/function () {
350
377
  break;
351
378
  case 'ClientEdgeToClientObject':
352
379
  case 'ClientEdgeToServerObject':
353
- this._readClientEdge(selection, record, data);
380
+ if (this._useExecTimeResolvers && (selection.backingField.kind === 'RelayResolver' || selection.backingField.kind === 'RelayLiveResolver')) {
381
+ var linkedField = selection.linkedField;
382
+ if (linkedField.plural) {
383
+ this._readPluralLink(linkedField, record, data);
384
+ } else {
385
+ this._readLink(linkedField, record, data);
386
+ }
387
+ } else {
388
+ this._readClientEdge(selection, record, data);
389
+ }
354
390
  break;
355
391
  default:
356
392
  selection;
@@ -370,22 +406,41 @@ var RelayReader = /*#__PURE__*/function () {
370
406
  return this._readLink(selection.field, record, data);
371
407
  }
372
408
  case 'RelayResolver':
373
- return this._readResolverField(selection.field, record, data);
374
409
  case 'RelayLiveResolver':
375
- return this._readResolverField(selection.field, record, data);
410
+ {
411
+ if (this._useExecTimeResolvers) {
412
+ return this._readScalar(selection.field, record, data);
413
+ } else {
414
+ return this._readResolverField(selection.field, record, data);
415
+ }
416
+ }
376
417
  case 'ClientEdgeToClientObject':
377
418
  case 'ClientEdgeToServerObject':
378
- return this._readClientEdge(selection.field, record, data);
419
+ if (this._useExecTimeResolvers && (selection.field.backingField.kind === 'RelayResolver' || selection.field.backingField.kind === 'RelayLiveResolver')) {
420
+ var field = selection.field;
421
+ if (field.linkedField.plural) {
422
+ return this._readPluralLink(field.linkedField, record, data);
423
+ } else {
424
+ return this._readLink(field.linkedField, record, data);
425
+ }
426
+ } else {
427
+ return this._readClientEdge(selection.field, record, data);
428
+ }
429
+ case 'AliasedInlineFragmentSpread':
430
+ return this._readAliasedInlineFragment(selection.field, record, data);
379
431
  default:
380
432
  selection.field.kind;
381
- !false ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayReader(): Unexpected ast kind `%s`.', selection.kind) : invariant(false) : void 0;
433
+ !false ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayReader(): Unexpected ast kind `%s`.', selection.field.kind) : invariant(false) : void 0;
382
434
  }
383
435
  };
384
436
  _proto._readResolverField = function _readResolverField(field, record, data) {
385
437
  var _field$alias2;
386
438
  var parentRecordID = RelayModernRecord.getDataID(record);
439
+ var prevErrors = this._fieldErrors;
440
+ this._fieldErrors = null;
387
441
  var result = this._readResolverFieldImpl(field, parentRecordID);
388
442
  var fieldName = (_field$alias2 = field.alias) !== null && _field$alias2 !== void 0 ? _field$alias2 : field.name;
443
+ this._prependPreviousErrors(prevErrors, fieldName);
389
444
  data[fieldName] = result;
390
445
  return result;
391
446
  };
@@ -398,14 +453,14 @@ var RelayReader = /*#__PURE__*/function () {
398
453
  return {
399
454
  data: snapshot.data,
400
455
  isMissingData: snapshot.isMissingData,
401
- errorResponseFields: snapshot.errorResponseFields
456
+ fieldErrors: snapshot.fieldErrors
402
457
  };
403
458
  }
404
459
  snapshot = read(_this._recordSource, singularReaderSelector, _this._resolverCache);
405
460
  return {
406
461
  data: snapshot.data,
407
462
  isMissingData: snapshot.isMissingData,
408
- errorResponseFields: snapshot.errorResponseFields
463
+ fieldErrors: snapshot.fieldErrors
409
464
  };
410
465
  };
411
466
  var evaluate = function evaluate() {
@@ -450,74 +505,52 @@ var RelayReader = /*#__PURE__*/function () {
450
505
  return result;
451
506
  };
452
507
  _proto._propagateResolverMetadata = function _propagateResolverMetadata(fieldPath, cachedSnapshot, resolverError, seenRecord, suspenseID, updatedDataIDs) {
508
+ var _this2 = this;
453
509
  if (cachedSnapshot != null) {
454
510
  if (cachedSnapshot.missingClientEdges != null) {
455
- var _iterator2 = (0, _createForOfIteratorHelper2["default"])(cachedSnapshot.missingClientEdges),
456
- _step2;
457
- try {
458
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
459
- var missing = _step2.value;
460
- this._missingClientEdges.push(missing);
461
- }
462
- } catch (err) {
463
- _iterator2.e(err);
464
- } finally {
465
- _iterator2.f();
511
+ for (var i = 0; i < cachedSnapshot.missingClientEdges.length; i++) {
512
+ var missing = cachedSnapshot.missingClientEdges[i];
513
+ this._missingClientEdges.push(missing);
466
514
  }
467
515
  }
468
516
  if (cachedSnapshot.missingLiveResolverFields != null) {
469
517
  this._isMissingData = this._isMissingData || cachedSnapshot.missingLiveResolverFields.length > 0;
470
- var _iterator3 = (0, _createForOfIteratorHelper2["default"])(cachedSnapshot.missingLiveResolverFields),
471
- _step3;
472
- try {
473
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
474
- var missingResolverField = _step3.value;
475
- this._missingLiveResolverFields.push(missingResolverField);
476
- }
477
- } catch (err) {
478
- _iterator3.e(err);
479
- } finally {
480
- _iterator3.f();
518
+ for (var _i = 0; _i < cachedSnapshot.missingLiveResolverFields.length; _i++) {
519
+ var missingResolverField = cachedSnapshot.missingLiveResolverFields[_i];
520
+ this._missingLiveResolverFields.push(missingResolverField);
481
521
  }
482
522
  }
483
- if (cachedSnapshot.errorResponseFields != null) {
484
- if (this._errorResponseFields == null) {
485
- this._errorResponseFields = [];
523
+ if (cachedSnapshot.fieldErrors != null) {
524
+ if (this._fieldErrors == null) {
525
+ this._fieldErrors = [];
486
526
  }
487
- var _iterator4 = (0, _createForOfIteratorHelper2["default"])(cachedSnapshot.errorResponseFields),
488
- _step4;
489
- try {
490
- for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
491
- var _this$_selector$node$5;
492
- var error = _step4.value;
493
- if (((_this$_selector$node$5 = this._selector.node.metadata) === null || _this$_selector$node$5 === void 0 ? void 0 : _this$_selector$node$5.throwOnFieldError) === true) {
494
- this._errorResponseFields.push(error);
495
- } else {
496
- this._errorResponseFields.push(markFieldErrorHasHandled(error));
497
- }
527
+ for (var _i2 = 0; _i2 < cachedSnapshot.fieldErrors.length; _i2++) {
528
+ var _this$_selector$node$6;
529
+ var error = cachedSnapshot.fieldErrors[_i2];
530
+ if (((_this$_selector$node$6 = this._selector.node.metadata) === null || _this$_selector$node$6 === void 0 ? void 0 : _this$_selector$node$6.throwOnFieldError) === true) {
531
+ this._fieldErrors.push(error);
532
+ } else {
533
+ this._fieldErrors.push(markFieldErrorHasHandled(error));
498
534
  }
499
- } catch (err) {
500
- _iterator4.e(err);
501
- } finally {
502
- _iterator4.f();
503
535
  }
504
536
  }
505
537
  this._isMissingData = this._isMissingData || cachedSnapshot.isMissingData;
506
538
  }
507
539
  if (resolverError) {
508
- var _this$_selector$node$6, _this$_selector$node$7;
540
+ var _this$_selector$node$7, _this$_selector$node$8;
509
541
  var errorEvent = {
510
542
  kind: 'relay_resolver.error',
511
543
  fieldPath: fieldPath,
512
544
  owner: this._fragmentName,
513
545
  error: resolverError,
514
- shouldThrow: (_this$_selector$node$6 = (_this$_selector$node$7 = this._selector.node.metadata) === null || _this$_selector$node$7 === void 0 ? void 0 : _this$_selector$node$7.throwOnFieldError) !== null && _this$_selector$node$6 !== void 0 ? _this$_selector$node$6 : false,
515
- handled: false
546
+ shouldThrow: (_this$_selector$node$7 = (_this$_selector$node$8 = this._selector.node.metadata) === null || _this$_selector$node$8 === void 0 ? void 0 : _this$_selector$node$8.throwOnFieldError) !== null && _this$_selector$node$7 !== void 0 ? _this$_selector$node$7 : false,
547
+ handled: false,
548
+ uiContext: undefined
516
549
  };
517
- if (this._errorResponseFields == null) {
518
- this._errorResponseFields = [errorEvent];
550
+ if (this._fieldErrors == null) {
551
+ this._fieldErrors = [errorEvent];
519
552
  } else {
520
- this._errorResponseFields.push(errorEvent);
553
+ this._fieldErrors.push(errorEvent);
521
554
  }
522
555
  }
523
556
  if (seenRecord != null) {
@@ -525,28 +558,16 @@ var RelayReader = /*#__PURE__*/function () {
525
558
  }
526
559
  if (suspenseID != null) {
527
560
  this._isMissingData = true;
528
- this._missingLiveResolverFields.push({
529
- path: "".concat(this._fragmentName, ".").concat(fieldPath),
530
- liveStateID: suspenseID
531
- });
561
+ this._missingLiveResolverFields.push(suspenseID);
532
562
  }
533
563
  if (updatedDataIDs != null) {
534
- var _iterator5 = (0, _createForOfIteratorHelper2["default"])(updatedDataIDs),
535
- _step5;
536
- try {
537
- for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
538
- var recordID = _step5.value;
539
- this._updatedDataIDs.add(recordID);
540
- }
541
- } catch (err) {
542
- _iterator5.e(err);
543
- } finally {
544
- _iterator5.f();
545
- }
564
+ updatedDataIDs.forEach(function (recordID) {
565
+ _this2._updatedDataIDs.add(recordID);
566
+ });
546
567
  }
547
568
  };
548
569
  _proto._readClientEdge = function _readClientEdge(field, record, data) {
549
- var _this2 = this;
570
+ var _this3 = this;
550
571
  var _backingField$alias;
551
572
  var backingField = field.backingField;
552
573
  !(backingField.kind !== 'ClientExtension') ? process.env.NODE_ENV !== "production" ? invariant(false, 'Client extension client edges are not yet implemented.') : invariant(false) : void 0;
@@ -566,21 +587,21 @@ var RelayReader = /*#__PURE__*/function () {
566
587
  storeIDs = clientEdgeResolverResponse.map(function (itemResponse) {
567
588
  var _field$concreteType;
568
589
  var concreteType = (_field$concreteType = field.concreteType) !== null && _field$concreteType !== void 0 ? _field$concreteType : itemResponse.__typename;
569
- !(typeof concreteType === 'string') ? process.env.NODE_ENV !== "production" ? invariant(false, 'Expected resolver for field at `%s` in `%s` modeling an edge to an abstract type to return an object with a `__typename` property.', backingField.path, _this2._owner.identifier) : invariant(false) : void 0;
570
- var localId = extractIdFromResponse(itemResponse, backingField.path, _this2._owner.identifier);
571
- var id = _this2._resolverCache.ensureClientRecord(localId, concreteType);
590
+ !(typeof concreteType === 'string') ? process.env.NODE_ENV !== "production" ? invariant(false, 'Expected resolver for field at `%s` in `%s` modeling an edge to an abstract type to return an object with a `__typename` property.', backingField.path, _this3._owner.identifier) : invariant(false) : void 0;
591
+ var localId = extractIdFromResponse(itemResponse, backingField.path, _this3._owner.identifier);
592
+ var id = _this3._resolverCache.ensureClientRecord(localId, concreteType);
572
593
  var modelResolvers = field.modelResolvers;
573
594
  if (modelResolvers != null) {
574
595
  var modelResolver = modelResolvers[concreteType];
575
- !(modelResolver !== undefined) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Invalid `__typename` returned by resolver at `%s` in `%s`. Expected one of %s but got `%s`.', backingField.path, _this2._owner.identifier, Object.keys(modelResolvers).join(', '), concreteType) : invariant(false) : void 0;
576
- var model = _this2._readResolverFieldImpl(modelResolver, id);
596
+ !(modelResolver !== undefined) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Invalid `__typename` returned by resolver at `%s` in `%s`. Expected one of %s but got `%s`.', backingField.path, _this3._owner.identifier, Object.keys(modelResolvers).join(', '), concreteType) : invariant(false) : void 0;
597
+ var model = _this3._readResolverFieldImpl(modelResolver, id);
577
598
  return model != null ? id : null;
578
599
  }
579
600
  return id;
580
601
  });
581
602
  } else {
582
603
  storeIDs = clientEdgeResolverResponse.map(function (obj) {
583
- return extractIdFromResponse(obj, backingField.path, _this2._owner.identifier);
604
+ return extractIdFromResponse(obj, backingField.path, _this3._owner.identifier);
584
605
  });
585
606
  }
586
607
  this._clientEdgeTraversalPath.push(null);
@@ -624,7 +645,10 @@ var RelayReader = /*#__PURE__*/function () {
624
645
  this._clientEdgeTraversalPath.push(traversalPathSegment);
625
646
  var prevData = data[fieldName];
626
647
  !(prevData == null || typeof prevData === 'object') ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayReader(): Expected data for field at `%s` in `%s` on record `%s` ' + 'to be an object, got `%s`.', backingField.path, this._owner.identifier, RelayModernRecord.getDataID(record), prevData) : invariant(false) : void 0;
648
+ var prevErrors = this._fieldErrors;
649
+ this._fieldErrors = null;
627
650
  var edgeValue = this._traverse(field.linkedField, storeID, prevData);
651
+ this._prependPreviousErrors(prevErrors, fieldName);
628
652
  this._clientEdgeTraversalPath.pop();
629
653
  data[fieldName] = edgeValue;
630
654
  return edgeValue;
@@ -635,10 +659,10 @@ var RelayReader = /*#__PURE__*/function () {
635
659
  var fieldName = (_field$alias3 = field.alias) !== null && _field$alias3 !== void 0 ? _field$alias3 : field.name;
636
660
  var storageKey = getStorageKey(field, this._variables);
637
661
  var value = RelayModernRecord.getValue(record, storageKey);
638
- if (value === null) {
639
- this._maybeAddErrorResponseFields(record, storageKey);
662
+ if (value === null || RelayFeatureFlags.ENABLE_NONCOMPLIANT_ERROR_HANDLING_ON_LISTS && Array.isArray(value) && value.length === 0) {
663
+ this._maybeAddFieldErrors(record, storageKey);
640
664
  } else if (value === undefined) {
641
- this._markDataAsMissing();
665
+ this._markDataAsMissing(fieldName);
642
666
  }
643
667
  data[fieldName] = value;
644
668
  return value;
@@ -651,18 +675,39 @@ var RelayReader = /*#__PURE__*/function () {
651
675
  if (linkedID == null) {
652
676
  data[fieldName] = linkedID;
653
677
  if (linkedID === null) {
654
- this._maybeAddErrorResponseFields(record, storageKey);
678
+ this._maybeAddFieldErrors(record, storageKey);
655
679
  } else if (linkedID === undefined) {
656
- this._markDataAsMissing();
680
+ this._markDataAsMissing(fieldName);
657
681
  }
658
682
  return linkedID;
659
683
  }
660
684
  var prevData = data[fieldName];
661
685
  !(prevData == null || typeof prevData === 'object') ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayReader(): Expected data for field `%s` at `%s` on record `%s` ' + 'to be an object, got `%s`.', fieldName, this._owner.identifier, RelayModernRecord.getDataID(record), prevData) : invariant(false) : void 0;
686
+ var prevErrors = this._fieldErrors;
687
+ this._fieldErrors = null;
662
688
  var value = this._traverse(field, linkedID, prevData);
689
+ this._prependPreviousErrors(prevErrors, fieldName);
663
690
  data[fieldName] = value;
664
691
  return value;
665
692
  };
693
+ _proto._prependPreviousErrors = function _prependPreviousErrors(prevErrors, fieldNameOrIndex) {
694
+ if (this._fieldErrors != null) {
695
+ for (var i = 0; i < this._fieldErrors.length; i++) {
696
+ var event = this._fieldErrors[i];
697
+ if (event.owner === this._fragmentName && (event.kind === 'missing_expected_data.throw' || event.kind === 'missing_expected_data.log' || event.kind === 'missing_required_field.throw' || event.kind === 'missing_required_field.log')) {
698
+ event.fieldPath = "".concat(fieldNameOrIndex, ".").concat(event.fieldPath);
699
+ }
700
+ }
701
+ if (prevErrors != null) {
702
+ for (var _i3 = this._fieldErrors.length - 1; _i3 >= 0; _i3--) {
703
+ prevErrors.push(this._fieldErrors[_i3]);
704
+ }
705
+ this._fieldErrors = prevErrors;
706
+ }
707
+ } else {
708
+ this._fieldErrors = prevErrors;
709
+ }
710
+ };
666
711
  _proto._readActorChange = function _readActorChange(field, record, data) {
667
712
  var _field$alias5;
668
713
  var fieldName = (_field$alias5 = field.alias) !== null && _field$alias5 !== void 0 ? _field$alias5 : field.name;
@@ -671,9 +716,9 @@ var RelayReader = /*#__PURE__*/function () {
671
716
  if (externalRef == null) {
672
717
  data[fieldName] = externalRef;
673
718
  if (externalRef === undefined) {
674
- this._markDataAsMissing();
719
+ this._markDataAsMissing(fieldName);
675
720
  } else if (externalRef === null) {
676
- this._maybeAddErrorResponseFields(record, storageKey);
721
+ this._maybeAddFieldErrors(record, storageKey);
677
722
  }
678
723
  return data[fieldName];
679
724
  }
@@ -692,47 +737,53 @@ var RelayReader = /*#__PURE__*/function () {
692
737
  _proto._readPluralLink = function _readPluralLink(field, record, data) {
693
738
  var storageKey = getStorageKey(field, this._variables);
694
739
  var linkedIDs = RelayModernRecord.getLinkedRecordIDs(record, storageKey);
695
- if (linkedIDs === null) {
696
- this._maybeAddErrorResponseFields(record, storageKey);
740
+ if (linkedIDs === null || RelayFeatureFlags.ENABLE_NONCOMPLIANT_ERROR_HANDLING_ON_LISTS && Array.isArray(linkedIDs) && linkedIDs.length === 0) {
741
+ this._maybeAddFieldErrors(record, storageKey);
697
742
  }
698
743
  return this._readLinkedIds(field, linkedIDs, record, data);
699
744
  };
700
745
  _proto._readLinkedIds = function _readLinkedIds(field, linkedIDs, record, data) {
701
- var _this3 = this;
746
+ var _this4 = this;
702
747
  var _field$alias6;
703
748
  var fieldName = (_field$alias6 = field.alias) !== null && _field$alias6 !== void 0 ? _field$alias6 : field.name;
704
749
  if (linkedIDs == null) {
705
750
  data[fieldName] = linkedIDs;
706
751
  if (linkedIDs === undefined) {
707
- this._markDataAsMissing();
752
+ this._markDataAsMissing(fieldName);
708
753
  }
709
754
  return linkedIDs;
710
755
  }
711
756
  var prevData = data[fieldName];
712
757
  !(prevData == null || Array.isArray(prevData)) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayReader(): Expected data for field `%s` on record `%s` ' + 'to be an array, got `%s`.', fieldName, RelayModernRecord.getDataID(record), prevData) : invariant(false) : void 0;
758
+ var prevErrors = this._fieldErrors;
759
+ this._fieldErrors = null;
713
760
  var linkedArray = prevData || [];
714
761
  linkedIDs.forEach(function (linkedID, nextIndex) {
715
762
  if (linkedID == null) {
716
763
  if (linkedID === undefined) {
717
- _this3._markDataAsMissing();
764
+ _this4._markDataAsMissing(String(nextIndex));
718
765
  }
719
766
  linkedArray[nextIndex] = linkedID;
720
767
  return;
721
768
  }
722
769
  var prevItem = linkedArray[nextIndex];
723
770
  !(prevItem == null || typeof prevItem === 'object') ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayReader(): Expected data for field `%s` on record `%s` ' + 'to be an object, got `%s`.', fieldName, RelayModernRecord.getDataID(record), prevItem) : invariant(false) : void 0;
724
- linkedArray[nextIndex] = _this3._traverse(field, linkedID, prevItem);
771
+ var prevErrors = _this4._fieldErrors;
772
+ _this4._fieldErrors = null;
773
+ linkedArray[nextIndex] = _this4._traverse(field, linkedID, prevItem);
774
+ _this4._prependPreviousErrors(prevErrors, nextIndex);
725
775
  });
776
+ this._prependPreviousErrors(prevErrors, fieldName);
726
777
  data[fieldName] = linkedArray;
727
778
  return linkedArray;
728
779
  };
729
780
  _proto._readModuleImport = function _readModuleImport(moduleImport, record, data) {
730
- var _moduleImport$compone;
731
781
  var componentKey = getModuleComponentKey(moduleImport.documentName);
732
- var component = (_moduleImport$compone = moduleImport.componentModuleProvider) !== null && _moduleImport$compone !== void 0 ? _moduleImport$compone : RelayModernRecord.getValue(record, componentKey);
782
+ var relayStoreComponent = RelayModernRecord.getValue(record, componentKey);
783
+ var component = relayStoreComponent !== undefined ? relayStoreComponent : moduleImport.componentModuleProvider;
733
784
  if (component == null) {
734
785
  if (component === undefined) {
735
- this._markDataAsMissing();
786
+ this._markDataAsMissing('<module-import>');
736
787
  }
737
788
  return;
738
789
  }
@@ -744,6 +795,16 @@ var RelayReader = /*#__PURE__*/function () {
744
795
  data[FRAGMENT_PROP_NAME_KEY] = moduleImport.fragmentPropName;
745
796
  data[MODULE_COMPONENT_KEY] = component;
746
797
  };
798
+ _proto._readAliasedInlineFragment = function _readAliasedInlineFragment(aliasedInlineFragment, record, data) {
799
+ var prevErrors = this._fieldErrors;
800
+ this._fieldErrors = null;
801
+ var fieldValue = this._readInlineFragment(aliasedInlineFragment.fragment, record, {}, true);
802
+ this._prependPreviousErrors(prevErrors, aliasedInlineFragment.name);
803
+ if (fieldValue === false) {
804
+ fieldValue = null;
805
+ }
806
+ data[aliasedInlineFragment.name] = fieldValue;
807
+ };
747
808
  _proto._readInlineFragment = function _readInlineFragment(inlineFragment, record, data, skipUnmatchedAbstractTypes) {
748
809
  if (inlineFragment.type == null) {
749
810
  var hasExpectedData = this._traverseSelections(inlineFragment.selections, record, data);
@@ -827,7 +888,7 @@ var RelayReader = /*#__PURE__*/function () {
827
888
  var typeRecord = this._recordSource.get(generateTypeID(typeName));
828
889
  var implementsInterface = typeRecord != null ? RelayModernRecord.getValue(typeRecord, abstractKey) : null;
829
890
  if (implementsInterface == null) {
830
- this._markDataAsMissing();
891
+ this._markDataAsMissing('<abstract-type-hint>');
831
892
  }
832
893
  return implementsInterface;
833
894
  };