react-relay 20.1.1 → 21.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 (129) hide show
  1. package/ReactRelayContext.js +1 -1
  2. package/ReactRelayContext.js.flow +2 -2
  3. package/ReactRelayFragmentContainer.js.flow +8 -9
  4. package/ReactRelayLocalQueryRenderer.js.flow +11 -3
  5. package/ReactRelayLoggingContext.js.flow +3 -3
  6. package/ReactRelayPaginationContainer.js.flow +31 -24
  7. package/ReactRelayQueryFetcher.js.flow +1 -1
  8. package/ReactRelayQueryRenderer.js.flow +2 -2
  9. package/ReactRelayQueryRendererContext.js.flow +2 -2
  10. package/ReactRelayRefetchContainer.js.flow +17 -14
  11. package/ReactRelayTestMocker.js.flow +10 -10
  12. package/ReactRelayTypes.js.flow +18 -20
  13. package/RelayContext.js.flow +3 -3
  14. package/__flowtests__/ReactRelayFragmentContainer-flowtest.js.flow +11 -11
  15. package/__flowtests__/ReactRelayPaginationContainer-flowtest.js.flow +5 -5
  16. package/__flowtests__/ReactRelayRefetchContainer-flowtest.js.flow +5 -5
  17. package/__flowtests__/RelayModern-flowtest.js.flow +24 -27
  18. package/__flowtests__/RelayModernFlowtest_users.graphql.js.flow +1 -1
  19. package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer.graphql.js.flow +3 -4
  20. package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer2.graphql.js.flow +3 -4
  21. package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtestQuery.graphql.js.flow +9 -10
  22. package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtest_viewer.graphql.js.flow +4 -5
  23. package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtestQuery.graphql.js.flow +9 -10
  24. package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtest_viewer.graphql.js.flow +4 -5
  25. package/__flowtests__/__generated__/RelayModernFlowtest_badref.graphql.js.flow +3 -4
  26. package/__flowtests__/__generated__/RelayModernFlowtest_notref.graphql.js.flow +3 -4
  27. package/__flowtests__/__generated__/RelayModernFlowtest_user.graphql.js.flow +3 -4
  28. package/__flowtests__/__generated__/RelayModernFlowtest_users.graphql.js.flow +5 -6
  29. package/buildReactRelayContainer.js.flow +4 -4
  30. package/getRootVariablesForFragments.js.flow +1 -1
  31. package/hooks.js +1 -1
  32. package/hooks.js.flow +23 -8
  33. package/index.js +1 -1
  34. package/index.js.flow +40 -14
  35. package/isRelayEnvironment.js.flow +1 -1
  36. package/jest-react/internalAct.js.flow +1 -1
  37. package/legacy.js +1 -1
  38. package/legacy.js.flow +32 -13
  39. package/lib/ReactRelayFragmentContainer.js +1 -1
  40. package/lib/ReactRelayPaginationContainer.js +8 -8
  41. package/lib/ReactRelayRefetchContainer.js +8 -8
  42. package/lib/ReactRelayTestMocker.js +5 -5
  43. package/lib/hooks.js +18 -8
  44. package/lib/index.js +30 -14
  45. package/lib/legacy.js +26 -13
  46. package/lib/relay-hooks/legacy/useBlockingPaginationFragment.js +5 -5
  47. package/lib/relay-hooks/legacy/useRefetchableFragmentNode.js +34 -34
  48. package/lib/relay-hooks/loadEntryPoint.js +2 -2
  49. package/lib/relay-hooks/loadQuery.js +14 -14
  50. package/lib/relay-hooks/preloadQuery_DEPRECATED.js +10 -10
  51. package/lib/relay-hooks/readFragmentInternal.js +6 -6
  52. package/lib/relay-hooks/rsc/serverFetchQuery.js +20 -0
  53. package/lib/relay-hooks/rsc/serverPreloadQuery.js +31 -0
  54. package/lib/relay-hooks/rsc/serverReadFragment.js +15 -0
  55. package/lib/relay-hooks/rsc/useQueryFromServer.js +62 -0
  56. package/lib/relay-hooks/useFragmentInternal_CURRENT.js +49 -25
  57. package/lib/relay-hooks/useFragmentInternal_EXPERIMENTAL.js +81 -44
  58. package/lib/relay-hooks/useLazyLoadQueryNode.js +32 -19
  59. package/lib/relay-hooks/useMutation.js +6 -14
  60. package/lib/relay-hooks/useMutationAction_EXPERIMENTAL.js +26 -0
  61. package/lib/relay-hooks/usePreloadedQuery.js +52 -47
  62. package/lib/relay-hooks/useQueryLoader.js +2 -2
  63. package/lib/relay-hooks/useQueryLoader_EXPERIMENTAL.js +2 -2
  64. package/lib/relay-hooks/useRefetchableFragmentInternal.js +31 -31
  65. package/lib/rsc-client_EXPERIMENTAL.js +7 -0
  66. package/lib/rsc_EXPERIMENTAL.js +43 -0
  67. package/multi-actor/ActorChange.js.flow +1 -1
  68. package/package.json +3 -2
  69. package/relay-hooks/EntryPointContainer.react.js.flow +6 -6
  70. package/relay-hooks/EntryPointTypes.flow.js.flow +61 -67
  71. package/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js.flow +23 -21
  72. package/relay-hooks/MatchContainer.js.flow +12 -6
  73. package/relay-hooks/NestedRelayEntryPointBuilderUtils.js.flow +3 -9
  74. package/relay-hooks/QueryResource.js.flow +6 -6
  75. package/relay-hooks/RelayEnvironmentProvider.js.flow +2 -2
  76. package/relay-hooks/__flowtests__/EntryPointTypes/EntryPointElementConfig-flowtest.js.flow +6 -6
  77. package/relay-hooks/__flowtests__/EntryPointTypes/ExtractQueryTypes-flowtest.js.flow +48 -1
  78. package/relay-hooks/__flowtests__/EntryPointTypes/NestedEntrypoints-flowtest.js.flow +9 -9
  79. package/relay-hooks/__flowtests__/__generated__/useFragmentFlowtest_user.graphql.js.flow +3 -4
  80. package/relay-hooks/__flowtests__/__generated__/useFragmentFlowtest_users.graphql.js.flow +5 -6
  81. package/relay-hooks/__flowtests__/useBlockingPaginationFragment-flowtest.js.flow +27 -32
  82. package/relay-hooks/__flowtests__/useFragment-flowtest.js.flow +25 -25
  83. package/relay-hooks/__flowtests__/usePaginationFragment-flowtest.js.flow +26 -32
  84. package/relay-hooks/__flowtests__/useRefetchableFragment-flowtest.js.flow +23 -30
  85. package/relay-hooks/__flowtests__/utils.js.flow +4 -4
  86. package/relay-hooks/getConnectionState.js.flow +2 -2
  87. package/relay-hooks/legacy/FragmentResource.js.flow +13 -13
  88. package/relay-hooks/legacy/useBlockingPaginationFragment.js.flow +24 -25
  89. package/relay-hooks/legacy/useFragmentNode.js.flow +4 -4
  90. package/relay-hooks/legacy/useRefetchableFragmentNode.js.flow +79 -81
  91. package/relay-hooks/loadEntryPoint.js.flow +15 -13
  92. package/relay-hooks/loadQuery.js.flow +18 -18
  93. package/relay-hooks/preloadQuery_DEPRECATED.js.flow +16 -13
  94. package/relay-hooks/prepareEntryPoint_DEPRECATED.js.flow +7 -7
  95. package/relay-hooks/readFragmentInternal.js.flow +9 -9
  96. package/relay-hooks/rsc/serverFetchQuery.js.flow +31 -0
  97. package/relay-hooks/rsc/serverPreloadQuery.js.flow +69 -0
  98. package/relay-hooks/rsc/serverReadFragment.js.flow +33 -0
  99. package/relay-hooks/rsc/useQueryFromServer.js.flow +135 -0
  100. package/relay-hooks/useClientQuery.js.flow +2 -2
  101. package/relay-hooks/useEntryPointLoader.js.flow +11 -11
  102. package/relay-hooks/useFragment.js.flow +7 -7
  103. package/relay-hooks/useFragmentInternal.js.flow +1 -1
  104. package/relay-hooks/useFragmentInternal_CURRENT.js.flow +54 -22
  105. package/relay-hooks/useFragmentInternal_EXPERIMENTAL.js.flow +95 -46
  106. package/relay-hooks/useIsOperationNodeActive.js.flow +1 -1
  107. package/relay-hooks/useIsParentQueryActive.js.flow +1 -1
  108. package/relay-hooks/useLazyLoadQuery.js.flow +10 -3
  109. package/relay-hooks/useLazyLoadQueryNode.js.flow +67 -28
  110. package/relay-hooks/useLoadMoreFunction.js.flow +7 -6
  111. package/relay-hooks/useLoadMoreFunction_EXPERIMENTAL.js.flow +5 -5
  112. package/relay-hooks/useMemoVariables.js.flow +1 -1
  113. package/relay-hooks/useMutation.js.flow +8 -16
  114. package/relay-hooks/useMutationAction_EXPERIMENTAL.js.flow +68 -0
  115. package/relay-hooks/usePaginationFragment.js.flow +15 -11
  116. package/relay-hooks/usePrefetchableForwardPaginationFragment.js.flow +19 -18
  117. package/relay-hooks/usePrefetchableForwardPaginationFragment_EXPERIMENTAL.js.flow +19 -18
  118. package/relay-hooks/usePreloadedQuery.js.flow +119 -85
  119. package/relay-hooks/useQueryLoader.js.flow +27 -23
  120. package/relay-hooks/useQueryLoader_EXPERIMENTAL.js.flow +10 -10
  121. package/relay-hooks/useRefetchableFragment.js.flow +16 -11
  122. package/relay-hooks/useRefetchableFragmentInternal.js.flow +77 -79
  123. package/relay-hooks/useRelayLoggingContext.js.flow +1 -1
  124. package/relay-hooks/useSubscribeToInvalidationState.js.flow +1 -1
  125. package/relay-hooks/useSubscription.js.flow +1 -1
  126. package/rsc-client_EXPERIMENTAL.js +10 -0
  127. package/rsc-client_EXPERIMENTAL.js.flow +23 -0
  128. package/rsc_EXPERIMENTAL.js +10 -0
  129. package/rsc_EXPERIMENTAL.js.flow +90 -0
