relay-runtime 11.0.2 → 12.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 (100) hide show
  1. package/index.js +1 -1
  2. package/index.js.flow +16 -1
  3. package/lib/index.js +15 -0
  4. package/lib/multi-actor-environment/ActorIdentifier.js +11 -1
  5. package/lib/multi-actor-environment/ActorSpecificEnvironment.js +59 -19
  6. package/lib/multi-actor-environment/ActorUtils.js +27 -0
  7. package/lib/multi-actor-environment/MultiActorEnvironment.js +305 -55
  8. package/lib/multi-actor-environment/index.js +5 -1
  9. package/lib/mutations/RelayRecordSourceSelectorProxy.js +6 -1
  10. package/lib/mutations/commitMutation.js +4 -1
  11. package/lib/mutations/validateMutation.js +6 -1
  12. package/lib/network/RelayObservable.js +3 -1
  13. package/lib/network/RelayQueryResponseCache.js +19 -3
  14. package/lib/network/wrapNetworkWithLogObserver.js +78 -0
  15. package/lib/store/DataChecker.js +110 -40
  16. package/lib/store/OperationExecutor.js +478 -204
  17. package/lib/store/RelayConcreteVariables.js +21 -0
  18. package/lib/store/RelayModernEnvironment.js +41 -85
  19. package/lib/store/RelayModernFragmentSpecResolver.js +48 -22
  20. package/lib/store/RelayModernRecord.js +35 -1
  21. package/lib/store/RelayModernStore.js +48 -14
  22. package/lib/store/RelayOperationTracker.js +33 -23
  23. package/lib/store/RelayPublishQueue.js +23 -5
  24. package/lib/store/RelayReader.js +138 -44
  25. package/lib/store/RelayRecordSource.js +87 -3
  26. package/lib/store/RelayReferenceMarker.js +28 -15
  27. package/lib/store/RelayResponseNormalizer.js +164 -91
  28. package/lib/store/RelayStoreReactFlightUtils.js +1 -7
  29. package/lib/store/RelayStoreSubscriptions.js +8 -5
  30. package/lib/store/RelayStoreUtils.js +7 -2
  31. package/lib/store/ResolverCache.js +213 -0
  32. package/lib/store/ResolverFragments.js +1 -1
  33. package/lib/store/createRelayContext.js +1 -1
  34. package/lib/subscription/requestSubscription.js +27 -29
  35. package/lib/util/RelayConcreteNode.js +1 -0
  36. package/lib/util/RelayFeatureFlags.js +3 -5
  37. package/lib/util/RelayReplaySubject.js +21 -6
  38. package/lib/util/getPaginationMetadata.js +41 -0
  39. package/lib/util/getPaginationVariables.js +67 -0
  40. package/lib/util/getPendingOperationsForFragment.js +55 -0
  41. package/lib/util/getRefetchMetadata.js +36 -0
  42. package/lib/util/getValueAtPath.js +51 -0
  43. package/lib/util/isEmptyObject.js +1 -1
  44. package/lib/util/registerEnvironmentWithDevTools.js +26 -0
  45. package/lib/util/withDuration.js +31 -0
  46. package/multi-actor-environment/ActorIdentifier.js.flow +17 -1
  47. package/multi-actor-environment/ActorSpecificEnvironment.js.flow +72 -44
  48. package/multi-actor-environment/ActorUtils.js.flow +33 -0
  49. package/multi-actor-environment/MultiActorEnvironment.js.flow +332 -80
  50. package/multi-actor-environment/MultiActorEnvironmentTypes.js.flow +61 -12
  51. package/multi-actor-environment/index.js.flow +3 -0
  52. package/mutations/RelayRecordSourceSelectorProxy.js.flow +7 -2
  53. package/mutations/commitMutation.js.flow +2 -0
  54. package/mutations/validateMutation.js.flow +8 -0
  55. package/network/RelayObservable.js.flow +2 -0
  56. package/network/RelayQueryResponseCache.js.flow +31 -18
  57. package/network/wrapNetworkWithLogObserver.js.flow +99 -0
  58. package/package.json +1 -1
  59. package/relay-runtime.js +2 -2
  60. package/relay-runtime.min.js +2 -2
  61. package/store/ClientID.js.flow +5 -1
  62. package/store/DataChecker.js.flow +126 -35
  63. package/store/OperationExecutor.js.flow +528 -265
  64. package/store/RelayConcreteVariables.js.flow +26 -1
  65. package/store/RelayModernEnvironment.js.flow +41 -94
  66. package/store/RelayModernFragmentSpecResolver.js.flow +40 -14
  67. package/store/RelayModernOperationDescriptor.js.flow +9 -3
  68. package/store/RelayModernRecord.js.flow +49 -0
  69. package/store/RelayModernStore.js.flow +50 -12
  70. package/store/RelayOperationTracker.js.flow +56 -34
  71. package/store/RelayPublishQueue.js.flow +31 -8
  72. package/store/RelayReader.js.flow +148 -42
  73. package/store/RelayRecordSource.js.flow +72 -6
  74. package/store/RelayReferenceMarker.js.flow +29 -12
  75. package/store/RelayResponseNormalizer.js.flow +164 -48
  76. package/store/RelayStoreReactFlightUtils.js.flow +1 -7
  77. package/store/RelayStoreSubscriptions.js.flow +10 -3
  78. package/store/RelayStoreTypes.js.flow +128 -12
  79. package/store/RelayStoreUtils.js.flow +17 -3
  80. package/store/ResolverCache.js.flow +247 -0
  81. package/store/ResolverFragments.js.flow +6 -3
  82. package/store/createRelayContext.js.flow +1 -1
  83. package/subscription/requestSubscription.js.flow +41 -29
  84. package/util/NormalizationNode.js.flow +10 -3
  85. package/util/ReaderNode.js.flow +15 -1
  86. package/util/RelayConcreteNode.js.flow +1 -0
  87. package/util/RelayFeatureFlags.js.flow +8 -10
  88. package/util/RelayReplaySubject.js.flow +7 -6
  89. package/util/getPaginationMetadata.js.flow +74 -0
  90. package/util/getPaginationVariables.js.flow +112 -0
  91. package/util/getPendingOperationsForFragment.js.flow +62 -0
  92. package/util/getRefetchMetadata.js.flow +80 -0
  93. package/util/getValueAtPath.js.flow +46 -0
  94. package/util/isEmptyObject.js.flow +1 -0
  95. package/util/registerEnvironmentWithDevTools.js.flow +33 -0
  96. package/util/withDuration.js.flow +32 -0
  97. package/lib/store/RelayRecordSourceMapImpl.js +0 -107
  98. package/lib/store/RelayStoreSubscriptionsUsingMapByID.js +0 -318
  99. package/store/RelayRecordSourceMapImpl.js.flow +0 -91
  100. package/store/RelayStoreSubscriptionsUsingMapByID.js.flow +0 -283
