react-relay 15.0.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 (119) hide show
  1. package/ReactRelayContext.js +1 -1
  2. package/ReactRelayQueryFetcher.js.flow +1 -5
  3. package/ReactRelayQueryRenderer.js.flow +9 -36
  4. package/ReactRelayTypes.js.flow +1 -0
  5. package/buildReactRelayContainer.js.flow +3 -1
  6. package/hooks.js +1 -1
  7. package/index.js +1 -1
  8. package/legacy.js +1 -1
  9. package/lib/ReactRelayContainerUtils.js +0 -11
  10. package/lib/ReactRelayContext.js +0 -11
  11. package/lib/ReactRelayFragmentContainer.js +6 -78
  12. package/lib/ReactRelayFragmentMockRenderer.js +0 -11
  13. package/lib/ReactRelayLocalQueryRenderer.js +0 -17
  14. package/lib/ReactRelayPaginationContainer.js +5 -208
  15. package/lib/ReactRelayQueryFetcher.js +2 -51
  16. package/lib/ReactRelayQueryRenderer.js +6 -94
  17. package/lib/ReactRelayQueryRendererContext.js +0 -11
  18. package/lib/ReactRelayRefetchContainer.js +5 -91
  19. package/lib/ReactRelayTestMocker.js +9 -85
  20. package/lib/ReactRelayTypes.js +0 -11
  21. package/lib/RelayContext.js +0 -21
  22. package/lib/assertFragmentMap.js +0 -15
  23. package/lib/buildReactRelayContainer.js +0 -19
  24. package/lib/getRootVariablesForFragments.js +0 -14
  25. package/lib/hooks.js +0 -15
  26. package/lib/index.js +0 -17
  27. package/lib/isRelayEnvironment.js +1 -18
  28. package/lib/jest-react/enqueueTask.js +0 -20
  29. package/lib/jest-react/internalAct.js +0 -38
  30. package/lib/legacy.js +0 -15
  31. package/lib/multi-actor/ActorChange.js +0 -11
  32. package/lib/multi-actor/index.js +0 -11
  33. package/lib/multi-actor/useRelayActorEnvironment.js +0 -11
  34. package/lib/relay-hooks/EntryPointContainer.react.js +0 -11
  35. package/lib/relay-hooks/EntryPointTypes.flow.js +1 -14
  36. package/lib/relay-hooks/FragmentResource.js +76 -132
  37. package/lib/relay-hooks/HooksImplementation.js +0 -11
  38. package/lib/relay-hooks/InternalLogger.js +0 -11
  39. package/lib/relay-hooks/LRUCache.js +0 -22
  40. package/lib/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js +0 -18
  41. package/lib/relay-hooks/MatchContainer.js +0 -94
  42. package/lib/relay-hooks/NestedRelayEntryPointBuilderUtils.js +9 -0
  43. package/lib/relay-hooks/ProfilerContext.js +0 -15
  44. package/lib/relay-hooks/QueryResource.js +2 -68
  45. package/lib/relay-hooks/RelayEnvironmentProvider.js +0 -11
  46. package/lib/relay-hooks/SuspenseResource.js +0 -34
  47. package/lib/relay-hooks/loadEntryPoint.js +1 -24
  48. package/lib/relay-hooks/loadQuery.js +2 -106
  49. package/lib/relay-hooks/preloadQuery_DEPRECATED.js +2 -27
  50. package/lib/relay-hooks/prepareEntryPoint_DEPRECATED.js +0 -13
  51. package/lib/relay-hooks/react-cache/RelayReactCache.js +0 -12
  52. package/lib/relay-hooks/react-cache/getQueryResultOrFetchQuery_REACT_CACHE.js +1 -36
  53. package/lib/relay-hooks/react-cache/readFragmentInternal_REACT_CACHE.js +3 -27
  54. package/lib/relay-hooks/react-cache/useFragmentInternal_REACT_CACHE.js +34 -99
  55. package/lib/relay-hooks/react-cache/useFragment_REACT_CACHE.js +0 -15
  56. package/lib/relay-hooks/react-cache/useLazyLoadQuery_REACT_CACHE.js +0 -16
  57. package/lib/relay-hooks/react-cache/usePaginationFragment_REACT_CACHE.js +1 -23
  58. package/lib/relay-hooks/react-cache/usePreloadedQuery_REACT_CACHE.js +0 -29
  59. package/lib/relay-hooks/react-cache/useRefetchableFragmentInternal_REACT_CACHE.js +12 -96
  60. package/lib/relay-hooks/react-cache/useRefetchableFragment_REACT_CACHE.js +0 -14
  61. package/lib/relay-hooks/useBlockingPaginationFragment.js +0 -42
  62. package/lib/relay-hooks/useClientQuery.js +0 -18
  63. package/lib/relay-hooks/useEntryPointLoader.js +0 -69
  64. package/lib/relay-hooks/useFetchTrackingRef.js +0 -26
  65. package/lib/relay-hooks/useFragment.js +0 -17
  66. package/lib/relay-hooks/useFragmentNode.js +2 -32
  67. package/lib/relay-hooks/useIsMountedRef.js +0 -11
  68. package/lib/relay-hooks/useIsOperationNodeActive.js +0 -11
  69. package/lib/relay-hooks/useIsParentQueryActive.js +0 -11
  70. package/lib/relay-hooks/useLazyLoadQuery.js +0 -18
  71. package/lib/relay-hooks/useLazyLoadQueryNode.js +0 -35
  72. package/lib/relay-hooks/useLoadMoreFunction.js +9 -34
  73. package/lib/relay-hooks/useMemoOperationDescriptor.js +0 -11
  74. package/lib/relay-hooks/useMemoVariables.js +0 -17
  75. package/lib/relay-hooks/useMutation.js +0 -11
  76. package/lib/relay-hooks/usePaginationFragment.js +1 -26
  77. package/lib/relay-hooks/usePreloadedQuery.js +0 -27
  78. package/lib/relay-hooks/useQueryLoader.js +0 -74
  79. package/lib/relay-hooks/useRefetchableFragment.js +0 -16
  80. package/lib/relay-hooks/useRefetchableFragmentNode.js +14 -97
  81. package/lib/relay-hooks/useRelayEnvironment.js +0 -11
  82. package/lib/relay-hooks/useStaticFragmentNodeWarning.js +0 -15
  83. package/lib/relay-hooks/useSubscribeToInvalidationState.js +0 -25
  84. package/lib/relay-hooks/useSubscription.js +0 -15
  85. package/lib/relay-hooks/useUnsafeRef_DEPRECATED.js +0 -17
  86. package/package.json +2 -2
  87. package/react-relay-hooks.js +2 -2
  88. package/react-relay-hooks.min.js +2 -2
  89. package/react-relay-legacy.js +2 -2
  90. package/react-relay-legacy.min.js +2 -2
  91. package/react-relay.js +2 -2
  92. package/react-relay.min.js +2 -2
  93. package/relay-hooks/EntryPointContainer.react.js.flow +5 -0
  94. package/relay-hooks/EntryPointTypes.flow.js.flow +20 -19
  95. package/relay-hooks/FragmentResource.js.flow +114 -26
  96. package/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js.flow +4 -2
  97. package/relay-hooks/NestedRelayEntryPointBuilderUtils.js.flow +51 -0
  98. package/relay-hooks/__flowtests__/EntryPointTypes/NestedEntrypoints-flowtest.js.flow +7 -5
  99. package/relay-hooks/__flowtests__/useBlockingPaginationFragment-flowtest.js.flow +5 -0
  100. package/relay-hooks/__flowtests__/usePaginationFragment-flowtest.js.flow +5 -0
  101. package/relay-hooks/__flowtests__/useRefetchableFragment-flowtest.js.flow +2 -0
  102. package/relay-hooks/loadEntryPoint.js.flow +4 -2
  103. package/relay-hooks/loadQuery.js.flow +21 -1
  104. package/relay-hooks/prepareEntryPoint_DEPRECATED.js.flow +4 -2
  105. package/relay-hooks/react-cache/readFragmentInternal_REACT_CACHE.js.flow +2 -1
  106. package/relay-hooks/react-cache/useFragmentInternal_REACT_CACHE.js.flow +28 -10
  107. package/relay-hooks/react-cache/useFragment_REACT_CACHE.js.flow +3 -9
  108. package/relay-hooks/react-cache/usePaginationFragment_REACT_CACHE.js.flow +28 -57
  109. package/relay-hooks/react-cache/useRefetchableFragmentInternal_REACT_CACHE.js.flow +19 -12
  110. package/relay-hooks/react-cache/useRefetchableFragment_REACT_CACHE.js.flow +15 -31
  111. package/relay-hooks/useBlockingPaginationFragment.js.flow +2 -4
  112. package/relay-hooks/useClientQuery.js.flow +2 -2
  113. package/relay-hooks/useFragmentNode.js.flow +2 -2
  114. package/relay-hooks/useLoadMoreFunction.js.flow +15 -9
  115. package/relay-hooks/useMutation.js.flow +26 -9
  116. package/relay-hooks/usePaginationFragment.js.flow +2 -8
  117. package/relay-hooks/useQueryLoader.js.flow +2 -8
  118. package/relay-hooks/useRefetchableFragment.js.flow +3 -2
  119. package/relay-hooks/useRefetchableFragmentNode.js.flow +28 -13