@@ -43,7 +43,7 @@ const {
43
43
  getValueAtPath,
44
44
  } = require('relay-runtime');
45
45
 
46
- type LoadMoreFn<TVariables: Variables> = (
46
+ type LoadMoreFn<TVariables extends Variables> = (
47
47
  count: number,
48
48
  options?: {
49
49
  onComplete?: (Error | null) => void,
@@ -55,7 +55,7 @@ export type ReturnType<TVariables, TData, TEdgeData, TKey> = {
55
55
  // NOTE: This type ensures that the type of the returned data is either:
56
56
  // - nullable if the provided ref type is nullable
57
57
  // - non-nullable if the provided ref type is non-nullable
58
- data: [+key: TKey] extends [+key: {+$fragmentSpreads: mixed, ...}]
58
+ data: [+key: TKey] extends [+key: {+$fragmentSpreads: unknown, ...}]
59
59
  ? TData
60
60
  : ?TData,
61
61
  loadNext: LoadMoreFn<TVariables>,
@@ -72,18 +72,18 @@ type LoadMoreOptions<TVariables> = {
72
72
 
73
73
  export type GetExtraVariablesFn<TEdgeData, TData, TVariables, TKey> = ({
74
74
  hasNext: boolean,
75
- data: [+key: TKey] extends [+key: {+$fragmentSpreads: mixed, ...}]
75
+ data: [+key: TKey] extends [+key: {+$fragmentSpreads: unknown, ...}]
76
76
  ? TData
77
77
  : ?TData,
78
78
  getServerEdges: () => TEdgeData,
79
79
  }) => Partial<TVariables>;
80
80
 
81
81
  hook usePrefetchableForwardPaginationFragment_EXPERIMENTAL<
82
- TFragmentType: FragmentType,
83
- TVariables: Variables,
82
+ TFragmentType extends FragmentType,
83
+ TVariables extends Variables,
84
84
  TData,
85
85
  TEdgeData,
86
- TKey: ?{+$fragmentSpreads: TFragmentType, ...},
86
+ TKey extends ?{+$fragmentSpreads: TFragmentType, ...},
87
87
  >(
88
88
  fragmentInput: PrefetchableRefetchableFragment<
89
89
  TFragmentType,
@@ -257,26 +257,26 @@ hook usePrefetchableForwardPaginationFragment_EXPERIMENTAL<
257
257
  onComplete: prefetchingOnComplete,
258
258
  UNSTABLE_extraVariables:
259
259
  typeof prefetchingUNSTABLE_extraVariables === 'function'
260
- ? // $FlowFixMe[incompatible-call]
260
+ ? // $FlowFixMe[incompatible-type]
261
261
  prefetchingUNSTABLE_extraVariables({
262
262
  hasNext,
263
- // $FlowFixMe[incompatible-call]
263
+ // $FlowFixMe[incompatible-type]
264
264
  data: fragmentData,
265
265
  getServerEdges: () => {
266
266
  const selector = getSelector(
267
- // $FlowFixMe[incompatible-call]
267
+ // $FlowFixMe[incompatible-type]
268
268
  edgesFragment,
269
269
  edgeKeys,
270
270
  );
271
271
  if (selector == null) {
272
- // $FlowFixMe[incompatible-call]
272
+ // $FlowFixMe[incompatible-type]
273
273
  return [];
274
274
  }
275
275
  invariant(
276
276
  selector.kind === 'PluralReaderSelector',
277
277
  'Expected a plural selector',
278
278
  );
279
- // $FlowFixMe[incompatible-call]
279
+ // $FlowFixMe[incompatible-type]
280
280
  return selector.selectors.map(
281
281
  sel => environment.lookup(sel).data,
282
282
  );
@@ -331,22 +331,22 @@ hook usePrefetchableForwardPaginationFragment_EXPERIMENTAL<
331
331
  onComplete,
332
332
  UNSTABLE_extraVariables:
333
333
  typeof prefetchingUNSTABLE_extraVariables === 'function'
334
- ? // $FlowFixMe[incompatible-call]
334
+ ? // $FlowFixMe[incompatible-type]
335
335
  prefetchingUNSTABLE_extraVariables({
336
336
  hasNext,
337
- // $FlowFixMe[incompatible-call]
337
+ // $FlowFixMe[incompatible-type]
338
338
  data: fragmentData,
339
339
  getServerEdges: () => {
340
340
  const selector = getSelector(edgesFragment, edgeKeys);
341
341
  if (selector == null) {
342
- // $FlowFixMe[incompatible-call]
342
+ // $FlowFixMe[incompatible-type]
343
343
  return [];
344
344
  }
345
345
  invariant(
346
346
  selector.kind === 'PluralReaderSelector',
347
347
  'Expected a plural selector',
348
348
  );
349
- // $FlowFixMe[incompatible-call]
349
+ // $FlowFixMe[incompatible-type]
350
350
  return selector.selectors.map(
351
351
  sel => environment.lookup(sel).data,
352
352
  );
@@ -374,12 +374,12 @@ hook usePrefetchableForwardPaginationFragment_EXPERIMENTAL<
374
374
 
375
375
  const realNumInUse = Math.min(numInUse, sourceSize);
376
376
 
377
- const derivedEdgeKeys: $ReadOnlyArray<mixed> = useMemo(
377
+ const derivedEdgeKeys: ReadonlyArray<unknown> = useMemo(
378
378
  () => edgeKeys?.slice(0, realNumInUse) ?? [],
379
379
  [edgeKeys, realNumInUse],
380
380
  );
381
381
 
382
- // $FlowExpectedError[incompatible-call] - we know derivedEdgeKeys are the correct keys
382
+ // $FlowExpectedError[incompatible-type] - we know derivedEdgeKeys are the correct keys
383
383
  const edges: TEdgeData = useFragment(edgesFragment, derivedEdgeKeys);
384
384
 
385
385
  const refetchPagination = useCallback(
@@ -421,13 +421,14 @@ hook usePrefetchableForwardPaginationFragment_EXPERIMENTAL<
421
421
 
422
422
  return {
423
423
  edges,
424
- // $FlowFixMe[incompatible-return]
424
+ // $FlowFixMe[incompatible-type]
425
425
  data: fragmentData,
426
426
  loadNext: showMore,
427
427
  hasNext: hasNext || sourceSize > numInUse,
428
428
  // Only reflect `isLoadingMore` if the product depends on it, do not refelect
429
429
  // `isLoaindgMore` state if it is for fufilling the buffer
430
430
  isLoadingNext: isLoadingMore && numInUse > sourceSize,
431
+ // $FlowFixMe[incompatible-type]
431
432
  refetch: refetchPagination,
432
433
  };
433
434
  }
@@ -29,7 +29,7 @@ const {
29
29
  const warning = require('warning');
30
30
 
31
31
  type PreloadedQuery<
32
- TVariables: Variables,
32
+ TVariables extends Variables,
33
33
  TData,
34
34
  TRawResponse,
35
35
  TEnvironmentProviderOptions = EnvironmentProviderOptions,
@@ -51,114 +51,147 @@ type PreloadedQuery<
51
51
  TEnvironmentProviderOptions,
52
52
  >;
53
53
 
54
- hook usePreloadedQuery<
55
- TVariables: Variables,
54
+ declare hook usePreloadedQuery<
55
+ TVariables extends Variables,
56
+ TData,
57
+ TRawResponse extends ?{...} = void,
58
+ >(
59
+ gqlQuery:
60
+ | Query<TVariables, TData, TRawResponse>
61
+ | ClientQuery<TVariables, TData, TRawResponse>,
62
+ preloadedQuery: PreloadedQuery<TVariables, TData, NonNullable<TRawResponse>>,
63
+ options?: {
64
+ UNSTABLE_renderPolicy?: RenderPolicy,
65
+ },
66
+ ): TData;
67
+
68
+ declare hook usePreloadedQuery<
69
+ TVariables extends Variables,
56
70
  TData,
57
- TRawResponse: ?{...} = void,
71
+ TRawResponse extends ?{...} = void,
58
72
  >(
59
73
  gqlQuery:
60
74
  | Query<TVariables, TData, TRawResponse>
61
75
  | ClientQuery<TVariables, TData, TRawResponse>,
62
- preloadedQuery: PreloadedQuery<
76
+ preloadedQuery: ?PreloadedQuery<TVariables, TData, NonNullable<TRawResponse>>,
77
+ options?: {
78
+ UNSTABLE_renderPolicy?: RenderPolicy,
79
+ },
80
+ ): ?TData;
81
+
82
+ hook usePreloadedQuery<
83
+ TVariables extends Variables,
84
+ TData,
85
+ TRawResponse extends ?{...} = void,
86
+ TPreloadedQuery extends ?PreloadedQuery<
63
87
  TVariables,
64
88
  TData,
65
- $NonMaybeType<TRawResponse>,
66
- >,
89
+ NonNullable<TRawResponse>,
90
+ > = PreloadedQuery<TVariables, TData, NonNullable<TRawResponse>>,
91
+ >(
92
+ gqlQuery:
93
+ | Query<TVariables, TData, TRawResponse>
94
+ | ClientQuery<TVariables, TData, TRawResponse>,
95
+ preloadedQuery: TPreloadedQuery,
67
96
  options?: {
68
97
  UNSTABLE_renderPolicy?: RenderPolicy,
69
98
  },
70
- ): TData {
99
+ ): ?TData {
71
100
  const environment = useRelayEnvironment();
72
- const {fetchKey, fetchPolicy, source, variables, networkCacheConfig} =
73
- preloadedQuery;
74
101
  const operation = useMemoOperationDescriptor(
75
102
  gqlQuery,
76
- variables,
77
- networkCacheConfig,
103
+ preloadedQuery != null ? preloadedQuery.variables : {},
104
+ preloadedQuery != null ? preloadedQuery.networkCacheConfig : undefined,
78
105
  );
79
106
 
80
107
  let useLazyLoadQueryNodeParams;
81
- if (preloadedQuery.kind === 'PreloadedQuery_DEPRECATED') {
82
- invariant(
83
- operation.request.node.params.name === preloadedQuery.name,
84
- 'usePreloadedQuery(): Expected data to be prefetched for query `%s`, ' +
85
- 'got prefetch results for query `%s`.',
86
- operation.request.node.params.name,
87
- preloadedQuery.name,
88
- );
89
-
90
- useLazyLoadQueryNodeParams = {
91
- componentDisplayName: 'usePreloadedQuery()',
92
- fetchKey,
93
- fetchObservable: fetchQueryDeduped(
94
- environment,
95
- operation.request.identifier,
96
- () => {
97
- if (environment === preloadedQuery.environment && source != null) {
98
- return environment.executeWithSource({operation, source});
99
- } else {
100
- return environment.execute({operation});
101
- }
102
- },
103
- ),
104
- fetchPolicy,
105
- query: operation,
106
- renderPolicy: options?.UNSTABLE_renderPolicy,
107
- };
108
- } else {
109
- warning(
110
- preloadedQuery.isDisposed === false,
111
- 'usePreloadedQuery(): Expected preloadedQuery to not be disposed yet. ' +
112
- 'This is because disposing the query marks it for future garbage ' +
113
- 'collection, and as such query results may no longer be present in the Relay ' +
114
- 'store. In the future, this will become a hard error.',
115
- );
108
+ if (preloadedQuery != null) {
109
+ const {fetchKey, fetchPolicy, source} = preloadedQuery;
110
+ if (preloadedQuery.kind === 'PreloadedQuery_DEPRECATED') {
111
+ invariant(
112
+ operation.request.node.params.name === preloadedQuery.name,
113
+ 'usePreloadedQuery(): Expected data to be prefetched for query `%s`, ' +
114
+ 'got prefetch results for query `%s`.',
115
+ operation.request.node.params.name,
116
+ preloadedQuery.name,
117
+ );
116
118
 
117
- const fallbackFetchObservable = fetchQuery(environment, operation);
118
- let fetchObservable;
119
- if (source != null && environment === preloadedQuery.environment) {
120
- // If the source observable exists and the environments match, reuse
121
- // the source observable.
122
- // If the source observable happens to be empty, we need to fall back
123
- // and re-execute and de-dupe the query (at render time).
124
- fetchObservable = source.ifEmpty(fallbackFetchObservable);
125
- } else if (environment !== preloadedQuery.environment) {
126
- // If a call to loadQuery is made with a particular environment, and that
127
- // preloaded query is passed to usePreloadedQuery in a different environment
128
- // context, we cannot re-use the existing preloaded query.
129
- // Instead, we need to fall back and re-execute and de-dupe the query with
130
- // the new environment (at render time).
131
- // TODO T68036756 track occurrences of this warning and turn it into a hard error
119
+ useLazyLoadQueryNodeParams = {
120
+ componentDisplayName: 'usePreloadedQuery()',
121
+ fetchKey,
122
+ fetchObservable: fetchQueryDeduped(
123
+ environment,
124
+ operation.request.identifier,
125
+ () => {
126
+ if (environment === preloadedQuery.environment && source != null) {
127
+ return environment.executeWithSource({operation, source});
128
+ } else {
129
+ return environment.execute({operation});
130
+ }
131
+ },
132
+ ),
133
+ fetchPolicy,
134
+ query: operation,
135
+ renderPolicy: options?.UNSTABLE_renderPolicy,
136
+ };
137
+ } else {
132
138
  warning(
133
- false,
134
- 'usePreloadedQuery(): usePreloadedQuery was passed a preloaded query ' +
135
- 'that was created with a different environment than the one that is currently ' +
136
- 'in context. In the future, this will become a hard error.',
139
+ preloadedQuery.isDisposed === false,
140
+ 'usePreloadedQuery(): Expected preloadedQuery to not be disposed yet. ' +
141
+ 'This is because disposing the query marks it for future garbage ' +
142
+ 'collection, and as such query results may no longer be present in the Relay ' +
143
+ 'store. In the future, this will become a hard error.',
137
144
  );
138
- fetchObservable = fallbackFetchObservable;
139
- } else {
140
- // if (source == null)
141
- // If the source observable does not exist, we need to
142
- // fall back and re-execute and de-dupe the query (at render time).
143
- fetchObservable = fallbackFetchObservable;
144
- }
145
145
 
146
+ const fallbackFetchObservable = fetchQuery(environment, operation);
147
+ let fetchObservable;
148
+ if (source != null && environment === preloadedQuery.environment) {
149
+ // If the source observable exists and the environments match, reuse
150
+ // the source observable.
151
+ // If the source observable happens to be empty, we need to fall back
152
+ // and re-execute and de-dupe the query (at render time).
153
+ fetchObservable = source.ifEmpty(fallbackFetchObservable);
154
+ } else if (environment !== preloadedQuery.environment) {
155
+ // If a call to loadQuery is made with a particular environment, and that
156
+ // preloaded query is passed to usePreloadedQuery in a different environment
157
+ // context, we cannot re-use the existing preloaded query.
158
+ // Instead, we need to fall back and re-execute and de-dupe the query with
159
+ // the new environment (at render time).
160
+ // TODO T68036756 track occurrences of this warning and turn it into a hard error
161
+ warning(
162
+ false,
163
+ 'usePreloadedQuery(): usePreloadedQuery was passed a preloaded query ' +
164
+ 'that was created with a different environment than the one that is currently ' +
165
+ 'in context. In the future, this will become a hard error.',
166
+ );
167
+ fetchObservable = fallbackFetchObservable;
168
+ } else {
169
+ // if (source == null)
170
+ // If the source observable does not exist, we need to
171
+ // fall back and re-execute and de-dupe the query (at render time).
172
+ fetchObservable = fallbackFetchObservable;
173
+ }
174
+
175
+ useLazyLoadQueryNodeParams = {
176
+ componentDisplayName: 'usePreloadedQuery()',
177
+ fetchKey,
178
+ fetchObservable,
179
+ fetchPolicy,
180
+ query: operation,
181
+ renderPolicy: options?.UNSTABLE_renderPolicy,
182
+ };
183
+ }
184
+ } else {
146
185
  useLazyLoadQueryNodeParams = {
147
186
  componentDisplayName: 'usePreloadedQuery()',
148
- fetchObservable,
149
- fetchKey,
150
- fetchPolicy,
151
- query: operation,
152
- renderPolicy: options?.UNSTABLE_renderPolicy,
187
+ fragmentNode: gqlQuery.fragment,
153
188
  };
154
189
  }
155
190
 
156
191
  const data = useLazyLoadQueryNode<{
157
192
  variables: TVariables,
158
193
  response: TData,
159
- rawResponse?: $NonMaybeType<TRawResponse>,
160
- /* $FlowFixMe[incompatible-call] Natural Inference rollout. See
161
- * https://fburl.com/gdoc/y8dn025u */
194
+ rawResponse?: NonNullable<TRawResponse>,
162
195
  }>(useLazyLoadQueryNodeParams);
163
196
 
164
197
  if (__DEV__) {
@@ -166,14 +199,15 @@ hook usePreloadedQuery<
166
199
  // $FlowFixMe[react-rule-hook]
167
200
  // $FlowFixMe[react-rule-hook-conditional]
168
201
  useDebugValue({
169
- query: preloadedQuery.name,
170
- variables: preloadedQuery.variables,
171
202
  data,
172
- fetchKey,
173
- fetchPolicy,
203
+ fetchKey: preloadedQuery?.fetchKey,
204
+ fetchPolicy: preloadedQuery?.fetchPolicy,
205
+ query: preloadedQuery?.name,
174
206
  renderPolicy: options?.UNSTABLE_renderPolicy,
207
+ variables: preloadedQuery?.variables,
175
208
  });
176
209
  }
210
+
177
211
  return data;
178
212
  }
179
213
 
@@ -30,12 +30,12 @@ const useRelayEnvironment = require('./useRelayEnvironment');
30
30
  const {useCallback, useEffect, useRef, useState} = require('react');
31
31
  const {RelayFeatureFlags, getRequest} = require('relay-runtime');
32
32
 
33
- export type LoaderFn<TQuery: OperationType> = (
33
+ export type LoaderFn<TQuery extends OperationType> = (
34
34
  variables: TQuery['variables'],
35
35
  options?: UseQueryLoaderLoadQueryOptions,
36
36
  ) => void;
37
37
 
38
- export type UseQueryLoaderLoadQueryOptions = $ReadOnly<{
38
+ export type UseQueryLoaderLoadQueryOptions = Readonly<{
39
39
  ...LoadQueryOptions,
40
40
  +__environment?: ?IEnvironment,
41
41
  }>;
@@ -51,13 +51,13 @@ const initialNullQueryReferenceState: NullQueryReference = {
51
51
  };
52
52
 
53
53
  function requestIsLiveQuery<
54
- TVariables: Variables,
54
+ TVariables extends Variables,
55
55
  TData,
56
- TRawResponse: ?{...} = void,
57
- TQuery: OperationType = {
56
+ TRawResponse extends ?{...} = void,
57
+ TQuery extends OperationType = {
58
58
  response: TData,
59
59
  variables: TVariables,
60
- rawResponse?: $NonMaybeType<TRawResponse>,
60
+ rawResponse?: NonNullable<TRawResponse>,
61
61
  },
62
62
  >(
63
63
  preloadableRequest:
@@ -72,51 +72,55 @@ function requestIsLiveQuery<
72
72
  }
73
73
 
74
74
  export type UseQueryLoaderHookReturnType<
75
- TVariables: Variables,
75
+ TVariables extends Variables,
76
76
  TData,
77
- TRawResponse: ?{...} = void,
77
+ TRawResponse extends ?{...} = void,
78
78
  > = [
79
79
  ?PreloadedQuery<{
80
80
  response: TData,
81
81
  variables: TVariables,
82
- rawResponse?: $NonMaybeType<TRawResponse>,
82
+ rawResponse?: NonNullable<TRawResponse>,
83
83
  }>,
84
84
  (variables: TVariables, options?: UseQueryLoaderLoadQueryOptions) => void,
85
85
  () => void,
86
86
  ];
87
87
 
88
88
  declare function useQueryLoader<
89
- TVariables: Variables,
89
+ TVariables extends Variables,
90
90
  TData,
91
- TRawResponse: ?{...} = void,
91
+ TRawResponse extends ?{...} = void,
92
92
  >(
93
93
  preloadableRequest: Query<TVariables, TData, TRawResponse>,
94
94
  ): UseQueryLoaderHookReturnType<TVariables, TData>;
95
95
 
96
96
  declare function useQueryLoader<
97
- TVariables: Variables,
97
+ TVariables extends Variables,
98
98
  TData,
99
- TRawResponse: ?{...} = void,
99
+ TRawResponse extends ?{...} = void,
100
100
  >(
101
101
  preloadableRequest: Query<TVariables, TData, TRawResponse>,
102
102
  initialQueryReference: ?PreloadedQuery<{
103
103
  response: TData,
104
104
  variables: TVariables,
105
- rawResponse?: $NonMaybeType<TRawResponse>,
105
+ rawResponse?: NonNullable<TRawResponse>,
106
106
  }>,
107
107
  ): UseQueryLoaderHookReturnType<TVariables, TData>;
108
108
 
109
- declare function useQueryLoader<TQuery: OperationType>(
109
+ declare function useQueryLoader<TQuery extends OperationType>(
110
110
  preloadableRequest: PreloadableConcreteRequest<TQuery>,
111
111
  initialQueryReference?: ?PreloadedQuery<TQuery>,
112
112
  ): UseQueryLoaderHookReturnType<TQuery['variables'], TQuery['response']>;
113
113
 
114
- hook useQueryLoader<TVariables: Variables, TData, TRawResponse: ?{...} = void>(
114
+ hook useQueryLoader<
115
+ TVariables extends Variables,
116
+ TData,
117
+ TRawResponse extends ?{...} = void,
118
+ >(
115
119
  preloadableRequest: Query<TVariables, TData, TRawResponse>,
116
120
  initialQueryReference?: ?PreloadedQuery<{
117
121
  response: TData,
118
122
  variables: TVariables,
119
- rawResponse?: $NonMaybeType<TRawResponse>,
123
+ rawResponse?: NonNullable<TRawResponse>,
120
124
  }>,
121
125
  ): UseQueryLoaderHookReturnType<TVariables, TData> {
122
126
  if (RelayFeatureFlags.ENABLE_ACTIVITY_COMPATIBILITY) {
@@ -133,21 +137,21 @@ hook useQueryLoader<TVariables: Variables, TData, TRawResponse: ?{...} = void>(
133
137
  }
134
138
 
135
139
  hook useQueryLoader_CURRENT<
136
- TVariables: Variables,
140
+ TVariables extends Variables,
137
141
  TData,
138
- TRawResponse: ?{...} = void,
142
+ TRawResponse extends ?{...} = void,
139
143
  >(
140
144
  preloadableRequest: Query<TVariables, TData, TRawResponse>,
141
145
  initialQueryReference?: ?PreloadedQuery<{
142
146
  response: TData,
143
147
  variables: TVariables,
144
- rawResponse?: $NonMaybeType<TRawResponse>,
148
+ rawResponse?: NonNullable<TRawResponse>,
145
149
  }>,
146
150
  ): UseQueryLoaderHookReturnType<TVariables, TData> {
147
151
  type QueryType = {
148
152
  response: TData,
149
153
  variables: TVariables,
150
- rawResponse?: $NonMaybeType<TRawResponse>,
154
+ rawResponse?: NonNullable<TRawResponse>,
151
155
  };
152
156
 
153
157
  /**
@@ -213,9 +217,9 @@ hook useQueryLoader_CURRENT<
213
217
  const mergedOptions: ?UseQueryLoaderLoadQueryOptions =
214
218
  options != null && options.hasOwnProperty('__environment')
215
219
  ? {
220
+ __nameForWarning: options.__nameForWarning,
216
221
  fetchPolicy: options.fetchPolicy,
217
222
  networkCacheConfig: options.networkCacheConfig,
218
- __nameForWarning: options.__nameForWarning,
219
223
  }
220
224
  : options;
221
225
  if (isMountedRef.current) {
@@ -223,7 +227,7 @@ hook useQueryLoader_CURRENT<
223
227
  options?.__environment ?? environment,
224
228
  preloadableRequest,
225
229
  variables,
226
- (mergedOptions: $FlowFixMe),
230
+ mergedOptions as $FlowFixMe,
227
231
  );
228
232
  undisposedQueryReferencesRef.current.add(updatedQueryReference);
229
233
  setQueryReference(updatedQueryReference);
@@ -40,13 +40,13 @@ const initialNullQueryReferenceState: NullQueryReference = {
40
40
  };
41
41
 
42
42
  function requestIsLiveQuery<
43
- TVariables: Variables,
43
+ TVariables extends Variables,
44
44
  TData,
45
- TRawResponse: ?{...} = void,
46
- TQuery: OperationType = {
45
+ TRawResponse extends ?{...} = void,
46
+ TQuery extends OperationType = {
47
47
  response: TData,
48
48
  variables: TVariables,
49
- rawResponse?: $NonMaybeType<TRawResponse>,
49
+ rawResponse?: NonNullable<TRawResponse>,
50
50
  },
51
51
  >(
52
52
  preloadableRequest:
@@ -63,21 +63,21 @@ function requestIsLiveQuery<
63
63
  const CLEANUP_TIMEOUT = 1000 * 60 * 5; // 5 minutes;
64
64
 
65
65
  hook useQueryLoader_EXPERIMENTAL<
66
- TVariables: Variables,
66
+ TVariables extends Variables,
67
67
  TData,
68
- TRawResponse: ?{...} = void,
68
+ TRawResponse extends ?{...} = void,
69
69
  >(
70
70
  preloadableRequest: Query<TVariables, TData, TRawResponse>,
71
71
  initialQueryReference?: ?PreloadedQuery<{
72
72
  response: TData,
73
73
  variables: TVariables,
74
- rawResponse?: $NonMaybeType<TRawResponse>,
74
+ rawResponse?: NonNullable<TRawResponse>,
75
75
  }>,
76
76
  ): UseQueryLoaderHookReturnType<TVariables, TData> {
77
77
  type QueryType = {
78
78
  response: TData,
79
79
  variables: TVariables,
80
- rawResponse?: $NonMaybeType<TRawResponse>,
80
+ rawResponse?: NonNullable<TRawResponse>,
81
81
  };
82
82
 
83
83
  /**
@@ -151,16 +151,16 @@ hook useQueryLoader_EXPERIMENTAL<
151
151
  const mergedOptions: ?UseQueryLoaderLoadQueryOptions =
152
152
  options != null && options.hasOwnProperty('__environment')
153
153
  ? {
154
+ __nameForWarning: options.__nameForWarning,
154
155
  fetchPolicy: options.fetchPolicy,
155
156
  networkCacheConfig: options.networkCacheConfig,
156
- __nameForWarning: options.__nameForWarning,
157
157
  }
158
158
  : options;
159
159
  const updatedQueryReference = loadQuery(
160
160
  options?.__environment ?? environment,
161
161
  preloadableRequest,
162
162
  variables,
163
- (mergedOptions: $FlowFixMe),
163
+ mergedOptions as $FlowFixMe,
164
164
  );
165
165
  undisposedQueryReferencesRef.current?.add(updatedQueryReference);
166
166
  setQueryReference(updatedQueryReference);
@@ -24,11 +24,14 @@ const useStaticFragmentNodeWarning = require('./useStaticFragmentNodeWarning');
24
24
  const {useDebugValue} = require('react');
25
25
  const {getFragment} = require('relay-runtime');
26
26
 
27
- type RefetchVariables<TVariables, TKey: ?{+$fragmentSpreads: mixed, ...}> =
27
+ type RefetchVariables<
28
+ TVariables,
29
+ TKey extends ?{+$fragmentSpreads: unknown, ...},
30
+ > =
28
31
  // NOTE: This type ensures that the type of the returned variables is either:
29
32
  // - nullable if the provided ref type is nullable
30
33
  // - non-nullable if the provided ref type is non-nullable
31
- [+key: TKey] extends [+key: {+$fragmentSpreads: mixed, ...}]
34
+ [+key: TKey] extends [+key: {+$fragmentSpreads: unknown, ...}]
32
35
  ? Partial<TVariables>
33
36
  : TVariables;
34
37
 
@@ -45,30 +48,32 @@ export type RefetchFn<TVariables, TKey, TOptions = Options> = RefetchFnBase<
45
48
  export type ReturnType<
46
49
  TVariables,
47
50
  TData,
48
- TKey: ?{+$fragmentSpreads: mixed, ...},
51
+ TKey extends ?{+$fragmentSpreads: unknown, ...},
49
52
  > = [
50
53
  // NOTE: This type ensures that the type of the returned data is either:
51
54
  // - nullable if the provided ref type is nullable
52
55
  // - non-nullable if the provided ref type is non-nullable
53
- [+key: TKey] extends [+key: {+$fragmentSpreads: mixed, ...}] ? TData : ?TData,
56
+ [+key: TKey] extends [+key: {+$fragmentSpreads: unknown, ...}]
57
+ ? TData
58
+ : ?TData,
54
59
  RefetchFn<TVariables, TKey>,
55
60
  ];
56
61
 
57
62
  export type UseRefetchableFragmentType = <
58
- TFragmentType: FragmentType,
59
- TVariables: Variables,
63
+ TFragmentType extends FragmentType,
64
+ TVariables extends Variables,
60
65
  TData,
61
- TKey: ?{+$fragmentSpreads: TFragmentType, ...},
66
+ TKey extends ?{+$fragmentSpreads: TFragmentType, ...},
62
67
  >(
63
68
  fragment: RefetchableFragment<TFragmentType, TData, TVariables>,
64
69
  key: TKey,
65
70
  ) => ReturnType<TVariables, TData, TKey>;
66
71
 
67
72
  hook useRefetchableFragment<
68
- TFragmentType: FragmentType,
69
- TVariables: Variables,
73
+ TFragmentType extends FragmentType,
74
+ TVariables extends Variables,
70
75
  TData,
71
- TKey: ?{+$fragmentSpreads: TFragmentType, ...},
76
+ TKey extends ?{+$fragmentSpreads: TFragmentType, ...},
72
77
  >(
73
78
  fragmentInput: RefetchableFragment<TFragmentType, TData, TVariables>,
74
79
  fragmentRef: TKey,
@@ -88,7 +93,7 @@ hook useRefetchableFragment<
88
93
  // $FlowFixMe[react-rule-hook-conditional]
89
94
  useDebugValue({fragment: fragmentNode.name, data: fragmentData});
90
95
  }
91
- // $FlowFixMe[incompatible-return]
96
+ // $FlowFixMe[incompatible-type]
92
97
  // $FlowFixMe[prop-missing]
93
98
  return [fragmentData, refetch];
94
99
  }