react-relay 14.1.0 → 16.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. package/ReactRelayContainerUtils.js.flow +1 -0
  2. package/ReactRelayContext.js +1 -1
  3. package/ReactRelayContext.js.flow +1 -0
  4. package/ReactRelayFragmentContainer.js.flow +6 -2
  5. package/ReactRelayFragmentMockRenderer.js.flow +1 -0
  6. package/ReactRelayLocalQueryRenderer.js.flow +5 -3
  7. package/ReactRelayPaginationContainer.js.flow +21 -12
  8. package/ReactRelayQueryFetcher.js.flow +20 -10
  9. package/ReactRelayQueryRenderer.js.flow +15 -11
  10. package/ReactRelayQueryRendererContext.js.flow +1 -0
  11. package/ReactRelayRefetchContainer.js.flow +9 -5
  12. package/ReactRelayTestMocker.js.flow +3 -1
  13. package/ReactRelayTypes.js.flow +2 -0
  14. package/RelayContext.js.flow +1 -0
  15. package/__flowtests__/ReactRelayFragmentContainer-flowtest.js.flow +2 -1
  16. package/__flowtests__/ReactRelayPaginationContainer-flowtest.js.flow +1 -0
  17. package/__flowtests__/ReactRelayRefetchContainer-flowtest.js.flow +1 -0
  18. package/__flowtests__/RelayModern-flowtest.js.flow +1 -0
  19. package/__flowtests__/RelayModernFlowtest_badref.graphql.js.flow +1 -0
  20. package/__flowtests__/RelayModernFlowtest_notref.graphql.js.flow +1 -0
  21. package/__flowtests__/RelayModernFlowtest_user.graphql.js.flow +1 -0
  22. package/__flowtests__/RelayModernFlowtest_users.graphql.js.flow +1 -0
  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 -0
  34. package/buildReactRelayContainer.js.flow +10 -6
  35. package/getRootVariablesForFragments.js.flow +1 -1
  36. package/hooks.js +1 -1
  37. package/hooks.js.flow +4 -0
  38. package/index.js +1 -1
  39. package/index.js.flow +4 -0
  40. package/isRelayEnvironment.js.flow +1 -0
  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 -0
  46. package/lib/ReactRelayContainerUtils.js +0 -11
  47. package/lib/ReactRelayContext.js +1 -12
  48. package/lib/ReactRelayFragmentContainer.js +23 -122
  49. package/lib/ReactRelayFragmentMockRenderer.js +0 -12
  50. package/lib/ReactRelayLocalQueryRenderer.js +12 -41
  51. package/lib/ReactRelayPaginationContainer.js +45 -341
  52. package/lib/ReactRelayQueryFetcher.js +36 -111
  53. package/lib/ReactRelayQueryRenderer.js +29 -137
  54. package/lib/ReactRelayQueryRendererContext.js +0 -10
  55. package/lib/ReactRelayRefetchContainer.js +33 -166
  56. package/lib/ReactRelayTestMocker.js +18 -128
  57. package/lib/ReactRelayTypes.js +0 -9
  58. package/lib/RelayContext.js +0 -23
  59. package/lib/assertFragmentMap.js +0 -16
  60. package/lib/buildReactRelayContainer.js +7 -41
  61. package/lib/getRootVariablesForFragments.js +2 -19
  62. package/lib/hooks.js +3 -30
  63. package/lib/index.js +3 -39
  64. package/lib/isRelayEnvironment.js +1 -16
  65. package/lib/jest-react/enqueueTask.js +1 -25
  66. package/lib/jest-react/index.js +0 -1
  67. package/lib/jest-react/internalAct.js +2 -51
  68. package/lib/legacy.js +0 -20
  69. package/lib/multi-actor/ActorChange.js +0 -14
  70. package/lib/multi-actor/index.js +0 -10
  71. package/lib/multi-actor/useRelayActorEnvironment.js +2 -16
  72. package/lib/relay-hooks/EntryPointContainer.react.js +7 -23
  73. package/lib/relay-hooks/EntryPointTypes.flow.js +0 -10
  74. package/lib/relay-hooks/FragmentResource.js +130 -280
  75. package/lib/relay-hooks/HooksImplementation.js +0 -14
  76. package/lib/relay-hooks/InternalLogger.js +0 -11
  77. package/lib/relay-hooks/LRUCache.js +0 -39
  78. package/lib/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js +27 -65
  79. package/lib/relay-hooks/MatchContainer.js +9 -111
  80. package/lib/relay-hooks/NestedRelayEntryPointBuilderUtils.js +9 -0
  81. package/lib/relay-hooks/ProfilerContext.js +0 -14
  82. package/lib/relay-hooks/QueryResource.js +14 -149
  83. package/lib/relay-hooks/RelayEnvironmentProvider.js +3 -17
  84. package/lib/relay-hooks/SuspenseResource.js +2 -59
  85. package/lib/relay-hooks/loadEntryPoint.js +10 -45
  86. package/lib/relay-hooks/loadQuery.js +29 -169
  87. package/lib/relay-hooks/preloadQuery_DEPRECATED.js +8 -58
  88. package/lib/relay-hooks/prepareEntryPoint_DEPRECATED.js +6 -24
  89. package/lib/relay-hooks/react-cache/RelayReactCache.js +4 -20
  90. package/lib/relay-hooks/react-cache/getQueryResultOrFetchQuery_REACT_CACHE.js +13 -102
  91. package/lib/relay-hooks/react-cache/readFragmentInternal_REACT_CACHE.js +18 -75
  92. package/lib/relay-hooks/react-cache/useFragmentInternal_REACT_CACHE.js +79 -222
  93. package/lib/relay-hooks/react-cache/useFragment_REACT_CACHE.js +3 -27
  94. package/lib/relay-hooks/react-cache/useLazyLoadQuery_REACT_CACHE.js +11 -33
  95. package/lib/relay-hooks/react-cache/usePaginationFragment_REACT_CACHE.js +62 -85
  96. package/lib/relay-hooks/react-cache/usePreloadedQuery_REACT_CACHE.js +20 -63
  97. package/lib/relay-hooks/react-cache/useRefetchableFragmentInternal_REACT_CACHE.js +53 -179
  98. package/lib/relay-hooks/react-cache/useRefetchableFragment_REACT_CACHE.js +5 -27
  99. package/lib/relay-hooks/useBlockingPaginationFragment.js +58 -121
  100. package/lib/relay-hooks/useClientQuery.js +0 -21
  101. package/lib/relay-hooks/useEntryPointLoader.js +12 -100
  102. package/lib/relay-hooks/useFetchTrackingRef.js +6 -33
  103. package/lib/relay-hooks/useFragment.js +5 -32
  104. package/lib/relay-hooks/useFragmentNode.js +14 -55
  105. package/lib/relay-hooks/useIsMountedRef.js +2 -14
  106. package/lib/relay-hooks/useIsOperationNodeActive.js +6 -29
  107. package/lib/relay-hooks/useIsParentQueryActive.js +1 -15
  108. package/lib/relay-hooks/useLazyLoadQuery.js +2 -23
  109. package/lib/relay-hooks/useLazyLoadQueryNode.js +18 -63
  110. package/lib/relay-hooks/useLoadMoreFunction.js +44 -100
  111. package/lib/relay-hooks/useMemoOperationDescriptor.js +4 -23
  112. package/lib/relay-hooks/useMemoVariables.js +8 -43
  113. package/lib/relay-hooks/useMutation.js +6 -34
  114. package/lib/relay-hooks/usePaginationFragment.js +49 -89
  115. package/lib/relay-hooks/usePreloadedQuery.js +10 -54
  116. package/lib/relay-hooks/useQueryLoader.js +18 -116
  117. package/lib/relay-hooks/useRefetchableFragment.js +4 -30
  118. package/lib/relay-hooks/useRefetchableFragmentNode.js +58 -184
  119. package/lib/relay-hooks/useRelayEnvironment.js +2 -16
  120. package/lib/relay-hooks/useStaticFragmentNodeWarning.js +2 -20
  121. package/lib/relay-hooks/useSubscribeToInvalidationState.js +3 -28
  122. package/lib/relay-hooks/useSubscription.js +3 -22
  123. package/lib/relay-hooks/useUnsafeRef_DEPRECATED.js +12 -0
  124. package/multi-actor/ActorChange.js.flow +1 -1
  125. package/multi-actor/index.js.flow +1 -1
  126. package/multi-actor/useRelayActorEnvironment.js.flow +2 -2
  127. package/package.json +2 -2
  128. package/react-relay-hooks.js +2 -2
  129. package/react-relay-hooks.min.js +2 -2
  130. package/react-relay-legacy.js +2 -2
  131. package/react-relay-legacy.min.js +2 -2
  132. package/react-relay.js +2 -2
  133. package/react-relay.min.js +2 -2
  134. package/relay-hooks/EntryPointContainer.react.js.flow +6 -1
  135. package/relay-hooks/EntryPointTypes.flow.js.flow +23 -20
  136. package/relay-hooks/FragmentResource.js.flow +148 -34
  137. package/relay-hooks/HooksImplementation.js.flow +1 -1
  138. package/relay-hooks/InternalLogger.js.flow +1 -1
  139. package/relay-hooks/LRUCache.js.flow +1 -1
  140. package/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js.flow +19 -10
  141. package/relay-hooks/MatchContainer.js.flow +1 -1
  142. package/relay-hooks/NestedRelayEntryPointBuilderUtils.js.flow +51 -0
  143. package/relay-hooks/ProfilerContext.js.flow +1 -1
  144. package/relay-hooks/QueryResource.js.flow +25 -5
  145. package/relay-hooks/RelayEnvironmentProvider.js.flow +2 -2
  146. package/relay-hooks/SuspenseResource.js.flow +1 -1
  147. package/relay-hooks/__flowtests__/EntryPointTypes/EntryPointElementConfig-flowtest.js.flow +3 -1
  148. package/relay-hooks/__flowtests__/EntryPointTypes/NestedEntrypoints-flowtest.js.flow +9 -7
  149. package/relay-hooks/__flowtests__/__generated__/useFragmentFlowtest_user.graphql.js.flow +3 -1
  150. package/relay-hooks/__flowtests__/__generated__/useFragmentFlowtest_users.graphql.js.flow +3 -1
  151. package/relay-hooks/__flowtests__/useBlockingPaginationFragment-flowtest.js.flow +40 -33
  152. package/relay-hooks/__flowtests__/useFragment-flowtest.js.flow +1 -1
  153. package/relay-hooks/__flowtests__/usePaginationFragment-flowtest.js.flow +38 -32
  154. package/relay-hooks/__flowtests__/useRefetchableFragment-flowtest.js.flow +20 -18
  155. package/relay-hooks/__flowtests__/utils.js.flow +13 -2
  156. package/relay-hooks/loadEntryPoint.js.flow +15 -8
  157. package/relay-hooks/loadQuery.js.flow +32 -8
  158. package/relay-hooks/preloadQuery_DEPRECATED.js.flow +5 -6
  159. package/relay-hooks/prepareEntryPoint_DEPRECATED.js.flow +17 -10
  160. package/relay-hooks/react-cache/RelayReactCache.js.flow +1 -1
  161. package/relay-hooks/react-cache/getQueryResultOrFetchQuery_REACT_CACHE.js.flow +4 -4
  162. package/relay-hooks/react-cache/readFragmentInternal_REACT_CACHE.js.flow +5 -4
  163. package/relay-hooks/react-cache/useFragmentInternal_REACT_CACHE.js.flow +32 -14
  164. package/relay-hooks/react-cache/useFragment_REACT_CACHE.js.flow +4 -10
  165. package/relay-hooks/react-cache/useLazyLoadQuery_REACT_CACHE.js.flow +1 -1
  166. package/relay-hooks/react-cache/usePaginationFragment_REACT_CACHE.js.flow +39 -49
  167. package/relay-hooks/react-cache/usePreloadedQuery_REACT_CACHE.js.flow +1 -2
  168. package/relay-hooks/react-cache/useRefetchableFragmentInternal_REACT_CACHE.js.flow +29 -16
  169. package/relay-hooks/react-cache/useRefetchableFragment_REACT_CACHE.js.flow +17 -33
  170. package/relay-hooks/useBlockingPaginationFragment.js.flow +85 -58
  171. package/relay-hooks/useClientQuery.js.flow +3 -3
  172. package/relay-hooks/useEntryPointLoader.js.flow +10 -6
  173. package/relay-hooks/useFetchTrackingRef.js.flow +5 -4
  174. package/relay-hooks/useFragment.js.flow +2 -2
  175. package/relay-hooks/useFragmentNode.js.flow +7 -6
  176. package/relay-hooks/useIsMountedRef.js.flow +1 -1
  177. package/relay-hooks/useIsOperationNodeActive.js.flow +1 -1
  178. package/relay-hooks/useIsParentQueryActive.js.flow +1 -1
  179. package/relay-hooks/useLazyLoadQuery.js.flow +2 -2
  180. package/relay-hooks/useLazyLoadQueryNode.js.flow +2 -2
  181. package/relay-hooks/useLoadMoreFunction.js.flow +27 -16
  182. package/relay-hooks/useMemoOperationDescriptor.js.flow +3 -3
  183. package/relay-hooks/useMemoVariables.js.flow +13 -29
  184. package/relay-hooks/useMutation.js.flow +30 -13
  185. package/relay-hooks/usePaginationFragment.js.flow +55 -54
  186. package/relay-hooks/usePreloadedQuery.js.flow +47 -22
  187. package/relay-hooks/useQueryLoader.js.flow +78 -21
  188. package/relay-hooks/useRefetchableFragment.js.flow +65 -33
  189. package/relay-hooks/useRefetchableFragmentNode.js.flow +38 -17
  190. package/relay-hooks/useRelayEnvironment.js.flow +2 -2
  191. package/relay-hooks/useStaticFragmentNodeWarning.js.flow +3 -3
  192. package/relay-hooks/useSubscribeToInvalidationState.js.flow +2 -2
  193. package/relay-hooks/useSubscription.js.flow +1 -1
  194. package/relay-hooks/useUnsafeRef_DEPRECATED.js.flow +25 -0
  195. package/lib/readContext.js +0 -27
  196. package/readContext.js.flow +0 -29