@@ -11,55 +11,39 @@
11
11
 
12
12
  'use strict';
13
13
 
14
- import type {RefetchFnDynamic} from './useRefetchableFragmentInternal_REACT_CACHE';
15
- import type {
16
- FragmentType,
17
- GraphQLTaggedNode,
18
- OperationType,
19
- } from 'relay-runtime';
14
+ import type {ReturnType} from '../useRefetchableFragment';
15
+ import type {FragmentType, RefetchableFragment, Variables} from 'relay-runtime';
20
16
 
21
17
  const useStaticFragmentNodeWarning = require('../useStaticFragmentNodeWarning');
22
18
  const useRefetchableFragmentInternal = require('./useRefetchableFragmentInternal_REACT_CACHE');
23
19
  const {useDebugValue} = require('react');
24
20
  const {getFragment} = require('relay-runtime');
25
21
 
26
- type ReturnType<TQuery: OperationType, TKey: ?{+$data?: mixed, ...}> = [
27
- // NOTE: This $Call ensures that the type of the returned data is either:
28
- // - nullable if the provided ref type is nullable
29
- // - non-nullable if the provided ref type is non-nullable
30
- // prettier-ignore
31
- $Call<
32
- & (<TFragmentData>( { +$data?: TFragmentData, ... }) => TFragmentData)
33
- & (<TFragmentData>(?{ +$data?: TFragmentData, ... }) => ?TFragmentData),
34
- TKey,
35
- >,
36
- RefetchFnDynamic<TQuery, TKey>,
37
- ];
38
-
39
22
  function useRefetchableFragment<
