relay-runtime 11.0.2 → 13.0.0-rc.2

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 (219) hide show
  1. package/README.md +67 -0
  2. package/handlers/RelayDefaultHandlerProvider.js.flow +3 -3
  3. package/handlers/connection/ConnectionHandler.js.flow +9 -18
  4. package/handlers/connection/ConnectionInterface.js.flow +1 -1
  5. package/handlers/connection/MutationHandlers.js.flow +8 -12
  6. package/index.js +1 -1
  7. package/index.js.flow +57 -35
  8. package/lib/handlers/RelayDefaultHandlerProvider.js +1 -1
  9. package/lib/handlers/connection/ConnectionHandler.js +13 -19
  10. package/lib/handlers/connection/ConnectionInterface.js +1 -1
  11. package/lib/handlers/connection/MutationHandlers.js +4 -7
  12. package/lib/index.js +59 -44
  13. package/lib/multi-actor-environment/ActorIdentifier.js +12 -2
  14. package/lib/multi-actor-environment/ActorSpecificEnvironment.js +64 -20
  15. package/lib/multi-actor-environment/ActorUtils.js +27 -0
  16. package/lib/multi-actor-environment/MultiActorEnvironment.js +324 -61
  17. package/lib/multi-actor-environment/MultiActorEnvironmentTypes.js +1 -1
  18. package/lib/multi-actor-environment/index.js +6 -2
  19. package/lib/mutations/RelayDeclarativeMutationConfig.js +5 -2
  20. package/lib/mutations/RelayRecordProxy.js +4 -3
  21. package/lib/mutations/RelayRecordSourceMutator.js +4 -3
  22. package/lib/mutations/RelayRecordSourceProxy.js +13 -5
  23. package/lib/mutations/RelayRecordSourceSelectorProxy.js +19 -6
  24. package/lib/mutations/applyOptimisticMutation.js +7 -7
  25. package/lib/mutations/commitLocalUpdate.js +1 -1
  26. package/lib/mutations/commitMutation.js +15 -11
  27. package/lib/mutations/readUpdatableQuery_EXPERIMENTAL.js +242 -0
  28. package/lib/mutations/validateMutation.js +11 -6
  29. package/lib/network/ConvertToExecuteFunction.js +3 -2
  30. package/lib/network/RelayNetwork.js +4 -3
  31. package/lib/network/RelayNetworkTypes.js +1 -1
  32. package/lib/network/RelayObservable.js +1 -1
  33. package/lib/network/RelayQueryResponseCache.js +22 -6
  34. package/lib/network/wrapNetworkWithLogObserver.js +79 -0
  35. package/lib/query/GraphQLTag.js +3 -2
  36. package/lib/query/PreloadableQueryRegistry.js +1 -1
  37. package/lib/query/fetchQuery.js +7 -6
  38. package/lib/query/fetchQueryInternal.js +1 -1
  39. package/lib/query/fetchQuery_DEPRECATED.js +3 -2
  40. package/lib/store/ClientID.js +8 -2
  41. package/lib/store/DataChecker.js +124 -55
  42. package/lib/store/OperationExecutor.js +489 -215
  43. package/lib/store/RelayConcreteVariables.js +27 -9
  44. package/lib/store/RelayExperimentalGraphResponseHandler.js +153 -0
  45. package/lib/store/RelayExperimentalGraphResponseTransform.js +391 -0
  46. package/lib/store/RelayModernEnvironment.js +100 -120
  47. package/lib/store/RelayModernFragmentSpecResolver.js +53 -27
  48. package/lib/store/RelayModernOperationDescriptor.js +3 -2
  49. package/lib/store/RelayModernRecord.js +48 -13
  50. package/lib/store/RelayModernSelector.js +15 -9
  51. package/lib/store/RelayModernStore.js +56 -23
  52. package/lib/store/RelayOperationTracker.js +34 -24
  53. package/lib/store/RelayOptimisticRecordSource.js +1 -1
  54. package/lib/store/RelayPublishQueue.js +35 -11
  55. package/lib/store/RelayReader.js +257 -72
  56. package/lib/store/RelayRecordSource.js +88 -4
  57. package/lib/store/RelayRecordState.js +1 -1
  58. package/lib/store/RelayReferenceMarker.js +34 -22
  59. package/lib/store/RelayResponseNormalizer.js +172 -96
  60. package/lib/store/RelayStoreReactFlightUtils.js +5 -11
  61. package/lib/store/RelayStoreSubscriptions.js +15 -10
  62. package/lib/store/RelayStoreTypes.js +1 -1
  63. package/lib/store/RelayStoreUtils.js +13 -8
  64. package/lib/store/ResolverCache.js +213 -0
  65. package/lib/store/ResolverFragments.js +10 -6
  66. package/lib/store/StoreInspector.js +1 -1
  67. package/lib/store/TypeID.js +1 -1
  68. package/lib/store/ViewerPattern.js +1 -1
  69. package/lib/store/cloneRelayHandleSourceField.js +6 -5
  70. package/lib/store/cloneRelayScalarHandleSourceField.js +6 -5
  71. package/lib/store/createFragmentSpecResolver.js +1 -1
  72. package/lib/store/createRelayContext.js +5 -3
  73. package/lib/store/defaultGetDataID.js +1 -1
  74. package/lib/store/defaultRequiredFieldLogger.js +1 -1
  75. package/lib/store/hasOverlappingIDs.js +1 -1
  76. package/lib/store/isRelayModernEnvironment.js +1 -1
  77. package/lib/store/normalizeRelayPayload.js +1 -1
  78. package/lib/store/readInlineData.js +7 -3
  79. package/lib/subscription/requestSubscription.js +32 -34
  80. package/lib/util/JSResourceTypes.flow.js +1 -1
  81. package/lib/util/NormalizationNode.js +1 -1
  82. package/lib/util/ReaderNode.js +1 -1
  83. package/lib/util/RelayConcreteNode.js +3 -1
  84. package/lib/util/RelayDefaultHandleKey.js +1 -1
  85. package/lib/util/RelayError.js +1 -1
  86. package/lib/util/RelayFeatureFlags.js +10 -7
  87. package/lib/util/RelayProfiler.js +1 -1
  88. package/lib/util/RelayReplaySubject.js +22 -7
  89. package/lib/util/RelayRuntimeTypes.js +1 -7
  90. package/lib/util/StringInterner.js +71 -0
  91. package/lib/util/createPayloadFor3DField.js +1 -1
  92. package/lib/util/deepFreeze.js +1 -1
  93. package/lib/util/generateID.js +1 -1
  94. package/lib/util/getAllRootVariables.js +29 -0
  95. package/lib/util/getFragmentIdentifier.js +16 -8
  96. package/lib/util/getOperation.js +3 -2
  97. package/lib/util/getPaginationMetadata.js +41 -0
  98. package/lib/util/getPaginationVariables.js +66 -0
  99. package/lib/util/getPendingOperationsForFragment.js +55 -0
  100. package/lib/util/getRefetchMetadata.js +36 -0
  101. package/lib/util/getRelayHandleKey.js +3 -3
  102. package/lib/util/getRequestIdentifier.js +3 -3
  103. package/lib/util/getValueAtPath.js +51 -0
  104. package/lib/util/isEmptyObject.js +2 -2
  105. package/lib/util/isPromise.js +1 -1
  106. package/lib/util/isScalarAndEqual.js +1 -1
  107. package/lib/util/recycleNodesInto.js +1 -1
  108. package/lib/util/registerEnvironmentWithDevTools.js +26 -0
  109. package/lib/util/reportMissingRequiredFields.js +1 -1
  110. package/lib/util/resolveImmediate.js +1 -1
  111. package/lib/util/stableCopy.js +1 -1
  112. package/lib/util/withDuration.js +31 -0
  113. package/multi-actor-environment/ActorIdentifier.js.flow +18 -2
  114. package/multi-actor-environment/ActorSpecificEnvironment.js.flow +94 -58
  115. package/multi-actor-environment/ActorUtils.js.flow +33 -0
  116. package/multi-actor-environment/MultiActorEnvironment.js.flow +366 -93
  117. package/multi-actor-environment/MultiActorEnvironmentTypes.js.flow +88 -23
  118. package/multi-actor-environment/index.js.flow +3 -1
  119. package/mutations/RelayDeclarativeMutationConfig.js.flow +33 -27
  120. package/mutations/RelayRecordProxy.js.flow +5 -6
  121. package/mutations/RelayRecordSourceMutator.js.flow +5 -7
  122. package/mutations/RelayRecordSourceProxy.js.flow +20 -11
  123. package/mutations/RelayRecordSourceSelectorProxy.js.flow +23 -8
  124. package/mutations/applyOptimisticMutation.js.flow +14 -15
  125. package/mutations/commitLocalUpdate.js.flow +2 -2
  126. package/mutations/commitMutation.js.flow +36 -47
  127. package/mutations/readUpdatableQuery_EXPERIMENTAL.js.flow +318 -0
  128. package/mutations/validateMutation.js.flow +27 -17
  129. package/network/ConvertToExecuteFunction.js.flow +3 -3
  130. package/network/RelayNetwork.js.flow +5 -6
  131. package/network/RelayNetworkTypes.js.flow +1 -1
  132. package/network/RelayObservable.js.flow +2 -2
  133. package/network/RelayQueryResponseCache.js.flow +35 -22
  134. package/network/wrapNetworkWithLogObserver.js.flow +99 -0
  135. package/package.json +2 -2
  136. package/query/GraphQLTag.js.flow +11 -11
  137. package/query/PreloadableQueryRegistry.js.flow +5 -3
  138. package/query/fetchQuery.js.flow +19 -19
  139. package/query/fetchQueryInternal.js.flow +7 -10
  140. package/query/fetchQuery_DEPRECATED.js.flow +7 -7
  141. package/relay-runtime.js +2 -2
  142. package/relay-runtime.min.js +2 -2
  143. package/store/ClientID.js.flow +15 -4
  144. package/store/DataChecker.js.flow +142 -60
  145. package/store/OperationExecutor.js.flow +575 -320
  146. package/store/RelayConcreteVariables.js.flow +28 -9
  147. package/store/RelayExperimentalGraphResponseHandler.js.flow +121 -0
  148. package/store/RelayExperimentalGraphResponseTransform.js.flow +470 -0
  149. package/store/RelayModernEnvironment.js.flow +91 -115
  150. package/store/RelayModernFragmentSpecResolver.js.flow +56 -32
  151. package/store/RelayModernOperationDescriptor.js.flow +13 -8
  152. package/store/RelayModernRecord.js.flow +68 -12
  153. package/store/RelayModernSelector.js.flow +25 -15
  154. package/store/RelayModernStore.js.flow +67 -32
  155. package/store/RelayOperationTracker.js.flow +60 -44
  156. package/store/RelayOptimisticRecordSource.js.flow +3 -3
  157. package/store/RelayPublishQueue.js.flow +74 -32
  158. package/store/RelayReader.js.flow +319 -100
  159. package/store/RelayRecordSource.js.flow +73 -7
  160. package/store/RelayRecordState.js.flow +1 -1
  161. package/store/RelayReferenceMarker.js.flow +41 -27
  162. package/store/RelayResponseNormalizer.js.flow +204 -86
  163. package/store/RelayStoreReactFlightUtils.js.flow +5 -12
  164. package/store/RelayStoreSubscriptions.js.flow +20 -12
  165. package/store/RelayStoreTypes.js.flow +200 -41
  166. package/store/RelayStoreUtils.js.flow +25 -12
  167. package/store/ResolverCache.js.flow +249 -0
  168. package/store/ResolverFragments.js.flow +16 -20
  169. package/store/StoreInspector.js.flow +3 -3
  170. package/store/TypeID.js.flow +2 -2
  171. package/store/ViewerPattern.js.flow +3 -3
  172. package/store/cloneRelayHandleSourceField.js.flow +6 -7
  173. package/store/cloneRelayScalarHandleSourceField.js.flow +6 -7
  174. package/store/createFragmentSpecResolver.js.flow +4 -5
  175. package/store/createRelayContext.js.flow +4 -4
  176. package/store/defaultGetDataID.js.flow +1 -1
  177. package/store/defaultRequiredFieldLogger.js.flow +1 -1
  178. package/store/hasOverlappingIDs.js.flow +1 -1
  179. package/store/isRelayModernEnvironment.js.flow +1 -1
  180. package/store/normalizeRelayPayload.js.flow +7 -8
  181. package/store/readInlineData.js.flow +8 -9
  182. package/subscription/requestSubscription.js.flow +55 -51
  183. package/util/JSResourceTypes.flow.js.flow +1 -1
  184. package/util/NormalizationNode.js.flow +11 -4
  185. package/util/ReaderNode.js.flow +25 -2
  186. package/util/RelayConcreteNode.js.flow +5 -1
  187. package/util/RelayDefaultHandleKey.js.flow +1 -1
  188. package/util/RelayError.js.flow +1 -1
  189. package/util/RelayFeatureFlags.js.flow +23 -15
  190. package/util/RelayProfiler.js.flow +1 -1
  191. package/util/RelayReplaySubject.js.flow +10 -10
  192. package/util/RelayRuntimeTypes.js.flow +70 -3
  193. package/util/StringInterner.js.flow +69 -0
  194. package/util/createPayloadFor3DField.js.flow +4 -4
  195. package/util/deepFreeze.js.flow +1 -1
  196. package/util/generateID.js.flow +1 -1
  197. package/util/getAllRootVariables.js.flow +36 -0
  198. package/util/getFragmentIdentifier.js.flow +28 -16
  199. package/util/getOperation.js.flow +3 -3
  200. package/util/getPaginationMetadata.js.flow +69 -0
  201. package/util/getPaginationVariables.js.flow +108 -0
  202. package/util/getPendingOperationsForFragment.js.flow +62 -0
  203. package/util/getRefetchMetadata.js.flow +76 -0
  204. package/util/getRelayHandleKey.js.flow +2 -3
  205. package/util/getRequestIdentifier.js.flow +4 -4
  206. package/util/getValueAtPath.js.flow +46 -0
  207. package/util/isEmptyObject.js.flow +2 -1
  208. package/util/isPromise.js.flow +1 -1
  209. package/util/isScalarAndEqual.js.flow +1 -1
  210. package/util/recycleNodesInto.js.flow +1 -1
  211. package/util/registerEnvironmentWithDevTools.js.flow +33 -0
  212. package/util/reportMissingRequiredFields.js.flow +1 -1
  213. package/util/resolveImmediate.js.flow +2 -2
  214. package/util/stableCopy.js.flow +1 -1
  215. package/util/withDuration.js.flow +32 -0
  216. package/lib/store/RelayRecordSourceMapImpl.js +0 -107
  217. package/lib/store/RelayStoreSubscriptionsUsingMapByID.js +0 -318
  218. package/store/RelayRecordSourceMapImpl.js.flow +0 -91
  219. package/store/RelayStoreSubscriptionsUsingMapByID.js.flow +0 -283
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -12,19 +12,11 @@
12
12
 