@@ -18,9 +18,9 @@ var invariant = require('invariant');
18
18
 
19
19
  var RelayOperationTracker = /*#__PURE__*/function () {
20
20
  function RelayOperationTracker() {
21
- this._ownersToPendingOperationsIdentifier = new Map();
22
- this._pendingOperationsToOwnersIdentifier = new Map();
23
- this._ownersIdentifierToPromise = new Map();
21
+ this._ownersToPendingOperations = new Map();
22
+ this._pendingOperationsToOwners = new Map();
23
+ this._ownersToPendingPromise = new Map();
24
24
  }
25
25
  /**
26
26
  * Update the map of current processing operations with the set of
@@ -46,19 +46,19 @@ var RelayOperationTracker = /*#__PURE__*/function () {
46
46
  var owner = _step.value;
47
47
  var ownerIdentifier = owner.identifier;
48
48
 
49
- var pendingOperationsAffectingOwner = this._ownersToPendingOperationsIdentifier.get(ownerIdentifier);
49
+ var pendingOperationsAffectingOwner = this._ownersToPendingOperations.get(ownerIdentifier);
50
50
 
51
51
  if (pendingOperationsAffectingOwner != null) {
52
52
  // In this case the `ownerIdentifier` already affected by some operations
53
53
  // We just need to detect, is it the same operation that we already
54
54
  // have in the list, or it's a new operation
55
55
  if (!pendingOperationsAffectingOwner.has(pendingOperationIdentifier)) {
56
- pendingOperationsAffectingOwner.add(pendingOperationIdentifier);
56
+ pendingOperationsAffectingOwner.set(pendingOperationIdentifier, pendingOperation);
57
57
  newlyAffectedOwnersIdentifier.add(ownerIdentifier);
58
58
  }
59
59
  } else {
60
60
  // This is a new `ownerIdentifier` that is affected by the operation
61
- this._ownersToPendingOperationsIdentifier.set(ownerIdentifier, new Set([pendingOperationIdentifier]));
61
+ this._ownersToPendingOperations.set(ownerIdentifier, new Map([[pendingOperationIdentifier, pendingOperation]]));
62
62
 
63
63
  newlyAffectedOwnersIdentifier.add(ownerIdentifier);
64
64
  }
@@ -73,10 +73,10 @@ var RelayOperationTracker = /*#__PURE__*/function () {
73
73
  if (newlyAffectedOwnersIdentifier.size === 0) {
74
74
  return;
75
75
  } // But, if some owners were affected we need to add them to
76
- // the `_pendingOperationsToOwnersIdentifier` set
76
+ // the `_pendingOperationsToOwners` set
77
77
 
78
78
 
79
- var ownersAffectedByOperationIdentifier = this._pendingOperationsToOwnersIdentifier.get(pendingOperationIdentifier) || new Set();
79
+ var ownersAffectedByPendingOperation = this._pendingOperationsToOwners.get(pendingOperationIdentifier) || new Set();
80
80
 
81
81
  var _iterator2 = (0, _createForOfIteratorHelper2["default"])(newlyAffectedOwnersIdentifier),
82
82
  _step2;
@@ -87,7 +87,7 @@ var RelayOperationTracker = /*#__PURE__*/function () {
87
87
 
88
88
  this._resolveOwnerResolvers(_ownerIdentifier);
89
89
 
90
- ownersAffectedByOperationIdentifier.add(_ownerIdentifier);
90
+ ownersAffectedByPendingOperation.add(_ownerIdentifier);
91
91
  }
92
92
  } catch (err) {
93
93
  _iterator2.e(err);
@@ -95,7 +95,7 @@ var RelayOperationTracker = /*#__PURE__*/function () {
95
95
  _iterator2.f();
96
96
  }
97
97
 
98
- this._pendingOperationsToOwnersIdentifier.set(pendingOperationIdentifier, ownersAffectedByOperationIdentifier);
98
+ this._pendingOperationsToOwners.set(pendingOperationIdentifier, ownersAffectedByPendingOperation);
99
99
  }
100
100
  /**
101
101
  * Once pending operation is completed we need to remove it
@@ -106,7 +106,7 @@ var RelayOperationTracker = /*#__PURE__*/function () {
106
106
  _proto.complete = function complete(pendingOperation) {
107
107
  var pendingOperationIdentifier = pendingOperation.identifier;
108
108
 
109
- var affectedOwnersIdentifier = this._pendingOperationsToOwnersIdentifier.get(pendingOperationIdentifier);
109
+ var affectedOwnersIdentifier = this._pendingOperationsToOwners.get(pendingOperationIdentifier);
110
110
 
111
111
  if (affectedOwnersIdentifier == null) {
112
112
  return;
@@ -125,7 +125,7 @@ var RelayOperationTracker = /*#__PURE__*/function () {
125
125
  for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
126
126
  var ownerIdentifier = _step3.value;
127
127
 
128
- var pendingOperationsAffectingOwner = this._ownersToPendingOperationsIdentifier.get(ownerIdentifier);
128
+ var pendingOperationsAffectingOwner = this._ownersToPendingOperations.get(ownerIdentifier);
129
129
 
130
130
  if (!pendingOperationsAffectingOwner) {
131
131
  continue;
@@ -155,7 +155,7 @@ var RelayOperationTracker = /*#__PURE__*/function () {
155
155
 
156
156
  this._resolveOwnerResolvers(_ownerIdentifier2);
157
157
 
158
- this._ownersToPendingOperationsIdentifier["delete"](_ownerIdentifier2);
158
+ this._ownersToPendingOperations["delete"](_ownerIdentifier2);
159
159
  } // Update all ownerIdentifier that were updated by `pendingOperationIdentifier` but still
160
160
  // are affected by other operations
161
161
 
@@ -181,30 +181,35 @@ var RelayOperationTracker = /*#__PURE__*/function () {
181
181
  _iterator5.f();
182
182
  }
183
183
 
184
- this._pendingOperationsToOwnersIdentifier["delete"](pendingOperationIdentifier);
184
+ this._pendingOperationsToOwners["delete"](pendingOperationIdentifier);
185
185
  };
186
186
 
187
187
  _proto._resolveOwnerResolvers = function _resolveOwnerResolvers(ownerIdentifier) {
188
- var promiseEntry = this._ownersIdentifierToPromise.get(ownerIdentifier);
188
+ var promiseEntry = this._ownersToPendingPromise.get(ownerIdentifier);
189
189
 
190
190
  if (promiseEntry != null) {
191
191
  promiseEntry.resolve();
192
192
  }
193
193
 
194
- this._ownersIdentifierToPromise["delete"](ownerIdentifier);
194
+ this._ownersToPendingPromise["delete"](ownerIdentifier);
195
195
  };
196
196
 
197
- _proto.getPromiseForPendingOperationsAffectingOwner = function getPromiseForPendingOperationsAffectingOwner(owner) {
197
+ _proto.getPendingOperationsAffectingOwner = function getPendingOperationsAffectingOwner(owner) {
198
198
  var ownerIdentifier = owner.identifier;
199
199
 
200
- if (!this._ownersToPendingOperationsIdentifier.has(ownerIdentifier)) {
200
+ var pendingOperationsForOwner = this._ownersToPendingOperations.get(ownerIdentifier);
201
+
202
+ if (pendingOperationsForOwner == null || pendingOperationsForOwner.size === 0) {
201
203
  return null;
202
204
  }
203
205
 
204
- var cachedPromiseEntry = this._ownersIdentifierToPromise.get(ownerIdentifier);
206
+ var cachedPromiseEntry = this._ownersToPendingPromise.get(ownerIdentifier);
205
207
 
206
208
  if (cachedPromiseEntry != null) {
207
- return cachedPromiseEntry.promise;
209
+ return {
210
+ promise: cachedPromiseEntry.promise,
211
+ pendingOperations: cachedPromiseEntry.pendingOperations
212
+ };
208
213
  }
209
214
 
210
215
  var resolve;
@@ -212,13 +217,18 @@ var RelayOperationTracker = /*#__PURE__*/function () {
212
217
  resolve = r;
213
218
  });
214
219
  !(resolve != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayOperationTracker: Expected resolver to be defined. If you' + 'are seeing this, it is likely a bug in Relay.') : invariant(false) : void 0;
220
+ var pendingOperations = Array.from(pendingOperationsForOwner.values());
215
221
 
216
- this._ownersIdentifierToPromise.set(ownerIdentifier, {
222
+ this._ownersToPendingPromise.set(ownerIdentifier, {
217
223
  promise: promise,
218
- resolve: resolve
224
+ resolve: resolve,
225
+ pendingOperations: pendingOperations
219
226
  });
220
227
 
221
- return promise;
228
+ return {
229
+ promise: promise,
230
+ pendingOperations: pendingOperations
231
+ };
222
232
  };
223
233
 
224
234
  return RelayOperationTracker;
@@ -10,7 +10,7 @@
10
10
  // flowlint ambiguous-object-type:error
11
11
  'use strict';
12
12
 
13
- var _global$ErrorUtils$ap, _global$ErrorUtils;
13
+ var _global$ErrorUtils$ap, _global, _global$ErrorUtils;
14
14
 
15
15
  var RelayReader = require('./RelayReader');
16
16
 
@@ -26,7 +26,7 @@ var invariant = require('invariant');
26
26
 
27
27
  var warning = require("fbjs/lib/warning");
28
28
 
29
- var applyWithGuard = (_global$ErrorUtils$ap = (_global$ErrorUtils = global.ErrorUtils) === null || _global$ErrorUtils === void 0 ? void 0 : _global$ErrorUtils.applyWithGuard) !== null && _global$ErrorUtils$ap !== void 0 ? _global$ErrorUtils$ap : function (callback, context, args, onError, name) {
29
+ var applyWithGuard = (_global$ErrorUtils$ap = (_global = global) === null || _global === void 0 ? void 0 : (_global$ErrorUtils = _global.ErrorUtils) === null || _global$ErrorUtils === void 0 ? void 0 : _global$ErrorUtils.applyWithGuard) !== null && _global$ErrorUtils$ap !== void 0 ? _global$ErrorUtils$ap : function (callback, context, args, onError, name) {
30
30
  return callback.apply(context, args);
31
31
  };
32
32
  /**
@@ -149,11 +149,25 @@ var RelayPublishQueue = /*#__PURE__*/function () {
149
149
  ;
150
150
 
151
151
  _proto.run = function run(sourceOperation) {
152
+ var runWillClearGcHold = this._appliedOptimisticUpdates === 0 && !!this._gcHold;
153
+ var runIsANoop = // this._pendingBackupRebase is true if an applied optimistic
154
+ // update has potentially been reverted or if this._pendingData is not empty.
155
+ !this._pendingBackupRebase && this._pendingOptimisticUpdates.size === 0 && !runWillClearGcHold;
156
+
152
157
  if (process.env.NODE_ENV !== "production") {
158
+ process.env.NODE_ENV !== "production" ? warning(!runIsANoop, 'RelayPublishQueue.run was called, but the call would have been a noop.') : void 0;
153
159
  process.env.NODE_ENV !== "production" ? warning(this._isRunning !== true, 'A store update was detected within another store update. Please ' + "make sure new store updates aren't being executed within an " + 'updater function for a different update.') : void 0;
154
160
  this._isRunning = true;
155
161
  }
156
162
 
163
+ if (runIsANoop) {
164
+ if (process.env.NODE_ENV !== "production") {
165
+ this._isRunning = false;
166
+ }
167
+
168
+ return [];
169
+ }
170
+
157
171
  if (this._pendingBackupRebase) {
158
172
  if (this._hasStoreSnapshot) {
159
173
  this._store.restore();
@@ -299,15 +313,19 @@ var RelayPublishQueue = /*#__PURE__*/function () {
299
313
  updater = optimisticUpdate.updater;
300
314
  var source = payload.source,
301
315
  fieldPayloads = payload.fieldPayloads;
302
- var recordSourceSelectorProxy = new RelayRecordSourceSelectorProxy(mutator, recordSourceProxy, operation.fragment);
303
- var selectorData;
304
316
 
305
317
  if (source) {
306
318
  recordSourceProxy.publishSource(source, fieldPayloads);
307
- selectorData = lookupSelector(source, operation.fragment);
308
319
  }
309
320
 
310
321
  if (updater) {
322
+ var selectorData;
323
+
324
+ if (source) {
325
+ selectorData = lookupSelector(source, operation.fragment);
326
+ }
327
+
328
+ var recordSourceSelectorProxy = new RelayRecordSourceSelectorProxy(mutator, recordSourceProxy, operation.fragment);
311
329
  applyWithGuard(updater, null, [recordSourceSelectorProxy, selectorData], null, 'RelayPublishQueue:applyUpdates');
312
330
  }
313
331
  }
@@ -14,6 +14,8 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
14
14
 
15
15
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
16
16
 
17
+ var ClientID = require('./ClientID');
18
+
17
19
  var RelayFeatureFlags = require('../util/RelayFeatureFlags');
18
20
 
19
21
  var RelayModernRecord = require('./RelayModernRecord');
@@ -21,6 +23,7 @@ var RelayModernRecord = require('./RelayModernRecord');
21
23
  var invariant = require('invariant');
22
24
 
23
25
  var _require = require('../util/RelayConcreteNode'),
26
+ ACTOR_CHANGE = _require.ACTOR_CHANGE,
24
27
  CLIENT_EXTENSION = _require.CLIENT_EXTENSION,
25
28
  CONDITION = _require.CONDITION,
26
29
  DEFER = _require.DEFER,
@@ -50,14 +53,17 @@ var _require3 = require('./RelayStoreUtils'),
50
53
  getStorageKey = _require3.getStorageKey,
51
54
  getModuleComponentKey = _require3.getModuleComponentKey;
52
55
 
53
- var _require4 = require('./ResolverFragments'),
54
- withResolverContext = _require4.withResolverContext;
56
+ var _require4 = require('./ResolverCache'),
57
+ NoopResolverCache = _require4.NoopResolverCache;
58
+
59
+ var _require5 = require('./ResolverFragments'),
60
+ withResolverContext = _require5.withResolverContext;
55
61
 
56
- var _require5 = require('./TypeID'),
57
- generateTypeID = _require5.generateTypeID;
62
+ var _require6 = require('./TypeID'),
63
+ generateTypeID = _require6.generateTypeID;
58
64
 
59
- function read(recordSource, selector) {
60
- var reader = new RelayReader(recordSource, selector);
65
+ function read(recordSource, selector, resolverCache) {
66
+ var reader = new RelayReader(recordSource, selector, resolverCache !== null && resolverCache !== void 0 ? resolverCache : new NoopResolverCache());
61
67
  return reader.read();
62
68
  }
63
69
  /**
@@ -66,7 +72,7 @@ function read(recordSource, selector) {
66
72
 
67
73
 
68
74
  var RelayReader = /*#__PURE__*/function () {
69
- function RelayReader(recordSource, selector) {
75
+ function RelayReader(recordSource, selector, resolverCache) {
70
76
  this._isMissingData = false;
71
77
  this._isWithinUnmatchedTypeRefinement = false;
72
78
  this._missingRequiredFields = null;
@@ -75,6 +81,7 @@ var RelayReader = /*#__PURE__*/function () {
75
81
  this._seenRecords = new Set();
76
82
  this._selector = selector;
77
83
  this._variables = selector.variables;
84
+ this._resolverCache = resolverCache;
78
85
  }
79
86
 
80
87
  var _proto = RelayReader.prototype;
@@ -103,7 +110,15 @@ var RelayReader = /*#__PURE__*/function () {
103
110
  if (isDataExpectedToBePresent && abstractKey == null && record != null) {
104
111
  var recordType = RelayModernRecord.getType(record);
105
112
 
106
- if (recordType !== node.type && dataID !== ROOT_ID) {
113
+ if (recordType !== node.type && // The root record type is a special `__Root` type and may not match the
114
+ // type on the ast, so ignore type mismatches at the root.
115
+ // We currently detect whether we're at the root by checking against ROOT_ID,
116
+ // but this does not work for mutations/subscriptions which generate unique
117
+ // root ids. This is acceptable in practice as we don't read data for mutations/
118
+ // subscriptions in a situation where we would use isMissingData to decide whether
119
+ // to suspend or not.
120
+ // TODO T96653810: Correctly detect reading from root of mutation/subscription
121
+ dataID !== ROOT_ID) {
107
122
  isDataExpectedToBePresent = false;
108
123
  }
109
124
  } // If this is an abstract fragment (and the precise refinement GK is enabled)
@@ -112,7 +127,7 @@ var RelayReader = /*#__PURE__*/function () {
112
127
  // the interface, that itself constitutes "expected" data being missing.
113
128
 
114
129
 
115
- if (isDataExpectedToBePresent && abstractKey != null && record != null && RelayFeatureFlags.ENABLE_PRECISE_TYPE_REFINEMENT) {
130
+ if (isDataExpectedToBePresent && abstractKey != null && record != null) {
116
131
  var _recordType = RelayModernRecord.getType(record);
117
132
 
118
133
  var typeID = generateTypeID(_recordType);
@@ -254,7 +269,7 @@ var RelayReader = /*#__PURE__*/function () {
254
269
  break;
255
270
 
256
271
  case CONDITION:
257
- var conditionValue = this._getVariableValue(selection.condition);
272
+ var conditionValue = Boolean(this._getVariableValue(selection.condition));
258
273
 
259
274
  if (conditionValue === selection.passingValue) {
260
275
  var hasExpectedData = this._traverseSelections(selection.selections, record, data);
@@ -281,7 +296,7 @@ var RelayReader = /*#__PURE__*/function () {
281
296
  return false;
282
297
  }
283
298
  }
284
- } else if (RelayFeatureFlags.ENABLE_PRECISE_TYPE_REFINEMENT) {
299
+ } else {
285
300
  // Similar to the logic in read(): data is only expected to be present
286
301
  // if the record is known to conform to the interface. If we don't know
287
302
  // whether the type conforms or not, that constitutes missing data.
@@ -309,10 +324,6 @@ var RelayReader = /*#__PURE__*/function () {
309
324
  // Don't know if the type implements the interface or not
310
325
  this._isMissingData = true;
311
326
  }
312
- } else {
313
- // legacy behavior for abstract refinements: always read even
314
- // if the type doesn't conform and don't reset isMissingData
315
- this._traverseSelections(selection.selections, record, data);
316
327
  }
317
328
 
318
329
  break;
@@ -380,6 +391,11 @@ var RelayReader = /*#__PURE__*/function () {
380
391
 
381
392
  break;
382
393
 
394
+ case ACTOR_CHANGE:
395
+ this._readActorChange(selection, record, data);
396
+
397
+ break;
398
+
383
399
  default:
384
400
  selection;
385
401
  !false ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayReader(): Unexpected ast kind `%s`.', selection.kind) : invariant(false) : void 0;
@@ -401,44 +417,93 @@ var RelayReader = /*#__PURE__*/function () {
401
417
  return this._readLink(selection.field, record, data);
402
418
  }
403
419
 
420
+ case RELAY_RESOLVER:
421
+ if (!RelayFeatureFlags.ENABLE_RELAY_RESOLVERS) {
422
+ throw new Error('Relay Resolver fields are not yet supported.');
423
+ }
424
+
425
+ this._readResolverField(selection.field, record, data);
426
+
427
+ break;
428
+
404
429
  default:
405
430
  selection.field.kind;
406
431
  !false ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayReader(): Unexpected ast kind `%s`.', selection.kind) : invariant(false) : void 0;
407
432
  }
408
433
  };
409
434
 
410
- _proto._readResolverField = function _readResolverField(selection, record, data) {
435
+ _proto._readResolverField = function _readResolverField(field, record, data) {
411
436
  var _this = this;
412
437
 
413
- var name = selection.name,
414
- alias = selection.alias,
415
- resolverModule = selection.resolverModule,
416
- fragment = selection.fragment;
417
- var key = {
418
- __id: RelayModernRecord.getDataID(record),
419
- __fragmentOwner: this._owner,
420
- __fragments: (0, _defineProperty2["default"])({}, fragment.name, {})
421
- };
422
- var resolverContext = {
423
- getDataForResolverFragment: function getDataForResolverFragment(singularReaderSelector) {
438
+ var resolverModule = field.resolverModule,
439
+ fragment = field.fragment;
440
+ var storageKey = getStorageKey(field, this._variables);
441
+ var resolverID = ClientID.generateClientID(RelayModernRecord.getDataID(record), storageKey); // Found when reading the resolver fragment, which can happen either when
442
+ // evaluating the resolver and it calls readFragment, or when checking if the
443
+ // inputs have changed since a previous evaluation:
444
+
445
+ var fragmentValue;
446
+ var fragmentReaderSelector;
447
+ var fragmentSeenRecordIDs = new Set();
448
+
449
+ var getDataForResolverFragment = function getDataForResolverFragment(singularReaderSelector) {
450
+ if (fragmentValue != null) {
451
+ // It was already read when checking for input staleness; no need to read it again.
452
+ // Note that the variables like fragmentSeenRecordIDs in the outer closure will have
453
+ // already been set and will still be used in this case.
454
+ return fragmentValue;
455
+ }
456
+
457
+ fragmentReaderSelector = singularReaderSelector;
458
+ var existingSeenRecords = _this._seenRecords;
459
+
460
+ try {
424
461
  var _resolverFragmentData;
425
462
 
463
+ _this._seenRecords = fragmentSeenRecordIDs;
426
464
  var resolverFragmentData = {};
427
465
 
428
466
  _this._createInlineDataOrResolverFragmentPointer(singularReaderSelector.node, record, resolverFragmentData);
429
467
 
430
- var answer = (_resolverFragmentData = resolverFragmentData[FRAGMENTS_KEY]) === null || _resolverFragmentData === void 0 ? void 0 : _resolverFragmentData[fragment.name];
431
- !(typeof answer === 'object' && answer !== 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;
432
- return answer;
468
+ fragmentValue = (_resolverFragmentData = resolverFragmentData[FRAGMENTS_KEY]) === null || _resolverFragmentData === void 0 ? void 0 : _resolverFragmentData[fragment.name];
469
+ !(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;
470
+ return fragmentValue;
471
+ } finally {
472
+ _this._seenRecords = existingSeenRecords;
433
473
  }
434
474
  };
435
- var resolverResult = withResolverContext(resolverContext, function () {
436
- return (// $FlowFixMe[prop-missing] - resolver module's type signature is a lie
437
- resolverModule(key)
438
- );
439
- });
440
- data[alias !== null && alias !== void 0 ? alias : name] = resolverResult;
441
- return resolverResult;
475
+
476
+ var resolverContext = {
477
+ getDataForResolverFragment: getDataForResolverFragment
478
+ };
479
+
480
+ var _this$_resolverCache$ = this._resolverCache.readFromCacheOrEvaluate(record, field, this._variables, function () {
481
+ var key = {
482
+ __id: RelayModernRecord.getDataID(record),
483
+ __fragmentOwner: _this._owner,
484
+ __fragments: (0, _defineProperty2["default"])({}, fragment.name, {})
485
+ };
486
+ return withResolverContext(resolverContext, function () {
487
+ // $FlowFixMe[prop-missing] - resolver module's type signature is a lie
488
+ var resolverResult = resolverModule(key);
489
+ return {
490
+ resolverResult: resolverResult,
491
+ fragmentValue: fragmentValue,
492
+ resolverID: resolverID,
493
+ seenRecordIDs: fragmentSeenRecordIDs,
494
+ readerSelector: fragmentReaderSelector
495
+ };
496
+ });
497
+ }, getDataForResolverFragment),
498
+ result = _this$_resolverCache$[0],
499
+ seenRecord = _this$_resolverCache$[1];
500
+
501
+ if (seenRecord != null) {
502
+ this._seenRecords.add(seenRecord);
503
+ }
504
+
505
+ data[storageKey] = result;
506
+ return result;
442
507
  };
443
508
 
444
509
  _proto._readFlightField = function _readFlightField(field, record, data) {
@@ -518,12 +583,44 @@ var RelayReader = /*#__PURE__*/function () {
518
583
  return value;
519
584
  };
520
585
 
586
+ _proto._readActorChange = function _readActorChange(field, record, data) {
587
+ var _field$alias4;
588
+
589
+ var applicationName = (_field$alias4 = field.alias) !== null && _field$alias4 !== void 0 ? _field$alias4 : field.name;
590
+ var storageKey = getStorageKey(field, this._variables);
591
+ var externalRef = RelayModernRecord.getActorLinkedRecordID(record, storageKey);
592
+
593
+ if (externalRef == null) {
594
+ data[applicationName] = externalRef;
595
+
596
+ if (externalRef === undefined) {
597
+ this._isMissingData = true;
598
+ }
599
+
600
+ return data[applicationName];
601
+ }
602
+
603
+ var actorIdentifier = externalRef[0],
604
+ dataID = externalRef[1];
605
+ var fragmentRef = {};
606
+
607
+ this._createFragmentPointer(field.fragmentSpread, {
608
+ __id: dataID
609
+ }, fragmentRef);
610
+
611
+ data[applicationName] = {
612
+ __fragmentRef: fragmentRef,
613
+ __viewer: actorIdentifier
614
+ };
615
+ return data[applicationName];
616
+ };
617
+
521
618
  _proto._readPluralLink = function _readPluralLink(field, record, data) {
522
619
  var _this2 = this;
523
620
 
524
- var _field$alias4;
621
+ var _field$alias5;
525
622
 
526
- var applicationName = (_field$alias4 = field.alias) !== null && _field$alias4 !== void 0 ? _field$alias4 : field.name;
623
+ var applicationName = (_field$alias5 = field.alias) !== null && _field$alias5 !== void 0 ? _field$alias5 : field.name;
527
624
  var storageKey = getStorageKey(field, this._variables);
528
625
  var linkedIDs = RelayModernRecord.getLinkedRecordIDs(record, storageKey);
529
626
 
@@ -588,7 +685,7 @@ var RelayReader = /*#__PURE__*/function () {
588
685
  this._createFragmentPointer({
589
686
  kind: 'FragmentSpread',
590
687
  name: moduleImport.fragmentName,
591
- args: null
688
+ args: moduleImport.args
592
689
  }, record, data);
593
690
 
594
691
  data[FRAGMENT_PROP_NAME_KEY] = moduleImport.fragmentPropName;
@@ -611,10 +708,7 @@ var RelayReader = /*#__PURE__*/function () {
611
708
 
612
709
  fragmentPointers[fragmentSpread.name] = fragmentSpread.args ? getArgumentValues(fragmentSpread.args, this._variables) : {};
613
710
  data[FRAGMENT_OWNER_KEY] = this._owner;
614
-
615
- if (RelayFeatureFlags.ENABLE_PRECISE_TYPE_REFINEMENT) {
616
- data[IS_WITHIN_UNMATCHED_TYPE_REFINEMENT] = this._isWithinUnmatchedTypeRefinement;
617
- }
711
+ data[IS_WITHIN_UNMATCHED_TYPE_REFINEMENT] = this._isWithinUnmatchedTypeRefinement;
618
712
  };
619
713
 
620
714
  _proto._createInlineDataOrResolverFragmentPointer = function _createInlineDataOrResolverFragmentPointer(fragmentSpreadOrFragment, record, data) {
@@ -10,15 +10,99 @@
10
10
  // flowlint ambiguous-object-type:error
11
11
  'use strict';
12
12
 
13
- var RelayRecordSourceMapImpl = require('./RelayRecordSourceMapImpl');
13
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
14
+
15
+ var _createForOfIteratorHelper2 = _interopRequireDefault(require("@babel/runtime/helpers/createForOfIteratorHelper"));
16
+
17
+ var RelayRecordState = require('./RelayRecordState');
18
+
19
+ var EXISTENT = RelayRecordState.EXISTENT,
20
+ NONEXISTENT = RelayRecordState.NONEXISTENT,
21
+ UNKNOWN = RelayRecordState.UNKNOWN;
22
+ /**
23
+ * An implementation of the `MutableRecordSource` interface (defined in
24
+ * `RelayStoreTypes`) that holds all records in memory (JS Map).
25
+ */
14
26
 
15
27
  var RelayRecordSource = /*#__PURE__*/function () {
16
28
  function RelayRecordSource(records) {
17
- return RelayRecordSource.create(records);
29
+ var _this = this;
30
+
31
+ this._records = new Map();
32
+
33
+ if (records != null) {
34
+ Object.keys(records).forEach(function (key) {
35
+ _this._records.set(key, records[key]);
36
+ });
37
+ }
18
38
  }
19
39
 
20
40
  RelayRecordSource.create = function create(records) {
21
- return new RelayRecordSourceMapImpl(records);
41
+ return new RelayRecordSource(records);
42
+ };
43
+
44
+ var _proto = RelayRecordSource.prototype;
45
+
46
+ _proto.clear = function clear() {
47
+ this._records = new Map();
48
+ };
49
+
50
+ _proto["delete"] = function _delete(dataID) {
51
+ this._records.set(dataID, null);
52
+ };
53
+
54
+ _proto.get = function get(dataID) {
55
+ return this._records.get(dataID);
56
+ };
57
+
58
+ _proto.getRecordIDs = function getRecordIDs() {
59
+ return Array.from(this._records.keys());
60
+ };
61
+
62
+ _proto.getStatus = function getStatus(dataID) {
63
+ if (!this._records.has(dataID)) {
64
+ return UNKNOWN;
65
+ }
66
+
67
+ return this._records.get(dataID) == null ? NONEXISTENT : EXISTENT;
68
+ };
69
+
70
+ _proto.has = function has(dataID) {
71
+ return this._records.has(dataID);
72
+ };
73
+
74
+ _proto.remove = function remove(dataID) {
75
+ this._records["delete"](dataID);
76
+ };
77
+
78
+ _proto.set = function set(dataID, record) {
79
+ this._records.set(dataID, record);
80
+ };
81
+
82
+ _proto.size = function size() {
83
+ return this._records.size;
84
+ };
85
+
86
+ _proto.toJSON = function toJSON() {
87
+ var obj = {};
88
+
89
+ var _iterator = (0, _createForOfIteratorHelper2["default"])(this._records),
90
+ _step;
91
+
92
+ try {
93
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
94
+ var _step$value = _step.value,
95
+ key = _step$value[0],
96
+ value = _step$value[1];
97
+ obj[key] = value;
98
+ }
99
+ } catch (err) {
100
+ _iterator.e(err);
101
+ } finally {
102
+ _iterator.f();
103
+ }
104
+
105
+ return obj;
22
106
  };
23
107
 
24
108
  return RelayRecordSource;