40
- TQuery: OperationType,
41
- TKey: ?{+$data?: mixed, +$fragmentSpreads: FragmentType, ...},
23
+ TFragmentType: FragmentType,
24
+ TVariables: Variables,
25
+ TData,
26
+ TKey: ?{+$fragmentSpreads: TFragmentType, ...},
42
27
  >(
43
- fragmentInput: GraphQLTaggedNode,
28
+ fragmentInput: RefetchableFragment<TFragmentType, TData, TVariables>,
44
29
  fragmentRef: TKey,
45
- ): ReturnType<TQuery, TKey> {
30
+ ): ReturnType<TVariables, TData, TKey> {
46
31
  const fragmentNode = getFragment(fragmentInput);
47
32
  useStaticFragmentNodeWarning(
48
33
  fragmentNode,
49
34
  'first argument of useRefetchableFragment()',
50
35
  );
51
- const {fragmentData, refetch} = useRefetchableFragmentInternal<TQuery, TKey>(
52
- fragmentNode,
53
- fragmentRef,
54
- 'useRefetchableFragment()',
55
- );
36
+ const {fragmentData, refetch} = useRefetchableFragmentInternal<
37
+ {variables: TVariables, response: TData},
38
+ {data?: TData},
39
+ >(fragmentNode, fragmentRef, 'useRefetchableFragment()');
56
40
  if (__DEV__) {
57
41
  // eslint-disable-next-line react-hooks/rules-of-hooks
58
42
  useDebugValue({fragment: fragmentNode.name, data: fragmentData});
59
43
  }
60
- /* $FlowExpectedError[prop-missing] : Exposed options is a subset of internal
61
- * options */
62
- return [fragmentData, (refetch: RefetchFnDynamic<TQuery, TKey>)];
44
+ // $FlowFixMe[incompatible-return]
45
+ // $FlowFixMe[prop-missing]
46
+ return [fragmentData, refetch];
63
47
  }
