react-relay 14.1.0 → 16.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
  ? {