@@ -4,9 +4,9 @@
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.
6
6
  *
7
- * @emails oncall+relay
8
7
  * @flow strict-local
9
8
  * @format
9
+ * @oncall relay
10
10
  */
11
11
 
12
12
  'use strict';
@@ -29,8 +29,8 @@ function useMemoOperationDescriptor(
29
29
  variables: Variables,
30
30
  cacheConfig?: ?CacheConfig,
31
31
  ): OperationDescriptor {
32
- const [memoVariables] = useMemoVariables(variables);
33
- const [memoCacheConfig] = useMemoVariables(cacheConfig || {});
32
+ const memoVariables = useMemoVariables(variables);
33
+ const memoCacheConfig = useMemoVariables(cacheConfig || {});
34
34
  return useMemo(
35
35
  () =>
36
36
  createOperationDescriptor(
@@ -4,9 +4,9 @@
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.
6
6
  *
7
- * @emails oncall+relay
8
7
  * @flow strict-local
9
8
  * @format
9
+ * @oncall relay
10
10
  */
11
11
 
12
12
  'use strict';
@@ -14,39 +14,23 @@
14
14
  import type {Variables} from 'relay-runtime';
15
15
 
16
16
  const areEqual = require('areEqual');
17
- const React = require('react');
18
-
19
- const {useMemo, useRef, useState} = React;
17
+ const {useState} = require('react');
20
18
 
19
+ /**
20
+ * Memoizes the passed in `variables` object based on `areEqual` equality.
21
+ * This is useful when a `variables` object is used as a value in a depencency
22
+ * array as it might often be constructed during render.
23
+ */
21
24
  function useMemoVariables<TVariables: Variables | null>(
22
25
  variables: TVariables,
23
- ): [TVariables, number] {
24
- // The value of this ref is a counter that should be incremented when
25
- // variables change. This allows us to use the counter as a
26
- // memoization value to indicate if the computation for useMemo
27
- // should be re-executed.
28
- const variablesChangedGenerationRef = useRef(0);
29
-
30
- // We mirror the variables to check if they have changed between renders
31
- const [mirroredVariables, setMirroredVariables] = useState<Variables | null>(
32
- variables,
33
- );
34
-
35
- const variablesChanged = !areEqual(variables, mirroredVariables);
36
- if (variablesChanged) {
37
- variablesChangedGenerationRef.current =
38
- (variablesChangedGenerationRef.current ?? 0) + 1;
26
+ ): TVariables {
27
+ const [mirroredVariables, setMirroredVariables] = useState(variables);
28
+ if (areEqual(variables, mirroredVariables)) {
29
+ return mirroredVariables;
30
+ } else {
39
31
  setMirroredVariables(variables);
32
+ return variables;
40
33
  }
41
-
42
- // NOTE: We disable react-hooks-deps warning because we explicitly
43
- // don't want to memoize on object identity
44
- // eslint-disable-next-line react-hooks/exhaustive-deps
45
- const memoVariables = useMemo(
46
- () => variables,
47
- [variablesChangedGenerationRef.current],
48
- );
49
- return [memoVariables, variablesChangedGenerationRef.current ?? 0];
50
34
  }
51
35
 
52
36
  module.exports = useMemoVariables;
@@ -4,23 +4,24 @@
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.
6
6
  *
7
- * @emails oncall+relay
8
7
  * @flow strict-local
9
8
  * @format
9
+ * @oncall relay
10
10
  */
11
11
 
12
12
  'use strict';
13
13
 
14
14
  import type {
15
+ CommitMutationConfig,
15
16
  DeclarativeMutationConfig,
16
17
  Disposable,
17
- GraphQLTaggedNode,
18
18
  IEnvironment,
19
- MutationConfig,
19
+ Mutation,
20
20
  MutationParameters,
21
21
  PayloadError,
22
22
  SelectorStoreUpdater,
23
23
  UploadableMap,
24
+ Variables,
24
25
  } from 'relay-runtime';
25
26
 
26
27
  const useIsMountedRef = require('./useIsMountedRef');
@@ -50,22 +51,38 @@ export type UseMutationConfig<TMutation: MutationParameters> = {
50
51
  variables: TMutation['variables'],
51
52
  };
52
53
 
53
- function useMutation<TMutation: MutationParameters>(
54
- mutation: GraphQLTaggedNode,
54
+ type UseMutationConfigInternal<TVariables, TData, TRawResponse> = {
55
+ configs?: Array<DeclarativeMutationConfig>,
56
+ onError?: ?(error: Error) => void,
57
+ onCompleted?: ?(response: TData, errors: ?Array<PayloadError>) => void,
58
+ onNext?: ?() => void,
59
+ onUnsubscribe?: ?() => void,
60
+ optimisticResponse?: TRawResponse,
61
+ optimisticUpdater?: ?SelectorStoreUpdater<TData>,
62
+ updater?: ?SelectorStoreUpdater<TData>,
63
+ uploadables?: UploadableMap,
64
+ variables: TVariables,
65
+ };
66
+
67
+ function useMutation<TVariables: Variables, TData, TRawResponse = {...}>(
68
+ mutation: Mutation<TVariables, TData, TRawResponse>,
55
69
  commitMutationFn?: (
56
70
  environment: IEnvironment,
57
- config: MutationConfig<TMutation>,
71
+ config: CommitMutationConfig<TVariables, TData, TRawResponse>,
58
72
  ) => Disposable = defaultCommitMutation,
59
- ): [(UseMutationConfig<TMutation>) => Disposable, boolean] {
73
+ ): [
74
+ (UseMutationConfigInternal<TVariables, TData, TRawResponse>) => Disposable,
75
+ boolean,
76
+ ] {
60
77
  const environment = useRelayEnvironment();
61
78
  const isMountedRef = useIsMountedRef();
62
79
  const environmentRef = useRef(environment);
63
80
  const mutationRef = useRef(mutation);
64
- const inFlightMutationsRef = useRef(new Set());
81
+ const inFlightMutationsRef = useRef(new Set<Disposable>());
65
82
  const [isMutationInFlight, setMutationInFlight] = useState(false);
66
83
 
67
84
  const cleanup = useCallback(
68
- disposable => {
85
+ (disposable: Disposable) => {
69
86
  if (
70
87
  environmentRef.current === environment &&
71
88
  mutationRef.current === mutation
@@ -94,18 +111,18 @@ function useMutation<TMutation: MutationParameters>(
94
111
  }, [environment, isMountedRef, mutation]);
95
112
 
96
113
  const commit = useCallback(
97
- (config: UseMutationConfig<TMutation>) => {
114
+ (config: UseMutationConfigInternal<TVariables, TData, TRawResponse>) => {
98
115
  if (isMountedRef.current) {
99
116
  setMutationInFlight(true);
100
117
  }
101
- const disposable = commitMutationFn(environment, {
118
+ const disposable: Disposable = commitMutationFn(environment, {
102
119
  ...config,
103
120
  mutation,
104
- onCompleted: (response, errors) => {
121
+ onCompleted: (response: TData, errors: ?Array<PayloadError>) => {
105
122
  cleanup(disposable);
106
123
  config.onCompleted?.(response, errors);
107
124
  },
108
- onError: error => {
125
+ onError: (error: Error) => {
109
126
  cleanup(disposable);
110
127
  config.onError?.(error);
111
128
  },
@@ -4,21 +4,22 @@
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.
6
6
  *
7
- * @emails oncall+relay
8
7
  * @flow strict-local
9
8
  * @format
9
+ * @oncall relay
10
10
  */
11
11
 
12
12
  'use strict';
13
13
 
14
14
  import type {LoadMoreFn, UseLoadMoreFunctionArgs} from './useLoadMoreFunction';
15
- import type {RefetchFnDynamic} from './useRefetchableFragmentNode';
15
+ import type {RefetchFn} from './useRefetchableFragment';
16
+ import type {Options} from './useRefetchableFragmentNode';
16
17
  import type {
17
18
  FragmentType,
18
19
  GraphQLResponse,
19
- GraphQLTaggedNode,
20
20
  Observer,
21
- OperationType,
21
+ RefetchableFragment,
22
+ Variables,
22
23
  } from 'relay-runtime';
23
24
 
24
25
  const HooksImplementation = require('./HooksImplementation');
@@ -32,43 +33,28 @@ const {
32
33
  getPaginationMetadata,
33
34
  } = require('relay-runtime');
34
35
 
35
- export type ReturnType<TQuery: OperationType, TKey> = {
36
- // NOTE: This $Call ensures that the type of the returned data is either:
37
- // - nullable if the provided ref type is nullable
38
- // - non-nullable if the provided ref type is non-nullable
39
- // prettier-ignore
40
- data: $Call<
41
- & (<TFragmentData>( { +$data?: TFragmentData, ... }) => TFragmentData)
42
- & (<TFragmentData>(?{ +$data?: TFragmentData, ... }) => ?TFragmentData),
43
- TKey,
44
- >,
45
- loadNext: LoadMoreFn<TQuery>,
46
- loadPrevious: LoadMoreFn<TQuery>,
47
- hasNext: boolean,
48
- hasPrevious: boolean,
49
- isLoadingNext: boolean,
50
- isLoadingPrevious: boolean,
51
- refetch: RefetchFnDynamic<TQuery, TKey>,
52
- };
53
-
54
36
  // This separate type export is only needed as long as we are injecting
55
37
  // a separate hooks implementation in ./HooksImplementation -- it can
56
38
  // be removed after we stop doing that.
57
39
  export type UsePaginationFragmentType = <
58
- TQuery: OperationType,
59
- TKey: ?{+$data?: mixed, +$fragmentSpreads: FragmentType, ...},
40
+ TFragmentType: FragmentType,
41
+ TVariables: Variables,
42
+ TData,
43
+ TKey: ?{+$fragmentSpreads: TFragmentType, ...},
60
44
  >(
61
- fragmentInput: GraphQLTaggedNode,
45
+ fragmentInput: RefetchableFragment<TFragmentType, TData, TVariables>,
62
46
  parentFragmentRef: TKey,
63
- ) => ReturnType<TQuery, TKey>;
47
+ ) => ReturnType<TVariables, TData, TKey>;
64
48
 
65
49
  function usePaginationFragment_LEGACY<
66
- TQuery: OperationType,
67
- TKey: ?{+$data?: mixed, +$fragmentSpreads: FragmentType, ...},
50
+ TFragmentType: FragmentType,
51
+ TVariables: Variables,
52
+ TData,
53
+ TKey: ?{+$fragmentSpreads: TFragmentType, ...},
68
54
  >(
69
- fragmentInput: GraphQLTaggedNode,
55
+ fragmentInput: RefetchableFragment<TFragmentType, TData, TVariables>,
70
56
  parentFragmentRef: TKey,
71
- ): ReturnType<TQuery, TKey> {
57
+ ): ReturnType<TVariables, TData, TKey> {
72
58
  const fragmentNode = getFragment(fragmentInput);
73
59
  useStaticFragmentNodeWarning(
74
60
  fragmentNode,
@@ -76,22 +62,18 @@ function usePaginationFragment_LEGACY<
76
62
  );
77
63
  const componentDisplayName = 'usePaginationFragment()';
78
64
 
79
- const {
80
- connectionPathInFragmentData,
81
- paginationRequest,
82
- paginationMetadata,
83
- identifierField,
84
- } = getPaginationMetadata(fragmentNode, componentDisplayName);
65
+ const {connectionPathInFragmentData, paginationRequest, paginationMetadata} =
66
+ getPaginationMetadata(fragmentNode, componentDisplayName);
85
67
 
86
68
  const {fragmentData, fragmentRef, refetch} = useRefetchableFragmentNode<
87
- TQuery,
88
- TKey,
69
+ $FlowFixMe,
70
+ $FlowFixMe,
89
71
  >(fragmentNode, parentFragmentRef, componentDisplayName);
90
72
  const fragmentIdentifier = getFragmentIdentifier(fragmentNode, fragmentRef);
91
73
 
92
74
  // Backward pagination
93
75
  const [loadPrevious, hasPrevious, isLoadingPrevious, disposeFetchPrevious] =
94
- useLoadMore<TQuery>({
76
+ useLoadMore<TVariables>({
95
77
  componentDisplayName,
96
78
  connectionPathInFragmentData,
97
79
  direction: 'backward',
@@ -99,14 +81,13 @@ function usePaginationFragment_LEGACY<
99
81
  fragmentIdentifier,
100
82
  fragmentNode,
101
83
  fragmentRef,
102
- identifierField,
103
84
  paginationMetadata,
104
85
  paginationRequest,
105
86
  });
106
87
 
107
88
  // Forward pagination
108
89
  const [loadNext, hasNext, isLoadingNext, disposeFetchNext] =
109
- useLoadMore<TQuery>({
90
+ useLoadMore<TVariables>({
110
91
  componentDisplayName,
111
92
  connectionPathInFragmentData,
112
93
  direction: 'forward',
@@ -114,13 +95,12 @@ function usePaginationFragment_LEGACY<
114
95
  fragmentIdentifier,
115
96
  fragmentNode,
116
97
  fragmentRef,
117
- identifierField,
118
98
  paginationMetadata,
119
99
  paginationRequest,
120
100
  });
121
101
 
122
- const refetchPagination: RefetchFnDynamic<TQuery, TKey> = useCallback(
123
- (variables, options) => {
102
+ const refetchPagination: RefetchFn<TVariables, TKey> = useCallback(
103
+ (variables: TVariables, options: void | Options) => {
124
104
  disposeFetchNext();
125
105
  disposeFetchPrevious();
126
106
  return refetch(variables, {...options, __environment: undefined});
@@ -140,7 +120,7 @@ function usePaginationFragment_LEGACY<
140
120
  });
141
121
  }
142
122
  return {
143
- data: fragmentData,
123
+ data: (fragmentData: $FlowFixMe),
144
124
  loadNext,
145
125
  loadPrevious,
146
126
  hasNext,
@@ -151,7 +131,7 @@ function usePaginationFragment_LEGACY<
151
131
  };
152
132
  }
153
133
 
154
- function useLoadMore<TQuery: OperationType>(
134
+ function useLoadMore<TVariables: Variables>(
155
135
  args: $Diff<
156
136
  UseLoadMoreFunctionArgs,
157
137
  {
@@ -160,7 +140,7 @@ function useLoadMore<TQuery: OperationType>(
160
140
  ...
161
141
  },
162
142
  >,
163
- ): [LoadMoreFn<TQuery>, boolean, boolean, () => void] {
143
+ ): [LoadMoreFn<TVariables>, boolean, boolean, () => void] {
164
144
  const [isLoadingMore, setIsLoadingMore] = useState(false);
165
145
  const observer = {
166
146
  start: () => setIsLoadingMore(true),
@@ -168,7 +148,7 @@ function useLoadMore<TQuery: OperationType>(
168
148
  error: () => setIsLoadingMore(false),
169
149
  };
170
150
  const handleReset = () => setIsLoadingMore(false);
171
- const [loadMore, hasMore, disposeFetch] = useLoadMoreFunction({
151
+ const [loadMore, hasMore, disposeFetch] = useLoadMoreFunction<TVariables>({
172
152
  ...args,
173
153
  observer,
174
154
  onReset: handleReset,
@@ -176,16 +156,37 @@ function useLoadMore<TQuery: OperationType>(
176
156
  return [loadMore, hasMore, isLoadingMore, disposeFetch];
177
157
  }
178
158
 
159
+ export type ReturnType<TVariables, TData, TKey> = {
160
+ // NOTE: This $Call ensures that the type of the returned data is either:
161
+ // - nullable if the provided ref type is nullable
162
+ // - non-nullable if the provided ref type is non-nullable
163
+ // prettier-ignore
164
+ data: $Call<
165
+ & (<TFragmentType>( { +$fragmentSpreads: TFragmentType, ... }) => TData)
166
+ & (<TFragmentType>(?{ +$fragmentSpreads: TFragmentType, ... }) => ?TData),
167
+ TKey,
168
+ >,
169
+ loadNext: LoadMoreFn<TVariables>,
170
+ loadPrevious: LoadMoreFn<TVariables>,
171
+ hasNext: boolean,
172
+ hasPrevious: boolean,
173
+ isLoadingNext: boolean,
174
+ isLoadingPrevious: boolean,
175
+ refetch: RefetchFn<TVariables, TKey>,
176
+ };
177
+
179
178
  function usePaginationFragment<
180
- TQuery: OperationType,
181
- TKey: ?{+$data?: mixed, +$fragmentSpreads: FragmentType, ...},
179
+ TFragmentType: FragmentType,
180
+ TVariables: Variables,
181
+ TData,
182
+ TKey: ?{+$fragmentSpreads: TFragmentType, ...},
182
183
  >(
183
- fragmentInput: GraphQLTaggedNode,
184
+ fragmentInput: RefetchableFragment<TFragmentType, TData, TVariables>,
184
185
  parentFragmentRef: TKey,
185
- ): ReturnType<TQuery, TKey> {
186
+ ): ReturnType<TVariables, TData, TKey> {
186
187
  const impl = HooksImplementation.get();
187
188
  if (impl) {
188
- return impl.usePaginationFragment<TQuery, TKey>(
189
+ return impl.usePaginationFragment<TFragmentType, TVariables, TData, TKey>(
189
190
  fragmentInput,
190
191
  parentFragmentRef,
191
192
  );
@@ -4,19 +4,19 @@
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.
6
6
  *
7
- * @emails oncall+relay
8
7
  * @flow strict-local
9
8
  * @format
9
+ * @oncall relay
10
10
  */
11
11
 
12
12
  'use strict';
13
13
 
14
- import type {PreloadedQuery} from './EntryPointTypes.flow';
15
14
  import type {
16
- GraphQLTaggedNode,
17
- OperationType,
18
- RenderPolicy,
19
- } from 'relay-runtime';
15
+ EnvironmentProviderOptions,
16
+ PreloadedQueryInner,
17
+ PreloadedQueryInner_DEPRECATED,
18
+ } from './EntryPointTypes.flow';
19
+ import type {Query, RenderPolicy, Variables} from 'relay-runtime';
20
20
 
21
21
  const {useTrackLoadQueryInRender} = require('./loadQuery');
22
22
  const useLazyLoadQueryNode = require('./useLazyLoadQueryNode');
@@ -29,24 +29,44 @@ const {
29
29
  } = require('relay-runtime');
30
30
  const warning = require('warning');
31
31
 
32
- // This separate type export is only needed as long as we are injecting
33
- // a separate hooks implementation in ./HooksImplementation -- it can
34
- // be removed after we stop doing that.
35
- export type UsePreloadedQueryHookType = <TQuery: OperationType>(
36
- gqlQuery: GraphQLTaggedNode,
37
- preloadedQuery: PreloadedQuery<TQuery>,
38
- options?: {
39
- UNSTABLE_renderPolicy?: RenderPolicy,
40
- },
41
- ) => TQuery['response'];
32
+ type PreloadedQuery<
33
+ TVariables: Variables,
34
+ TData,
35
+ TRawResponse,
36
+ TEnvironmentProviderOptions = EnvironmentProviderOptions,
37
+ > =
38
+ | PreloadedQueryInner_DEPRECATED<
39
+ {
40
+ variables: TVariables,
41
+ response: TData,
42
+ rawResponse?: TRawResponse,
43
+ },
44
+ TEnvironmentProviderOptions,
45
+ >
46
+ | PreloadedQueryInner<
47
+ {
48
+ variables: TVariables,
49
+ response: TData,
50
+ rawResponse?: TRawResponse,
51
+ },
52
+ TEnvironmentProviderOptions,
53
+ >;
42
54
 
43
- function usePreloadedQuery<TQuery: OperationType>(
44
- gqlQuery: GraphQLTaggedNode,
45
- preloadedQuery: PreloadedQuery<TQuery>,
55
+ function usePreloadedQuery<
56
+ TVariables: Variables,
57
+ TData,
58
+ TRawResponse: ?{...} = void,
59
+ >(
60
+ gqlQuery: Query<TVariables, TData, TRawResponse>,
61
+ preloadedQuery: PreloadedQuery<
62
+ TVariables,
63
+ TData,
64
+ $NonMaybeType<TRawResponse>,
65
+ >,
46
66
  options?: {
47
67
  UNSTABLE_renderPolicy?: RenderPolicy,
48
68
  },
49
- ): TQuery['response'] {
69
+ ): TData {
50
70
  // We need to use this hook in order to be able to track if
51
71
  // loadQuery was called during render
52
72
  useTrackLoadQueryInRender();
@@ -136,7 +156,12 @@ function usePreloadedQuery<TQuery: OperationType>(
136
156
  };
137
157
  }
138
158
 
139
- const data = useLazyLoadQueryNode(useLazyLoadQueryNodeParams);
159
+ const data = useLazyLoadQueryNode<{
160
+ variables: TVariables,
161
+ response: TData,
162
+ rawResponse?: $NonMaybeType<TRawResponse>,
163
+ }>(useLazyLoadQueryNodeParams);
164
+
140
165
  if (__DEV__) {
141
166
  // eslint-disable-next-line react-hooks/rules-of-hooks
142
167
  useDebugValue({
@@ -151,4 +176,4 @@ function usePreloadedQuery<TQuery: OperationType>(
151
176
  return data;
152
177
  }
153
178
 
154
- module.exports = (usePreloadedQuery: UsePreloadedQueryHookType);
179
+ module.exports = usePreloadedQuery;
@@ -4,9 +4,9 @@
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.
6
6
  *
7
- * @emails oncall+relay
8
7
  * @flow strict-local
9
8
  * @format
9
+ * @oncall relay
10
10
  */
11
11
 
12
12
  'use strict';
@@ -17,9 +17,10 @@ import type {
17
17
  PreloadedQuery,
18
18
  } from './EntryPointTypes.flow';
19
19
  import type {
20
- GraphQLTaggedNode,
21
20
  IEnvironment,
22
21
  OperationType,
22
+ Query,
23
+ Variables,
23
24
  } from 'relay-runtime';
24
25
 
25
26
  const {loadQuery, useTrackLoadQueryInRender} = require('./loadQuery');
@@ -38,12 +39,6 @@ export type UseQueryLoaderLoadQueryOptions = $ReadOnly<{
38
39
  +__environment?: ?IEnvironment,
39
40
  }>;
40
41
 
41
- type UseQueryLoaderHookReturnType<TQuery: OperationType> = [
42
- ?PreloadedQuery<TQuery>,
43
- LoaderFn<TQuery>,
44
- () => void,
45
- ];
46
-
47
42
  // NullQueryReference needs to implement referential equality,
48
43
  // so that multiple NullQueryReferences can be in the same set
49
44
  // (corresponding to multiple calls to disposeQuery).
@@ -52,20 +47,85 @@ type NullQueryReference = {
52
47
  };
53
48
  const initialNullQueryReferenceState = {kind: 'NullQueryReference'};
54
49
 
55
- function requestIsLiveQuery<TQuery: OperationType>(
56
- preloadableRequest: GraphQLTaggedNode | PreloadableConcreteRequest<TQuery>,
50
+ function requestIsLiveQuery<
51
+ TVariables: Variables,
52
+ TData,
53
+ TRawResponse: ?{...} = void,
54
+ TQuery: OperationType = {
55
+ response: TData,
56
+ variables: TVariables,
57
+ rawResponse?: $NonMaybeType<TRawResponse>,
58
+ },
59
+ >(
60
+ preloadableRequest:
61
+ | Query<TVariables, TData, TRawResponse>
62
+ | PreloadableConcreteRequest<TQuery>,
57
63
  ): boolean {
58
64
  if (preloadableRequest.kind === 'PreloadableConcreteRequest') {
59
- return (preloadableRequest: $FlowFixMe).params.metadata.live !== undefined;
65
+ return preloadableRequest.params.metadata.live !== undefined;
60
66
  }
61
67
  const request = getRequest(preloadableRequest);
62
68
  return request.params.metadata.live !== undefined;
63
69
  }
64
70
 
65
- function useQueryLoader<TQuery: OperationType>(
66
- preloadableRequest: GraphQLTaggedNode | PreloadableConcreteRequest<TQuery>,
71
+ type UseQueryLoaderHookReturnType<
72
+ TVariables: Variables,
73
+ TData,
74
+ TRawResponse: ?{...} = void,
75
+ > = [
76
+ ?PreloadedQuery<{
77
+ response: TData,
78
+ variables: TVariables,
79
+ rawResponse?: $NonMaybeType<TRawResponse>,
80
+ }>,
81
+ (variables: TVariables, options?: UseQueryLoaderLoadQueryOptions) => void,
82
+ () => void,
83
+ ];
84
+
85
+ declare function useQueryLoader<
86
+ TVariables: Variables,
87
+ TData,
88
+ TRawResponse: ?{...} = void,
89
+ >(
90
+ preloadableRequest: Query<TVariables, TData, TRawResponse>,
91
+ ): UseQueryLoaderHookReturnType<TVariables, TData>;
92
+
93
+ declare function useQueryLoader<
94
+ TVariables: Variables,
95
+ TData,
96
+ TRawResponse: ?{...} = void,
97
+ >(
98
+ preloadableRequest: Query<TVariables, TData, TRawResponse>,
99
+ initialQueryReference: ?PreloadedQuery<{
100
+ response: TData,
101
+ variables: TVariables,
102
+ rawResponse?: $NonMaybeType<TRawResponse>,
103
+ }>,
104
+ ): UseQueryLoaderHookReturnType<TVariables, TData>;
105
+
106
+ declare function useQueryLoader<TQuery: OperationType>(
107
+ preloadableRequest: PreloadableConcreteRequest<TQuery>,
67
108
  initialQueryReference?: ?PreloadedQuery<TQuery>,
68
- ): UseQueryLoaderHookReturnType<TQuery> {
109
+ ): UseQueryLoaderHookReturnType<TQuery['variables'], TQuery['response']>;
110
+
111
+ function useQueryLoader<
112
+ TVariables: Variables,
113
+ TData,
114
+ TRawResponse: ?{...} = void,
115
+ >(
116
+ preloadableRequest: Query<TVariables, TData, TRawResponse>,
117
+ initialQueryReference?: ?PreloadedQuery<{
118
+ response: TData,
119
+ variables: TVariables,
120
+ rawResponse?: $NonMaybeType<TRawResponse>,
121
+ }>,
122
+ ): UseQueryLoaderHookReturnType<TVariables, TData> {
123
+ type QueryType = {
124
+ response: TData,
125
+ variables: TVariables,
126
+ rawResponse?: $NonMaybeType<TRawResponse>,
127
+ };
128
+
69
129
  /**
70
130
  * We want to always call `queryReference.dispose()` for every call to
71
131
  * `setQueryReference(loadQuery(...))` so that no leaks of data in Relay stores
@@ -94,15 +154,15 @@ function useQueryLoader<TQuery: OperationType>(
94
154
 
95
155
  const isMountedRef = useIsMountedRef();
96
156
  const undisposedQueryReferencesRef = useRef<
97
- Set<PreloadedQuery<TQuery> | NullQueryReference>,
157
+ Set<PreloadedQuery<QueryType> | NullQueryReference>,
98
158
  >(new Set([initialQueryReferenceInternal]));
99
159
 
100
160
  const [queryReference, setQueryReference] = useState<
101
- PreloadedQuery<TQuery> | NullQueryReference,
161
+ PreloadedQuery<QueryType> | NullQueryReference,
102
162
  >(() => initialQueryReferenceInternal);
103
163
 
104
164
  const [previousInitialQueryReference, setPreviousInitialQueryReference] =
105
- useState<PreloadedQuery<TQuery> | NullQueryReference>(
165
+ useState<PreloadedQuery<QueryType> | NullQueryReference>(
106
166
  () => initialQueryReferenceInternal,
107
167
  );
108
168
 
@@ -125,10 +185,7 @@ function useQueryLoader<TQuery: OperationType>(
125
185
  }, [isMountedRef]);
126
186
 
127
187
  const queryLoaderCallback = useCallback(
128
- (
129
- variables: TQuery['variables'],
130
- options?: ?UseQueryLoaderLoadQueryOptions,
131
- ) => {
188
+ (variables: TVariables, options?: ?UseQueryLoaderLoadQueryOptions) => {
132
189
  const mergedOptions: ?UseQueryLoaderLoadQueryOptions =
133
190
  options != null && options.hasOwnProperty('__environment')
134
191
  ? {