react-relay 14.0.0 → 15.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.
- package/ReactRelayContainerUtils.js.flow +1 -2
- package/ReactRelayContext.js +1 -1
- package/ReactRelayContext.js.flow +1 -2
- package/ReactRelayFragmentContainer.js.flow +6 -4
- package/ReactRelayFragmentMockRenderer.js.flow +1 -2
- package/ReactRelayLocalQueryRenderer.js.flow +5 -5
- package/ReactRelayPaginationContainer.js.flow +21 -14
- package/ReactRelayQueryFetcher.js.flow +28 -16
- package/ReactRelayQueryRenderer.js.flow +42 -13
- package/ReactRelayQueryRendererContext.js.flow +2 -3
- package/ReactRelayRefetchContainer.js.flow +9 -9
- package/ReactRelayTestMocker.js.flow +3 -3
- package/ReactRelayTypes.js.flow +7 -8
- package/RelayContext.js.flow +1 -2
- package/__flowtests__/ReactRelayFragmentContainer-flowtest.js.flow +4 -5
- package/__flowtests__/ReactRelayPaginationContainer-flowtest.js.flow +4 -5
- package/__flowtests__/ReactRelayRefetchContainer-flowtest.js.flow +4 -5
- package/__flowtests__/RelayModern-flowtest.js.flow +3 -4
- package/__flowtests__/RelayModernFlowtest_badref.graphql.js.flow +3 -4
- package/__flowtests__/RelayModernFlowtest_notref.graphql.js.flow +3 -4
- package/__flowtests__/RelayModernFlowtest_user.graphql.js.flow +3 -4
- package/__flowtests__/RelayModernFlowtest_users.graphql.js.flow +3 -4
- package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer.graphql.js.flow +3 -1
- package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer2.graphql.js.flow +3 -1
- package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtestQuery.graphql.js.flow +4 -2
- package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtest_viewer.graphql.js.flow +3 -1
- package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtestQuery.graphql.js.flow +4 -2
- package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtest_viewer.graphql.js.flow +3 -1
- package/__flowtests__/__generated__/RelayModernFlowtest_badref.graphql.js.flow +4 -2
- package/__flowtests__/__generated__/RelayModernFlowtest_notref.graphql.js.flow +4 -2
- package/__flowtests__/__generated__/RelayModernFlowtest_user.graphql.js.flow +3 -1
- package/__flowtests__/__generated__/RelayModernFlowtest_users.graphql.js.flow +3 -1
- package/assertFragmentMap.js.flow +1 -2
- package/buildReactRelayContainer.js.flow +7 -7
- package/getRootVariablesForFragments.js.flow +1 -3
- package/hooks.js +1 -1
- package/hooks.js.flow +4 -2
- package/index.js +1 -1
- package/index.js.flow +6 -2
- package/isRelayEnvironment.js.flow +1 -2
- package/jest-react/enqueueTask.js.flow +1 -1
- package/jest-react/index.js.flow +1 -1
- package/jest-react/internalAct.js.flow +1 -1
- package/legacy.js +1 -1
- package/legacy.js.flow +1 -2
- package/lib/ReactRelayContainerUtils.js +2 -3
- package/lib/ReactRelayContext.js +3 -4
- package/lib/ReactRelayFragmentContainer.js +47 -73
- package/lib/ReactRelayFragmentMockRenderer.js +2 -4
- package/lib/ReactRelayLocalQueryRenderer.js +18 -31
- package/lib/ReactRelayPaginationContainer.js +74 -164
- package/lib/ReactRelayQueryFetcher.js +49 -76
- package/lib/ReactRelayQueryRenderer.js +63 -84
- package/lib/ReactRelayQueryRendererContext.js +2 -2
- package/lib/ReactRelayRefetchContainer.js +58 -108
- package/lib/ReactRelayTestMocker.js +33 -68
- package/lib/ReactRelayTypes.js +2 -1
- package/lib/RelayContext.js +4 -7
- package/lib/assertFragmentMap.js +3 -5
- package/lib/buildReactRelayContainer.js +11 -27
- package/lib/getRootVariablesForFragments.js +6 -10
- package/lib/hooks.js +5 -18
- package/lib/index.js +7 -24
- package/lib/isRelayEnvironment.js +5 -4
- package/lib/jest-react/enqueueTask.js +5 -9
- package/lib/jest-react/index.js +0 -1
- package/lib/jest-react/internalAct.js +9 -20
- package/lib/legacy.js +2 -8
- package/lib/multi-actor/ActorChange.js +2 -5
- package/lib/multi-actor/index.js +2 -1
- package/lib/multi-actor/useRelayActorEnvironment.js +4 -8
- package/lib/relay-hooks/EntryPointContainer.react.js +9 -15
- package/lib/relay-hooks/EntryPointTypes.flow.js +5 -3
- package/lib/relay-hooks/FragmentResource.js +109 -203
- package/lib/relay-hooks/HooksImplementation.js +3 -6
- package/lib/relay-hooks/InternalLogger.js +2 -3
- package/lib/relay-hooks/LRUCache.js +2 -20
- package/lib/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js +33 -54
- package/lib/relay-hooks/MatchContainer.js +15 -24
- package/lib/relay-hooks/ProfilerContext.js +3 -3
- package/lib/relay-hooks/QueryResource.js +31 -101
- package/lib/relay-hooks/RelayEnvironmentProvider.js +5 -9
- package/lib/relay-hooks/SuspenseResource.js +9 -33
- package/lib/relay-hooks/loadEntryPoint.js +19 -31
- package/lib/relay-hooks/loadQuery.js +42 -78
- package/lib/relay-hooks/preloadQuery_DEPRECATED.js +11 -37
- package/lib/relay-hooks/prepareEntryPoint_DEPRECATED.js +9 -15
- package/lib/relay-hooks/react-cache/RelayReactCache.js +7 -12
- package/lib/relay-hooks/react-cache/getQueryResultOrFetchQuery_REACT_CACHE.js +27 -81
- package/lib/relay-hooks/react-cache/readFragmentInternal_REACT_CACHE.js +206 -0
- package/lib/relay-hooks/react-cache/useFragmentInternal_REACT_CACHE.js +195 -215
- package/lib/relay-hooks/react-cache/useFragment_REACT_CACHE.js +5 -15
- package/lib/relay-hooks/react-cache/useLazyLoadQuery_REACT_CACHE.js +17 -24
- package/lib/relay-hooks/react-cache/usePaginationFragment_REACT_CACHE.js +149 -0
- package/lib/relay-hooks/react-cache/usePreloadedQuery_REACT_CACHE.js +24 -39
- package/lib/relay-hooks/react-cache/useRefetchableFragmentInternal_REACT_CACHE.js +325 -0
- package/lib/relay-hooks/react-cache/useRefetchableFragment_REACT_CACHE.js +37 -0
- package/lib/relay-hooks/useBlockingPaginationFragment.js +73 -93
- package/lib/relay-hooks/useClientQuery.js +30 -0
- package/lib/relay-hooks/useEntryPointLoader.js +18 -38
- package/lib/relay-hooks/useFetchTrackingRef.js +10 -12
- package/lib/relay-hooks/useFragment.js +8 -19
- package/lib/relay-hooks/useFragmentNode.js +20 -32
- package/lib/relay-hooks/useIsMountedRef.js +4 -6
- package/lib/relay-hooks/useIsOperationNodeActive.js +8 -20
- package/lib/relay-hooks/useIsParentQueryActive.js +3 -6
- package/lib/relay-hooks/useLazyLoadQuery.js +7 -24
- package/lib/relay-hooks/useLazyLoadQueryNode.js +23 -34
- package/lib/relay-hooks/useLoadMoreFunction.js +46 -78
- package/lib/relay-hooks/useMemoOperationDescriptor.js +6 -15
- package/lib/relay-hooks/useMemoVariables.js +15 -34
- package/lib/relay-hooks/useMutation.js +9 -27
- package/lib/relay-hooks/usePaginationFragment.js +73 -76
- package/lib/relay-hooks/usePreloadedQuery.js +13 -44
- package/lib/relay-hooks/useQueryLoader.js +24 -49
- package/lib/relay-hooks/useRefetchableFragment.js +19 -17
- package/lib/relay-hooks/useRefetchableFragmentNode.js +65 -109
- package/lib/relay-hooks/useRelayEnvironment.js +4 -8
- package/lib/relay-hooks/useStaticFragmentNodeWarning.js +4 -8
- package/lib/relay-hooks/useSubscribeToInvalidationState.js +8 -9
- package/lib/relay-hooks/useSubscription.js +5 -10
- package/lib/relay-hooks/useUnsafeRef_DEPRECATED.js +29 -0
- package/multi-actor/ActorChange.js.flow +1 -1
- package/multi-actor/index.js.flow +1 -1
- package/multi-actor/useRelayActorEnvironment.js.flow +2 -4
- package/package.json +2 -2
- package/react-relay-hooks.js +2 -2
- package/react-relay-hooks.min.js +2 -2
- package/react-relay-legacy.js +2 -2
- package/react-relay-legacy.min.js +2 -2
- package/react-relay.js +2 -2
- package/react-relay.min.js +2 -2
- package/relay-hooks/EntryPointContainer.react.js.flow +3 -5
- package/relay-hooks/EntryPointTypes.flow.js.flow +37 -37
- package/relay-hooks/FragmentResource.js.flow +43 -19
- package/relay-hooks/HooksImplementation.js.flow +7 -9
- package/relay-hooks/InternalLogger.js.flow +1 -3
- package/relay-hooks/LRUCache.js.flow +1 -3
- package/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js.flow +19 -14
- package/relay-hooks/MatchContainer.js.flow +6 -8
- package/relay-hooks/ProfilerContext.js.flow +1 -3
- package/relay-hooks/QueryResource.js.flow +29 -11
- package/relay-hooks/RelayEnvironmentProvider.js.flow +4 -6
- package/relay-hooks/SuspenseResource.js.flow +1 -3
- package/relay-hooks/__flowtests__/EntryPointTypes/EntryPointElementConfig-flowtest.js.flow +6 -4
- package/relay-hooks/__flowtests__/EntryPointTypes/NestedEntrypoints-flowtest.js.flow +4 -4
- package/relay-hooks/__flowtests__/__generated__/useFragmentFlowtest_user.graphql.js.flow +3 -1
- package/relay-hooks/__flowtests__/__generated__/useFragmentFlowtest_users.graphql.js.flow +3 -1
- package/relay-hooks/__flowtests__/useBlockingPaginationFragment-flowtest.js.flow +39 -39
- package/relay-hooks/__flowtests__/useFragment-flowtest.js.flow +1 -3
- package/relay-hooks/__flowtests__/usePaginationFragment-flowtest.js.flow +37 -38
- package/relay-hooks/__flowtests__/useRefetchableFragment-flowtest.js.flow +18 -20
- package/relay-hooks/__flowtests__/utils.js.flow +21 -12
- package/relay-hooks/loadEntryPoint.js.flow +11 -6
- package/relay-hooks/loadQuery.js.flow +11 -7
- package/relay-hooks/preloadQuery_DEPRECATED.js.flow +9 -12
- package/relay-hooks/prepareEntryPoint_DEPRECATED.js.flow +13 -10
- package/relay-hooks/react-cache/RelayReactCache.js.flow +1 -3
- package/relay-hooks/react-cache/getQueryResultOrFetchQuery_REACT_CACHE.js.flow +26 -20
- package/relay-hooks/react-cache/readFragmentInternal_REACT_CACHE.js.flow +297 -0
- package/relay-hooks/react-cache/useFragmentInternal_REACT_CACHE.js.flow +136 -96
- package/relay-hooks/react-cache/useFragment_REACT_CACHE.js.flow +1 -3
- package/relay-hooks/react-cache/useLazyLoadQuery_REACT_CACHE.js.flow +3 -5
- package/relay-hooks/react-cache/usePaginationFragment_REACT_CACHE.js.flow +190 -0
- package/relay-hooks/react-cache/usePreloadedQuery_REACT_CACHE.js.flow +3 -6
- package/relay-hooks/react-cache/useRefetchableFragmentInternal_REACT_CACHE.js.flow +601 -0
- package/relay-hooks/react-cache/useRefetchableFragment_REACT_CACHE.js.flow +65 -0
- package/relay-hooks/useBlockingPaginationFragment.js.flow +86 -59
- package/relay-hooks/useClientQuery.js.flow +39 -0
- package/relay-hooks/useEntryPointLoader.js.flow +16 -14
- package/relay-hooks/useFetchTrackingRef.js.flow +7 -8
- package/relay-hooks/useFragment.js.flow +2 -4
- package/relay-hooks/useFragmentNode.js.flow +7 -8
- package/relay-hooks/useIsMountedRef.js.flow +2 -4
- package/relay-hooks/useIsOperationNodeActive.js.flow +1 -1
- package/relay-hooks/useIsParentQueryActive.js.flow +1 -1
- package/relay-hooks/useLazyLoadQuery.js.flow +9 -32
- package/relay-hooks/useLazyLoadQueryNode.js.flow +4 -6
- package/relay-hooks/useLoadMoreFunction.js.flow +20 -17
- package/relay-hooks/useMemoOperationDescriptor.js.flow +3 -5
- package/relay-hooks/useMemoVariables.js.flow +13 -31
- package/relay-hooks/useMutation.js.flow +6 -8
- package/relay-hooks/usePaginationFragment.js.flow +75 -43
- package/relay-hooks/usePreloadedQuery.js.flow +49 -43
- package/relay-hooks/useQueryLoader.js.flow +89 -28
- package/relay-hooks/useRefetchableFragment.js.flow +83 -23
- package/relay-hooks/useRefetchableFragmentNode.js.flow +26 -22
- package/relay-hooks/useRelayEnvironment.js.flow +2 -4
- package/relay-hooks/useStaticFragmentNodeWarning.js.flow +3 -5
- package/relay-hooks/useSubscribeToInvalidationState.js.flow +2 -4
- package/relay-hooks/useSubscription.js.flow +1 -3
- package/relay-hooks/useUnsafeRef_DEPRECATED.js.flow +25 -0
- package/lib/readContext.js +0 -28
- package/readContext.js.flow +0 -31
|
@@ -5,14 +5,13 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
7
|
* @flow strict-local
|
|
8
|
-
* @emails oncall+relay
|
|
9
8
|
* @format
|
|
9
|
+
* @oncall relay
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
// flowlint ambiguous-object-type:error
|
|
13
|
-
|
|
14
12
|
'use strict';
|
|
15
13
|
|
|
14
|
+
import type {QueryResult} from '../QueryResource';
|
|
16
15
|
import type {
|
|
17
16
|
CacheConfig,
|
|
18
17
|
FetchPolicy,
|
|
@@ -22,13 +21,17 @@ import type {
|
|
|
22
21
|
SelectorData,
|
|
23
22
|
Snapshot,
|
|
24
23
|
} from 'relay-runtime';
|
|
25
|
-
import type {
|
|
24
|
+
import type {
|
|
25
|
+
MissingClientEdgeRequestInfo,
|
|
26
|
+
MissingLiveResolverField,
|
|
27
|
+
} from 'relay-runtime/store/RelayStoreTypes';
|
|
26
28
|
|
|
29
|
+
const {getQueryResourceForEnvironment} = require('../QueryResource');
|
|
27
30
|
const useRelayEnvironment = require('../useRelayEnvironment');
|
|
28
|
-
const getQueryResultOrFetchQuery = require('./getQueryResultOrFetchQuery_REACT_CACHE');
|
|
29
31
|
const invariant = require('invariant');
|
|
30
32
|
const {useDebugValue, useEffect, useMemo, useRef, useState} = require('react');
|
|
31
33
|
const {
|
|
34
|
+
__internal: {fetchQuery: fetchQueryInternal},
|
|
32
35
|
areEqualSelectors,
|
|
33
36
|
createOperationDescriptor,
|
|
34
37
|
getPendingOperationsForFragment,
|
|
@@ -39,18 +42,17 @@ const {
|
|
|
39
42
|
} = require('relay-runtime');
|
|
40
43
|
const warning = require('warning');
|
|
41
44
|
|
|
42
|
-
type FragmentQueryOptions = {
|
|
45
|
+
type FragmentQueryOptions = {
|
|
43
46
|
fetchPolicy?: FetchPolicy,
|
|
44
47
|
networkCacheConfig?: ?CacheConfig,
|
|
45
|
-
|
|
48
|
+
};
|
|
46
49
|
|
|
47
50
|
type FragmentState = $ReadOnly<
|
|
48
|
-
| {
|
|
49
|
-
| {
|
|
50
|
-
| {
|
|
51
|
+
| {kind: 'bailout'}
|
|
52
|
+
| {kind: 'singular', snapshot: Snapshot, epoch: number}
|
|
53
|
+
| {kind: 'plural', snapshots: $ReadOnlyArray<Snapshot>, epoch: number},
|
|
51
54
|
>;
|
|
52
55
|
|
|
53
|
-
type StateUpdater<T> = (T | (T => T)) => void;
|
|
54
56
|
type StateUpdaterFunction<T> = ((T) => T) => void;
|
|
55
57
|
|
|
56
58
|
function isMissingData(state: FragmentState): boolean {
|
|
@@ -71,7 +73,7 @@ function getMissingClientEdges(
|
|
|
71
73
|
} else if (state.kind === 'singular') {
|
|
72
74
|
return state.snapshot.missingClientEdges ?? null;
|
|
73
75
|
} else {
|
|
74
|
-
let edges = null;
|
|
76
|
+
let edges: null | Array<MissingClientEdgeRequestInfo> = null;
|
|
75
77
|
for (const snapshot of state.snapshots) {
|
|
76
78
|
if (snapshot.missingClientEdges) {
|
|
77
79
|
edges = edges ?? [];
|
|
@@ -84,6 +86,27 @@ function getMissingClientEdges(
|
|
|
84
86
|
}
|
|
85
87
|
}
|
|
86
88
|
|
|
89
|
+
function getSuspendingLiveResolver(
|
|
90
|
+
state: FragmentState,
|
|
91
|
+
): $ReadOnlyArray<MissingLiveResolverField> | null {
|
|
92
|
+
if (state.kind === 'bailout') {
|
|
93
|
+
return null;
|
|
94
|
+
} else if (state.kind === 'singular') {
|
|
95
|
+
return state.snapshot.missingLiveResolverFields ?? null;
|
|
96
|
+
} else {
|
|
97
|
+
let missingFields: null | Array<MissingLiveResolverField> = null;
|
|
98
|
+
for (const snapshot of state.snapshots) {
|
|
99
|
+
if (snapshot.missingLiveResolverFields) {
|
|
100
|
+
missingFields = missingFields ?? [];
|
|
101
|
+
for (const edge of snapshot.missingLiveResolverFields) {
|
|
102
|
+
missingFields.push(edge);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return missingFields;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
87
110
|
function handlePotentialSnapshotErrorsForState(
|
|
88
111
|
environment: IEnvironment,
|
|
89
112
|
state: FragmentState,
|
|
@@ -190,7 +213,7 @@ function handleMissingClientEdge(
|
|
|
190
213
|
parentFragmentRef: mixed,
|
|
191
214
|
missingClientEdgeRequestInfo: MissingClientEdgeRequestInfo,
|
|
192
215
|
queryOptions?: FragmentQueryOptions,
|
|
193
|
-
):
|
|
216
|
+
): QueryResult {
|
|
194
217
|
const originalVariables = getVariablesFromFragment(
|
|
195
218
|
parentFragmentNode,
|
|
196
219
|
parentFragmentRef,
|
|
@@ -206,16 +229,14 @@ function handleMissingClientEdge(
|
|
|
206
229
|
);
|
|
207
230
|
// This may suspend. We don't need to do anything with the results; all we're
|
|
208
231
|
// doing here is started the query if needed and retaining and releasing it
|
|
209
|
-
// according to the component mount/suspense cycle;
|
|
232
|
+
// according to the component mount/suspense cycle; QueryResource
|
|
210
233
|
// already handles this by itself.
|
|
211
|
-
const
|
|
212
|
-
|
|
234
|
+
const QueryResource = getQueryResourceForEnvironment(environment);
|
|
235
|
+
return QueryResource.prepare(
|
|
213
236
|
queryOperationDescriptor,
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
},
|
|
237
|
+
fetchQueryInternal(environment, queryOperationDescriptor),
|
|
238
|
+
queryOptions?.fetchPolicy,
|
|
217
239
|
);
|
|
218
|
-
return effect;
|
|
219
240
|
}
|
|
220
241
|
|
|
221
242
|
function subscribeToSnapshot(
|
|
@@ -227,11 +248,22 @@ function subscribeToSnapshot(
|
|
|
227
248
|
return () => {};
|
|
228
249
|
} else if (state.kind === 'singular') {
|
|
229
250
|
const disposable = environment.subscribe(state.snapshot, latestSnapshot => {
|
|
230
|
-
setState(
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
251
|
+
setState(prevState => {
|
|
252
|
+
// In theory a setState from a subscription could be batched together
|
|
253
|
+
// with a setState to change the fragment selector. Guard against this
|
|
254
|
+
// by bailing out of the state update if the selector has changed.
|
|
255
|
+
if (
|
|
256
|
+
prevState.kind !== 'singular' ||
|
|
257
|
+
prevState.snapshot.selector !== latestSnapshot.selector
|
|
258
|
+
) {
|
|
259
|
+
return prevState;
|
|
260
|
+
}
|
|
261
|
+
return {
|
|
262
|
+
kind: 'singular',
|
|
263
|
+
snapshot: latestSnapshot,
|
|
264
|
+
epoch: environment.getStore().getEpoch(),
|
|
265
|
+
};
|
|
266
|
+
});
|
|
235
267
|
});
|
|
236
268
|
return () => {
|
|
237
269
|
disposable.dispose();
|
|
@@ -239,12 +271,17 @@ function subscribeToSnapshot(
|
|
|
239
271
|
} else {
|
|
240
272
|
const disposables = state.snapshots.map((snapshot, index) =>
|
|
241
273
|
environment.subscribe(snapshot, latestSnapshot => {
|
|
242
|
-
setState(
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
274
|
+
setState(prevState => {
|
|
275
|
+
// In theory a setState from a subscription could be batched together
|
|
276
|
+
// with a setState to change the fragment selector. Guard against this
|
|
277
|
+
// by bailing out of the state update if the selector has changed.
|
|
278
|
+
if (
|
|
279
|
+
prevState.kind !== 'plural' ||
|
|
280
|
+
prevState.snapshots[index]?.selector !== latestSnapshot.selector
|
|
281
|
+
) {
|
|
282
|
+
return prevState;
|
|
283
|
+
}
|
|
284
|
+
const updated = [...prevState.snapshots];
|
|
248
285
|
updated[index] = latestSnapshot;
|
|
249
286
|
return {
|
|
250
287
|
kind: 'plural',
|
|
@@ -265,11 +302,12 @@ function subscribeToSnapshot(
|
|
|
265
302
|
function getFragmentState(
|
|
266
303
|
environment: IEnvironment,
|
|
267
304
|
fragmentSelector: ?ReaderSelector,
|
|
268
|
-
isPlural: boolean,
|
|
269
305
|
): FragmentState {
|
|
270
306
|
if (fragmentSelector == null) {
|
|
271
307
|
return {kind: 'bailout'};
|
|
272
308
|
} else if (fragmentSelector.kind === 'PluralReaderSelector') {
|
|
309
|
+
// Note that if fragmentRef is an empty array, fragmentSelector will be null so we'll hit the above case.
|
|
310
|
+
// Null is returned by getSelector if fragmentRef has no non-null items.
|
|
273
311
|
return {
|
|
274
312
|
kind: 'plural',
|
|
275
313
|
snapshots: fragmentSelector.selectors.map(s => environment.lookup(s)),
|
|
@@ -345,29 +383,17 @@ function useFragmentInternal_REACT_CACHE(
|
|
|
345
383
|
);
|
|
346
384
|
|
|
347
385
|
const environment = useRelayEnvironment();
|
|
348
|
-
const [
|
|
349
|
-
getFragmentState(environment, fragmentSelector
|
|
386
|
+
const [_state, setState] = useState<FragmentState>(() =>
|
|
387
|
+
getFragmentState(environment, fragmentSelector),
|
|
350
388
|
);
|
|
351
|
-
|
|
352
|
-
// put into getFragmentState. Exception: can we properly handle the case where the
|
|
353
|
-
// fragmentRef goes from non-null to null?
|
|
354
|
-
const stateFromRawState = (state: FragmentState) => {
|
|
355
|
-
if (fragmentRef == null) {
|
|
356
|
-
return {kind: 'bailout'};
|
|
357
|
-
} else if (state.kind === 'plural' && state.snapshots.length === 0) {
|
|
358
|
-
return {kind: 'bailout'};
|
|
359
|
-
} else {
|
|
360
|
-
return state;
|
|
361
|
-
}
|
|
362
|
-
};
|
|
363
|
-
let state = stateFromRawState(rawState);
|
|
389
|
+
let state = _state;
|
|
364
390
|
|
|
365
391
|
// This copy of the state we only update when something requires us to
|
|
366
392
|
// unsubscribe and re-subscribe, namely a changed environment or
|
|
367
393
|
// fragment selector.
|
|
368
|
-
const [
|
|
394
|
+
const [_subscribedState, setSubscribedState] = useState(state);
|
|
369
395
|
// FIXME since this is used as an effect dependency, it needs to be memoized.
|
|
370
|
-
let subscribedState =
|
|
396
|
+
let subscribedState = _subscribedState;
|
|
371
397
|
|
|
372
398
|
const [previousFragmentSelector, setPreviousFragmentSelector] =
|
|
373
399
|
useState(fragmentSelector);
|
|
@@ -379,9 +405,7 @@ function useFragmentInternal_REACT_CACHE(
|
|
|
379
405
|
// Enqueue setState to record the new selector and state
|
|
380
406
|
setPreviousFragmentSelector(fragmentSelector);
|
|
381
407
|
setPreviousEnvironment(environment);
|
|
382
|
-
const newState =
|
|
383
|
-
getFragmentState(environment, fragmentSelector, isPlural),
|
|
384
|
-
);
|
|
408
|
+
const newState = getFragmentState(environment, fragmentSelector);
|
|
385
409
|
setState(newState);
|
|
386
410
|
setSubscribedState(newState); // This causes us to form a new subscription
|
|
387
411
|
// But render with the latest state w/o waiting for the setState. Otherwise
|
|
@@ -391,6 +415,17 @@ function useFragmentInternal_REACT_CACHE(
|
|
|
391
415
|
subscribedState = newState;
|
|
392
416
|
}
|
|
393
417
|
|
|
418
|
+
// The purpose of this is to detect whether we have ever committed, because we
|
|
419
|
+
// don't suspend on store updates, only when the component either is first trying
|
|
420
|
+
// to mount or when the our selector changes. The selector change in particular is
|
|
421
|
+
// how we suspend for pagination and refetech. Also, fragment selector can be null
|
|
422
|
+
// or undefined, so we use false as a special value to distinguish from all fragment
|
|
423
|
+
// selectors; false means that the component hasn't mounted yet.
|
|
424
|
+
const committedFragmentSelectorRef = useRef<false | ?ReaderSelector>(false);
|
|
425
|
+
useEffect(() => {
|
|
426
|
+
committedFragmentSelectorRef.current = fragmentSelector;
|
|
427
|
+
}, [fragmentSelector]);
|
|
428
|
+
|
|
394
429
|
// Handle the queries for any missing client edges; this may suspend.
|
|
395
430
|
// FIXME handle client edges in parallel.
|
|
396
431
|
if (fragmentNode.metadata?.hasClientEdges === true) {
|
|
@@ -398,14 +433,14 @@ function useFragmentInternal_REACT_CACHE(
|
|
|
398
433
|
// a static (constant) property of the fragment. In practice, this effect will
|
|
399
434
|
// always or never run for a given invocation of this hook.
|
|
400
435
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
401
|
-
const
|
|
436
|
+
const clientEdgeQueries = useMemo(() => {
|
|
402
437
|
const missingClientEdges = getMissingClientEdges(state);
|
|
403
438
|
// eslint-disable-next-line no-shadow
|
|
404
|
-
let
|
|
439
|
+
let clientEdgeQueries;
|
|
405
440
|
if (missingClientEdges?.length) {
|
|
406
|
-
|
|
441
|
+
clientEdgeQueries = ([]: Array<QueryResult>);
|
|
407
442
|
for (const edge of missingClientEdges) {
|
|
408
|
-
|
|
443
|
+
clientEdgeQueries.push(
|
|
409
444
|
handleMissingClientEdge(
|
|
410
445
|
environment,
|
|
411
446
|
fragmentNode,
|
|
@@ -416,41 +451,59 @@ function useFragmentInternal_REACT_CACHE(
|
|
|
416
451
|
);
|
|
417
452
|
}
|
|
418
453
|
}
|
|
419
|
-
return
|
|
454
|
+
return clientEdgeQueries;
|
|
420
455
|
}, [state, environment, fragmentNode, fragmentRef, queryOptions]);
|
|
421
456
|
|
|
422
457
|
// See above note
|
|
423
458
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
424
459
|
useEffect(() => {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
460
|
+
const QueryResource = getQueryResourceForEnvironment(environment);
|
|
461
|
+
if (clientEdgeQueries?.length) {
|
|
462
|
+
const disposables = [];
|
|
463
|
+
for (const query of clientEdgeQueries) {
|
|
464
|
+
disposables.push(QueryResource.retain(query));
|
|
429
465
|
}
|
|
430
466
|
return () => {
|
|
431
|
-
for (const
|
|
432
|
-
|
|
467
|
+
for (const disposable of disposables) {
|
|
468
|
+
disposable.dispose();
|
|
433
469
|
}
|
|
434
470
|
};
|
|
435
471
|
}
|
|
436
|
-
}, [
|
|
472
|
+
}, [environment, clientEdgeQueries]);
|
|
437
473
|
}
|
|
438
474
|
|
|
439
475
|
if (isMissingData(state)) {
|
|
476
|
+
// Suspend if a Live Resolver within this fragment is in a suspended state:
|
|
477
|
+
const suspendingLiveResolvers = getSuspendingLiveResolver(state);
|
|
478
|
+
if (suspendingLiveResolvers != null && suspendingLiveResolvers.length > 0) {
|
|
479
|
+
throw Promise.all(
|
|
480
|
+
suspendingLiveResolvers.map(({liveStateID}) => {
|
|
481
|
+
// $FlowFixMe[prop-missing] This is expected to be a LiveResolverStore
|
|
482
|
+
return environment.getStore().getLiveResolverPromise(liveStateID);
|
|
483
|
+
}),
|
|
484
|
+
);
|
|
485
|
+
}
|
|
440
486
|
// Suspend if an active operation bears on this fragment, either the
|
|
441
|
-
// fragment's owner or some other mutation etc. that could affect it
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
487
|
+
// fragment's owner or some other mutation etc. that could affect it.
|
|
488
|
+
// We only suspend when the component is first trying to mount or changing
|
|
489
|
+
// selectors, not if data becomes missing later:
|
|
490
|
+
if (
|
|
491
|
+
!committedFragmentSelectorRef.current ||
|
|
492
|
+
!areEqualSelectors(committedFragmentSelectorRef.current, fragmentSelector)
|
|
493
|
+
) {
|
|
494
|
+
invariant(fragmentSelector != null, 'refinement, see invariants above');
|
|
495
|
+
const fragmentOwner =
|
|
496
|
+
fragmentSelector.kind === 'PluralReaderSelector'
|
|
497
|
+
? fragmentSelector.selectors[0].owner
|
|
498
|
+
: fragmentSelector.owner;
|
|
499
|
+
const pendingOperationsResult = getPendingOperationsForFragment(
|
|
500
|
+
environment,
|
|
501
|
+
fragmentNode,
|
|
502
|
+
fragmentOwner,
|
|
503
|
+
);
|
|
504
|
+
if (pendingOperationsResult) {
|
|
505
|
+
throw pendingOperationsResult.promise;
|
|
506
|
+
}
|
|
454
507
|
}
|
|
455
508
|
// Report required fields only if we're not suspending, since that means
|
|
456
509
|
// they're missing even though we are out of options for possibly fetching them:
|
|
@@ -475,23 +528,7 @@ function useFragmentInternal_REACT_CACHE(
|
|
|
475
528
|
}
|
|
476
529
|
currentState = updatedState;
|
|
477
530
|
}
|
|
478
|
-
return subscribeToSnapshot(environment, currentState,
|
|
479
|
-
setState(latestState => {
|
|
480
|
-
if (
|
|
481
|
-
latestState.snapshot?.selector !== currentState.snapshot?.selector
|
|
482
|
-
) {
|
|
483
|
-
// Ignore updates to the subscription if it's for a previous fragment selector
|
|
484
|
-
// than the latest one to be rendered. This can happen if the store is updated
|
|
485
|
-
// after we re-render with a new fragmentRef prop but before the effect fires
|
|
486
|
-
// in which we unsubscribe to the old one and subscribe to the new one.
|
|
487
|
-
// (NB: it's safe to compare the selectors by reference because the selector
|
|
488
|
-
// is recycled into new snapshots.)
|
|
489
|
-
return latestState;
|
|
490
|
-
} else {
|
|
491
|
-
return updater(latestState);
|
|
492
|
-
}
|
|
493
|
-
});
|
|
494
|
-
});
|
|
531
|
+
return subscribeToSnapshot(environment, currentState, setState);
|
|
495
532
|
}, [environment, subscribedState]);
|
|
496
533
|
|
|
497
534
|
let data: ?SelectorData | Array<?SelectorData>;
|
|
@@ -501,10 +538,13 @@ function useFragmentInternal_REACT_CACHE(
|
|
|
501
538
|
//
|
|
502
539
|
// Note that isPlural is a constant property of the fragment and does not change
|
|
503
540
|
// for a particular useFragment invocation site
|
|
541
|
+
const fragmentRefIsNullish = fragmentRef == null; // for less sensitive memoization
|
|
504
542
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
505
543
|
data = useMemo(() => {
|
|
506
544
|
if (state.kind === 'bailout') {
|
|
507
|
-
|
|
545
|
+
// Bailout state can happen if the fragmentRef is a plural array that is empty or has no
|
|
546
|
+
// non-null entries. In that case, the compatible behavior is to return [] instead of null.
|
|
547
|
+
return fragmentRefIsNullish ? null : [];
|
|
508
548
|
} else {
|
|
509
549
|
invariant(
|
|
510
550
|
state.kind === 'plural',
|
|
@@ -512,7 +552,7 @@ function useFragmentInternal_REACT_CACHE(
|
|
|
512
552
|
);
|
|
513
553
|
return state.snapshots.map(s => s.data);
|
|
514
554
|
}
|
|
515
|
-
}, [state]);
|
|
555
|
+
}, [state, fragmentRefIsNullish]);
|
|
516
556
|
} else if (state.kind === 'bailout') {
|
|
517
557
|
// This case doesn't allocate a new object so it doesn't have to be memoized
|
|
518
558
|
data = null;
|
|
@@ -4,13 +4,11 @@
|
|
|
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
|
-
// flowlint ambiguous-object-type:error
|
|
13
|
-
|
|
14
12
|
'use strict';
|
|
15
13
|
|
|
16
14
|
import type {Fragment, FragmentType, GraphQLTaggedNode} from 'relay-runtime';
|
|
@@ -5,12 +5,10 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
7
|
* @flow strict-local
|
|
8
|
-
* @emails oncall+relay
|
|
9
8
|
* @format
|
|
9
|
+
* @oncall relay
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
// flowlint ambiguous-object-type:error
|
|
13
|
-
|
|
14
12
|
'use strict';
|
|
15
13
|
|
|
16
14
|
import type {
|
|
@@ -31,12 +29,12 @@ const {useEffect} = require('react');
|
|
|
31
29
|
function useLazyLoadQuery_REACT_CACHE<TVariables: Variables, TData>(
|
|
32
30
|
gqlQuery: Query<TVariables, TData>,
|
|
33
31
|
variables: TVariables,
|
|
34
|
-
options?: {
|
|
32
|
+
options?: {
|
|
35
33
|
fetchKey?: string | number,
|
|
36
34
|
fetchPolicy?: FetchPolicy,
|
|
37
35
|
networkCacheConfig?: CacheConfig,
|
|
38
36
|
UNSTABLE_renderPolicy?: RenderPolicy,
|
|
39
|
-
|
|
37
|
+
},
|
|
40
38
|
): TData {
|
|
41
39
|
useTrackLoadQueryInRender();
|
|
42
40
|
const environment = useRelayEnvironment();
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @flow strict-local
|
|
8
|
+
* @format
|
|
9
|
+
* @oncall relay
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
'use strict';
|
|
13
|
+
|
|
14
|
+
import type {LoadMoreFn, UseLoadMoreFunctionArgs} from '../useLoadMoreFunction';
|
|
15
|
+
import type {Options} from './useRefetchableFragmentInternal_REACT_CACHE';
|
|
16
|
+
import type {RefetchFnDynamic} from './useRefetchableFragmentInternal_REACT_CACHE';
|
|
17
|
+
import type {
|
|
18
|
+
FragmentType,
|
|
19
|
+
GraphQLResponse,
|
|
20
|
+
GraphQLTaggedNode,
|
|
21
|
+
Observer,
|
|
22
|
+
OperationType,
|
|
23
|
+
Variables,
|
|
24
|
+
} from 'relay-runtime';
|
|
25
|
+
import type {VariablesOf} from 'relay-runtime/util/RelayRuntimeTypes';
|
|
26
|
+
|
|
27
|
+
const useLoadMoreFunction = require('../useLoadMoreFunction');
|
|
28
|
+
const useRelayEnvironment = require('../useRelayEnvironment');
|
|
29
|
+
const useStaticFragmentNodeWarning = require('../useStaticFragmentNodeWarning');
|
|
30
|
+
const useRefetchableFragmentInternal = require('./useRefetchableFragmentInternal_REACT_CACHE');
|
|
31
|
+
const {useCallback, useDebugValue, useState} = require('react');
|
|
32
|
+
const {
|
|
33
|
+
getFragment,
|
|
34
|
+
getFragmentIdentifier,
|
|
35
|
+
getPaginationMetadata,
|
|
36
|
+
} = require('relay-runtime');
|
|
37
|
+
|
|
38
|
+
export type ReturnType<TQuery: OperationType, TKey, TFragmentData> = {
|
|
39
|
+
data: TFragmentData,
|
|
40
|
+
loadNext: LoadMoreFn<TQuery['variables']>,
|
|
41
|
+
loadPrevious: LoadMoreFn<TQuery['variables']>,
|
|
42
|
+
hasNext: boolean,
|
|
43
|
+
hasPrevious: boolean,
|
|
44
|
+
isLoadingNext: boolean,
|
|
45
|
+
isLoadingPrevious: boolean,
|
|
46
|
+
refetch: RefetchFnDynamic<TQuery, TKey>,
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
function usePaginationFragment<
|
|
50
|
+
TQuery: OperationType,
|
|
51
|
+
TKey: ?{+$data?: mixed, +$fragmentSpreads: FragmentType, ...},
|
|
52
|
+
>(
|
|
53
|
+
fragmentInput: GraphQLTaggedNode,
|
|
54
|
+
parentFragmentRef: TKey,
|
|
55
|
+
): ReturnType<
|
|
56
|
+
TQuery,
|
|
57
|
+
TKey,
|
|
58
|
+
// NOTE: This $Call ensures that the type of the returned data is either:
|
|
59
|
+
// - nullable if the provided ref type is nullable
|
|
60
|
+
// - non-nullable if the provided ref type is non-nullable
|
|
61
|
+
// prettier-ignore
|
|
62
|
+
$Call<
|
|
63
|
+
& (<TFragmentData>( { +$data?: TFragmentData, ... }) => TFragmentData)
|
|
64
|
+
& (<TFragmentData>(?{ +$data?: TFragmentData, ... }) => ?TFragmentData),
|
|
65
|
+
TKey,
|
|
66
|
+
>,
|
|
67
|
+
> {
|
|
68
|
+
const fragmentNode = getFragment(fragmentInput);
|
|
69
|
+
useStaticFragmentNodeWarning(
|
|
70
|
+
fragmentNode,
|
|
71
|
+
'first argument of usePaginationFragment()',
|
|
72
|
+
);
|
|
73
|
+
const componentDisplayName = 'usePaginationFragment()';
|
|
74
|
+
|
|
75
|
+
const {
|
|
76
|
+
connectionPathInFragmentData,
|
|
77
|
+
paginationRequest,
|
|
78
|
+
paginationMetadata,
|
|
79
|
+
identifierField,
|
|
80
|
+
} = getPaginationMetadata(fragmentNode, componentDisplayName);
|
|
81
|
+
|
|
82
|
+
const {fragmentData, fragmentRef, refetch} = useRefetchableFragmentInternal<
|
|
83
|
+
TQuery,
|
|
84
|
+
TKey,
|
|
85
|
+
>(fragmentNode, parentFragmentRef, componentDisplayName);
|
|
86
|
+
const fragmentIdentifier = getFragmentIdentifier(fragmentNode, fragmentRef);
|
|
87
|
+
|
|
88
|
+
// Backward pagination
|
|
89
|
+
const [loadPrevious, hasPrevious, isLoadingPrevious, disposeFetchPrevious] =
|
|
90
|
+
useLoadMore<TQuery['variables']>({
|
|
91
|
+
componentDisplayName,
|
|
92
|
+
connectionPathInFragmentData,
|
|
93
|
+
direction: 'backward',
|
|
94
|
+
fragmentData,
|
|
95
|
+
fragmentIdentifier,
|
|
96
|
+
fragmentNode,
|
|
97
|
+
fragmentRef,
|
|
98
|
+
identifierField,
|
|
99
|
+
paginationMetadata,
|
|
100
|
+
paginationRequest,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Forward pagination
|
|
104
|
+
const [loadNext, hasNext, isLoadingNext, disposeFetchNext] = useLoadMore<
|
|
105
|
+
TQuery['variables'],
|
|
106
|
+
>({
|
|
107
|
+
componentDisplayName,
|
|
108
|
+
connectionPathInFragmentData,
|
|
109
|
+
direction: 'forward',
|
|
110
|
+
fragmentData,
|
|
111
|
+
fragmentIdentifier,
|
|
112
|
+
fragmentNode,
|
|
113
|
+
fragmentRef,
|
|
114
|
+
identifierField,
|
|
115
|
+
paginationMetadata,
|
|
116
|
+
paginationRequest,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const refetchPagination: RefetchFnDynamic<TQuery, TKey> = useCallback(
|
|
120
|
+
(variables: VariablesOf<TQuery>, options: void | Options) => {
|
|
121
|
+
disposeFetchNext();
|
|
122
|
+
disposeFetchPrevious();
|
|
123
|
+
return refetch(variables, {...options, __environment: undefined});
|
|
124
|
+
},
|
|
125
|
+
[disposeFetchNext, disposeFetchPrevious, refetch],
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
if (__DEV__) {
|
|
129
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
130
|
+
useDebugValue({
|
|
131
|
+
fragment: fragmentNode.name,
|
|
132
|
+
data: fragmentData,
|
|
133
|
+
hasNext,
|
|
134
|
+
isLoadingNext,
|
|
135
|
+
hasPrevious,
|
|
136
|
+
isLoadingPrevious,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
data: fragmentData,
|
|
141
|
+
loadNext,
|
|
142
|
+
loadPrevious,
|
|
143
|
+
hasNext,
|
|
144
|
+
hasPrevious,
|
|
145
|
+
isLoadingNext,
|
|
146
|
+
isLoadingPrevious,
|
|
147
|
+
refetch: refetchPagination,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function useLoadMore<TVariables: Variables>(
|
|
152
|
+
args: $Diff<
|
|
153
|
+
UseLoadMoreFunctionArgs,
|
|
154
|
+
{
|
|
155
|
+
observer: Observer<GraphQLResponse>,
|
|
156
|
+
onReset: () => void,
|
|
157
|
+
...
|
|
158
|
+
},
|
|
159
|
+
>,
|
|
160
|
+
): [LoadMoreFn<TVariables>, boolean, boolean, () => void] {
|
|
161
|
+
const environment = useRelayEnvironment();
|
|
162
|
+
const [isLoadingMore, reallySetIsLoadingMore] = useState(false);
|
|
163
|
+
// Schedule this update since it must be observed by components at the same
|
|
164
|
+
// batch as when hasNext changes. hasNext is read from the store and store
|
|
165
|
+
// updates are scheduled, so this must be scheduled too.
|
|
166
|
+
const setIsLoadingMore = (value: boolean) => {
|
|
167
|
+
const schedule = environment.getScheduler()?.schedule;
|
|
168
|
+
if (schedule) {
|
|
169
|
+
schedule(() => {
|
|
170
|
+
reallySetIsLoadingMore(value);
|
|
171
|
+
});
|
|
172
|
+
} else {
|
|
173
|
+
reallySetIsLoadingMore(value);
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
const observer = {
|
|
177
|
+
start: () => setIsLoadingMore(true),
|
|
178
|
+
complete: () => setIsLoadingMore(false),
|
|
179
|
+
error: () => setIsLoadingMore(false),
|
|
180
|
+
};
|
|
181
|
+
const handleReset = () => setIsLoadingMore(false);
|
|
182
|
+
const [loadMore, hasMore, disposeFetch] = useLoadMoreFunction<TVariables>({
|
|
183
|
+
...args,
|
|
184
|
+
observer,
|
|
185
|
+
onReset: handleReset,
|
|
186
|
+
});
|
|
187
|
+
return [loadMore, hasMore, isLoadingMore, disposeFetch];
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
module.exports = usePaginationFragment;
|
|
@@ -5,12 +5,10 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
7
|
* @flow strict-local
|
|
8
|
-
* @emails oncall+relay
|
|
9
8
|
* @format
|
|
9
|
+
* @oncall relay
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
// flowlint ambiguous-object-type:error
|
|
13
|
-
|
|
14
12
|
'use strict';
|
|
15
13
|
|
|
16
14
|
import type {PreloadedQuery} from '../EntryPointTypes.flow';
|
|
@@ -35,9 +33,9 @@ const warning = require('warning');
|
|
|
35
33
|
function usePreloadedQuery_REACT_CACHE<TQuery: OperationType>(
|
|
36
34
|
gqlQuery: GraphQLTaggedNode,
|
|
37
35
|
preloadedQuery: PreloadedQuery<TQuery>,
|
|
38
|
-
options?: {
|
|
36
|
+
options?: {
|
|
39
37
|
UNSTABLE_renderPolicy?: RenderPolicy,
|
|
40
|
-
|
|
38
|
+
},
|
|
41
39
|
): TQuery['response'] {
|
|
42
40
|
const environment = useRelayEnvironment();
|
|
43
41
|
|
|
@@ -124,7 +122,6 @@ function usePreloadedQuery_REACT_CACHE<TQuery: OperationType>(
|
|
|
124
122
|
|
|
125
123
|
// Read the query's root fragment -- this may suspend.
|
|
126
124
|
const {fragmentNode, fragmentRef} = queryResult;
|
|
127
|
-
// $FlowExpectedError[incompatible-return] Is this a fixable incompatible-return?
|
|
128
125
|
const data = useFragmentInternal(
|
|
129
126
|
fragmentNode,
|
|
130
127
|
fragmentRef,
|