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.
@@ -13,33 +13,14 @@
13
13
 
14
14
  'use strict';
15
15
 
16
- const OperationExecutor = require('./OperationExecutor');
17
- const RelayDefaultHandlerProvider = require('../handlers/RelayDefaultHandlerProvider');
18
- const RelayFeatureFlags = require('../util/RelayFeatureFlags');
19
- const RelayObservable = require('../network/RelayObservable');
20
- const RelayOperationTracker = require('../store/RelayOperationTracker');
21
- const RelayPublishQueue = require('./RelayPublishQueue');
22
- const RelayRecordSource = require('./RelayRecordSource');
23
-
24
- const defaultGetDataID = require('./defaultGetDataID');
25
- const defaultRequiredFieldLogger = require('./defaultRequiredFieldLogger');
26
- const generateID = require('../util/generateID');
27
- const invariant = require('invariant');
28
-
29
16
  import type {HandlerProvider} from '../handlers/RelayDefaultHandlerProvider';
17
+ import type {ActorIdentifier} from '../multi-actor-environment/ActorIdentifier';
30
18
  import type {
31
19
  GraphQLResponse,
32
20
  INetwork,
33
21
  PayloadData,
34
- UploadableMap,
35
22
  } from '../network/RelayNetworkTypes';
36
- import type {RequestParameters} from '../util/RelayConcreteNode';
37
- import type {
38
- CacheConfig,
39
- Disposable,
40
- RenderPolicy,
41
- Variables,
42
- } from '../util/RelayRuntimeTypes';
23
+ import type {Disposable, RenderPolicy} from '../util/RelayRuntimeTypes';
43
24
  import type {ActiveState, TaskScheduler} from './OperationExecutor';
44
25
  import type {GetDataID} from './RelayResponseNormalizer';