64
48
 
65
49
  module.exports = useRefetchableFragment;
@@ -39,7 +39,7 @@ type RefetchVariables<TVariables, TKey> =
39
39
  // - non-nullable if the provided ref type is nullable, and the caller need to provide the full set of variables
40
40
  // prettier-ignore
41
41
  $Call<
42
- & (<TFragmentType>( { +$fragmentSpreads: TFragmentType, ... }) => $Shape<TVariables>)
42
+ & (<TFragmentType>( { +$fragmentSpreads: TFragmentType, ... }) => Partial<TVariables>)
43
43
  & (<TFragmentType>(?{ +$fragmentSpreads: TFragmentType, ... }) => TVariables),
44
44
  TKey,
45
45
  >;
@@ -89,7 +89,6 @@ function useBlockingPaginationFragment<
89
89
 
90
90
  const {
91
91
  connectionPathInFragmentData,
92
- identifierField,
93
92
  paginationRequest,
94
93
  paginationMetadata,
95
94
  stream,
@@ -132,7 +131,6 @@ function useBlockingPaginationFragment<
132
131
  fragmentIdentifier,
133
132
  fragmentNode,
134
133
  fragmentRef,
135
- identifierField,
136
134
  paginationMetadata,
137
135
  paginationRequest,
138
136
  });
@@ -148,7 +146,6 @@ function useBlockingPaginationFragment<
148
146
  fragmentIdentifier,
149
147
  fragmentNode,
150
148
  fragmentRef,
151
- identifierField,
152
149
  paginationMetadata,
153
150
  paginationRequest,
154
151
  });
@@ -157,6 +154,7 @@ function useBlockingPaginationFragment<
157
154
  (variables: TVariables, options: void | Options) => {
158
155
  disposeFetchNext();
159
156
  disposeFetchPrevious();
157
+ // $FlowFixMe[incompatible-variance]
160
158
  return refetch(variables, {...options, __environment: undefined});
161
159
  },
162
160
  [disposeFetchNext, disposeFetchPrevious, refetch],
@@ -20,8 +20,8 @@ const useLazyLoadQuery = require('./useLazyLoadQuery');
20
20
  * These queries are consist of queries for client-only data,
21
21
  * schematized via local schema extensions and/or Relay resolvers.
22
22
  */
