react-relay 14.0.0 → 15.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (194) hide show
  1. package/ReactRelayContainerUtils.js.flow +1 -2
  2. package/ReactRelayContext.js +1 -1
  3. package/ReactRelayContext.js.flow +1 -2
  4. package/ReactRelayFragmentContainer.js.flow +6 -4
  5. package/ReactRelayFragmentMockRenderer.js.flow +1 -2
  6. package/ReactRelayLocalQueryRenderer.js.flow +5 -5
  7. package/ReactRelayPaginationContainer.js.flow +21 -14
  8. package/ReactRelayQueryFetcher.js.flow +28 -16
  9. package/ReactRelayQueryRenderer.js.flow +42 -13
  10. package/ReactRelayQueryRendererContext.js.flow +2 -3
  11. package/ReactRelayRefetchContainer.js.flow +9 -9
  12. package/ReactRelayTestMocker.js.flow +3 -3
  13. package/ReactRelayTypes.js.flow +7 -8
  14. package/RelayContext.js.flow +1 -2
  15. package/__flowtests__/ReactRelayFragmentContainer-flowtest.js.flow +4 -5
  16. package/__flowtests__/ReactRelayPaginationContainer-flowtest.js.flow +4 -5
  17. package/__flowtests__/ReactRelayRefetchContainer-flowtest.js.flow +4 -5
  18. package/__flowtests__/RelayModern-flowtest.js.flow +3 -4
  19. package/__flowtests__/RelayModernFlowtest_badref.graphql.js.flow +3 -4
  20. package/__flowtests__/RelayModernFlowtest_notref.graphql.js.flow +3 -4
  21. package/__flowtests__/RelayModernFlowtest_user.graphql.js.flow +3 -4
  22. package/__flowtests__/RelayModernFlowtest_users.graphql.js.flow +3 -4
  23. package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer.graphql.js.flow +3 -1
  24. package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer2.graphql.js.flow +3 -1
  25. package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtestQuery.graphql.js.flow +4 -2
  26. package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtest_viewer.graphql.js.flow +3 -1
  27. package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtestQuery.graphql.js.flow +4 -2
  28. package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtest_viewer.graphql.js.flow +3 -1
  29. package/__flowtests__/__generated__/RelayModernFlowtest_badref.graphql.js.flow +4 -2
  30. package/__flowtests__/__generated__/RelayModernFlowtest_notref.graphql.js.flow +4 -2
  31. package/__flowtests__/__generated__/RelayModernFlowtest_user.graphql.js.flow +3 -1
  32. package/__flowtests__/__generated__/RelayModernFlowtest_users.graphql.js.flow +3 -1
  33. package/assertFragmentMap.js.flow +1 -2
  34. package/buildReactRelayContainer.js.flow +7 -7
  35. package/getRootVariablesForFragments.js.flow +1 -3
  36. package/hooks.js +1 -1
  37. package/hooks.js.flow +4 -2
  38. package/index.js +1 -1
  39. package/index.js.flow +6 -2
  40. package/isRelayEnvironment.js.flow +1 -2
  41. package/jest-react/enqueueTask.js.flow +1 -1
  42. package/jest-react/index.js.flow +1 -1
  43. package/jest-react/internalAct.js.flow +1 -1
  44. package/legacy.js +1 -1
  45. package/legacy.js.flow +1 -2
  46. package/lib/ReactRelayContainerUtils.js +2 -3
  47. package/lib/ReactRelayContext.js +3 -4
  48. package/lib/ReactRelayFragmentContainer.js +47 -73
  49. package/lib/ReactRelayFragmentMockRenderer.js +2 -4
  50. package/lib/ReactRelayLocalQueryRenderer.js +18 -31
  51. package/lib/ReactRelayPaginationContainer.js +74 -164
  52. package/lib/ReactRelayQueryFetcher.js +49 -76
  53. package/lib/ReactRelayQueryRenderer.js +63 -84
  54. package/lib/ReactRelayQueryRendererContext.js +2 -2
  55. package/lib/ReactRelayRefetchContainer.js +58 -108
  56. package/lib/ReactRelayTestMocker.js +33 -68
  57. package/lib/ReactRelayTypes.js +2 -1
  58. package/lib/RelayContext.js +4 -7
  59. package/lib/assertFragmentMap.js +3 -5
  60. package/lib/buildReactRelayContainer.js +11 -27
  61. package/lib/getRootVariablesForFragments.js +6 -10
  62. package/lib/hooks.js +5 -18
  63. package/lib/index.js +7 -24
  64. package/lib/isRelayEnvironment.js +5 -4
  65. package/lib/jest-react/enqueueTask.js +5 -9
  66. package/lib/jest-react/index.js +0 -1
  67. package/lib/jest-react/internalAct.js +9 -20
  68. package/lib/legacy.js +2 -8
  69. package/lib/multi-actor/ActorChange.js +2 -5
  70. package/lib/multi-actor/index.js +2 -1
  71. package/lib/multi-actor/useRelayActorEnvironment.js +4 -8
  72. package/lib/relay-hooks/EntryPointContainer.react.js +9 -15
  73. package/lib/relay-hooks/EntryPointTypes.flow.js +5 -3
  74. package/lib/relay-hooks/FragmentResource.js +109 -203
  75. package/lib/relay-hooks/HooksImplementation.js +3 -6
  76. package/lib/relay-hooks/InternalLogger.js +2 -3
  77. package/lib/relay-hooks/LRUCache.js +2 -20
  78. package/lib/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js +33 -54
  79. package/lib/relay-hooks/MatchContainer.js +15 -24
  80. package/lib/relay-hooks/ProfilerContext.js +3 -3
  81. package/lib/relay-hooks/QueryResource.js +31 -101
  82. package/lib/relay-hooks/RelayEnvironmentProvider.js +5 -9
  83. package/lib/relay-hooks/SuspenseResource.js +9 -33
  84. package/lib/relay-hooks/loadEntryPoint.js +19 -31
  85. package/lib/relay-hooks/loadQuery.js +42 -78
  86. package/lib/relay-hooks/preloadQuery_DEPRECATED.js +11 -37
  87. package/lib/relay-hooks/prepareEntryPoint_DEPRECATED.js +9 -15
  88. package/lib/relay-hooks/react-cache/RelayReactCache.js +7 -12
  89. package/lib/relay-hooks/react-cache/getQueryResultOrFetchQuery_REACT_CACHE.js +27 -81
  90. package/lib/relay-hooks/react-cache/readFragmentInternal_REACT_CACHE.js +206 -0
  91. package/lib/relay-hooks/react-cache/useFragmentInternal_REACT_CACHE.js +195 -215
  92. package/lib/relay-hooks/react-cache/useFragment_REACT_CACHE.js +5 -15
  93. package/lib/relay-hooks/react-cache/useLazyLoadQuery_REACT_CACHE.js +17 -24
  94. package/lib/relay-hooks/react-cache/usePaginationFragment_REACT_CACHE.js +149 -0
  95. package/lib/relay-hooks/react-cache/usePreloadedQuery_REACT_CACHE.js +24 -39
  96. package/lib/relay-hooks/react-cache/useRefetchableFragmentInternal_REACT_CACHE.js +325 -0
  97. package/lib/relay-hooks/react-cache/useRefetchableFragment_REACT_CACHE.js +37 -0
  98. package/lib/relay-hooks/useBlockingPaginationFragment.js +73 -93
  99. package/lib/relay-hooks/useClientQuery.js +30 -0
  100. package/lib/relay-hooks/useEntryPointLoader.js +18 -38
  101. package/lib/relay-hooks/useFetchTrackingRef.js +10 -12
  102. package/lib/relay-hooks/useFragment.js +8 -19
  103. package/lib/relay-hooks/useFragmentNode.js +20 -32
  104. package/lib/relay-hooks/useIsMountedRef.js +4 -6
  105. package/lib/relay-hooks/useIsOperationNodeActive.js +8 -20
  106. package/lib/relay-hooks/useIsParentQueryActive.js +3 -6
  107. package/lib/relay-hooks/useLazyLoadQuery.js +7 -24
  108. package/lib/relay-hooks/useLazyLoadQueryNode.js +23 -34
  109. package/lib/relay-hooks/useLoadMoreFunction.js +46 -78
  110. package/lib/relay-hooks/useMemoOperationDescriptor.js +6 -15
  111. package/lib/relay-hooks/useMemoVariables.js +15 -34
  112. package/lib/relay-hooks/useMutation.js +9 -27
  113. package/lib/relay-hooks/usePaginationFragment.js +73 -76
  114. package/lib/relay-hooks/usePreloadedQuery.js +13 -44
  115. package/lib/relay-hooks/useQueryLoader.js +24 -49
  116. package/lib/relay-hooks/useRefetchableFragment.js +19 -17
  117. package/lib/relay-hooks/useRefetchableFragmentNode.js +65 -109
  118. package/lib/relay-hooks/useRelayEnvironment.js +4 -8
  119. package/lib/relay-hooks/useStaticFragmentNodeWarning.js +4 -8
  120. package/lib/relay-hooks/useSubscribeToInvalidationState.js +8 -9
  121. package/lib/relay-hooks/useSubscription.js +5 -10
  122. package/lib/relay-hooks/useUnsafeRef_DEPRECATED.js +29 -0
  123. package/multi-actor/ActorChange.js.flow +1 -1
  124. package/multi-actor/index.js.flow +1 -1
  125. package/multi-actor/useRelayActorEnvironment.js.flow +2 -4
  126. package/package.json +2 -2
  127. package/react-relay-hooks.js +2 -2
  128. package/react-relay-hooks.min.js +2 -2
  129. package/react-relay-legacy.js +2 -2
  130. package/react-relay-legacy.min.js +2 -2
  131. package/react-relay.js +2 -2
  132. package/react-relay.min.js +2 -2
  133. package/relay-hooks/EntryPointContainer.react.js.flow +3 -5
  134. package/relay-hooks/EntryPointTypes.flow.js.flow +37 -37
  135. package/relay-hooks/FragmentResource.js.flow +43 -19
  136. package/relay-hooks/HooksImplementation.js.flow +7 -9
  137. package/relay-hooks/InternalLogger.js.flow +1 -3
  138. package/relay-hooks/LRUCache.js.flow +1 -3
  139. package/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js.flow +19 -14
  140. package/relay-hooks/MatchContainer.js.flow +6 -8
  141. package/relay-hooks/ProfilerContext.js.flow +1 -3
  142. package/relay-hooks/QueryResource.js.flow +29 -11
  143. package/relay-hooks/RelayEnvironmentProvider.js.flow +4 -6
  144. package/relay-hooks/SuspenseResource.js.flow +1 -3
  145. package/relay-hooks/__flowtests__/EntryPointTypes/EntryPointElementConfig-flowtest.js.flow +6 -4
  146. package/relay-hooks/__flowtests__/EntryPointTypes/NestedEntrypoints-flowtest.js.flow +4 -4
  147. package/relay-hooks/__flowtests__/__generated__/useFragmentFlowtest_user.graphql.js.flow +3 -1
  148. package/relay-hooks/__flowtests__/__generated__/useFragmentFlowtest_users.graphql.js.flow +3 -1
  149. package/relay-hooks/__flowtests__/useBlockingPaginationFragment-flowtest.js.flow +39 -39
  150. package/relay-hooks/__flowtests__/useFragment-flowtest.js.flow +1 -3
  151. package/relay-hooks/__flowtests__/usePaginationFragment-flowtest.js.flow +37 -38
  152. package/relay-hooks/__flowtests__/useRefetchableFragment-flowtest.js.flow +18 -20
  153. package/relay-hooks/__flowtests__/utils.js.flow +21 -12
  154. package/relay-hooks/loadEntryPoint.js.flow +11 -6
  155. package/relay-hooks/loadQuery.js.flow +11 -7
  156. package/relay-hooks/preloadQuery_DEPRECATED.js.flow +9 -12
  157. package/relay-hooks/prepareEntryPoint_DEPRECATED.js.flow +13 -10
  158. package/relay-hooks/react-cache/RelayReactCache.js.flow +1 -3
  159. package/relay-hooks/react-cache/getQueryResultOrFetchQuery_REACT_CACHE.js.flow +26 -20
  160. package/relay-hooks/react-cache/readFragmentInternal_REACT_CACHE.js.flow +297 -0
  161. package/relay-hooks/react-cache/useFragmentInternal_REACT_CACHE.js.flow +136 -96
  162. package/relay-hooks/react-cache/useFragment_REACT_CACHE.js.flow +1 -3
  163. package/relay-hooks/react-cache/useLazyLoadQuery_REACT_CACHE.js.flow +3 -5
  164. package/relay-hooks/react-cache/usePaginationFragment_REACT_CACHE.js.flow +190 -0
  165. package/relay-hooks/react-cache/usePreloadedQuery_REACT_CACHE.js.flow +3 -6
  166. package/relay-hooks/react-cache/useRefetchableFragmentInternal_REACT_CACHE.js.flow +601 -0
  167. package/relay-hooks/react-cache/useRefetchableFragment_REACT_CACHE.js.flow +65 -0
  168. package/relay-hooks/useBlockingPaginationFragment.js.flow +86 -59
  169. package/relay-hooks/useClientQuery.js.flow +39 -0
  170. package/relay-hooks/useEntryPointLoader.js.flow +16 -14
  171. package/relay-hooks/useFetchTrackingRef.js.flow +7 -8
  172. package/relay-hooks/useFragment.js.flow +2 -4
  173. package/relay-hooks/useFragmentNode.js.flow +7 -8
  174. package/relay-hooks/useIsMountedRef.js.flow +2 -4
  175. package/relay-hooks/useIsOperationNodeActive.js.flow +1 -1
  176. package/relay-hooks/useIsParentQueryActive.js.flow +1 -1
  177. package/relay-hooks/useLazyLoadQuery.js.flow +9 -32
  178. package/relay-hooks/useLazyLoadQueryNode.js.flow +4 -6
  179. package/relay-hooks/useLoadMoreFunction.js.flow +20 -17
  180. package/relay-hooks/useMemoOperationDescriptor.js.flow +3 -5
  181. package/relay-hooks/useMemoVariables.js.flow +13 -31
  182. package/relay-hooks/useMutation.js.flow +6 -8
  183. package/relay-hooks/usePaginationFragment.js.flow +75 -43
  184. package/relay-hooks/usePreloadedQuery.js.flow +49 -43
  185. package/relay-hooks/useQueryLoader.js.flow +89 -28
  186. package/relay-hooks/useRefetchableFragment.js.flow +83 -23
  187. package/relay-hooks/useRefetchableFragmentNode.js.flow +26 -22
  188. package/relay-hooks/useRelayEnvironment.js.flow +2 -4
  189. package/relay-hooks/useStaticFragmentNodeWarning.js.flow +3 -5
  190. package/relay-hooks/useSubscribeToInvalidationState.js.flow +2 -4
  191. package/relay-hooks/useSubscription.js.flow +1 -3
  192. package/relay-hooks/useUnsafeRef_DEPRECATED.js.flow +25 -0
  193. package/lib/readContext.js +0 -28
  194. package/readContext.js.flow +0 -31