13
13
  'use strict';
14
14
 
15
- const RelayReader = require('./RelayReader');
16
- const RelayRecordSource = require('./RelayRecordSource');
17
- const RelayRecordSourceMutator = require('../mutations/RelayRecordSourceMutator');
18
- const RelayRecordSourceProxy = require('../mutations/RelayRecordSourceProxy');
19
- const RelayRecordSourceSelectorProxy = require('../mutations/RelayRecordSourceSelectorProxy');
20
-
21
- const invariant = require('invariant');
22
- const warning = require('warning');
23
-
24
15
  import type {HandlerProvider} from '../handlers/RelayDefaultHandlerProvider';
25
16
  import type {Disposable} from '../util/RelayRuntimeTypes';
26
17
  import type {GetDataID} from './RelayResponseNormalizer';
27
18
  import type {
19
+ MutationParameters,
28
20
  OperationDescriptor,
29
21
  OptimisticUpdate,
30
22
  PublishQueue,
@@ -38,12 +30,23 @@ import type {
38
30
  StoreUpdater,
39
31
  } from './RelayStoreTypes';
40
32
 
41
- type PendingCommit = PendingRelayPayload | PendingRecordSource | PendingUpdater;
42
- type PendingRelayPayload = {|
33
+ const RelayRecordSourceMutator = require('../mutations/RelayRecordSourceMutator');
34
+ const RelayRecordSourceProxy = require('../mutations/RelayRecordSourceProxy');
35
+ const RelayRecordSourceSelectorProxy = require('../mutations/RelayRecordSourceSelectorProxy');
36
+ const RelayReader = require('./RelayReader');
37
+ const RelayRecordSource = require('./RelayRecordSource');
38
+ const invariant = require('invariant');
39
+ const warning = require('warning');
40
+
41
+ type PendingCommit<TMutation: MutationParameters> =
42
+ | PendingRelayPayload<TMutation>
43
+ | PendingRecordSource
44
+ | PendingUpdater;
45
+ type PendingRelayPayload<TMutation: MutationParameters> = {|
43
46
  +kind: 'payload',
44
47
  +operation: OperationDescriptor,
45
48
  +payload: RelayResponsePayload,
46
- +updater: ?SelectorStoreUpdater,
49
+ +updater: ?SelectorStoreUpdater<TMutation['response']>,
47
50
  |};
48
51
  type PendingRecordSource = {|
49
52
  +kind: 'source',
@@ -55,7 +58,7 @@ type PendingUpdater = {|
55
58
  |};
56
59
 
57
60
  const applyWithGuard =
58
- global.ErrorUtils?.applyWithGuard ??
61
+ global?.ErrorUtils?.applyWithGuard ??
59
62
  ((callback, context, args, onError, name) => callback.apply(context, args));
60
63
 
61
64
  /**
@@ -79,12 +82,19 @@ class RelayPublishQueue implements PublishQueue {
79
82
  // updates performing a rebase.
80
83
  _pendingBackupRebase: boolean;
81
84
  // Payloads to apply or Sources to publish to the store with the next `run()`.
82
- _pendingData: Set<PendingCommit>;
85
+ // $FlowFixMe[unclear-type] See explanation below.
86
+ _pendingData: Set<PendingCommit<any>>;
83
87
  // Optimistic updaters to add with the next `run()`.
84
- _pendingOptimisticUpdates: Set<OptimisticUpdate>;
88
+ // $FlowFixMe[unclear-type] See explanation below.
89
+ _pendingOptimisticUpdates: Set<OptimisticUpdate<any>>;
85
90
  // Optimistic updaters that are already added and might be rerun in order to
86
91
  // rebase them.
87
- _appliedOptimisticUpdates: Set<OptimisticUpdate>;
92
+ // $FlowFixMe[unclear-type] See explanation below.
93
+ _appliedOptimisticUpdates: Set<OptimisticUpdate<any>>;
94
+ // For _pendingOptimisticUpdates, _appliedOptimisticUpdates, and _pendingData,
95
+ // we want to parametrize by "any" since the type is effectively
96
+ // "the union of all T's that PublishQueue's methods were called with".
97
+
88
98
  // Garbage collection hold, should rerun gc on dispose
89
99
  _gcHold: ?Disposable;
90
100
  _isRunning: ?boolean;
@@ -108,7 +118,9 @@ class RelayPublishQueue implements PublishQueue {
108
118
  /**
109
119
  * Schedule applying an optimistic updates on the next `run()`.
110
120
  */
111
- applyUpdate(updater: OptimisticUpdate): void {
121
+ applyUpdate<TMutation: MutationParameters>(
122
+ updater: OptimisticUpdate<TMutation>,
123
+ ): void {
112
124
  invariant(
113
125
  !this._appliedOptimisticUpdates.has(updater) &&
114
126
  !this._pendingOptimisticUpdates.has(updater),
@@ -121,7 +133,9 @@ class RelayPublishQueue implements PublishQueue {
121
133
  /**
122
134
  * Schedule reverting an optimistic updates on the next `run()`.
123
135
  */
124
- revertUpdate(updater: OptimisticUpdate): void {
136
+ revertUpdate<TMutation: MutationParameters>(
137
+ updater: OptimisticUpdate<TMutation>,
138
+ ): void {
125
139
  if (this._pendingOptimisticUpdates.has(updater)) {
126
140
  // Reverted before it was applied
127
141
  this._pendingOptimisticUpdates.delete(updater);
@@ -143,10 +157,10 @@ class RelayPublishQueue implements PublishQueue {
143
157
  /**
144
158
  * Schedule applying a payload to the store on the next `run()`.
145
159
  */
146
- commitPayload(
160
+ commitPayload<TMutation: MutationParameters>(
147
161
  operation: OperationDescriptor,
148
162
  payload: RelayResponsePayload,
149
- updater?: ?SelectorStoreUpdater,
163
+ updater?: ?SelectorStoreUpdater<TMutation['response']>,
150
164
  ): void {
151
165
  this._pendingBackupRebase = true;
152
166
  this._pendingData.add({
@@ -185,7 +199,20 @@ class RelayPublishQueue implements PublishQueue {
185
199
  run(
186
200
  sourceOperation?: OperationDescriptor,
187
201
  ): $ReadOnlyArray<RequestDescriptor> {
202
+ const runWillClearGcHold =
203
+ this._appliedOptimisticUpdates === 0 && !!this._gcHold;
204
+ const runIsANoop =
205
+ // this._pendingBackupRebase is true if an applied optimistic
206
+ // update has potentially been reverted or if this._pendingData is not empty.
207
+ !this._pendingBackupRebase &&
208
+ this._pendingOptimisticUpdates.size === 0 &&
209
+ !runWillClearGcHold;
210
+
188
211
  if (__DEV__) {
212
+ warning(
213
+ !runIsANoop,
214
+ 'RelayPublishQueue.run was called, but the call would have been a noop.',
215
+ );
189
216
  warning(
190
217
  this._isRunning !== true,
191
218
  'A store update was detected within another store update. Please ' +
@@ -194,6 +221,14 @@ class RelayPublishQueue implements PublishQueue {
194
221
  );
195
222
  this._isRunning = true;
196
223
  }
224
+
225
+ if (runIsANoop) {
226
+ if (__DEV__) {
227
+ this._isRunning = false;
228
+ }
229
+ return [];
230
+ }
231
+
197
232
  if (this._pendingBackupRebase) {
198
233
  if (this._hasStoreSnapshot) {
199
234
  this._store.restore();
@@ -232,7 +267,9 @@ class RelayPublishQueue implements PublishQueue {
232
267
  * _publishSourceFromPayload will return a boolean indicating if the
233
268
  * publish caused the store to be globally invalidated.
234
269
  */
235
- _publishSourceFromPayload(pendingPayload: PendingRelayPayload): boolean {
270
+ _publishSourceFromPayload<TMutation: MutationParameters>(
271
+ pendingPayload: PendingRelayPayload<TMutation>,
272
+ ): boolean {
236
273
  const {payload, operation, updater} = pendingPayload;
237
274
  const {source, fieldPayloads} = payload;
238
275
  const mutator = new RelayRecordSourceMutator(
@@ -270,7 +307,8 @@ class RelayPublishQueue implements PublishQueue {
270
307
  const selectorData = lookupSelector(source, selector);
271
308
  updater(recordSourceSelectorProxy, selectorData);
272
309
  }
273
- const idsMarkedForInvalidation = recordSourceProxy.getIDsMarkedForInvalidation();
310
+ const idsMarkedForInvalidation =
311
+ recordSourceProxy.getIDsMarkedForInvalidation();
274
312
  this._store.publish(source, idsMarkedForInvalidation);
275
313
  return recordSourceProxy.isStoreMarkedForInvalidation();
276
314
  }
@@ -311,7 +349,8 @@ class RelayPublishQueue implements PublishQueue {
311
349
  );
312
350
  invalidatedStore =
313
351
  invalidatedStore || recordSourceProxy.isStoreMarkedForInvalidation();
314
- const idsMarkedForInvalidation = recordSourceProxy.getIDsMarkedForInvalidation();
352
+ const idsMarkedForInvalidation =
353
+ recordSourceProxy.getIDsMarkedForInvalidation();
315
354
 
316
355
  this._store.publish(sink, idsMarkedForInvalidation);
317
356
  }
@@ -334,7 +373,8 @@ class RelayPublishQueue implements PublishQueue {
334
373
  this._handlerProvider,
335
374
  );
336
375
 
337
- const processUpdate = optimisticUpdate => {
376
+ // $FlowFixMe[unclear-type] see explanation above.
377
+ const processUpdate = (optimisticUpdate: OptimisticUpdate<any>) => {
338
378
  if (optimisticUpdate.storeUpdater) {
339
379
  const {storeUpdater} = optimisticUpdate;
340
380
  applyWithGuard(
@@ -347,17 +387,19 @@ class RelayPublishQueue implements PublishQueue {
347
387
  } else {
348
388
  const {operation, payload, updater} = optimisticUpdate;
349
389
  const {source, fieldPayloads} = payload;
350
- const recordSourceSelectorProxy = new RelayRecordSourceSelectorProxy(
351
- mutator,
352
- recordSourceProxy,
353
- operation.fragment,
354
- );
355
- let selectorData;
356
390
  if (source) {
357
391
  recordSourceProxy.publishSource(source, fieldPayloads);
358
- selectorData = lookupSelector(source, operation.fragment);
359
392
  }
360
393
  if (updater) {
394
+ let selectorData;
395
+ if (source) {
396
+ selectorData = lookupSelector(source, operation.fragment);
397
+ }
398
+ const recordSourceSelectorProxy = new RelayRecordSourceSelectorProxy(
399
+ mutator,
400
+ recordSourceProxy,
401
+ operation.fragment,
402
+ );
361
403
  applyWithGuard(
362
404
  updater,
363
405
  null,