react-relay 15.0.0 → 16.1.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/ReactRelayContext.js +1 -1
- package/ReactRelayQueryFetcher.js.flow +1 -5
- package/ReactRelayQueryRenderer.js.flow +9 -36
- package/ReactRelayTypes.js.flow +1 -0
- package/buildReactRelayContainer.js.flow +3 -1
- package/hooks.js +1 -1
- package/index.js +1 -1
- package/legacy.js +1 -1
- package/lib/ReactRelayContainerUtils.js +0 -11
- package/lib/ReactRelayContext.js +0 -11
- package/lib/ReactRelayFragmentContainer.js +6 -78
- package/lib/ReactRelayFragmentMockRenderer.js +0 -11
- package/lib/ReactRelayLocalQueryRenderer.js +0 -17
- package/lib/ReactRelayPaginationContainer.js +5 -208
- package/lib/ReactRelayQueryFetcher.js +2 -51
- package/lib/ReactRelayQueryRenderer.js +6 -94
- package/lib/ReactRelayQueryRendererContext.js +0 -11
- package/lib/ReactRelayRefetchContainer.js +5 -91
- package/lib/ReactRelayTestMocker.js +9 -85
- package/lib/ReactRelayTypes.js +0 -11
- package/lib/RelayContext.js +0 -21
- package/lib/assertFragmentMap.js +0 -15
- package/lib/buildReactRelayContainer.js +0 -19
- package/lib/getRootVariablesForFragments.js +0 -14
- package/lib/hooks.js +0 -15
- package/lib/index.js +0 -17
- package/lib/isRelayEnvironment.js +1 -18
- package/lib/jest-react/enqueueTask.js +0 -20
- package/lib/jest-react/internalAct.js +0 -38
- package/lib/legacy.js +0 -15
- package/lib/multi-actor/ActorChange.js +0 -11
- package/lib/multi-actor/index.js +0 -11
- package/lib/multi-actor/useRelayActorEnvironment.js +0 -11
- package/lib/relay-hooks/EntryPointContainer.react.js +0 -11
- package/lib/relay-hooks/EntryPointTypes.flow.js +1 -14
- package/lib/relay-hooks/FragmentResource.js +76 -132
- package/lib/relay-hooks/HooksImplementation.js +1 -12
- package/lib/relay-hooks/InternalLogger.js +0 -11
- package/lib/relay-hooks/LRUCache.js +0 -22
- package/lib/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js +0 -18
- package/lib/relay-hooks/MatchContainer.js +0 -94
- package/lib/relay-hooks/NestedRelayEntryPointBuilderUtils.js +9 -0
- package/lib/relay-hooks/ProfilerContext.js +0 -15
- package/lib/relay-hooks/QueryResource.js +2 -68
- package/lib/relay-hooks/RelayEnvironmentProvider.js +0 -11
- package/lib/relay-hooks/SuspenseResource.js +0 -34
- package/lib/relay-hooks/{react-cache/readFragmentInternal_REACT_CACHE.js → experimental/readFragmentInternal_EXPERIMENTAL.js} +5 -29
- package/lib/relay-hooks/{react-cache/useFragmentInternal_REACT_CACHE.js → experimental/useFragmentInternal_EXPERIMENTAL.js} +35 -100
- package/lib/relay-hooks/{react-cache/useFragment_REACT_CACHE.js → experimental/useFragment_EXPERIMENTAL.js} +1 -16
- package/lib/relay-hooks/{react-cache/usePaginationFragment_REACT_CACHE.js → experimental/usePaginationFragment_EXPERIMENTAL.js} +2 -24
- package/lib/relay-hooks/{react-cache/useRefetchableFragmentInternal_REACT_CACHE.js → experimental/useRefetchableFragmentInternal_EXPERIMENTAL.js} +14 -98
- package/lib/relay-hooks/{react-cache/useRefetchableFragment_REACT_CACHE.js → experimental/useRefetchableFragment_EXPERIMENTAL.js} +1 -15
- package/lib/relay-hooks/loadEntryPoint.js +1 -24
- package/lib/relay-hooks/loadQuery.js +2 -106
- package/lib/relay-hooks/preloadQuery_DEPRECATED.js +2 -27
- package/lib/relay-hooks/prepareEntryPoint_DEPRECATED.js +0 -13
- package/lib/relay-hooks/useBlockingPaginationFragment.js +0 -42
- package/lib/relay-hooks/useClientQuery.js +0 -18
- package/lib/relay-hooks/useEntryPointLoader.js +0 -69
- package/lib/relay-hooks/useFetchTrackingRef.js +0 -26
- package/lib/relay-hooks/useFragment.js +0 -17
- package/lib/relay-hooks/useFragmentNode.js +2 -32
- package/lib/relay-hooks/useIsMountedRef.js +0 -11
- package/lib/relay-hooks/useIsOperationNodeActive.js +0 -11
- package/lib/relay-hooks/useIsParentQueryActive.js +0 -11
- package/lib/relay-hooks/useLazyLoadQuery.js +0 -18
- package/lib/relay-hooks/useLazyLoadQueryNode.js +12 -37
- package/lib/relay-hooks/useLoadMoreFunction.js +9 -34
- package/lib/relay-hooks/useMemoOperationDescriptor.js +0 -11
- package/lib/relay-hooks/useMemoVariables.js +0 -17
- package/lib/relay-hooks/useMutation.js +0 -11
- package/lib/relay-hooks/usePaginationFragment.js +1 -26
- package/lib/relay-hooks/usePreloadedQuery.js +0 -27
- package/lib/relay-hooks/useQueryLoader.js +0 -74
- package/lib/relay-hooks/useRefetchableFragment.js +0 -16
- package/lib/relay-hooks/useRefetchableFragmentNode.js +14 -97
- package/lib/relay-hooks/useRelayEnvironment.js +0 -11
- package/lib/relay-hooks/useStaticFragmentNodeWarning.js +0 -15
- package/lib/relay-hooks/useSubscribeToInvalidationState.js +0 -25
- package/lib/relay-hooks/useSubscription.js +0 -15
- package/lib/relay-hooks/useUnsafeRef_DEPRECATED.js +0 -17
- 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 +5 -0
- package/relay-hooks/EntryPointTypes.flow.js.flow +34 -35
- package/relay-hooks/FragmentResource.js.flow +114 -26
- package/relay-hooks/HooksImplementation.js.flow +3 -1
- package/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js.flow +4 -2
- package/relay-hooks/NestedRelayEntryPointBuilderUtils.js.flow +51 -0
- package/relay-hooks/__flowtests__/EntryPointTypes/NestedEntrypoints-flowtest.js.flow +7 -5
- package/relay-hooks/__flowtests__/useBlockingPaginationFragment-flowtest.js.flow +5 -0
- package/relay-hooks/__flowtests__/usePaginationFragment-flowtest.js.flow +5 -0
- package/relay-hooks/__flowtests__/useRefetchableFragment-flowtest.js.flow +2 -0
- package/relay-hooks/{react-cache/readFragmentInternal_REACT_CACHE.js.flow → experimental/readFragmentInternal_EXPERIMENTAL.js.flow} +4 -3
- package/relay-hooks/{react-cache/useFragmentInternal_REACT_CACHE.js.flow → experimental/useFragmentInternal_EXPERIMENTAL.js.flow} +32 -14
- package/relay-hooks/{react-cache/useFragment_REACT_CACHE.js.flow → experimental/useFragment_EXPERIMENTAL.js.flow} +4 -10
- package/relay-hooks/{react-cache/usePaginationFragment_REACT_CACHE.js.flow → experimental/usePaginationFragment_EXPERIMENTAL.js.flow} +30 -59
- package/relay-hooks/{react-cache/useRefetchableFragmentInternal_REACT_CACHE.js.flow → experimental/useRefetchableFragmentInternal_EXPERIMENTAL.js.flow} +30 -23
- package/relay-hooks/experimental/useRefetchableFragment_EXPERIMENTAL.js.flow +49 -0
- package/relay-hooks/loadEntryPoint.js.flow +4 -2
- package/relay-hooks/loadQuery.js.flow +21 -1
- package/relay-hooks/prepareEntryPoint_DEPRECATED.js.flow +4 -2
- package/relay-hooks/useBlockingPaginationFragment.js.flow +10 -17
- package/relay-hooks/useClientQuery.js.flow +2 -2
- package/relay-hooks/useFragmentNode.js.flow +2 -2
- package/relay-hooks/useLazyLoadQueryNode.js.flow +17 -1
- package/relay-hooks/useLoadMoreFunction.js.flow +15 -9
- package/relay-hooks/useMutation.js.flow +26 -9
- package/relay-hooks/usePaginationFragment.js.flow +7 -15
- package/relay-hooks/useQueryLoader.js.flow +2 -8
- package/relay-hooks/useRefetchableFragment.js.flow +14 -16
- package/relay-hooks/useRefetchableFragmentNode.js.flow +33 -20
- package/lib/relay-hooks/react-cache/RelayReactCache.js +0 -32
- package/lib/relay-hooks/react-cache/getQueryResultOrFetchQuery_REACT_CACHE.js +0 -290
- package/lib/relay-hooks/react-cache/useLazyLoadQuery_REACT_CACHE.js +0 -49
- package/lib/relay-hooks/react-cache/usePreloadedQuery_REACT_CACHE.js +0 -110
- package/relay-hooks/react-cache/RelayReactCache.js.flow +0 -40
- package/relay-hooks/react-cache/getQueryResultOrFetchQuery_REACT_CACHE.js.flow +0 -430
- package/relay-hooks/react-cache/useLazyLoadQuery_REACT_CACHE.js.flow +0 -70
- package/relay-hooks/react-cache/usePreloadedQuery_REACT_CACHE.js.flow +0 -150
- package/relay-hooks/react-cache/useRefetchableFragment_REACT_CACHE.js.flow +0 -65
|
@@ -12,22 +12,20 @@
|
|
|
12
12
|
'use strict';
|
|
13
13
|
|
|
14
14
|
import type {LoadMoreFn, UseLoadMoreFunctionArgs} from '../useLoadMoreFunction';
|
|
15
|
-
import type {
|
|
16
|
-
import type {
|
|
15
|
+
import type {ReturnType} from '../usePaginationFragment';
|
|
16
|
+
import type {Options} from './useRefetchableFragmentInternal_EXPERIMENTAL';
|
|
17
17
|
import type {
|
|
18
18
|
FragmentType,
|
|
19
19
|
GraphQLResponse,
|
|
20
|
-
GraphQLTaggedNode,
|
|
21
20
|
Observer,
|
|
22
|
-
|
|
21
|
+
RefetchableFragment,
|
|
23
22
|
Variables,
|
|
24
23
|
} from 'relay-runtime';
|
|
25
|
-
import type {VariablesOf} from 'relay-runtime/util/RelayRuntimeTypes';
|
|
26
24
|
|
|
27
25
|
const useLoadMoreFunction = require('../useLoadMoreFunction');
|
|
28
26
|
const useRelayEnvironment = require('../useRelayEnvironment');
|
|
29
27
|
const useStaticFragmentNodeWarning = require('../useStaticFragmentNodeWarning');
|
|
30
|
-
const useRefetchableFragmentInternal = require('./
|
|
28
|
+
const useRefetchableFragmentInternal = require('./useRefetchableFragmentInternal_EXPERIMENTAL');
|
|
31
29
|
const {useCallback, useDebugValue, useState} = require('react');
|
|
32
30
|
const {
|
|
33
31
|
getFragment,
|
|
@@ -35,36 +33,15 @@ const {
|
|
|
35
33
|
getPaginationMetadata,
|
|
36
34
|
} = require('relay-runtime');
|
|
37
35
|
|
|
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
36
|
function usePaginationFragment<
|
|
50
|
-
|
|
51
|
-
|
|
37
|
+
TFragmentType: FragmentType,
|
|
38
|
+
TVariables: Variables,
|
|
39
|
+
TData,
|
|
40
|
+
TKey: ?{+$fragmentSpreads: TFragmentType, ...},
|
|
52
41
|
>(
|
|
53
|
-
fragmentInput:
|
|
42
|
+
fragmentInput: RefetchableFragment<TFragmentType, TData, TVariables>,
|
|
54
43
|
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
|
-
> {
|
|
44
|
+
): ReturnType<TVariables, TData, TKey> {
|
|
68
45
|
const fragmentNode = getFragment(fragmentInput);
|
|
69
46
|
useStaticFragmentNodeWarning(
|
|
70
47
|
fragmentNode,
|
|
@@ -72,22 +49,18 @@ function usePaginationFragment<
|
|
|
72
49
|
);
|
|
73
50
|
const componentDisplayName = 'usePaginationFragment()';
|
|
74
51
|
|
|
75
|
-
const {
|
|
76
|
-
|
|
77
|
-
paginationRequest,
|
|
78
|
-
paginationMetadata,
|
|
79
|
-
identifierField,
|
|
80
|
-
} = getPaginationMetadata(fragmentNode, componentDisplayName);
|
|
52
|
+
const {connectionPathInFragmentData, paginationRequest, paginationMetadata} =
|
|
53
|
+
getPaginationMetadata(fragmentNode, componentDisplayName);
|
|
81
54
|
|
|
82
55
|
const {fragmentData, fragmentRef, refetch} = useRefetchableFragmentInternal<
|
|
83
|
-
|
|
84
|
-
|
|
56
|
+
{variables: TVariables, response: TData},
|
|
57
|
+
{data?: TData},
|
|
85
58
|
>(fragmentNode, parentFragmentRef, componentDisplayName);
|
|
86
59
|
const fragmentIdentifier = getFragmentIdentifier(fragmentNode, fragmentRef);
|
|
87
60
|
|
|
88
61
|
// Backward pagination
|
|
89
62
|
const [loadPrevious, hasPrevious, isLoadingPrevious, disposeFetchPrevious] =
|
|
90
|
-
useLoadMore<
|
|
63
|
+
useLoadMore<TVariables>({
|
|
91
64
|
componentDisplayName,
|
|
92
65
|
connectionPathInFragmentData,
|
|
93
66
|
direction: 'backward',
|
|
@@ -95,29 +68,26 @@ function usePaginationFragment<
|
|
|
95
68
|
fragmentIdentifier,
|
|
96
69
|
fragmentNode,
|
|
97
70
|
fragmentRef,
|
|
98
|
-
identifierField,
|
|
99
71
|
paginationMetadata,
|
|
100
72
|
paginationRequest,
|
|
101
73
|
});
|
|
102
74
|
|
|
103
75
|
// Forward pagination
|
|
104
|
-
const [loadNext, hasNext, isLoadingNext, disposeFetchNext] =
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
paginationRequest,
|
|
117
|
-
});
|
|
76
|
+
const [loadNext, hasNext, isLoadingNext, disposeFetchNext] =
|
|
77
|
+
useLoadMore<TVariables>({
|
|
78
|
+
componentDisplayName,
|
|
79
|
+
connectionPathInFragmentData,
|
|
80
|
+
direction: 'forward',
|
|
81
|
+
fragmentData,
|
|
82
|
+
fragmentIdentifier,
|
|
83
|
+
fragmentNode,
|
|
84
|
+
fragmentRef,
|
|
85
|
+
paginationMetadata,
|
|
86
|
+
paginationRequest,
|
|
87
|
+
});
|
|
118
88
|
|
|
119
|
-
const refetchPagination
|
|
120
|
-
(variables:
|
|
89
|
+
const refetchPagination = useCallback(
|
|
90
|
+
(variables: TVariables, options: void | Options) => {
|
|
121
91
|
disposeFetchNext();
|
|
122
92
|
disposeFetchPrevious();
|
|
123
93
|
return refetch(variables, {...options, __environment: undefined});
|
|
@@ -137,6 +107,7 @@ function usePaginationFragment<
|
|
|
137
107
|
});
|
|
138
108
|
}
|
|
139
109
|
return {
|
|
110
|
+
// $FlowFixMe[incompatible-return]
|
|
140
111
|
data: fragmentData,
|
|
141
112
|
loadNext,
|
|
142
113
|
loadPrevious,
|
|
@@ -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,
|
|
@@ -30,8 +31,8 @@ const {getQueryResourceForEnvironment} = require('../QueryResource');
|
|
|
30
31
|
const useIsMountedRef = require('../useIsMountedRef');
|
|
31
32
|
const useQueryLoader = require('../useQueryLoader');
|
|
32
33
|
const useRelayEnvironment = require('../useRelayEnvironment');
|
|
33
|
-
const readFragmentInternal = require('./
|
|
34
|
-
const useFragmentInternal = require('./
|
|
34
|
+
const readFragmentInternal = require('./readFragmentInternal_EXPERIMENTAL');
|
|
35
|
+
const useFragmentInternal = require('./useFragmentInternal_EXPERIMENTAL');
|
|
35
36
|
const invariant = require('invariant');
|
|
36
37
|
const {useCallback, useContext, useReducer} = require('react');
|
|
37
38
|
const {
|
|
@@ -54,16 +55,13 @@ export type RefetchFn<
|
|
|
54
55
|
// /nullable/.
|
|
55
56
|
// - Or, expects /a subset/ of the query variables if the provided key type is
|
|
56
57
|
// /non-null/.
|
|
57
|
-
// prettier-ignore
|
|
58
58
|
export type RefetchFnDynamic<
|
|
59
59
|
TQuery: OperationType,
|
|
60
|
-
TKey: ?{
|
|
60
|
+
TKey: ?{+$data?: mixed, ...},
|
|
61
61
|
TOptions = Options,
|
|
62
|
-
> =
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
TKey
|
|
66
|
-
>;
|
|
62
|
+
> = [TKey] extends [{+$data?: mixed, ...}]
|
|
63
|
+
? RefetchFnInexact<TQuery, TOptions>
|
|
64
|
+
: RefetchFnExact<TQuery, TOptions>;
|
|
67
65
|
|
|
68
66
|
export type ReturnType<
|
|
69
67
|
TQuery: OperationType,
|
|
@@ -98,7 +96,7 @@ type RefetchFnExact<TQuery: OperationType, TOptions = Options> = RefetchFnBase<
|
|
|
98
96
|
type RefetchFnInexact<
|
|
99
97
|
TQuery: OperationType,
|
|
100
98
|
TOptions = Options,
|
|
101
|
-
> = RefetchFnBase<Partial<VariablesOf<TQuery
|
|
99
|
+
> = RefetchFnBase<$ReadOnly<Partial<VariablesOf<TQuery>>>, TOptions>;
|
|
102
100
|
|
|
103
101
|
type Action =
|
|
104
102
|
| {
|
|
@@ -171,7 +169,7 @@ function useRefetchableFragmentNode<
|
|
|
171
169
|
componentDisplayName: string,
|
|
172
170
|
): ReturnType<TQuery, TKey, InternalOptions> {
|
|
173
171
|
const parentEnvironment = useRelayEnvironment();
|
|
174
|
-
const {refetchableRequest, fragmentRefPathInResponse,
|
|
172
|
+
const {refetchableRequest, fragmentRefPathInResponse, identifierInfo} =
|
|
175
173
|
getRefetchMetadata(fragmentNode, componentDisplayName);
|
|
176
174
|
const fragmentIdentifier = getFragmentIdentifier(
|
|
177
175
|
fragmentNode,
|
|
@@ -236,6 +234,7 @@ function useRefetchableFragmentNode<
|
|
|
236
234
|
debugPreviousIDAndTypename = debugFunctions.getInitialIDAndType(
|
|
237
235
|
refetchQuery.request.variables,
|
|
238
236
|
fragmentRefPathInResponse,
|
|
237
|
+
identifierInfo?.identifierQueryVariableName,
|
|
239
238
|
environment,
|
|
240
239
|
);
|
|
241
240
|
}
|
|
@@ -343,7 +342,7 @@ function useRefetchableFragmentNode<
|
|
|
343
342
|
fragmentIdentifier,
|
|
344
343
|
fragmentNode,
|
|
345
344
|
fragmentRefPathInResponse,
|
|
346
|
-
|
|
345
|
+
identifierInfo,
|
|
347
346
|
loadQuery,
|
|
348
347
|
parentFragmentRef,
|
|
349
348
|
refetchableRequest,
|
|
@@ -351,6 +350,7 @@ function useRefetchableFragmentNode<
|
|
|
351
350
|
return {
|
|
352
351
|
fragmentData,
|
|
353
352
|
fragmentRef,
|
|
353
|
+
// $FlowFixMe[incompatible-return] RefetchFn not compatible with RefetchFnDynamic
|
|
354
354
|
refetch,
|
|
355
355
|
};
|
|
356
356
|
}
|
|
@@ -377,17 +377,17 @@ function useRefetchFunction<TQuery: OperationType>(
|
|
|
377
377
|
fragmentIdentifier: string,
|
|
378
378
|
fragmentNode: ReaderFragment,
|
|
379
379
|
fragmentRefPathInResponse: $ReadOnlyArray<string | number>,
|
|
380
|
-
|
|
380
|
+
identifierInfo: ?RefetchableIdentifierInfo,
|
|
381
381
|
loadQuery: LoaderFn<TQuery>,
|
|
382
382
|
parentFragmentRef: mixed,
|
|
383
383
|
refetchableRequest: ConcreteRequest,
|
|
384
384
|
): RefetchFn<TQuery, InternalOptions> {
|
|
385
385
|
const isMountedRef = useIsMountedRef();
|
|
386
386
|
const identifierValue =
|
|
387
|
-
identifierField != null &&
|
|
387
|
+
identifierInfo?.identifierField != null &&
|
|
388
388
|
fragmentData != null &&
|
|
389
389
|
typeof fragmentData === 'object'
|
|
390
|
-
? fragmentData[identifierField]
|
|
390
|
+
? fragmentData[identifierInfo.identifierField]
|
|
391
391
|
: null;
|
|
392
392
|
return useCallback(
|
|
393
393
|
(
|
|
@@ -454,8 +454,10 @@ function useRefetchFunction<TQuery: OperationType>(
|
|
|
454
454
|
// If the query needs an identifier value ('id' or similar) and one
|
|
455
455
|
// was not explicitly provided, read it from the fragment data.
|
|
456
456
|
if (
|
|
457
|
-
|
|
458
|
-
!providedRefetchVariables.hasOwnProperty(
|
|
457
|
+
identifierInfo != null &&
|
|
458
|
+
!providedRefetchVariables.hasOwnProperty(
|
|
459
|
+
identifierInfo.identifierQueryVariableName,
|
|
460
|
+
)
|
|
459
461
|
) {
|
|
460
462
|
// @refetchable fragments are guaranteed to have an `id` selection
|
|
461
463
|
// if the type is Node, implements Node, or is @fetchable. Double-check
|
|
@@ -465,21 +467,25 @@ function useRefetchFunction<TQuery: OperationType>(
|
|
|
465
467
|
false,
|
|
466
468
|
'Relay: Expected result to have a string ' +
|
|
467
469
|
'`%s` in order to refetch, got `%s`.',
|
|
468
|
-
identifierField,
|
|
470
|
+
identifierInfo.identifierField,
|
|
469
471
|
identifierValue,
|
|
470
472
|
);
|
|
471
473
|
}
|
|
472
|
-
(refetchVariables: $FlowFixMe)
|
|
474
|
+
(refetchVariables: $FlowFixMe)[
|
|
475
|
+
identifierInfo.identifierQueryVariableName
|
|
476
|
+
] = identifierValue;
|
|
473
477
|
}
|
|
474
478
|
|
|
475
479
|
const refetchQuery = createOperationDescriptor(
|
|
476
480
|
refetchableRequest,
|
|
477
481
|
refetchVariables,
|
|
478
|
-
{
|
|
482
|
+
{
|
|
483
|
+
force: true,
|
|
484
|
+
},
|
|
479
485
|
);
|
|
480
486
|
|
|
481
487
|
// We call loadQuery which will start a network request if necessary
|
|
482
|
-
// and update the
|
|
488
|
+
// and update the queryRef from useQueryLoader.
|
|
483
489
|
// Note the following:
|
|
484
490
|
// - loadQuery will dispose of any previously refetched queries.
|
|
485
491
|
// - We use the variables extracted off the OperationDescriptor
|
|
@@ -518,10 +524,11 @@ if (__DEV__) {
|
|
|
518
524
|
getInitialIDAndType(
|
|
519
525
|
memoRefetchVariables: ?Variables,
|
|
520
526
|
fragmentRefPathInResponse: $ReadOnlyArray<string | number>,
|
|
527
|
+
identifierQueryVariableName: ?string,
|
|
521
528
|
environment: IEnvironment,
|
|
522
529
|
): ?DebugIDandTypename {
|
|
523
530
|
const {Record} = require('relay-runtime');
|
|
524
|
-
const id = memoRefetchVariables?.id;
|
|
531
|
+
const id = memoRefetchVariables?.[identifierQueryVariableName ?? 'id'];
|
|
525
532
|
if (
|
|
526
533
|
fragmentRefPathInResponse.length !== 1 ||
|
|
527
534
|
fragmentRefPathInResponse[0] !== 'node' ||
|
|
@@ -531,7 +538,7 @@ if (__DEV__) {
|
|
|
531
538
|
}
|
|
532
539
|
const recordSource = environment.getStore().getSource();
|
|
533
540
|
const record = recordSource.get(id);
|
|
534
|
-
const typename = record
|
|
541
|
+
const typename = record == null ? null : Record.getType(record);
|
|
535
542
|
if (typename == null) {
|
|
536
543
|
return null;
|
|
537
544
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
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 {ReturnType} from '../useRefetchableFragment';
|
|
15
|
+
import type {FragmentType, RefetchableFragment, Variables} from 'relay-runtime';
|
|
16
|
+
|
|
17
|
+
const useStaticFragmentNodeWarning = require('../useStaticFragmentNodeWarning');
|
|
18
|
+
const useRefetchableFragmentInternal = require('./useRefetchableFragmentInternal_EXPERIMENTAL');
|
|
19
|
+
const {useDebugValue} = require('react');
|
|
20
|
+
const {getFragment} = require('relay-runtime');
|
|
21
|
+
|
|
22
|
+
function useRefetchableFragment<
|
|
23
|
+
TFragmentType: FragmentType,
|
|
24
|
+
TVariables: Variables,
|
|
25
|
+
TData,
|
|
26
|
+
TKey: ?{+$fragmentSpreads: TFragmentType, ...},
|
|
27
|
+
>(
|
|
28
|
+
fragmentInput: RefetchableFragment<TFragmentType, TData, TVariables>,
|
|
29
|
+
fragmentRef: TKey,
|
|
30
|
+
): ReturnType<TVariables, TData, TKey> {
|
|
31
|
+
const fragmentNode = getFragment(fragmentInput);
|
|
32
|
+
useStaticFragmentNodeWarning(
|
|
33
|
+
fragmentNode,
|
|
34
|
+
'first argument of useRefetchableFragment()',
|
|
35
|
+
);
|
|
36
|
+
const {fragmentData, refetch} = useRefetchableFragmentInternal<
|
|
37
|
+
{variables: TVariables, response: TData},
|
|
38
|
+
{data?: TData},
|
|
39
|
+
>(fragmentNode, fragmentRef, 'useRefetchableFragment()');
|
|
40
|
+
if (__DEV__) {
|
|
41
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
42
|
+
useDebugValue({fragment: fragmentNode.name, data: fragmentData});
|
|
43
|
+
}
|
|
44
|
+
// $FlowFixMe[incompatible-return]
|
|
45
|
+
// $FlowFixMe[prop-missing]
|
|
46
|
+
return [fragmentData, refetch];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
module.exports = useRefetchableFragment;
|
|
@@ -46,8 +46,10 @@ function loadEntryPoint<
|
|
|
46
46
|
}
|
|
47
47
|
const preloadProps = entryPoint.getPreloadProps(entryPointParams);
|
|
48
48
|
const {queries, entryPoints, extraProps} = preloadProps;
|
|
49
|
-
|
|
50
|
-
const
|
|
49
|
+
// $FlowFixMe[incompatible-type]
|
|
50
|
+
const preloadedQueries: Partial<TPreloadedQueries> = {};
|
|
51
|
+
// $FlowFixMe[incompatible-type]
|
|
52
|
+
const preloadedEntryPoints: Partial<TPreloadedEntryPoints> = {};
|
|
51
53
|
if (queries != null) {
|
|
52
54
|
const queriesPropNames = Object.keys(queries);
|
|
53
55
|
queriesPropNames.forEach(queryPropName => {
|
|
@@ -24,6 +24,7 @@ import type {
|
|
|
24
24
|
IEnvironment,
|
|
25
25
|
OperationDescriptor,
|
|
26
26
|
OperationType,
|
|
27
|
+
Query,
|
|
27
28
|
RequestIdentifier,
|
|
28
29
|
RequestParameters,
|
|
29
30
|
} from 'relay-runtime';
|
|
@@ -56,12 +57,31 @@ function useTrackLoadQueryInRender() {
|
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
|
|
60
|
+
type QueryType<T> = T extends Query<infer V, infer D, infer RR>
|
|
61
|
+
? {
|
|
62
|
+
variables: V,
|
|
63
|
+
response: D,
|
|
64
|
+
rawResponse?: $NonMaybeType<RR>,
|
|
65
|
+
}
|
|
66
|
+
: $Call<<T>(PreloadableConcreteRequest<T>) => T, T>;
|
|
67
|
+
|
|
68
|
+
declare function loadQuery<
|
|
69
|
+
T,
|
|
70
|
+
TEnvironmentProviderOptions = EnvironmentProviderOptions,
|
|
71
|
+
>(
|
|
72
|
+
environment: IEnvironment,
|
|
73
|
+
preloadableRequest: T,
|
|
74
|
+
variables: QueryType<T>['variables'],
|
|
75
|
+
options?: ?LoadQueryOptions,
|
|
76
|
+
environmentProviderOptions?: ?TEnvironmentProviderOptions,
|
|
77
|
+
): PreloadedQueryInner<QueryType<T>, TEnvironmentProviderOptions>;
|
|
78
|
+
|
|
59
79
|
function loadQuery<
|
|
60
80
|
TQuery: OperationType,
|
|
61
81
|
TEnvironmentProviderOptions = EnvironmentProviderOptions,
|
|
62
82
|
>(
|
|
63
83
|
environment: IEnvironment,
|
|
64
|
-
preloadableRequest:
|
|
84
|
+
preloadableRequest: PreloadableConcreteRequest<TQuery>,
|
|
65
85
|
variables: TQuery['variables'],
|
|
66
86
|
options?: ?LoadQueryOptions,
|
|
67
87
|
environmentProviderOptions?: ?TEnvironmentProviderOptions,
|
|
@@ -45,8 +45,10 @@ function prepareEntryPoint<
|
|
|
45
45
|
}
|
|
46
46
|
const preloadProps = entryPoint.getPreloadProps(entryPointParams);
|
|
47
47
|
const {queries, entryPoints} = preloadProps;
|
|
48
|
-
|
|
49
|
-
const
|
|
48
|
+
// $FlowFixMe[incompatible-type]
|
|
49
|
+
const preloadedQueries: Partial<TPreloadedQueries> = {};
|
|
50
|
+
// $FlowFixMe[incompatible-type]
|
|
51
|
+
const preloadedEntryPoints: Partial<TPreloadedEntryPoints> = {};
|
|
50
52
|
if (queries != null) {
|
|
51
53
|
const queriesPropNames = Object.keys(queries);
|
|
52
54
|
queriesPropNames.forEach(queryPropName => {
|
|
@@ -34,15 +34,12 @@ const {
|
|
|
34
34
|
} = require('relay-runtime');
|
|
35
35
|
|
|
36
36
|
type RefetchVariables<TVariables, TKey> =
|
|
37
|
-
// NOTE: This
|
|
37
|
+
// NOTE: This type ensures that the type of the variables is either:
|
|
38
38
|
// - nullable if the provided ref type is non-nullable
|
|
39
39
|
// - non-nullable if the provided ref type is nullable, and the caller need to provide the full set of variables
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
& (<TFragmentType>(?{ +$fragmentSpreads: TFragmentType, ... }) => TVariables),
|
|
44
|
-
TKey,
|
|
45
|
-
>;
|
|
40
|
+
[+key: TKey] extends [+key: {+$fragmentSpreads: mixed, ...}]
|
|
41
|
+
? Partial<TVariables>
|
|
42
|
+
: TVariables;
|
|
46
43
|
|
|
47
44
|
type RefetchFnBase<TVars, TOptions> = (
|
|
48
45
|
vars: TVars,
|
|
@@ -55,15 +52,12 @@ type RefetchFn<TVariables, TKey, TOptions = Options> = RefetchFnBase<
|
|
|
55
52
|
>;
|
|
56
53
|
|
|
57
54
|
type ReturnType<TVariables, TData, TKey> = {
|
|
58
|
-
// NOTE: This
|
|
55
|
+
// NOTE: This rtpw ensures that the type of the returned data is either:
|
|
59
56
|
// - nullable if the provided ref type is nullable
|
|
60
57
|
// - non-nullable if the provided ref type is non-nullable
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
& (<TFragmentType>(?{ +$fragmentSpreads: TFragmentType, ... }) => ?TData),
|
|
65
|
-
TKey,
|
|
66
|
-
>,
|
|
58
|
+
data: [+key: TKey] extends [+key: {+$fragmentSpreads: mixed, ...}]
|
|
59
|
+
? TData
|
|
60
|
+
: ?TData,
|
|
67
61
|
loadNext: LoadMoreFn<TVariables>,
|
|
68
62
|
loadPrevious: LoadMoreFn<TVariables>,
|
|
69
63
|
hasNext: boolean,
|
|
@@ -89,7 +83,6 @@ function useBlockingPaginationFragment<
|
|
|
89
83
|
|
|
90
84
|
const {
|
|
91
85
|
connectionPathInFragmentData,
|
|
92
|
-
identifierField,
|
|
93
86
|
paginationRequest,
|
|
94
87
|
paginationMetadata,
|
|
95
88
|
stream,
|
|
@@ -132,7 +125,6 @@ function useBlockingPaginationFragment<
|
|
|
132
125
|
fragmentIdentifier,
|
|
133
126
|
fragmentNode,
|
|
134
127
|
fragmentRef,
|
|
135
|
-
identifierField,
|
|
136
128
|
paginationMetadata,
|
|
137
129
|
paginationRequest,
|
|
138
130
|
});
|
|
@@ -148,7 +140,6 @@ function useBlockingPaginationFragment<
|
|
|
148
140
|
fragmentIdentifier,
|
|
149
141
|
fragmentNode,
|
|
150
142
|
fragmentRef,
|
|
151
|
-
identifierField,
|
|
152
143
|
paginationMetadata,
|
|
153
144
|
paginationRequest,
|
|
154
145
|
});
|
|
@@ -157,6 +148,7 @@ function useBlockingPaginationFragment<
|
|
|
157
148
|
(variables: TVariables, options: void | Options) => {
|
|
158
149
|
disposeFetchNext();
|
|
159
150
|
disposeFetchPrevious();
|
|
151
|
+
// $FlowFixMe[incompatible-variance]
|
|
160
152
|
return refetch(variables, {...options, __environment: undefined});
|
|
161
153
|
},
|
|
162
154
|
[disposeFetchNext, disposeFetchPrevious, refetch],
|
|
@@ -164,6 +156,7 @@ function useBlockingPaginationFragment<
|
|
|
164
156
|
|
|
165
157
|
return {
|
|
166
158
|
// $FlowFixMe[incompatible-cast]
|
|
159
|
+
// $FlowFixMe[incompatible-return]
|
|
167
160
|
data: (fragmentData: TData),
|
|
168
161
|
loadNext,
|
|
169
162
|
loadPrevious,
|
|
@@ -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 ||
|
|
@@ -19,7 +19,9 @@ import type {
|
|
|
19
19
|
OperationType,
|
|
20
20
|
RenderPolicy,
|
|
21
21
|
} from 'relay-runtime';
|
|
22
|
+
import type {ReaderFragment} from 'relay-runtime/util/ReaderNode';
|
|
22
23
|
|
|
24
|
+
const HooksImplementation = require('./HooksImplementation');
|
|
23
25
|
const ProfilerContext = require('./ProfilerContext');
|
|
24
26
|
const {
|
|
25
27
|
getQueryCacheIdentifier,
|
|
@@ -125,7 +127,7 @@ function useLazyLoadQueryNode<TQuery: OperationType>({
|
|
|
125
127
|
});
|
|
126
128
|
|
|
127
129
|
const {fragmentNode, fragmentRef} = preparedQueryResult;
|
|
128
|
-
const
|
|
130
|
+
const data = useFragmentNodeImpl(
|
|
129
131
|
fragmentNode,
|
|
130
132
|
fragmentRef,
|
|
131
133
|
componentDisplayName,
|
|
@@ -133,4 +135,18 @@ function useLazyLoadQueryNode<TQuery: OperationType>({
|
|
|
133
135
|
return data;
|
|
134
136
|
}
|
|
135
137
|
|
|
138
|
+
function useFragmentNodeImpl(
|
|
139
|
+
fragment: ReaderFragment,
|
|
140
|
+
key: mixed,
|
|
141
|
+
componentDisplayName: string,
|
|
142
|
+
): mixed {
|
|
143
|
+
const impl = HooksImplementation.get();
|
|
144
|
+
if (impl && impl.useFragment__internal) {
|
|
145
|
+
return impl.useFragment__internal(fragment, key, componentDisplayName);
|
|
146
|
+
} else {
|
|
147
|
+
const {data} = useFragmentNode<mixed>(fragment, key, componentDisplayName);
|
|
148
|
+
return data;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
136
152
|
module.exports = useLazyLoadQueryNode;
|
|
@@ -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?:
|
|
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?:
|
|
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 (
|
|
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.
|
|
222
|
+
paginationVariables[identifierInfo.identifierQueryVariableName] =
|
|
223
|
+
identifierValue;
|
|
218
224
|
}
|
|
219
225
|
|
|
220
226
|
const paginationQuery = createOperationDescriptor(
|