45
26
  import type {
@@ -47,6 +28,7 @@ import type {
47
28
  IEnvironment,
48
29
  LogFunction,
49
30
  MissingFieldHandler,
31
+ MutationParameters,
50
32
  OperationAvailability,
51
33
  OperationDescriptor,
52
34
  OperationLoader,
@@ -64,6 +46,23 @@ import type {
64
46
  StoreUpdater,
65
47
  } from './RelayStoreTypes';
66
48
 
49
+ const RelayDefaultHandlerProvider = require('../handlers/RelayDefaultHandlerProvider');
50
+ const {
51
+ INTERNAL_ACTOR_IDENTIFIER_DO_NOT_USE,
52
+ assertInternalActorIndentifier,
53
+ } = require('../multi-actor-environment/ActorIdentifier');
54
+ const RelayObservable = require('../network/RelayObservable');
55
+ const wrapNetworkWithLogObserver = require('../network/wrapNetworkWithLogObserver');
56
+ const RelayOperationTracker = require('../store/RelayOperationTracker');
57
+ const registerEnvironmentWithDevTools = require('../util/registerEnvironmentWithDevTools');
58
+ const RelayFeatureFlags = require('../util/RelayFeatureFlags');
59
+ const defaultGetDataID = require('./defaultGetDataID');
60
+ const defaultRequiredFieldLogger = require('./defaultRequiredFieldLogger');
61
+ const OperationExecutor = require('./OperationExecutor');
62
+ const RelayPublishQueue = require('./RelayPublishQueue');
63
+ const RelayRecordSource = require('./RelayRecordSource');
64
+ const invariant = require('invariant');
65
+
67
66
  export type EnvironmentConfig = {|
68
67
  +configName?: string,
69
68
  +handlerProvider?: ?HandlerProvider,
@@ -143,7 +142,7 @@ class RelayModernEnvironment implements IEnvironment {
143
142
  : 'full';
144
143
  this._operationLoader = operationLoader;
145
144
  this._operationExecutions = new Map();
146
- this._network = this.__wrapNetworkWithLogObserver(config.network);
145
+ this._network = wrapNetworkWithLogObserver(this, config.network);
147
146
  this._getDataID = config.getDataID ?? defaultGetDataID;
148
147
  this._publishQueue = new RelayPublishQueue(
149
148
  config.store,
@@ -156,31 +155,23 @@ class RelayModernEnvironment implements IEnvironment {
156
155
  this._isServer = config.isServer ?? false;
157
156
 
158
157
  (this: any).__setNet = newNet =>
159
- (this._network = this.__wrapNetworkWithLogObserver(newNet));
158
+ (this._network = wrapNetworkWithLogObserver(this, newNet));
160
159
 
161
160
  if (__DEV__) {
162
161
  const {inspect} = require('./StoreInspector');
163
162
  (this: any).DEBUG_inspect = (dataID: ?string) => inspect(this, dataID);
164
163
  }
165
164
 
166
- // Register this Relay Environment with Relay DevTools if it exists.
167
- // Note: this must always be the last step in the constructor.
168
- const _global =
169
- typeof global !== 'undefined'
170
- ? global
171
- : typeof window !== 'undefined'
172
- ? window
173
- : undefined;
174
- const devToolsHook = _global && _global.__RELAY_DEVTOOLS_HOOK__;
175
- if (devToolsHook) {
176
- devToolsHook.registerEnvironment(this);
177
- }
178
165
  this._missingFieldHandlers = config.missingFieldHandlers;
179
166
  this._operationTracker =
180
167
  config.operationTracker ?? new RelayOperationTracker();
181
168
  this._reactFlightPayloadDeserializer = reactFlightPayloadDeserializer;
182
169
  this._reactFlightServerErrorHandler = reactFlightServerErrorHandler;
183
170
  this._shouldProcessClientComponents = config.shouldProcessClientComponents;
171
+
172
+ // Register this Relay Environment with Relay DevTools if it exists.
173
+ // Note: this must always be the last step in the constructor.
174
+ registerEnvironmentWithDevTools(this);
184
175
  }
185
176
 
186
177
  getStore(): Store {
@@ -236,7 +227,9 @@ class RelayModernEnvironment implements IEnvironment {
236
227
  });
237
228
  }
238
229
 
239
- applyMutation(optimisticConfig: OptimisticResponseConfig): Disposable {
230
+ applyMutation<TMutation: MutationParameters>(
231
+ optimisticConfig: OptimisticResponseConfig<TMutation>,
232
+ ): Disposable {
240
233
  const subscription = this._execute({
241
234
  createSource: () => RelayObservable.create(_sink => {}),
242
235
  isClientPayload: false,
@@ -303,7 +296,19 @@ class RelayModernEnvironment implements IEnvironment {
303
296
  handlers: $ReadOnlyArray<MissingFieldHandler>,
304
297
  ): OperationAvailability {
305
298
  const target = RelayRecordSource.create();
306
- const result = this._store.check(operation, {target, handlers});
299
+ const source = this._store.getSource();
300
+ const result = this._store.check(operation, {
301
+ handlers,
302
+ defaultActorIdentifier: INTERNAL_ACTOR_IDENTIFIER_DO_NOT_USE,
303
+ getSourceForActor(actorIdentifier: ActorIdentifier) {
304
+ assertInternalActorIndentifier(actorIdentifier);
305
+ return source;
306
+ },
307
+ getTargetForActor(actorIdentifier: ActorIdentifier) {
308
+ assertInternalActorIndentifier(actorIdentifier);
309
+ return target;
310
+ },
311
+ });
307
312
  if (target.size() > 0) {
308
313
  this._scheduleUpdates(() => {
309
314
  this._publishQueue.commitSource(target);
@@ -324,7 +329,7 @@ class RelayModernEnvironment implements IEnvironment {
324
329
 
325
330
  /**
326
331
  * Returns an Observable of GraphQLResponse resulting from executing the
327
- * provided Query or Subscription operation, each result of which is then
332
+ * provided Query operation, each result of which is then
328
333
  * normalized and committed to the publish queue.
329
334
  *
330
335
  * Note: Observables are lazy, so calling this method will do nothing until
@@ -332,10 +337,38 @@ class RelayModernEnvironment implements IEnvironment {
332
337
  */
333
338
  execute({
334
339
  operation,
340
+ }: {|
341
+ operation: OperationDescriptor,
342
+ |}): RelayObservable<GraphQLResponse> {
343
+ return this._execute({
344
+ createSource: () =>
345
+ this._network.execute(
346
+ operation.request.node.params,
347
+ operation.request.variables,
348
+ operation.request.cacheConfig || {},
349
+ null,
350
+ ),
351
+ isClientPayload: false,
352
+ operation,
353
+ optimisticConfig: null,
354
+ updater: null,
355
+ });
356
+ }
357
+
358
+ /**
359
+ * Returns an Observable of GraphQLResponse resulting from executing the
360
+ * provided Subscription operation, each result of which is then
361
+ * normalized and committed to the publish queue.
362
+ *
363
+ * Note: Observables are lazy, so calling this method will do nothing until
364
+ * the result is subscribed to: environment.execute({...}).subscribe({...}).
365
+ */
366
+ executeSubscription<TMutation: MutationParameters>({
367
+ operation,
335
368
  updater,
336
369
  }: {|
337
370
  operation: OperationDescriptor,
338
- updater?: ?SelectorStoreUpdater,
371
+ updater?: ?SelectorStoreUpdater<TMutation['response']>,
339
372
  |}): RelayObservable<GraphQLResponse> {
340
373
  return this._execute({
341
374
  createSource: () =>
@@ -362,13 +395,13 @@ class RelayModernEnvironment implements IEnvironment {
362
395
  * the result is subscribed to:
363
396
  * environment.executeMutation({...}).subscribe({...}).
364
397
  */
365
- executeMutation({
398
+ executeMutation<TMutation: MutationParameters>({
366
399
  operation,
367
400
  optimisticResponse,
368
401
  optimisticUpdater,
369
402
  updater,
370
403
  uploadables,
371
- }: ExecuteMutationConfig): RelayObservable<GraphQLResponse> {
404
+ }: ExecuteMutationConfig<TMutation>): RelayObservable<GraphQLResponse> {
372
405
  let optimisticConfig;
373
406
  if (optimisticResponse || optimisticUpdater) {
374
407
  optimisticConfig = {
@@ -398,7 +431,7 @@ class RelayModernEnvironment implements IEnvironment {
398
431
  /**
399
432
  * Returns an Observable of GraphQLResponse resulting from executing the
400
433
  * provided Query or Subscription operation responses, the result of which is
401
- * then normalized and comitted to the publish queue.
434
+ * then normalized and committed to the publish queue.
402
435
  *
403
436
  * Note: Observables are lazy, so calling this method will do nothing until
404
437
  * the result is subscribed to:
@@ -424,7 +457,7 @@ class RelayModernEnvironment implements IEnvironment {
424
457
  return `RelayModernEnvironment(${this.configName ?? ''})`;
425
458
  }
426
459
 
427
- _execute({
460
+ _execute<TMutation: MutationParameters>({
428
461
  createSource,
429
462
  isClientPayload,
430
463
  operation,
@@ -434,19 +467,26 @@ class RelayModernEnvironment implements IEnvironment {
434
467
  createSource: () => RelayObservable<GraphQLResponse>,
435
468
  isClientPayload: boolean,
436
469
  operation: OperationDescriptor,
437
- optimisticConfig: ?OptimisticResponseConfig,
438
- updater: ?SelectorStoreUpdater,
470
+ optimisticConfig: ?OptimisticResponseConfig<TMutation>,
471
+ updater: ?SelectorStoreUpdater<TMutation['response']>,
439
472
  |}): RelayObservable<GraphQLResponse> {
473
+ const publishQueue = this._publishQueue;
474
+ const store = this._store;
440
475
  return RelayObservable.create(sink => {
441
476
  const executor = OperationExecutor.execute({
477
+ actorIdentifier: INTERNAL_ACTOR_IDENTIFIER_DO_NOT_USE,
442
478
  getDataID: this._getDataID,
443
479
  isClientPayload,
480
+ log: this.__log,
444
481
  operation,
445
482
  operationExecutions: this._operationExecutions,
446
483
  operationLoader: this._operationLoader,
447
484
  operationTracker: this._operationTracker,
448
485
  optimisticConfig,
449
- publishQueue: this._publishQueue,
486
+ getPublishQueue(actorIdentifier: ActorIdentifier) {
487
+ assertInternalActorIndentifier(actorIdentifier);
488
+ return publishQueue;
489
+ },
450
490
  reactFlightPayloadDeserializer: this._reactFlightPayloadDeserializer,
451
491
  reactFlightServerErrorHandler: this._reactFlightServerErrorHandler,
452
492
  scheduler: this._scheduler,
@@ -455,80 +495,16 @@ class RelayModernEnvironment implements IEnvironment {
455
495
  // NOTE: Some product tests expect `Network.execute` to be called only
456
496
  // when the Observable is executed.
457
497
  source: createSource(),
458
- store: this._store,
498
+ getStore(actorIdentifier: ActorIdentifier) {
499
+ assertInternalActorIndentifier(actorIdentifier);
500
+ return store;
501
+ },
459
502
  treatMissingFieldsAsNull: this._treatMissingFieldsAsNull,
460
503
  updater,
461
504
  });
462
505
  return () => executor.cancel();
463
506
  });
464
507
  }
465
-
466
- /**
467
- * Wraps the network with logging to ensure that network requests are
468
- * always logged. Relying on each network callsite to be wrapped is
469
- * untenable and will eventually lead to holes in the logging.
470
- */
471
- __wrapNetworkWithLogObserver(network: INetwork): INetwork {
472
- const that = this;
473
- return {
474
- execute(
475
- params: RequestParameters,
476
- variables: Variables,
477
- cacheConfig: CacheConfig,
478
- uploadables?: ?UploadableMap,
479
- ): RelayObservable<GraphQLResponse> {
480
- const transactionID = generateID();
481
- const log = that.__log;
482
- const logObserver = {
483
- start: subscription => {
484
- log({
485
- name: 'network.start',
486
- transactionID,
487
- params,
488
- variables,
489
- cacheConfig,
490
- });
491
- },
492
- next: response => {
493
- log({
494
- name: 'network.next',
495
- transactionID,
496
- response,
497
- });
498
- },
499
- error: error => {
500
- log({
501
- name: 'network.error',
502
- transactionID,
503
- error,
504
- });
505
- },
506
- complete: () => {
507
- log({
508
- name: 'network.complete',
509
- transactionID,
510
- });
511
- },
512
- unsubscribe: () => {
513
- log({
514
- name: 'network.unsubscribe',
515
- transactionID,
516
- });
517
- },
518
- };
519
- const logRequestInfo = info => {
520
- log({
521
- name: 'network.info',
522
- transactionID,
523
- info,
524
- });
525
- };
526
- return network
527
- .execute(params, variables, cacheConfig, uploadables, logRequestInfo)
528
- .do(logObserver);
529
- },
530
- };
531
- }
532
508
  }
533
509
 
534
510
  // Add a sigil for detection by `isRelayModernEnvironment()` to avoid a
@@ -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,29 +12,13 @@
12
12
 
13
13
  'use strict';
14
14
 
15
- const RelayFeatureFlags = require('../util/RelayFeatureFlags');
16
-
17
- const areEqual = require('areEqual');
18
- const invariant = require('invariant');
19
- const isScalarAndEqual = require('../util/isScalarAndEqual');
20
- const reportMissingRequiredFields = require('../util/reportMissingRequiredFields');
21
- const warning = require('warning');
22
-
23
- const {getPromiseForActiveRequest} = require('../query/fetchQueryInternal');
24
- const {createRequestDescriptor} = require('./RelayModernOperationDescriptor');
25
- const {
26
- areEqualSelectors,
27
- createReaderSelector,
28
- getSelectorsFromObject,
29
- } = require('./RelayModernSelector');
30
-
31
15
  import type {ConcreteRequest} from '../util/RelayConcreteNode';
32
16
  import type {Disposable, Variables} from '../util/RelayRuntimeTypes';
33
17
  import type {
34
- IEnvironment,
35
18
  FragmentMap,
36
19
  FragmentSpecResolver,
37
20
  FragmentSpecResults,
21
+ IEnvironment,
38
22
  MissingRequiredFields,
39
23
  PluralReaderSelector,
40
24
  RelayContext,
@@ -43,10 +27,25 @@ import type {
43
27
  Snapshot,
44
28
  } from './RelayStoreTypes';
45
29
 
30
+ const getPendingOperationsForFragment = require('../util/getPendingOperationsForFragment');
31
+ const isScalarAndEqual = require('../util/isScalarAndEqual');
32
+ const recycleNodesInto = require('../util/recycleNodesInto');
33
+ const RelayFeatureFlags = require('../util/RelayFeatureFlags');
34
+ const reportMissingRequiredFields = require('../util/reportMissingRequiredFields');
35
+ const {createRequestDescriptor} = require('./RelayModernOperationDescriptor');
36
+ const {
37
+ areEqualSelectors,
38
+ createReaderSelector,
39
+ getSelectorsFromObject,
40
+ } = require('./RelayModernSelector');
41
+ const areEqual = require('areEqual');
42
+ const invariant = require('invariant');
43
+ const warning = require('warning');
44
+
46
45
  type Props = {[key: string]: mixed, ...};
47
46
  type Resolvers = {
48
47
  [key: string]: ?(SelectorListResolver | SelectorResolver),
49
- ...,
48
+ ...
50
49
  };
51
50
 
52
51
  /**
@@ -137,13 +136,16 @@ class RelayModernFragmentSpecResolver implements FragmentSpecResolver {
137
136
  return this._data;
138
137
  }
139
138
 
140
- setCallback(callback: () => void): void {
139
+ setCallback(props: Props, callback: () => void): void {
141
140
  this._callback = callback;
141
+ if (RelayFeatureFlags.ENABLE_CONTAINERS_SUBSCRIBE_ON_COMMIT === true) {
142
+ this.setProps(props);
143
+ }
142
144
  }
143
145
 
144
146
  setProps(props: Props): void {
145
- const ownedSelectors = getSelectorsFromObject(this._fragments, props);
146
147
  this._props = {};
148
+ const ownedSelectors = getSelectorsFromObject(this._fragments, props);
147
149
 
148
150
  for (const key in ownedSelectors) {
149
151
  if (ownedSelectors.hasOwnProperty(key)) {
@@ -160,6 +162,7 @@ class RelayModernFragmentSpecResolver implements FragmentSpecResolver {
160
162
  this._context.environment,
161
163
  this._rootIsQueryRenderer,
162
164
  ownedSelector,
165
+ this._callback != null,
163
166
  this._onChange,
164
167
  );
165
168
  } else {
@@ -176,6 +179,7 @@ class RelayModernFragmentSpecResolver implements FragmentSpecResolver {
176
179
  this._context.environment,
177
180
  this._rootIsQueryRenderer,
178
181
  ownedSelector,
182
+ this._callback != null,
179
183
  this._onChange,
180
184
  );
181
185
  } else {
@@ -232,6 +236,7 @@ class SelectorResolver {
232
236
  environment: IEnvironment,
233
237
  rootIsQueryRenderer: boolean,
234
238
  selector: SingularReaderSelector,
239
+ subscribeOnConstruction: boolean,
235
240
  callback: () => void,
236
241
  ) {
237
242
  const snapshot = environment.lookup(selector);
@@ -242,7 +247,13 @@ class SelectorResolver {
242
247
  this._environment = environment;
243
248
  this._rootIsQueryRenderer = rootIsQueryRenderer;
244
249
  this._selector = selector;
245
- this._subscription = environment.subscribe(snapshot, this._onChange);
250
+ if (RelayFeatureFlags.ENABLE_CONTAINERS_SUBSCRIBE_ON_COMMIT === true) {
251
+ if (subscribeOnConstruction) {
252
+ this._subscription = environment.subscribe(snapshot, this._onChange);
253
+ }
254
+ } else {
255
+ this._subscription = environment.subscribe(snapshot, this._onChange);
256
+ }
246
257
  }
247
258
 
248
259
  dispose(): void {
@@ -253,10 +264,7 @@ class SelectorResolver {
253
264
  }
254
265
 
255
266
  resolve(): ?Object {
256
- if (
257
- RelayFeatureFlags.ENABLE_RELAY_CONTAINERS_SUSPENSE === true &&
258
- this._isMissingData === true
259
- ) {
267
+ if (this._isMissingData === true) {
260
268
  // NOTE: This branch exists to handle the case in which:
261
269
  // - A RelayModern container is rendered as a descendant of a Relay Hook
262
270
  // root using a "partial" renderPolicy (this means that eargerly
@@ -278,11 +286,12 @@ class SelectorResolver {
278
286
  // This should eventually go away with something like @optional, where we only
279
287
  // suspend at specific boundaries depending on whether the boundary
280
288
  // can be fulfilled or not.
281
- const promise =
282
- getPromiseForActiveRequest(this._environment, this._selector.owner) ??
283
- this._environment
284
- .getOperationTracker()
285
- .getPromiseForPendingOperationsAffectingOwner(this._selector.owner);
289
+ const pendingOperationsResult = getPendingOperationsForFragment(
290
+ this._environment,
291
+ this._selector.node,
292
+ this._selector.owner,
293
+ );
294
+ const promise: void | Promise<void> = pendingOperationsResult?.promise;
286
295
  if (promise != null) {
287
296
  if (this._rootIsQueryRenderer) {
288
297
  warning(
@@ -293,6 +302,8 @@ class SelectorResolver {
293
302
  this._selector.node.name,
294
303
  );
295
304
  } else {
305
+ const pendingOperations =
306
+ pendingOperationsResult?.pendingOperations ?? [];
296
307
  warning(
297
308
  false,
298
309
  'Relay: Relay Container for fragment `%s` suspended. When using ' +
@@ -300,6 +311,15 @@ class SelectorResolver {
300
311
  'of a Relay Container.',
301
312
  this._selector.node.name,
302
313
  );
314
+ this._environment.__log({
315
+ name: 'suspense.fragment',
316
+ data: this._data,
317
+ fragment: this._selector.node,
318
+ isRelayHooks: false,
319
+ isMissingData: this._isMissingData,
320
+ isPromiseCached: false,
321
+ pendingOperations,
322
+ });
303
323
  throw promise;
304
324
  }
305
325
  }
@@ -322,7 +342,7 @@ class SelectorResolver {
322
342
  }
323
343
  this.dispose();
324
344
  const snapshot = this._environment.lookup(selector);
325
- this._data = snapshot.data;
345
+ this._data = recycleNodesInto(this._data, snapshot.data);
326
346
  this._isMissingData = snapshot.isMissingData;
327
347
  this._missingRequiredFields = snapshot.missingRequiredFields;
328
348
  this._selector = selector;
@@ -375,11 +395,13 @@ class SelectorListResolver {
375
395
  _resolvers: Array<SelectorResolver>;
376
396
  _rootIsQueryRenderer: boolean;
377
397
  _stale: boolean;
398
+ _subscribeOnConstruction: boolean;
378
399
 
379
400
  constructor(
380
401
  environment: IEnvironment,
381
402
  rootIsQueryRenderer: boolean,
382
403
  selector: PluralReaderSelector,
404
+ subscribeOnConstruction: boolean,
383
405
  callback: () => void,
384
406
  ) {
385
407
  this._callback = callback;
@@ -388,6 +410,7 @@ class SelectorListResolver {
388
410
  this._resolvers = [];
389
411
  this._stale = true;
390
412
  this._rootIsQueryRenderer = rootIsQueryRenderer;
413
+ this._subscribeOnConstruction = subscribeOnConstruction;
391
414
 
392
415
  this.setSelector(selector);
393
416
  }
@@ -433,6 +456,7 @@ class SelectorListResolver {
433
456
  this._environment,
434
457
  this._rootIsQueryRenderer,
435
458
  selectors[ii],
459
+ this._subscribeOnConstruction,
436
460
  this._onChange,
437
461
  );
438
462
  }
@@ -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,9 +12,18 @@
12
12
 
13
13
  'use strict';
14
14
 
15
+ import type {ConcreteRequest} from '../util/RelayConcreteNode';
16
+ import type {
17
+ CacheConfig,
18
+ DataID,
19
+ OperationType,
20
+ Variables,
21
+ VariablesOf,
22
+ } from '../util/RelayRuntimeTypes';
23
+ import type {OperationDescriptor, RequestDescriptor} from './RelayStoreTypes';
24
+
15
25
  const deepFreeze = require('../util/deepFreeze');
16
26
  const getRequestIdentifier = require('../util/getRequestIdentifier');
17
-
18
27
  const {getOperationVariables} = require('./RelayConcreteVariables');
19
28
  const {
20
29
  createNormalizationSelector,
@@ -22,19 +31,15 @@ const {
22
31
  } = require('./RelayModernSelector');
23
32
  const {ROOT_ID} = require('./RelayStoreUtils');
24
33
 
25
- import type {ConcreteRequest} from '../util/RelayConcreteNode';
26
- import type {CacheConfig, DataID, Variables} from '../util/RelayRuntimeTypes';
27
- import type {OperationDescriptor, RequestDescriptor} from './RelayStoreTypes';
28
-
29
34
  /**
30
35
  * Creates an instance of the `OperationDescriptor` type defined in
31
36
  * `RelayStoreTypes` given an operation and some variables. The input variables
32
37
  * are filtered to exclude variables that do not match defined arguments on the
33
38
  * operation, and default values are populated for null values.
34
39
  */
35
- function createOperationDescriptor(
40
+ function createOperationDescriptor<TQuery: OperationType>(
36
41
  request: ConcreteRequest,
37
- variables: Variables,
42
+ variables: VariablesOf<TQuery>,
38
43
  cacheConfig?: ?CacheConfig,
39
44
  dataID?: DataID = ROOT_ID,
40
45
  ): OperationDescriptor {