react-relay 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 (177) hide show
  1. package/README.md +47 -0
  2. package/ReactRelayContainerUtils.js.flow +1 -1
  3. package/ReactRelayContext.js +1 -1
  4. package/ReactRelayContext.js.flow +3 -4
  5. package/ReactRelayFragmentContainer.js.flow +25 -25
  6. package/ReactRelayFragmentMockRenderer.js.flow +2 -2
  7. package/ReactRelayLocalQueryRenderer.js.flow +7 -8
  8. package/ReactRelayPaginationContainer.js.flow +112 -59
  9. package/ReactRelayQueryFetcher.js.flow +10 -11
  10. package/ReactRelayQueryRenderer.js.flow +116 -82
  11. package/ReactRelayQueryRendererContext.js.flow +1 -1
  12. package/ReactRelayRefetchContainer.js.flow +42 -39
  13. package/ReactRelayTestMocker.js.flow +17 -15
  14. package/ReactRelayTypes.js.flow +11 -11
  15. package/RelayContext.js.flow +4 -4
  16. package/__flowtests__/ReactRelayFragmentContainer-flowtest.js.flow +2 -3
  17. package/__flowtests__/ReactRelayPaginationContainer-flowtest.js.flow +12 -8
  18. package/__flowtests__/ReactRelayRefetchContainer-flowtest.js.flow +11 -7
  19. package/__flowtests__/RelayModern-flowtest.js.flow +79 -47
  20. package/__flowtests__/RelayModernFlowtest_badref.graphql.js.flow +6 -5
  21. package/__flowtests__/RelayModernFlowtest_notref.graphql.js.flow +6 -5
  22. package/__flowtests__/RelayModernFlowtest_user.graphql.js.flow +5 -4
  23. package/__flowtests__/RelayModernFlowtest_users.graphql.js.flow +5 -4
  24. package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer.graphql.js.flow +72 -0
  25. package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer2.graphql.js.flow +72 -0
  26. package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtestQuery.graphql.js.flow +227 -0
  27. package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtest_viewer.graphql.js.flow +164 -0
  28. package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtestQuery.graphql.js.flow +227 -0
  29. package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtest_viewer.graphql.js.flow +164 -0
  30. package/__flowtests__/__generated__/RelayModernFlowtest_badref.graphql.js.flow +66 -0
  31. package/__flowtests__/__generated__/RelayModernFlowtest_notref.graphql.js.flow +66 -0
  32. package/__flowtests__/__generated__/RelayModernFlowtest_user.graphql.js.flow +59 -0
  33. package/__flowtests__/__generated__/RelayModernFlowtest_users.graphql.js.flow +61 -0
  34. package/assertFragmentMap.js.flow +3 -3
  35. package/buildReactRelayContainer.js.flow +12 -11
  36. package/getRootVariablesForFragments.js.flow +3 -5
  37. package/hooks.js +1 -1
  38. package/hooks.js.flow +6 -7
  39. package/index.js +1 -1
  40. package/index.js.flow +7 -8
  41. package/isRelayEnvironment.js.flow +1 -1
  42. package/jest-react/enqueueTask.js.flow +56 -0
  43. package/jest-react/index.js.flow +12 -0
  44. package/jest-react/internalAct.js.flow +138 -0
  45. package/legacy.js +1 -1
  46. package/legacy.js.flow +1 -1
  47. package/lib/ReactRelayContainerUtils.js +1 -1
  48. package/lib/ReactRelayContext.js +1 -1
  49. package/lib/ReactRelayFragmentContainer.js +22 -16
  50. package/lib/ReactRelayFragmentMockRenderer.js +3 -3
  51. package/lib/ReactRelayLocalQueryRenderer.js +8 -9
  52. package/lib/ReactRelayPaginationContainer.js +97 -39
  53. package/lib/ReactRelayQueryFetcher.js +3 -3
  54. package/lib/ReactRelayQueryRenderer.js +87 -54
  55. package/lib/ReactRelayQueryRendererContext.js +1 -1
  56. package/lib/ReactRelayRefetchContainer.js +39 -26
  57. package/lib/ReactRelayTestMocker.js +8 -9
  58. package/lib/ReactRelayTypes.js +1 -1
  59. package/lib/RelayContext.js +4 -3
  60. package/lib/assertFragmentMap.js +3 -2
  61. package/lib/buildReactRelayContainer.js +8 -8
  62. package/lib/getRootVariablesForFragments.js +2 -3
  63. package/lib/hooks.js +6 -6
  64. package/lib/index.js +8 -8
  65. package/lib/isRelayEnvironment.js +1 -1
  66. package/lib/jest-react/enqueueTask.js +53 -0
  67. package/lib/jest-react/index.js +13 -0
  68. package/lib/jest-react/internalAct.js +115 -0
  69. package/lib/legacy.js +1 -1
  70. package/lib/multi-actor/ActorChange.js +30 -0
  71. package/lib/multi-actor/index.js +11 -0
  72. package/lib/multi-actor/useRelayActorEnvironment.js +29 -0
  73. package/lib/readContext.js +1 -1
  74. package/lib/relay-hooks/EntryPointContainer.react.js +4 -4
  75. package/lib/relay-hooks/EntryPointTypes.flow.js +1 -1
  76. package/lib/relay-hooks/FragmentResource.js +342 -89
  77. package/lib/relay-hooks/InternalLogger.js +1 -1
  78. package/lib/relay-hooks/LRUCache.js +1 -1
  79. package/lib/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js +5 -5
  80. package/lib/relay-hooks/MatchContainer.js +2 -2
  81. package/lib/relay-hooks/ProfilerContext.js +1 -1
  82. package/lib/relay-hooks/QueryResource.js +172 -29
  83. package/lib/relay-hooks/RelayEnvironmentProvider.js +6 -4
  84. package/lib/relay-hooks/SuspenseResource.js +130 -0
  85. package/lib/relay-hooks/loadEntryPoint.js +1 -1
  86. package/lib/relay-hooks/loadQuery.js +42 -20
  87. package/lib/relay-hooks/preloadQuery_DEPRECATED.js +25 -16
  88. package/lib/relay-hooks/prepareEntryPoint_DEPRECATED.js +1 -1
  89. package/lib/relay-hooks/useBlockingPaginationFragment.js +5 -6
  90. package/lib/relay-hooks/useEntryPointLoader.js +3 -3
  91. package/lib/relay-hooks/useFetchTrackingRef.js +3 -2
  92. package/lib/relay-hooks/useFragment.js +7 -7
  93. package/lib/relay-hooks/useFragmentNode.js +5 -5
  94. package/lib/relay-hooks/useIsMountedRef.js +1 -1
  95. package/lib/relay-hooks/useIsOperationNodeActive.js +3 -3
  96. package/lib/relay-hooks/useIsParentQueryActive.js +1 -1
  97. package/lib/relay-hooks/useLazyLoadQuery.js +4 -4
  98. package/lib/relay-hooks/useLazyLoadQueryNode.js +11 -5
  99. package/lib/relay-hooks/useLoadMoreFunction.js +9 -13
  100. package/lib/relay-hooks/useMemoOperationDescriptor.js +3 -3
  101. package/lib/relay-hooks/useMemoVariables.js +3 -3
  102. package/lib/relay-hooks/useMutation.js +18 -7
  103. package/lib/relay-hooks/usePaginationFragment.js +3 -4
  104. package/lib/relay-hooks/usePreloadedQuery.js +6 -6
  105. package/lib/relay-hooks/useQueryLoader.js +31 -11
  106. package/lib/relay-hooks/useRefetchableFragment.js +1 -1
  107. package/lib/relay-hooks/useRefetchableFragmentNode.js +14 -18
  108. package/lib/relay-hooks/useRelayEnvironment.js +3 -3
  109. package/lib/relay-hooks/useStaticFragmentNodeWarning.js +3 -3
  110. package/lib/relay-hooks/useSubscribeToInvalidationState.js +3 -2
  111. package/lib/relay-hooks/useSubscription.js +11 -8
  112. package/multi-actor/ActorChange.js.flow +58 -0
  113. package/multi-actor/index.js.flow +14 -0
  114. package/multi-actor/useRelayActorEnvironment.js.flow +49 -0
  115. package/package.json +3 -3
  116. package/react-relay-hooks.js +2 -2
  117. package/react-relay-hooks.min.js +2 -2
  118. package/react-relay-legacy.js +2 -2
  119. package/react-relay-legacy.min.js +2 -2
  120. package/react-relay.js +2 -2
  121. package/react-relay.min.js +2 -2
  122. package/readContext.js.flow +1 -1
  123. package/relay-hooks/EntryPointContainer.react.js.flow +9 -16
  124. package/relay-hooks/EntryPointTypes.flow.js.flow +25 -26
  125. package/relay-hooks/FragmentResource.js.flow +359 -93
  126. package/relay-hooks/InternalLogger.js.flow +1 -1
  127. package/relay-hooks/LRUCache.js.flow +1 -1
  128. package/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js.flow +33 -47
  129. package/relay-hooks/MatchContainer.js.flow +4 -3
  130. package/relay-hooks/ProfilerContext.js.flow +1 -1
  131. package/relay-hooks/QueryResource.js.flow +217 -26
  132. package/relay-hooks/RelayEnvironmentProvider.js.flow +15 -5
  133. package/relay-hooks/SuspenseResource.js.flow +115 -0
  134. package/relay-hooks/__flowtests__/EntryPointTypes/EntryPointElementConfig-flowtest.js.flow +5 -4
  135. package/relay-hooks/__flowtests__/EntryPointTypes/NestedEntrypoints-flowtest.js.flow +2 -2
  136. package/relay-hooks/__flowtests__/__generated__/useFragmentFlowtest_user.graphql.js.flow +59 -0
  137. package/relay-hooks/__flowtests__/__generated__/useFragmentFlowtest_users.graphql.js.flow +61 -0
  138. package/relay-hooks/__flowtests__/useBlockingPaginationFragment-flowtest.js.flow +11 -10
  139. package/relay-hooks/__flowtests__/useFragment-flowtest.js.flow +55 -32
  140. package/relay-hooks/__flowtests__/usePaginationFragment-flowtest.js.flow +11 -10
  141. package/relay-hooks/__flowtests__/useRefetchableFragment-flowtest.js.flow +11 -10
  142. package/relay-hooks/__flowtests__/utils.js.flow +21 -32
  143. package/relay-hooks/loadEntryPoint.js.flow +7 -13
  144. package/relay-hooks/loadQuery.js.flow +50 -32
  145. package/relay-hooks/preloadQuery_DEPRECATED.js.flow +31 -22
  146. package/relay-hooks/prepareEntryPoint_DEPRECATED.js.flow +7 -13
  147. package/relay-hooks/useBlockingPaginationFragment.js.flow +14 -12
  148. package/relay-hooks/useEntryPointLoader.js.flow +8 -11
  149. package/relay-hooks/useFetchTrackingRef.js.flow +3 -3
  150. package/relay-hooks/useFragment.js.flow +31 -62
  151. package/relay-hooks/useFragmentNode.js.flow +6 -8
  152. package/relay-hooks/useIsMountedRef.js.flow +1 -1
  153. package/relay-hooks/useIsOperationNodeActive.js.flow +4 -6
  154. package/relay-hooks/useIsParentQueryActive.js.flow +4 -5
  155. package/relay-hooks/useLazyLoadQuery.js.flow +14 -16
  156. package/relay-hooks/useLazyLoadQueryNode.js.flow +20 -14
  157. package/relay-hooks/useLoadMoreFunction.js.flow +21 -30
  158. package/relay-hooks/useMemoOperationDescriptor.js.flow +6 -8
  159. package/relay-hooks/useMemoVariables.js.flow +7 -7
  160. package/relay-hooks/useMutation.js.flow +27 -27
  161. package/relay-hooks/usePaginationFragment.js.flow +39 -45
  162. package/relay-hooks/usePreloadedQuery.js.flow +14 -20
  163. package/relay-hooks/useQueryLoader.js.flow +42 -23
  164. package/relay-hooks/useRefetchableFragment.js.flow +8 -9
  165. package/relay-hooks/useRefetchableFragmentNode.js.flow +25 -33
  166. package/relay-hooks/useRelayEnvironment.js.flow +3 -5
  167. package/relay-hooks/useStaticFragmentNodeWarning.js.flow +3 -4
  168. package/relay-hooks/useSubscribeToInvalidationState.js.flow +4 -7
  169. package/relay-hooks/useSubscription.js.flow +21 -11
  170. package/lib/relay-hooks/getPaginationMetadata.js +0 -41
  171. package/lib/relay-hooks/getPaginationVariables.js +0 -67
  172. package/lib/relay-hooks/getRefetchMetadata.js +0 -36
  173. package/lib/relay-hooks/getValueAtPath.js +0 -51
  174. package/relay-hooks/getPaginationMetadata.js.flow +0 -74
  175. package/relay-hooks/getPaginationVariables.js.flow +0 -110
  176. package/relay-hooks/getRefetchMetadata.js.flow +0 -80
  177. package/relay-hooks/getValueAtPath.js.flow +0 -46