@@ -6,10 +6,9 @@
6
6
  *
7
7
  * @flow
8
8
  * @format
9
+ * @oncall relay
9
10
  */
10
11
 
11
- // flowlint ambiguous-object-type:error
12
-
13
12
  'use strict';
14
13
 
15
14
  function getComponentName(component: React$ComponentType<any>): string {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Relay v14.0.0
2
+ * Relay v15.0.0
3
3
  *
4
4
  * Copyright (c) Meta Platforms, Inc. and affiliates.
5
5
  *
@@ -6,10 +6,9 @@
6
6
  *
7
7
  * @flow strict-local
8
8
  * @format
9
+ * @oncall relay
9
10
  */
10
11
 
11
- // flowlint ambiguous-object-type:error
12
-
13
12
  'use strict';
14
13
  import type {RelayContext} from 'relay-runtime/store/RelayStoreTypes';
15
14
 
@@ -6,12 +6,11 @@
6
6
  *
7
7
  * @flow strict-local
8
8
  * @format
9
+ * @oncall relay
9
10
  */
10
11
 
11
- // flowlint ambiguous-object-type:error
12
-
13
12
  'use strict';
14
- import type {GeneratedNodeMap, RelayProp, $RelayProps} from './ReactRelayTypes';
13
+ import type {$RelayProps, GeneratedNodeMap, RelayProp} from './ReactRelayTypes';
15
14
  import type {
16
15
  FragmentMap,
17
16
  FragmentSpecResolver,
@@ -57,6 +56,7 @@ function createContainerWithFragments<
57
56
  const containerName = getContainerName(Component);
58
57
 
59
58
  return class extends React.Component<ContainerProps, ContainerState> {
59
+ // $FlowFixMe[missing-local-annot]
60
60
  static displayName = containerName;
61
61
  constructor(props: $FlowFixMe) {
62
62
  super(props);
@@ -90,7 +90,7 @@ function createContainerWithFragments<
90
90
  static getDerivedStateFromProps(
91
91
  nextProps: ContainerProps,
92
92
  prevState: ContainerState,
93
- ): $Shape<ContainerState> | null {
93
+ ): Partial<ContainerState> | null {
94
94
  // Any props change could impact the query, so we mirror props in state.
95
95
  // This is an unusual pattern, but necessary for this container usecase.
96
96
  const {prevProps} = prevState;
@@ -237,7 +237,9 @@ function createContainerWithFragments<
237
237
  }
238
238
  }
239
239
 
240
+ // $FlowFixMe[missing-local-annot]
240
241
  render() {
242
+ // eslint-disable-next-line no-unused-vars
241
243
  const {componentRef, __relayContext, __rootIsQueryRenderer, ...props} =
242
244
  this.props;
243
245
  return React.createElement(Component, {
@@ -6,10 +6,9 @@
6
6
  *
7
7
  * @flow
8
8
  * @format
9
+ * @oncall relay
9
10
  */
10
11
 
11
- // flowlint ambiguous-object-type:error
12
-
13
12
  'use strict';
14
13
 
15
14
  const ReactRelayContext = require('./ReactRelayContext');
@@ -6,14 +6,14 @@
6
6
  *
7
7
  * @flow strict-local
8
8
  * @format
9
+ * @oncall relay
9
10
  */
10
11
 
11
- // flowlint ambiguous-object-type:error
12
-
13
12
  'use strict';
14
13
 
15
14
  import type {ReactRelayQueryRendererContext as ReactRelayQueryRendererContextType} from './ReactRelayQueryRendererContext';
16
15
  import type {GraphQLTaggedNode, IEnvironment, Variables} from 'relay-runtime';
16
+ import type {SelectorData} from 'relay-runtime/store/RelayStoreTypes';
17
17
 
18
18
  const ReactRelayContext = require('./ReactRelayContext');
19
19
  const ReactRelayQueryRendererContext = require('./ReactRelayQueryRendererContext');
@@ -63,9 +63,9 @@ function ReactRelayLocalQueryRenderer(props: Props): React.Node {
63
63
 
64
64
  // Use a ref to prevent rendering twice when data changes
65
65
  // because of props change
66
- const dataRef = useRef(null);
67
- const [, forceUpdate] = useState(null);
68
- const cleanupFnRef = useRef(null);
66
+ const dataRef = useRef<?SelectorData>(null);
67
+ const [, forceUpdate] = useState<?SelectorData>(null);
68
+ const cleanupFnRef = useRef<null | (() => void)>(null);
69
69
 
70
70
  const snapshot = useMemo(() => {
71
71
  environment.check(operation);
@@ -6,18 +6,18 @@
6
6
  *
7
7
  * @flow
8
8
  * @format
9
+ * @oncall relay
9
10
  */
10
11
 
11
- // flowlint ambiguous-object-type:error
12
-
13
12
  'use strict';
14
13
 
14
+ import type {Sink} from '../relay-runtime/network/RelayObservable';
15
15
  import type {
16
+ $RelayProps,
16
17
  GeneratedNodeMap,
17
18
  ObserverOrCallback,
18
19
  RefetchOptions,
19
20
  RelayPaginationProp,
20
- $RelayProps,
21
21
  } from './ReactRelayTypes';
22
22
  import type {
23
23
  CacheConfig,
@@ -256,9 +256,9 @@ function createGetFragmentVariables(
256
256
  'ReactRelayPaginationContainer: Unable to synthesize a ' +
257
257
  'getFragmentVariables function.',
258
258
  );
259
- return (prevVars: Variables, totalCount: number) => ({
259
+ return (prevVars: Variables, totalCount: number): Variables => ({
260
260
  ...prevVars,
261
- [countVariable]: totalCount,
261
+ [(countVariable: string)]: totalCount,
262
262
  });
263
263
  }
264
264
 
@@ -348,6 +348,7 @@ function createContainerWithFragments<
348
348
  createGetFragmentVariables(metadata);
349
349
 
350
350
  return class extends React.Component<$FlowFixMeProps, ContainerState> {
351
+ // $FlowFixMe[missing-local-annot]
351
352
  static displayName = containerName;
352
353
 
353
354
  _isARequestInFlight: boolean;
@@ -566,6 +567,7 @@ function createContainerWithFragments<
566
567
  ...
567
568
  } {
568
569
  // Extract connection data and verify there are more edges to fetch
570
+ // eslint-disable-next-line no-unused-vars
569
571
  const {componentRef: _, ...restProps} = this.props;
570
572
  const props = {
571
573
  ...restProps,
@@ -696,7 +698,7 @@ function createContainerWithFragments<
696
698
  const observer = toObserver(observerOrCallback);
697
699
  const connectionData = this._getConnectionData();
698
700
  if (!connectionData) {
699
- Observable.create(sink => sink.complete()).subscribe(observer);
701
+ Observable.create<empty>(sink => sink.complete()).subscribe(observer);
700
702
  return null;
701
703
  }
702
704
  const totalCount = connectionData.edgeCount + pageSize;
@@ -757,8 +759,11 @@ function createContainerWithFragments<
757
759
  ): Subscription {
758
760
  const {environment} = assertRelayContext(this.props.__relayContext);
759
761
  const {
762
+ // eslint-disable-next-line no-unused-vars
760
763
  componentRef: _,
764
+ // eslint-disable-next-line no-unused-vars
761
765
  __relayContext,
766
+ // eslint-disable-next-line no-unused-vars
762
767
  __rootIsQueryRenderer,
763
768
  ...restProps
764
769
  } = this.props;
@@ -766,7 +771,7 @@ function createContainerWithFragments<
766
771
  ...restProps,
767
772
  ...this.state.data,
768
773
  };
769
- let fragmentVariables;
774
+ let fragmentVariables: Variables;
770
775
  const rootVariables = getRootVariablesForFragments(fragments, restProps);
771
776
  fragmentVariables = getVariablesFromObject(fragments, restProps);
772
777
  fragmentVariables = {
@@ -774,7 +779,7 @@ function createContainerWithFragments<
774
779
  ...fragmentVariables,
775
780
  ...this._refetchVariables,
776
781
  };
777
- let fetchVariables = connectionConfig.getVariables(
782
+ let fetchVariables: Variables = connectionConfig.getVariables(
778
783
  props,
779
784
  {
780
785
  count: paginatingVariables.count,
@@ -789,14 +794,14 @@ function createContainerWithFragments<
789
794
  fetchVariables,
790
795
  componentName,
791
796
  );
792
- fetchVariables = {
797
+ fetchVariables = ({
793
798
  ...fetchVariables,
794
799
  ...this._refetchVariables,
795
- };
796
- fragmentVariables = {
800
+ }: Variables);
801
+ fragmentVariables = ({
797
802
  ...fetchVariables,
798
803
  ...fragmentVariables,
799
- };
804
+ }: Variables);
800
805
 
801
806
  const cacheConfig: ?CacheConfig = options
802
807
  ? {force: !!options.force}
@@ -867,8 +872,8 @@ function createContainerWithFragments<
867
872
  operation,
868
873
  preservePreviousReferences: true,
869
874
  })
870
- .mergeMap(payload =>
871
- Observable.create(sink => {
875
+ .mergeMap<void>(payload =>
876
+ Observable.create<void>((sink: Sink<void>) => {
872
877
  onNext(payload, () => {
873
878
  sink.next(); // pass void to public observer's `next`
874
879
  sink.complete();
@@ -904,7 +909,9 @@ function createContainerWithFragments<
904
909
  }
905
910
  }
906
911
 
912
+ // $FlowFixMe[missing-local-annot]
907
913
  render() {
914
+ // eslint-disable-next-line no-unused-vars
908
915
  const {componentRef, __relayContext, __rootIsQueryRenderer, ...props} =
909
916
  this.props;
910
917
  return (
@@ -6,10 +6,9 @@
6
6
  *
7
7
  * @flow strict-local
8
8
  * @format
9
+ * @oncall relay
9
10
  */
10
11
 
11
- // flowlint ambiguous-object-type:error
12
-
13
12
  'use strict';
14
13
 
15
14
  import type {
@@ -35,26 +34,26 @@ type OnDataChange = ({
35
34
  }) => void;
36
35
 
37
36
  /** The external API of 'fetch' **/
38
- export type FetchOptions = {|
37
+ export type FetchOptions = {
39
38
  environment: IEnvironment,
40
39
  onDataChange?: null | OnDataChange,
41
40
  operation: OperationDescriptor,
42
- |};
41
+ };
43
42
 
44
43
  // Internally we keep an array of onDataChange callbacks, to support reusing
45
44
  // the queryRenderer for multiple components.
46
- type FetchOptionsInternal = {|
45
+ type FetchOptionsInternal = {
47
46
  environment: IEnvironment,
48
47
  onDataChangeCallbacks: Array<OnDataChange>,
49
48
  operation: OperationDescriptor,
50
- |};
49
+ };
51
50
 
52
- export type ExecuteConfig = {|
51
+ export type ExecuteConfig = {
53
52
  environment: IEnvironment,
54
53
  operation: OperationDescriptor,
55
54
  // Allows pagination container to retain results from previous queries
56
55
  preservePreviousReferences?: boolean,
57
- |};
56
+ };
58
57
 
59
58
  class ReactRelayQueryFetcher {
60
59
  _fetchOptions: ?FetchOptionsInternal;
@@ -64,7 +63,7 @@ class ReactRelayQueryFetcher {
64
63
  _snapshot: ?Snapshot; // results of the root fragment;
65
64
  _error: ?Error; // fetch error
66
65
  _cacheSelectionReference: ?Disposable;
67
- _callOnDataChangeWhenSet: boolean = false;
66
+ _didFetchFinish: boolean = false;
68
67
 
69
68
  constructor(args?: {
70
69
  cacheSelectionReference: ?Disposable,
@@ -77,10 +76,10 @@ class ReactRelayQueryFetcher {
77
76
  }
78
77
  }
79
78
 
80
- getSelectionReferences(): {|
79
+ getSelectionReferences(): {
81
80
  cacheSelectionReference: ?Disposable,
82
81
  selectionReferences: Array<Disposable>,
83
- |} {
82
+ } {
84
83
  return {
85
84
  cacheSelectionReference: this._cacheSelectionReference,
86
85
  selectionReferences: this._selectionReferences,
@@ -104,6 +103,19 @@ class ReactRelayQueryFetcher {
104
103
  return null;
105
104
  }
106
105
 
106
+ getFetchResult(): ?{error?: Error, snapshot?: Snapshot} {
107
+ if (this._didFetchFinish) {
108
+ // We don't reset '_didFetchFinish' because another callback may be set
109
+ if (this._error != null) {
110
+ return {error: this._error};
111
+ } else if (this._snapshot != null) {
112
+ return {snapshot: this._snapshot};
113
+ }
114
+ } else {
115
+ return null;
116
+ }
117
+ }
118
+
107
119
  execute({
108
120
  environment,
109
121
  operation,
@@ -153,8 +165,8 @@ class ReactRelayQueryFetcher {
153
165
  this._fetchOptions.onDataChangeCallbacks || [];
154
166
  this._fetchOptions.onDataChangeCallbacks.push(onDataChange);
155
167
 
156
- if (this._callOnDataChangeWhenSet) {
157
- // We don't reset '_callOnDataChangeWhenSet' because another callback may be set
168
+ if (this._didFetchFinish) {
169
+ // We don't reset '_didFetchFinish' because another callback may be set
158
170
  if (this._error != null) {
159
171
  onDataChange({error: this._error});
160
172
  } else if (this._snapshot != null) {
@@ -217,7 +229,7 @@ class ReactRelayQueryFetcher {
217
229
  next: () => {
218
230
  // If we received a response,
219
231
  // Make a note that to notify the callback when it's later added.
220
- this._callOnDataChangeWhenSet = true;
232
+ this._didFetchFinish = true;
221
233
  this._error = null;
222
234
 
223
235
  // Only notify of the first result if `next` is being called **asynchronously**
@@ -227,7 +239,7 @@ class ReactRelayQueryFetcher {
227
239
  error: err => {
228
240
  // If we received a response when we didn't have a change callback,
229
241
  // Make a note that to notify the callback when it's later added.
230
- this._callOnDataChangeWhenSet = true;
242
+ this._didFetchFinish = true;
231
243
  this._error = err;
232
244
  this._snapshot = null;
233
245
 
@@ -321,7 +333,7 @@ class ReactRelayQueryFetcher {
321
333
  }: {
322
334
  notifyFirstResult: boolean,
323
335
  ...
324
- }) {
336
+ }): void {
325
337
  invariant(
326
338
  this._fetchOptions,
327
339
  'ReactRelayQueryFetcher: `_onQueryDataAvailable` should have been called after having called `fetch`',
@@ -6,10 +6,9 @@
6
6
  *
7
7
  * @flow
8
8
  * @format
9
+ * @oncall relay
9
10
  */
10
11
 
11
- // flowlint ambiguous-object-type:error
12
-
13
12
  'use strict';
14
13
 
15
14
  import type {ReactRelayQueryRendererContext as ReactRelayQueryRendererContextType} from './ReactRelayQueryRendererContext';
@@ -28,13 +27,14 @@ const ReactRelayQueryFetcher = require('./ReactRelayQueryFetcher');
28
27
  const ReactRelayQueryRendererContext = require('./ReactRelayQueryRendererContext');
29
28
  const areEqual = require('areEqual');
30
29
  const React = require('react');
30
+ const {RelayFeatureFlags} = require('relay-runtime');
31
31
  const {
32
32
  createOperationDescriptor,
33
33
  deepFreeze,
34
34
  getRequest,
35
35
  } = require('relay-runtime');
36
36
 
37
- type RetryCallbacks = {|
37
+ type RetryCallbacks = {
38
38
  handleDataChange:
39
39
  | null
40
40
  | (({
@@ -43,39 +43,39 @@ type RetryCallbacks = {|
43
43
  ...
44
44
  }) => void),
45
45
  handleRetryAfterError: null | ((error: Error) => void),
46
- |};
46
+ };
47
47
 
48
- export type RenderProps<T> = {|
48
+ export type RenderProps<T> = {
49
49
  error: ?Error,
50
50
  props: ?T,
51
51
  retry: ?(cacheConfigOverride?: CacheConfig) => void,
52
- |};
52
+ };
53
53
  /**
54
54
  * React may double-fire the constructor, and we call 'fetch' in the
55
55
  * constructor. If a request is already in flight from a previous call to the
56
56
  * constructor, just reuse the query fetcher and wait for the response.
57
57
  */
58
58
  const requestCache: {
59
- [string]: void | {|
59
+ [string]: void | {
60
60
  queryFetcher: ReactRelayQueryFetcher,
61
61
  snapshot: ?Snapshot,
62
- |},
62
+ },
63
63
  } = {};
64
64
 
65
65
  const queryRendererContext: ReactRelayQueryRendererContextType = {
66
66
  rootIsQueryRenderer: true,
67
67
  };
68
68
 
69
- export type Props = {|
69
+ export type Props = {
70
70
  cacheConfig?: ?CacheConfig,
71
71
  fetchPolicy?: 'store-and-network' | 'network-only',
72
72
  environment: IEnvironment,
73
73
  query: ?GraphQLTaggedNode,
74
74
  render: (renderProps: RenderProps<Object>) => React.Node,
75
75
  variables: Variables,
76
- |};
76
+ };
77
77
 
78
- type State = {|
78
+ type State = {
79
79
  error: Error | null,
80
80
  prevPropsEnvironment: IEnvironment,
81
81
  prevPropsVariables: Variables,
@@ -86,7 +86,7 @@ type State = {|
86
86
  retryCallbacks: RetryCallbacks,
87
87
  requestCacheKey: ?string,
88
88
  snapshot: Snapshot | null,
89
- |};
89
+ };
90
90
 
91
91
  /**
92
92
  * @public
@@ -171,7 +171,36 @@ class ReactRelayQueryRenderer extends React.Component<Props, State> {
171
171
  this._maybeHiddenOrFastRefresh = false;
172
172
  // eslint-disable-next-line react/no-did-mount-set-state
173
173
  this.setState(prevState => {
174
- return resetQueryStateForUpdate(this.props, prevState);
174
+ const newState = resetQueryStateForUpdate(this.props, prevState);
175
+ const {requestCacheKey, queryFetcher} = newState;
176
+ if (requestCacheKey != null && requestCache[requestCacheKey] != null) {
177
+ if (RelayFeatureFlags.ENABLE_QUERY_RENDERER_SET_STATE_PREVENTION) {
178
+ const fetchResult = queryFetcher.getFetchResult();
179
+ if (fetchResult != null) {
180
+ const snapshot = fetchResult.snapshot ?? null;
181
+ const error = fetchResult.error ?? null;
182
+
183
+ const {requestCacheKey: prevRequestCacheKey} = prevState;
184
+ if (prevRequestCacheKey != null) {
185
+ delete requestCache[prevRequestCacheKey];
186
+ }
187
+
188
+ newState.renderProps = getRenderProps(
189
+ error,
190
+ snapshot,
191
+ queryFetcher,
192
+ prevState.retryCallbacks,
193
+ );
194
+ newState.snapshot = snapshot;
195
+ newState.requestCacheKey = null;
196
+ } else {
197
+ queryFetcher.setOnDataChange(this._handleDataChange);
198
+ }
199
+ } else {
200
+ queryFetcher.setOnDataChange(this._handleDataChange);
201
+ }
202
+ }
203
+ return newState;
175
204
  });
176
205
  return;
177
206
  }
@@ -6,14 +6,13 @@
6
6
  *
7
7
  * @flow strict-local
8
8
  * @format
9
+ * @oncall relay
9
10
  */
10
11
 
11
- // flowlint ambiguous-object-type:error
12
-
13
12
  'use strict';
14
13
  const React = require('react');
15
14
 
16
- export type ReactRelayQueryRendererContext = {|rootIsQueryRenderer: boolean|};
15
+ export type ReactRelayQueryRendererContext = {rootIsQueryRenderer: boolean};
17
16
 
18
17
  module.exports = (React.createContext({
19
18
  rootIsQueryRenderer: false,
@@ -6,18 +6,17 @@
6
6
  *
7
7
  * @flow
8
8
  * @format
9
+ * @oncall relay
9
10
  */
10
11
 
11
- // flowlint ambiguous-object-type:error
12
-
13
12
  'use strict';
14
13
 
15
14
  import type {
15
+ $RelayProps,
16
16
  GeneratedNodeMap,
17
17
  ObserverOrCallback,
18
18
  RefetchOptions,
19
19
  RelayRefetchProp,
20
- $RelayProps,
21
20
  } from './ReactRelayTypes';
22
21
  import type {
23
22
  CacheConfig,
@@ -81,6 +80,7 @@ function createContainerWithFragments<
81
80
  const containerName = getContainerName(Component);
82
81
 
83
82
  return class extends React.Component<ContainerProps, ContainerState> {
83
+ // $FlowFixMe[missing-local-annot]
84
84
  static displayName = containerName;
85
85
 
86
86
  _refetchSubscription: ?Subscription;
@@ -144,7 +144,7 @@ function createContainerWithFragments<
144
144
  static getDerivedStateFromProps(
145
145
  nextProps: ContainerProps,
146
146
  prevState: ContainerState,
147
- ): $Shape<ContainerState> | null {
147
+ ): Partial<ContainerState> | null {
148
148
  // Any props change could impact the query, so we mirror props in state.
149
149
  // This is an unusual pattern, but necessary for this container usecase.
150
150
  const {prevProps} = prevState;
@@ -364,16 +364,14 @@ function createContainerWithFragments<
364
364
  );
365
365
 
366
366
  // TODO: T26288752 find a better way
367
- /* eslint-disable lint/react-state-props-mutation */
368
367
  this.state.localVariables = fetchVariables;
369
- /* eslint-enable lint/react-state-props-mutation */
370
368
 
371
369
  // Cancel any previously running refetch.
372
370
  this._refetchSubscription && this._refetchSubscription.unsubscribe();
373
371
 
374
372
  // Declare refetchSubscription before assigning it in .start(), since
375
373
  // synchronous completion may call callbacks .subscribe() returns.
376
- let refetchSubscription;
374
+ let refetchSubscription: Subscription;
377
375
 
378
376
  const storeSnapshot = this._getQueryFetcher().lookupInStore(
379
377
  environment,
@@ -409,12 +407,12 @@ function createContainerWithFragments<
409
407
  // TODO (T26430099): Cleanup old references
410
408
  preservePreviousReferences: true,
411
409
  })
412
- .mergeMap(response => {
410
+ .mergeMap<void>(response => {
413
411
  this.state.resolver.setVariables(
414
412
  fragmentVariables,
415
413
  operation.request.node,
416
414
  );
417
- return Observable.create(sink =>
415
+ return Observable.create<void>(sink =>
418
416
  this.setState(
419
417
  latestState => ({
420
418
  data: latestState.resolver.resolve(),
@@ -451,7 +449,9 @@ function createContainerWithFragments<
451
449
  };
452
450
  };
453
451
 
452
+ // $FlowFixMe[missing-local-annot]
454
453
  render() {
454
+ // eslint-disable-next-line no-unused-vars
455
455
  const {componentRef, __relayContext, __rootIsQueryRenderer, ...props} =
456
456
  this.props;
457
457
  const {relayProp, contextForChildren} = this.state;
@@ -6,15 +6,15 @@
6
6
  *
7
7
  * @flow
8
8
  * @format
9
+ * @oncall relay
9
10
  */
10
11
 
11
- // flowlint ambiguous-object-type:error
12
-
13
12
  'use strict';
14
13
 
15
14
  import type {
16
15
  CacheConfig,
17
16
  ConcreteRequest,
17
+ GraphQLResponse,
18
18
  GraphQLSingularResponse,
19
19
  IEnvironment,
20
20
  PayloadError,
@@ -147,7 +147,7 @@ class ReactRelayTestMocker {
147
147
  ) => {
148
148
  let resolve;
149
149
  let reject;
150
- const promise = new Promise((res, rej) => {
150
+ const promise = new Promise<GraphQLResponse>((res, rej) => {
151
151
  resolve = res;
152
152
  reject = rej;
153
153
  });
@@ -6,10 +6,9 @@
6
6
  *
7
7
  * @flow strict-local
8
8
  * @format
9
+ * @oncall relay
9
10
  */
10
11
 
11
- // flowlint ambiguous-object-type:error
12
-
13
12
  'use strict';
14
13
 
15
14
  import type {
@@ -29,7 +28,7 @@ export type ObserverOrCallback = Observer<void> | ((error: ?Error) => mixed);
29
28
  // RelayRefetchProp to flow into a RelayProp.
30
29
  export type RelayProp = {+environment: IEnvironment, ...};
31
30
 
32
- export type RelayPaginationProp = {|
31
+ export type RelayPaginationProp = {
33
32
  +environment: IEnvironment,
34
33
  +hasMore: () => boolean,
35
34
  +isLoading: () => boolean,
@@ -43,9 +42,9 @@ export type RelayPaginationProp = {|
43
42
  observerOrCallback: ?ObserverOrCallback,
44
43
  refetchVariables: ?Variables,
45
44
  ) => ?Disposable,
46
- |};
45
+ };
47
46
 
48
- export type RelayRefetchProp = {|
47
+ export type RelayRefetchProp = {
49
48
  +environment: IEnvironment,
50
49
  +refetch: (
51
50
  refetchVariables: Variables | ((fragmentVariables: Variables) => Variables),
@@ -53,13 +52,13 @@ export type RelayRefetchProp = {|
53
52
  observerOrCallback: ?ObserverOrCallback,
54
53
  options?: RefetchOptions,
55
54
  ) => Disposable,
56
- |};
55
+ };
57
56
 
58
- export type RefetchOptions = {|
57
+ export type RefetchOptions = {
59
58
  +force?: boolean,
60
59
  +fetchPolicy?: 'store-or-network' | 'network-only',
61
60
  +metadata?: {[key: string]: mixed, ...},
62
- |};
61
+ };
63
62
 
64
63
  /**
65
64
  * A utility type which takes the type of a fragment's data (typically found in
@@ -6,10 +6,9 @@
6
6
  *
7
7
  * @flow
8
8
  * @format
9
+ * @oncall relay
9
10
  */
10
11
 
11
- // flowlint ambiguous-object-type:error
12
-
13
12
  'use strict';
14
13
 
15
14
  import type {RelayContext} from 'relay-runtime';