23
- function useClientQuery<TVariables: Variables, TData>(
24
- gqlQuery: ClientQuery<TVariables, TData>,
23
+ function useClientQuery<TVariables: Variables, TData, TRawResponse>(
24
+ gqlQuery: ClientQuery<TVariables, TData, TRawResponse>,
25
25
  variables: TVariables,
26
26
  options?: {
27
27
  UNSTABLE_renderPolicy?: RenderPolicy,
@@ -17,7 +17,7 @@ const {getFragmentResourceForEnvironment} = require('./FragmentResource');
17
17
  const useRelayEnvironment = require('./useRelayEnvironment');
18
18
  const useUnsafeRef_DEPRECATED = require('./useUnsafeRef_DEPRECATED');
19
19
  const {useEffect, useState} = require('react');
20
- const {getFragmentIdentifier} = require('relay-runtime');
20
+ const {RelayFeatureFlags, getFragmentIdentifier} = require('relay-runtime');
21
21
  const warning = require('warning');
22
22
 
23
23
  type ReturnType<TFragmentData: mixed> = {
@@ -99,7 +99,7 @@ function useFragmentNode<TFragmentData: mixed>(
99
99
  // eslint-disable-next-line react-hooks/exhaustive-deps
100
100
  }, [environment, fragmentIdentifier]);
101
101
 
102
- if (__DEV__) {
102
+ if (RelayFeatureFlags.LOG_MISSING_RECORDS_IN_PROD || __DEV__) {
103
103
  if (
104
104
  fragmentRef != null &&
105
105
  (fragmentResult.data === undefined ||
@@ -33,6 +33,7 @@ const {
33
33
  ConnectionInterface,
34
34
  createOperationDescriptor,
35
35
  getPaginationVariables,
36
+ getRefetchMetadata,
36
37
  getSelector,
37
38
  getValueAtPath,
38
39
  } = require('relay-runtime');
@@ -42,7 +43,7 @@ export type LoadMoreFn<TVariables: Variables> = (
42
43
  count: number,
43
44
  options?: {
44
45
  onComplete?: (Error | null) => void,
45
- UNSTABLE_extraVariables?: $Shape<TVariables>,
46
+ UNSTABLE_extraVariables?: Partial<TVariables>,
46
47
  },
47
48
  ) => Disposable;
48
49
 
@@ -53,7 +54,6 @@ export type UseLoadMoreFunctionArgs = {
53
54
  fragmentIdentifier: string,
54
55
  fragmentData: mixed,
55
56
  connectionPathInFragmentData: $ReadOnlyArray<string | number>,
56
- identifierField: ?string,
57
57
  paginationRequest: ConcreteRequest,
58
58
  paginationMetadata: ReaderPaginationMetadata,
59
59
  componentDisplayName: string,
@@ -76,17 +76,22 @@ function useLoadMoreFunction<TVariables: Variables>(
76
76
  componentDisplayName,
77
77
  observer,
78
78
  onReset,
79
- identifierField,
80
79
  } = args;
81
80
  const environment = useRelayEnvironment();
82
81
  const {isFetchingRef, startFetch, disposeFetch, completeFetch} =
83
82
  useFetchTrackingRef();
83
+
84
+ const {identifierInfo} = getRefetchMetadata(
85
+ fragmentNode,
86
+ componentDisplayName,
87
+ );
84
88
  const identifierValue =
85
- identifierField != null &&
89
+ identifierInfo?.identifierField != null &&
86
90
  fragmentData != null &&
87
91
  typeof fragmentData === 'object'
88
- ? fragmentData[identifierField]
92
+ ? fragmentData[identifierInfo.identifierField]
89
93
  : null;
94
+
90
95
  const isMountedRef = useIsMountedRef();
91
96
  const [mirroredEnvironment, setMirroredEnvironment] = useState(environment);
92
97
  const [mirroredFragmentIdentifier, setMirroredFragmentIdentifier] =
@@ -125,7 +130,7 @@ function useLoadMoreFunction<TVariables: Variables>(
125
130
  (
126
131
  count: number,
127
132
  options: void | {
128
- UNSTABLE_extraVariables?: $Shape<TVariables>,
133
+ UNSTABLE_extraVariables?: Partial<TVariables>,
129
134
  onComplete?: (Error | null) => void,
130
135
  },
131
136
  ) => {
@@ -201,7 +206,7 @@ function useLoadMoreFunction<TVariables: Variables>(
201
206
 
202
207
  // If the query needs an identifier value ('id' or similar) and one
203
208
  // was not explicitly provided, read it from the fragment data.
204
- if (identifierField != null) {
209
+ if (identifierInfo != null) {
205
210
  // @refetchable fragments are guaranteed to have an `id` selection
206
211
  // if the type is Node, implements Node, or is @fetchable. Double-check
207
212
  // that there actually is a value at runtime.
@@ -210,11 +215,12 @@ function useLoadMoreFunction<TVariables: Variables>(
210
215
  false,
211
216
  'Relay: Expected result to have a string ' +
212
217
  '`%s` in order to refetch, got `%s`.',
213
- identifierField,
218
+ identifierInfo.identifierField,
214
219
  identifierValue,
215
220
  );
216
221
  }
217
- paginationVariables.id = identifierValue;
222
+ paginationVariables[identifierInfo.identifierQueryVariableName] =
223
+ identifierValue;
218
224
  }
219
225
 
220
226
  const paginationQuery = createOperationDescriptor(
@@ -12,15 +12,16 @@
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,13 +51,29 @@ 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);
@@ -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
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
  },
@@ -62,12 +62,8 @@ function usePaginationFragment_LEGACY<
62
62
  );
63
63
  const componentDisplayName = 'usePaginationFragment()';
64
64
 
65
- const {
66
- connectionPathInFragmentData,
67
- paginationRequest,
68
- paginationMetadata,
69
- identifierField,
70
- } = getPaginationMetadata(fragmentNode, componentDisplayName);
65
+ const {connectionPathInFragmentData, paginationRequest, paginationMetadata} =
66
+ getPaginationMetadata(fragmentNode, componentDisplayName);
71
67
 
72
68
  const {fragmentData, fragmentRef, refetch} = useRefetchableFragmentNode<
73
69
  $FlowFixMe,
@@ -85,7 +81,6 @@ function usePaginationFragment_LEGACY<
85
81
  fragmentIdentifier,
86
82
  fragmentNode,
87
83
  fragmentRef,
88
- identifierField,
89
84
  paginationMetadata,
90
85
  paginationRequest,
91
86
  });
@@ -100,7 +95,6 @@ function usePaginationFragment_LEGACY<
100
95
  fragmentIdentifier,
101
96
  fragmentNode,
102
97
  fragmentRef,
103
- identifierField,
104
98
  paginationMetadata,
105
99
  paginationRequest,
106
100
  });
@@ -82,9 +82,6 @@ type UseQueryLoaderHookReturnType<
82
82
  () => void,
83
83
  ];
84
84
 
85
- type ExtractVariablesType = <T>({+variables: T, ...}) => T;
86
- type ExtractResponseType = <T>({+response: T, ...}) => T;
87
-
88
85
  declare function useQueryLoader<
89
86
  TVariables: Variables,
90
87
  TData,
@@ -109,10 +106,7 @@ declare function useQueryLoader<
109
106
  declare function useQueryLoader<TQuery: OperationType>(
110
107
  preloadableRequest: PreloadableConcreteRequest<TQuery>,
111
108
  initialQueryReference?: ?PreloadedQuery<TQuery>,
112
- ): UseQueryLoaderHookReturnType<
113
- $Call<ExtractVariablesType, TQuery>,
114
- $Call<ExtractResponseType, TQuery>,
115
- >;
109
+ ): UseQueryLoaderHookReturnType<TQuery['variables'], TQuery['response']>;
116
110
 
117
111
  function useQueryLoader<
118
112
  TVariables: Variables,
@@ -201,7 +195,7 @@ function useQueryLoader<
201
195
  }
202
196
  : options;
203
197
  if (isMountedRef.current) {
204
- const updatedQueryReference = loadQuery<QueryType>(
198
+ const updatedQueryReference = loadQuery(
205
199
  options?.__environment ?? environment,
206
200
  preloadableRequest,
207
201
  variables,
@@ -31,7 +31,7 @@ type RefetchVariables<TVariables, TKey> =
31
31
  // - non-nullable if the provided ref type is non-nullable
32
32
  // prettier-ignore
33
33
  $Call<
34
- & (<TFragmentType>( { +$fragmentSpreads: TFragmentType, ... }) => $Shape<TVariables>)
34
+ & (<TFragmentType>( { +$fragmentSpreads: TFragmentType, ... }) => Partial<TVariables>)
35
35
  & (<TFragmentType>(?{ +$fragmentSpreads: TFragmentType, ... }) => TVariables),
36
36
  TKey,
37
37
  >;
@@ -46,7 +46,7 @@ export type RefetchFn<TVariables, TKey, TOptions = Options> = RefetchFnBase<
46
46
  TOptions,
47
47
  >;
48
48
 
49
- type ReturnType<TVariables, TData, TKey> = [
49
+ export type ReturnType<TVariables, TData, TKey> = [
50
50
  // NOTE: This $Call ensures that the type of the returned data is either:
51
51
  // - nullable if the provided ref type is nullable
52
52
  // - non-nullable if the provided ref type is non-nullable
@@ -100,6 +100,7 @@ function useRefetchableFragment_LEGACY<
100
100
 
101
101
  // $FlowFixMe[incompatible-return]
102
102
  // $FlowFixMe[prop-missing]
103
+ // $FlowFixMe[incompatible-variance]
103
104
  return [fragmentData, refetch];
104
105
  }
105
106
 
@@ -11,6 +11,7 @@
11
11
 
12
12
  'use strict';
13
13
 
14
+ import type {RefetchableIdentifierInfo} from '../../relay-runtime/util/ReaderNode';
14
15
  import type {LoaderFn} from './useQueryLoader';
15
16
  import type {
16
17
  ConcreteRequest,
@@ -100,7 +101,7 @@ type RefetchFnExact<TQuery: OperationType, TOptions = Options> = RefetchFnBase<
100
101
  type RefetchFnInexact<
101
102
  TQuery: OperationType,
102
103
  TOptions = Options,
103
- > = RefetchFnBase<$Shape<VariablesOf<TQuery>>, TOptions>;
104
+ > = RefetchFnBase<Partial<VariablesOf<TQuery>>, TOptions>;
104
105
 
105
106
  type Action =
106
107
  | {
@@ -173,8 +174,10 @@ function useRefetchableFragmentNode<
173
174
  componentDisplayName: string,
174
175
  ): ReturnType<TQuery, TKey, InternalOptions> {
175
176
  const parentEnvironment = useRelayEnvironment();
176
- const {refetchableRequest, fragmentRefPathInResponse, identifierField} =
177
- getRefetchMetadata(fragmentNode, componentDisplayName);
177
+ const {refetchableRequest, fragmentRefPathInResponse} = getRefetchMetadata(
178
+ fragmentNode,
179
+ componentDisplayName,
180
+ );
178
181
  const fragmentIdentifier = getFragmentIdentifier(
179
182
  fragmentNode,
180
183
  parentFragmentRef,
@@ -214,6 +217,12 @@ function useRefetchableFragmentNode<
214
217
  >((refetchableRequest: $FlowFixMe));
215
218
 
216
219
  let fragmentRef = parentFragmentRef;
220
+
221
+ const {identifierInfo} = getRefetchMetadata(
222
+ fragmentNode,
223
+ componentDisplayName,
224
+ );
225
+
217
226
  if (shouldReset) {
218
227
  dispatch({
219
228
  type: 'reset',
@@ -239,6 +248,7 @@ function useRefetchableFragmentNode<
239
248
  debugPreviousIDAndTypename = debugFunctions.getInitialIDAndType(
240
249
  refetchQuery.request.variables,
241
250
  fragmentRefPathInResponse,
251
+ identifierInfo?.identifierQueryVariableName,
242
252
  environment,
243
253
  );
244
254
  }
@@ -345,7 +355,7 @@ function useRefetchableFragmentNode<
345
355
  fragmentIdentifier,
346
356
  fragmentNode,
347
357
  fragmentRefPathInResponse,
348
- identifierField,
358
+ identifierInfo,
349
359
  loadQuery,
350
360
  parentFragmentRef,
351
361
  refetchableRequest,
@@ -381,17 +391,17 @@ function useRefetchFunction<TQuery: OperationType>(
381
391
  fragmentIdentifier: string,
382
392
  fragmentNode: ReaderFragment,
383
393
  fragmentRefPathInResponse: $ReadOnlyArray<string | number>,
384
- identifierField: ?string,
394
+ identifierInfo: ?RefetchableIdentifierInfo,
385
395
  loadQuery: LoaderFn<TQuery>,
386
396
  parentFragmentRef: mixed,
387
397
  refetchableRequest: ConcreteRequest,
388
398
  ): RefetchFn<TQuery, InternalOptions> {
389
399
  const isMountedRef = useIsMountedRef();
390
400
  const identifierValue =
391
- identifierField != null &&
401
+ identifierInfo?.identifierField != null &&
392
402
  fragmentData != null &&
393
403
  typeof fragmentData === 'object'
394
- ? fragmentData[identifierField]
404
+ ? fragmentData[identifierInfo.identifierField]
395
405
  : null;
396
406
  return useCallback(
397
407
  (
@@ -458,8 +468,10 @@ function useRefetchFunction<TQuery: OperationType>(
458
468
  // If the query needs an identifier value ('id' or similar) and one
459
469
  // was not explicitly provided, read it from the fragment data.
460
470
  if (
461
- identifierField != null &&
462
- !providedRefetchVariables.hasOwnProperty('id')
471
+ identifierInfo != null &&
472
+ !providedRefetchVariables.hasOwnProperty(
473
+ identifierInfo.identifierQueryVariableName,
474
+ )
463
475
  ) {
464
476
  // @refetchable fragments are guaranteed to have an `id` selection
465
477
  // if the type is Node, implements Node, or is @fetchable. Double-check
@@ -469,11 +481,13 @@ function useRefetchFunction<TQuery: OperationType>(
469
481
  false,
470
482
  'Relay: Expected result to have a string ' +
471
483
  '`%s` in order to refetch, got `%s`.',
472
- identifierField,
484
+ identifierInfo.identifierField,
473
485
  identifierValue,
474
486
  );
475
487
  }
476
- (refetchVariables: $FlowFixMe).id = identifierValue;
488
+ (refetchVariables: $FlowFixMe)[
489
+ identifierInfo.identifierQueryVariableName
490
+ ] = identifierValue;
477
491
  }
478
492
 
479
493
  const refetchQuery = createOperationDescriptor(
@@ -522,10 +536,11 @@ if (__DEV__) {
522
536
  getInitialIDAndType(
523
537
  memoRefetchVariables: ?Variables,
524
538
  fragmentRefPathInResponse: $ReadOnlyArray<string | number>,
539
+ identifierQueryVariableName: ?string,
525
540
  environment: IEnvironment,
526
541
  ): ?DebugIDandTypename {
527
542
  const {Record} = require('relay-runtime');
528
- const id = memoRefetchVariables?.id;
543
+ const id = memoRefetchVariables?.[identifierQueryVariableName ?? 'id'];
529
544
  if (
530
545
  fragmentRefPathInResponse.length !== 1 ||
531
546
  fragmentRefPathInResponse[0] !== 'node' ||
@@ -535,7 +550,7 @@ if (__DEV__) {
535
550
  }
536
551
  const recordSource = environment.getStore().getSource();
537
552
  const record = recordSource.get(id);
538
- const typename = record && Record.getType(record);
553
+ const typename = record == null ? null : Record.getType(record);
539
554
  if (typename == null) {
540
555
  return null;
541
556
  }