@@ -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,6 @@
12
12
 
13
13
  'use strict';
14
14
 
15
- const React = require('react');
16
- const ReactRelayContext = require('./ReactRelayContext');
17
- const ReactRelayQueryFetcher = require('./ReactRelayQueryFetcher');
18
- const ReactRelayQueryRendererContext = require('./ReactRelayQueryRendererContext');
19
-
20
- const areEqual = require('areEqual');
21
-
22
- const {
23
- createOperationDescriptor,
24
- deepFreeze,
25
- getRequest,
26
- } = require('relay-runtime');
27
-
28
15
  import type {ReactRelayQueryRendererContext as ReactRelayQueryRendererContextType} from './ReactRelayQueryRendererContext';
29
16
  import type {
30
17
  CacheConfig,
@@ -35,7 +22,20 @@ import type {
35
22
  Snapshot,
36
23
  Variables,
37
24
  } from 'relay-runtime';
38
- type RetryCallbacks = {
25
+
26
+ const ReactRelayContext = require('./ReactRelayContext');
27
+ const ReactRelayQueryFetcher = require('./ReactRelayQueryFetcher');
28
+ const ReactRelayQueryRendererContext = require('./ReactRelayQueryRendererContext');
29
+ const areEqual = require('areEqual');
30
+ const React = require('react');
31
+ const {
32
+ RelayFeatureFlags,
33
+ createOperationDescriptor,
34
+ deepFreeze,
35
+ getRequest,
36
+ } = require('relay-runtime');
37
+
38
+ type RetryCallbacks = {|
39
39
  handleDataChange:
40
40
  | null
41
41
  | (({
@@ -44,8 +44,7 @@ type RetryCallbacks = {
44
44
  ...
45
45
  }) => void),
46
46
  handleRetryAfterError: null | ((error: Error) => void),
47
- ...
48
- };
47
+ |};
49
48
 
50
49
  export type RenderProps<T> = {|
51
50
  error: ?Error,
@@ -96,6 +95,8 @@ type State = {|
96
95
  * - Subscribes for updates to the root data and re-renders with any changes.
97
96
  */
98
97
  class ReactRelayQueryRenderer extends React.Component<Props, State> {
98
+ _maybeHiddenOrFastRefresh: boolean;
99
+
99
100
  constructor(props: Props) {
100
101
  super(props);
101
102
 
@@ -124,6 +125,8 @@ class ReactRelayQueryRenderer extends React.Component<Props, State> {
124
125
  queryFetcher = new ReactRelayQueryFetcher();
125
126
  }
126
127
 
128
+ this._maybeHiddenOrFastRefresh = false;
129
+
127
130
  this.state = {
128
131
  prevPropsEnvironment: props.environment,
129
132
  prevPropsVariables: props.variables,
@@ -148,77 +151,37 @@ class ReactRelayQueryRenderer extends React.Component<Props, State> {
148
151
  prevState.prevPropsEnvironment !== nextProps.environment ||
149
152
  !areEqual(prevState.prevPropsVariables, nextProps.variables)
150
153
  ) {
151
- const {query} = nextProps;
152
- const prevSelectionReferences = prevState.queryFetcher.getSelectionReferences();
153
- prevState.queryFetcher.disposeRequest();
154
-
155
- let queryFetcher;
156
- if (query) {
157
- const request = getRequest(query);
158
- const requestCacheKey = getRequestCacheKey(
159
- request.params,
160
- nextProps.variables,
161
- );
162
- queryFetcher = requestCache[requestCacheKey]
163
- ? requestCache[requestCacheKey].queryFetcher
164
- : new ReactRelayQueryFetcher(prevSelectionReferences);
165
- } else {
166
- queryFetcher = new ReactRelayQueryFetcher(prevSelectionReferences);
167
- }
168
- return {
169
- prevQuery: nextProps.query,
170
- prevPropsEnvironment: nextProps.environment,
171
- prevPropsVariables: nextProps.variables,
172
- queryFetcher: queryFetcher,
173
- ...fetchQueryAndComputeStateFromProps(
174
- nextProps,
175
- queryFetcher,
176
- prevState.retryCallbacks,
177
- // passing no requestCacheKey will cause it to be recalculated internally
178
- // and we want the updated requestCacheKey, since variables may have changed
179
- ),
180
- };
154
+ return resetQueryStateForUpdate(nextProps, prevState);
181
155
  }
182
-
183
156
  return null;
184
157
  }
185
158
 
186
159
  componentDidMount() {
160
+ if (
161
+ RelayFeatureFlags.ENABLE_QUERY_RENDERER_OFFSCREEN_SUPPORT === true &&
162
+ this._maybeHiddenOrFastRefresh === true
163
+ ) {
164
+ // This block only runs if the component has previously "unmounted"
165
+ // due to it being hidden by the Offscreen API, or during fast refresh.
166
+ // At this point, the current cached resource will have been disposed
167
+ // by the previous cleanup, so instead of attempting to
168
+ // do our regular commit setup, so that the query is re-evaluated
169
+ // (and potentially cause a refetch).
170
+ this._maybeHiddenOrFastRefresh = false;
171
+ // eslint-disable-next-line react/no-did-mount-set-state
172
+ this.setState(prevState => {
173
+ return resetQueryStateForUpdate(this.props, prevState);
174
+ });
175
+ return;
176
+ }
177
+
187
178
  const {retryCallbacks, queryFetcher, requestCacheKey} = this.state;
179
+ // We don't need to cache the request after the component commits
188
180
  if (requestCacheKey) {
189
181
  delete requestCache[requestCacheKey];
190
182
  }
191
183
 
192
- retryCallbacks.handleDataChange = (params: {
193
- error?: Error,
194
- snapshot?: Snapshot,
195
- ...
196
- }): void => {
197
- const error = params.error == null ? null : params.error;
198
- const snapshot = params.snapshot == null ? null : params.snapshot;
199
-
200
- this.setState(prevState => {
201
- const {requestCacheKey: prevRequestCacheKey} = prevState;
202
- if (prevRequestCacheKey) {
203
- delete requestCache[prevRequestCacheKey];
204
- }
205
-
206
- // Don't update state if nothing has changed.
207
- if (snapshot === prevState.snapshot && error === prevState.error) {
208
- return null;
209
- }
210
- return {
211
- renderProps: getRenderProps(
212
- error,
213
- snapshot,
214
- prevState.queryFetcher,
215
- prevState.retryCallbacks,
216
- ),
217
- snapshot,
218
- requestCacheKey: null,
219
- };
220
- });
221
- };
184
+ retryCallbacks.handleDataChange = this._handleDataChange;
222
185
 
223
186
  retryCallbacks.handleRetryAfterError = (error: Error) =>
224
187
  this.setState(prevState => {
@@ -236,22 +199,27 @@ class ReactRelayQueryRenderer extends React.Component<Props, State> {
236
199
  // Re-initialize the ReactRelayQueryFetcher with callbacks.
237
200
  // If data has changed since constructions, this will re-render.
238
201
  if (this.props.query) {
239
- queryFetcher.setOnDataChange(retryCallbacks.handleDataChange);
202
+ queryFetcher.setOnDataChange(this._handleDataChange);
240
203
  }
241
204
  }
242
205
 
243
- componentDidUpdate(): void {
206
+ componentDidUpdate(_prevProps: Props, prevState: State): void {
244
207
  // We don't need to cache the request after the component commits
245
- const {requestCacheKey} = this.state;
208
+ const {queryFetcher, requestCacheKey} = this.state;
246
209
  if (requestCacheKey) {
247
210
  delete requestCache[requestCacheKey];
248
211
  // HACK
249
212
  delete this.state.requestCacheKey;
250
213
  }
214
+
215
+ if (this.props.query && queryFetcher !== prevState.queryFetcher) {
216
+ queryFetcher.setOnDataChange(this._handleDataChange);
217
+ }
251
218
  }
252
219
 
253
220
  componentWillUnmount(): void {
254
221
  this.state.queryFetcher.dispose();
222
+ this._maybeHiddenOrFastRefresh = true;
255
223
  }
256
224
 
257
225
  shouldComponentUpdate(nextProps: Props, nextState: State): boolean {
@@ -261,6 +229,37 @@ class ReactRelayQueryRenderer extends React.Component<Props, State> {
261
229
  );
262
230
  }
263
231
 
232
+ _handleDataChange = (params: {
233
+ error?: Error,
234
+ snapshot?: Snapshot,
235
+ ...
236
+ }): void => {
237
+ const error = params.error == null ? null : params.error;
238
+ const snapshot = params.snapshot == null ? null : params.snapshot;
239
+
240
+ this.setState(prevState => {
241
+ const {requestCacheKey: prevRequestCacheKey} = prevState;
242
+ if (prevRequestCacheKey) {
243
+ delete requestCache[prevRequestCacheKey];
244
+ }
245
+
246
+ // Don't update state if nothing has changed.
247
+ if (snapshot === prevState.snapshot && error === prevState.error) {
248
+ return null;
249
+ }
250
+ return {
251
+ renderProps: getRenderProps(
252
+ error,
253
+ snapshot,
254
+ prevState.queryFetcher,
255
+ prevState.retryCallbacks,
256
+ ),
257
+ snapshot,
258
+ requestCacheKey: null,
259
+ };
260
+ });
261
+ };
262
+
264
263
  render(): React.Element<typeof ReactRelayContext.Provider> {
265
264
  const {renderProps, relayContext} = this.state;
266
265
  // Note that the root fragment results in `renderProps.props` is already
@@ -334,6 +333,41 @@ function getRequestCacheKey(
334
333
  });
335
334
  }
336
335
 
336
+ function resetQueryStateForUpdate(
337
+ props: Props,
338
+ prevState: State,
339
+ ): $Shape<State> {
340
+ const {query} = props;
341
+
342
+ const prevSelectionReferences =
343
+ prevState.queryFetcher.getSelectionReferences();
344
+ prevState.queryFetcher.disposeRequest();
345
+
346
+ let queryFetcher;
347
+ if (query) {
348
+ const request = getRequest(query);
349
+ const requestCacheKey = getRequestCacheKey(request.params, props.variables);
350
+ queryFetcher = requestCache[requestCacheKey]
351
+ ? requestCache[requestCacheKey].queryFetcher
352
+ : new ReactRelayQueryFetcher(prevSelectionReferences);
353
+ } else {
354
+ queryFetcher = new ReactRelayQueryFetcher(prevSelectionReferences);
355
+ }
356
+ return {
357
+ prevQuery: props.query,
358
+ prevPropsEnvironment: props.environment,
359
+ prevPropsVariables: props.variables,
360
+ queryFetcher: queryFetcher,
361
+ ...fetchQueryAndComputeStateFromProps(
362
+ props,
363
+ queryFetcher,
364
+ prevState.retryCallbacks,
365
+ // passing no requestCacheKey will cause it to be recalculated internally
366
+ // and we want the updated requestCacheKey, since variables may have changed
367
+ ),
368
+ };
369
+ }
370
+
337
371
  function fetchQueryAndComputeStateFromProps(
338
372
  props: Props,
339
373
  queryFetcher: ReactRelayQueryFetcher,
@@ -390,7 +424,7 @@ function fetchQueryAndComputeStateFromProps(
390
424
  );
391
425
  const querySnapshot = queryFetcher.fetch({
392
426
  environment: genericEnvironment,
393
- onDataChange: retryCallbacks.handleDataChange,
427
+ onDataChange: null,
394
428
  operation,
395
429
  });
396
430
 
@@ -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.
@@ -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,34 +12,12 @@
12
12
 
13
13
  'use strict';
14
14
 
15
- const React = require('react');
16
- const ReactRelayContext = require('./ReactRelayContext');
17
- const ReactRelayQueryFetcher = require('./ReactRelayQueryFetcher');
18
-
19
- const areEqual = require('areEqual');
20
- const buildReactRelayContainer = require('./buildReactRelayContainer');
21
- const getRootVariablesForFragments = require('./getRootVariablesForFragments');
22
- const warning = require('warning');
23
-
24
- const {getContainerName} = require('./ReactRelayContainerUtils');
25
- const {assertRelayContext} = require('./RelayContext');
26
- const {
27
- Observable,
28
- createFragmentSpecResolver,
29
- createOperationDescriptor,
30
- getDataIDsFromObject,
31
- getRequest,
32
- getSelector,
33
- getVariablesFromObject,
34
- isScalarAndEqual,
35
- } = require('relay-runtime');
36
-
37
15
  import type {
38
- $RelayProps,
39
- ObserverOrCallback,
40
16
  GeneratedNodeMap,
17
+ ObserverOrCallback,
41
18
  RefetchOptions,
42
19
  RelayRefetchProp,
20
+ $RelayProps,
43
21
  } from './ReactRelayTypes';
44
22
  import type {
45
23
  CacheConfig,
@@ -52,6 +30,25 @@ import type {
52
30
  } from 'relay-runtime';
53
31
  import type {FragmentSpecResolver} from 'relay-runtime';
54
32
 
33
+ const buildReactRelayContainer = require('./buildReactRelayContainer');
34
+ const getRootVariablesForFragments = require('./getRootVariablesForFragments');
35
+ const {getContainerName} = require('./ReactRelayContainerUtils');
36
+ const ReactRelayContext = require('./ReactRelayContext');
37
+ const ReactRelayQueryFetcher = require('./ReactRelayQueryFetcher');
38
+ const {assertRelayContext} = require('./RelayContext');
39
+ const areEqual = require('areEqual');
40
+ const React = require('react');
41
+ const {
42
+ Observable,
43
+ createFragmentSpecResolver,
44
+ createOperationDescriptor,
45
+ getDataIDsFromObject,
46
+ getRequest,
47
+ getVariablesFromObject,
48
+ isScalarAndEqual,
49
+ } = require('relay-runtime');
50
+ const warning = require('warning');
51
+
55
52
  type ContainerProps = $FlowFixMeProps;
56
53
 
57
54
  type ContainerState = {
@@ -119,7 +116,7 @@ function createContainerWithFragments<
119
116
 
120
117
  componentDidMount() {
121
118
  this._isUnmounted = false;
122
- this._subscribeToNewResolver();
119
+ this._subscribeToNewResolverAndRerenderIfStoreHasChanged();
123
120
  }
124
121
 
125
122
  componentDidUpdate(prevProps: ContainerProps, prevState: ContainerState) {
@@ -133,7 +130,9 @@ function createContainerWithFragments<
133
130
  this._queryFetcher && this._queryFetcher.dispose();
134
131
  this._refetchSubscription && this._refetchSubscription.unsubscribe();
135
132
 
136
- this._subscribeToNewResolver();
133
+ this._subscribeToNewResolverAndRerenderIfStoreHasChanged();
134
+ } else {
135
+ this._rerenderIfStoreHasChanged();
137
136
  }
138
137
  }
139
138
 
@@ -250,16 +249,26 @@ function createContainerWithFragments<
250
249
  return false;
251
250
  }
252
251
 
253
- _subscribeToNewResolver() {
252
+ _rerenderIfStoreHasChanged() {
254
253
  const {data, resolver} = this.state;
254
+ // External values could change between render and commit.
255
+ // Check for this case, even though it requires an extra store read.
256
+ const maybeNewData = resolver.resolve();
257
+ if (data !== maybeNewData) {
258
+ this.setState({data: maybeNewData});
259
+ }
260
+ }
261
+
262
+ _subscribeToNewResolverAndRerenderIfStoreHasChanged() {
263
+ const {data, resolver} = this.state;
264
+ const maybeNewData = resolver.resolve();
255
265
 
256
266
  // Event listeners are only safe to add during the commit phase,
257
267
  // So they won't leak if render is interrupted or errors.
258
- resolver.setCallback(this._handleFragmentDataUpdate);
268
+ resolver.setCallback(this.props, this._handleFragmentDataUpdate);
259
269
 
260
270
  // External values could change between render and commit.
261
271
  // Check for this case, even though it requires an extra store read.
262
- const maybeNewData = resolver.resolve();
263
272
  if (data !== maybeNewData) {
264
273
  this.setState({data: maybeNewData});
265
274
  }
@@ -321,11 +330,9 @@ function createContainerWithFragments<
321
330
  typeof refetchVariables === 'function'
322
331
  ? refetchVariables(this._getFragmentVariables())
323
332
  : refetchVariables;
324
- // $FlowFixMe[cannot-spread-interface]
325
333
  fetchVariables = {...rootVariables, ...fetchVariables};
326
334
  const fragmentVariables = renderVariables
327
- ? // $FlowFixMe[cannot-spread-interface]
328
- {...fetchVariables, ...renderVariables}
335
+ ? {...fetchVariables, ...renderVariables}
329
336
  : fetchVariables;
330
337
 
331
338
  const cacheConfig: ?CacheConfig = options
@@ -441,12 +448,8 @@ function createContainerWithFragments<
441
448
  };
442
449
 
443
450
  render() {
444
- const {
445
- componentRef,
446
- __relayContext,
447
- __rootIsQueryRenderer,
448
- ...props
449
- } = this.props;
451
+ const {componentRef, __relayContext, __rootIsQueryRenderer, ...props} =
452
+ this.props;
450
453
  const {relayProp, contextForChildren} = this.state;
451
454
  return (
452
455
  <ReactRelayContext.Provider value={contextForChildren}>
@@ -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,16 +12,6 @@
12
12
 
13
13
  'use strict';
14
14
 
15
- const areEqual = require('areEqual');
16
- const invariant = require('invariant');
17
- const warning = require('warning');
18
-
19
- const {
20
- createOperationDescriptor,
21
- isRelayModernEnvironment,
22
- Network,
23
- } = require('relay-runtime');
24
-
25
15
  import type {
26
16
  CacheConfig,
27
17
  ConcreteRequest,
@@ -32,6 +22,15 @@ import type {
32
22
  Variables,
33
23
  } from 'relay-runtime';
34
24
 
25
+ const areEqual = require('areEqual');
26
+ const invariant = require('invariant');
27
+ const {
28
+ Network,
29
+ createOperationDescriptor,
30
+ isRelayModernEnvironment,
31
+ } = require('relay-runtime');
32
+ const warning = require('warning');
33
+
35
34
  export type DataWriteConfig = {
36
35
  query: ConcreteRequest,
37
36
  variables: Variables,
@@ -66,7 +65,7 @@ let nextId = 0;
66
65
 
67
66
  class ReactRelayTestMocker {
68
67
  _environment: IEnvironment;
69
- _defaults: {[string]: $PropertyType<NetworkWriteConfig, 'payload'>, ...} = {};
68
+ _defaults: {[string]: NetworkWriteConfig['payload'], ...} = {};
70
69
  _pendingFetches: Array<PendingFetch> = [];
71
70
 
72
71
  constructor(env: IEnvironment) {
@@ -118,7 +117,6 @@ class ReactRelayTestMocker {
118
117
  * annoying to test (e.g. client_mutation_id, actor_id)
119
118
  */
120
119
  static stripUnused(variables: Variables): Variables {
121
- // $FlowFixMe[prop-missing]
122
120
  if (variables.input) {
123
121
  const toRemove = [
124
122
  'client_mutation_id',
@@ -126,7 +124,6 @@ class ReactRelayTestMocker {
126
124
  'clientMutationId',
127
125
  'actorId',
128
126
  ];
129
- // $FlowFixMe[cannot-spread-interface]
130
127
  const strippedVariables = {...variables, input: {...variables.input}};
131
128
  toRemove.forEach(item => (strippedVariables.input[item] = undefined));
132
129
  return strippedVariables;
@@ -143,7 +140,11 @@ class ReactRelayTestMocker {
143
140
  * their components behave under error conditions.
144
141
  */
145
142
  _mockNetworkLayer(env: IEnvironment): IEnvironment {
146
- const fetch = (request, variables, cacheConfig) => {
143
+ const fetch = (
144
+ request: RequestParameters,
145
+ variables: Variables,
146
+ cacheConfig: CacheConfig,
147
+ ) => {
147
148
  let resolve;
148
149
  let reject;
149
150
  const promise = new Promise((res, rej) => {
@@ -314,6 +315,7 @@ class ReactRelayTestMocker {
314
315
  );
315
316
 
316
317
  const realPayload =
318
+ // $FlowFixMe[incompatible-call]
317
319
  typeof payload === 'function' ? payload(toResolve.variables) : payload;
318
320
 
319
321
  // if there are errors, reject the query
@@ -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.
@@ -14,7 +14,7 @@
14
14
 
15
15
  import type {
16
16
  Disposable,
17
- FragmentReference,
17
+ FragmentType,
18
18
  GraphQLTaggedNode,
19
19
  IEnvironment,
20
20
  Observer,
@@ -94,7 +94,7 @@ export type RefetchOptions = {|
94
94
  *
95
95
  */
96
96
  export type $FragmentRef<T> = {
97
- +$fragmentRefs: $PropertyType<T, '$refType'>,
97
+ +$fragmentSpreads: T['$fragmentType'],
98
98
  ...
99
99
  };
100
100
 
@@ -105,14 +105,14 @@ export type $FragmentRef<T> = {
105
105
  // prettier-ignore
106
106
  export type $RelayProps<Props, RelayPropT = RelayProp> = $ObjMap<
107
107
  $Diff<Props, { relay: RelayPropT | void, ... }>,
108
- & (<T: { +$refType: empty, ... }>( T) => T)
109
- & (<T: { +$refType: empty, ... }>(?T) => ?T)
110
- & (<TRef: FragmentReference, T: { +$refType: TRef, ... }>( T ) => $FragmentRef<T> )
111
- & (<TRef: FragmentReference, T: { +$refType: TRef, ... }>(? T ) => ? $FragmentRef<T> )
112
- & (<TRef: FragmentReference, T: { +$refType: TRef, ... }>( $ReadOnlyArray< T>) => $ReadOnlyArray< $FragmentRef<T>>)
113
- & (<TRef: FragmentReference, T: { +$refType: TRef, ... }>(?$ReadOnlyArray< T>) => ?$ReadOnlyArray< $FragmentRef<T>>)
114
- & (<TRef: FragmentReference, T: { +$refType: TRef, ... }>( $ReadOnlyArray<?T>) => $ReadOnlyArray<?$FragmentRef<T>>)
115
- & (<TRef: FragmentReference, T: { +$refType: TRef, ... }>(?$ReadOnlyArray<?T>) => ?$ReadOnlyArray<?$FragmentRef<T>>)
108
+ & (<T: { +$fragmentType: empty, ... }>( T) => T)
109
+ & (<T: { +$fragmentType: empty, ... }>(?T) => ?T)
110
+ & (<TFragmentType: FragmentType, T: { +$fragmentType: TFragmentType, ... }>( T ) => $FragmentRef<T> )
111
+ & (<TFragmentType: FragmentType, T: { +$fragmentType: TFragmentType, ... }>(? T ) => ? $FragmentRef<T> )
112
+ & (<TFragmentType: FragmentType, T: { +$fragmentType: TFragmentType, ... }>( $ReadOnlyArray< T>) => $ReadOnlyArray< $FragmentRef<T>>)
113
+ & (<TFragmentType: FragmentType, T: { +$fragmentType: TFragmentType, ... }>(?$ReadOnlyArray< T>) => ?$ReadOnlyArray< $FragmentRef<T>>)
114
+ & (<TFragmentType: FragmentType, T: { +$fragmentType: TFragmentType, ... }>( $ReadOnlyArray<?T>) => $ReadOnlyArray<?$FragmentRef<T>>)
115
+ & (<TFragmentType: FragmentType, T: { +$fragmentType: TFragmentType, ... }>(?$ReadOnlyArray<?T>) => ?$ReadOnlyArray<?$FragmentRef<T>>)
116
116
  & (<T>(T) => T),
117
117
  >;
118
118
 
@@ -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,11 +12,11 @@
12
12
 
13
13
  'use strict';
14
14
 
15
- const invariant = require('invariant');
16
- const isRelayEnvironment = require('./isRelayEnvironment');
17
-
18
15
  import type {RelayContext} from 'relay-runtime';
19
16
 
17
+ const isRelayEnvironment = require('./isRelayEnvironment');
18
+ const invariant = require('invariant');
19
+
20
20
  /**
21
21
  * Asserts that the input is a matches the `RelayContext` type defined in
22
22
  * `RelayEnvironmentTypes` and returns it as that type.
@@ -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,11 +12,10 @@
12
12
 
13
13
  'use strict';
14
14
 
15
- const React = require('react');
16
-
17
15
  const {
18
16
  createContainer: createFragmentContainer,
19
17
  } = require('../ReactRelayFragmentContainer');
18
+ const React = require('react');
20
19
  const {graphql} = require('relay-runtime');
21
20
 
22
21
  /**
@@ -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,11 +12,10 @@
12
12
 
13
13
  'use strict';
14
14
 
15
- const React = require('react');
16
-
17
15
  const {
18
16
  createContainer: createPaginationContainer,
19
17
  } = require('../ReactRelayPaginationContainer');
18
+ const React = require('react');
20
19
  const {graphql} = require('relay-runtime');
21
20
 
22
21
  /**
@@ -63,10 +62,15 @@ const Foo = createPaginationContainer(
63
62
  {
64
63
  viewer: graphql`
65
64
  fragment ReactRelayPaginationContainerFlowtest_viewer on Viewer {
66
- all_friends(after: $cursor, first: $count) @connection {
67
- edges {
68
- node {
69
- __typename
65
+ account_user {
66
+ friends(after: $cursor, first: $count)
67
+ @connection(
68
+ key: "ReactRelayPaginationContainerFlowtest_viewer__friends"
69
+ ) {
70
+ edges {
71
+ node {
72
+ __typename
73
+ }
70
74
  }
71
75
  }
72
76
  }
@@ -75,7 +79,7 @@ const Foo = createPaginationContainer(
75
79
  },
76
80
  {
77
81
  direction: 'forward',
78
- getConnectionFromProps: props => props.viewer.all_friends,
82
+ getConnectionFromProps: props => props.viewer.account_user.friends,
79
83
  // $FlowFixMe[cannot-spread-interface]
80
84
  getFragmentVariables: (vars, totalCount) => ({
81
85
  ...vars,