react-relay 15.0.0 → 16.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +0 -11
- 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/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/react-cache/RelayReactCache.js +0 -12
- package/lib/relay-hooks/react-cache/getQueryResultOrFetchQuery_REACT_CACHE.js +1 -36
- package/lib/relay-hooks/react-cache/readFragmentInternal_REACT_CACHE.js +3 -27
- package/lib/relay-hooks/react-cache/useFragmentInternal_REACT_CACHE.js +34 -99
- package/lib/relay-hooks/react-cache/useFragment_REACT_CACHE.js +0 -15
- package/lib/relay-hooks/react-cache/useLazyLoadQuery_REACT_CACHE.js +0 -16
- package/lib/relay-hooks/react-cache/usePaginationFragment_REACT_CACHE.js +1 -23
- package/lib/relay-hooks/react-cache/usePreloadedQuery_REACT_CACHE.js +0 -29
- package/lib/relay-hooks/react-cache/useRefetchableFragmentInternal_REACT_CACHE.js +12 -96
- package/lib/relay-hooks/react-cache/useRefetchableFragment_REACT_CACHE.js +0 -14
- 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 +0 -35
- 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 +20 -19
- package/relay-hooks/FragmentResource.js.flow +114 -26
- 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/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/react-cache/readFragmentInternal_REACT_CACHE.js.flow +2 -1
- package/relay-hooks/react-cache/useFragmentInternal_REACT_CACHE.js.flow +28 -10
- package/relay-hooks/react-cache/useFragment_REACT_CACHE.js.flow +3 -9
- package/relay-hooks/react-cache/usePaginationFragment_REACT_CACHE.js.flow +28 -57
- package/relay-hooks/react-cache/useRefetchableFragmentInternal_REACT_CACHE.js.flow +19 -12
- package/relay-hooks/react-cache/useRefetchableFragment_REACT_CACHE.js.flow +15 -31
- package/relay-hooks/useBlockingPaginationFragment.js.flow +2 -4
- package/relay-hooks/useClientQuery.js.flow +2 -2
- package/relay-hooks/useFragmentNode.js.flow +2 -2
- package/relay-hooks/useLoadMoreFunction.js.flow +15 -9
- package/relay-hooks/useMutation.js.flow +26 -9
- package/relay-hooks/usePaginationFragment.js.flow +2 -8
- package/relay-hooks/useQueryLoader.js.flow +2 -8
- package/relay-hooks/useRefetchableFragment.js.flow +3 -2
- package/relay-hooks/useRefetchableFragmentNode.js.flow +28 -13
|
@@ -1,14 +1,3 @@
|
|
|
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
|
-
*
|
|
8
|
-
* @format
|
|
9
|
-
* @oncall relay
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
1
|
'use strict';
|
|
13
2
|
|
|
14
3
|
var _require = require('../loadQuery'),
|
|
@@ -26,8 +15,6 @@ function useLazyLoadQuery_REACT_CACHE(gqlQuery, variables, options) {
|
|
|
26
15
|
var queryOperationDescriptor = useMemoOperationDescriptor(gqlQuery, variables, (_options$networkCache = options === null || options === void 0 ? void 0 : options.networkCacheConfig) !== null && _options$networkCache !== void 0 ? _options$networkCache : {
|
|
27
16
|
force: true
|
|
28
17
|
});
|
|
29
|
-
|
|
30
|
-
// Get the query going if needed -- this may suspend.
|
|
31
18
|
var _getQueryResultOrFetc = getQueryResultOrFetchQuery(environment, queryOperationDescriptor, {
|
|
32
19
|
fetchPolicy: options === null || options === void 0 ? void 0 : options.fetchPolicy,
|
|
33
20
|
renderPolicy: options === null || options === void 0 ? void 0 : options.UNSTABLE_renderPolicy,
|
|
@@ -36,11 +23,8 @@ function useLazyLoadQuery_REACT_CACHE(gqlQuery, variables, options) {
|
|
|
36
23
|
queryResult = _getQueryResultOrFetc[0],
|
|
37
24
|
effect = _getQueryResultOrFetc[1];
|
|
38
25
|
useEffect(effect);
|
|
39
|
-
|
|
40
|
-
// Read the query's root fragment -- this may suspend.
|
|
41
26
|
var fragmentNode = queryResult.fragmentNode,
|
|
42
27
|
fragmentRef = queryResult.fragmentRef;
|
|
43
|
-
// $FlowExpectedError[incompatible-return] Is this a fixable incompatible-return?
|
|
44
28
|
return useFragmentInternal(fragmentNode, fragmentRef, 'useLazyLoadQuery()', {
|
|
45
29
|
fetchPolicy: options === null || options === void 0 ? void 0 : options.fetchPolicy,
|
|
46
30
|
networkCacheConfig: options === null || options === void 0 ? void 0 : options.networkCacheConfig
|
|
@@ -1,14 +1,3 @@
|
|
|
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
|
-
*
|
|
8
|
-
* @format
|
|
9
|
-
* @oncall relay
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
1
|
'use strict';
|
|
13
2
|
|
|
14
3
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
|
|
@@ -32,15 +21,12 @@ function usePaginationFragment(fragmentInput, parentFragmentRef) {
|
|
|
32
21
|
var _getPaginationMetadat = getPaginationMetadata(fragmentNode, componentDisplayName),
|
|
33
22
|
connectionPathInFragmentData = _getPaginationMetadat.connectionPathInFragmentData,
|
|
34
23
|
paginationRequest = _getPaginationMetadat.paginationRequest,
|
|
35
|
-
paginationMetadata = _getPaginationMetadat.paginationMetadata
|
|
36
|
-
identifierField = _getPaginationMetadat.identifierField;
|
|
24
|
+
paginationMetadata = _getPaginationMetadat.paginationMetadata;
|
|
37
25
|
var _useRefetchableFragme = useRefetchableFragmentInternal(fragmentNode, parentFragmentRef, componentDisplayName),
|
|
38
26
|
fragmentData = _useRefetchableFragme.fragmentData,
|
|
39
27
|
fragmentRef = _useRefetchableFragme.fragmentRef,
|
|
40
28
|
refetch = _useRefetchableFragme.refetch;
|
|
41
29
|
var fragmentIdentifier = getFragmentIdentifier(fragmentNode, fragmentRef);
|
|
42
|
-
|
|
43
|
-
// Backward pagination
|
|
44
30
|
var _useLoadMore = useLoadMore({
|
|
45
31
|
componentDisplayName: componentDisplayName,
|
|
46
32
|
connectionPathInFragmentData: connectionPathInFragmentData,
|
|
@@ -49,7 +35,6 @@ function usePaginationFragment(fragmentInput, parentFragmentRef) {
|
|
|
49
35
|
fragmentIdentifier: fragmentIdentifier,
|
|
50
36
|
fragmentNode: fragmentNode,
|
|
51
37
|
fragmentRef: fragmentRef,
|
|
52
|
-
identifierField: identifierField,
|
|
53
38
|
paginationMetadata: paginationMetadata,
|
|
54
39
|
paginationRequest: paginationRequest
|
|
55
40
|
}),
|
|
@@ -57,8 +42,6 @@ function usePaginationFragment(fragmentInput, parentFragmentRef) {
|
|
|
57
42
|
hasPrevious = _useLoadMore[1],
|
|
58
43
|
isLoadingPrevious = _useLoadMore[2],
|
|
59
44
|
disposeFetchPrevious = _useLoadMore[3];
|
|
60
|
-
|
|
61
|
-
// Forward pagination
|
|
62
45
|
var _useLoadMore2 = useLoadMore({
|
|
63
46
|
componentDisplayName: componentDisplayName,
|
|
64
47
|
connectionPathInFragmentData: connectionPathInFragmentData,
|
|
@@ -67,7 +50,6 @@ function usePaginationFragment(fragmentInput, parentFragmentRef) {
|
|
|
67
50
|
fragmentIdentifier: fragmentIdentifier,
|
|
68
51
|
fragmentNode: fragmentNode,
|
|
69
52
|
fragmentRef: fragmentRef,
|
|
70
|
-
identifierField: identifierField,
|
|
71
53
|
paginationMetadata: paginationMetadata,
|
|
72
54
|
paginationRequest: paginationRequest
|
|
73
55
|
}),
|
|
@@ -83,7 +65,6 @@ function usePaginationFragment(fragmentInput, parentFragmentRef) {
|
|
|
83
65
|
}));
|
|
84
66
|
}, [disposeFetchNext, disposeFetchPrevious, refetch]);
|
|
85
67
|
if (process.env.NODE_ENV !== "production") {
|
|
86
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
87
68
|
useDebugValue({
|
|
88
69
|
fragment: fragmentNode.name,
|
|
89
70
|
data: fragmentData,
|
|
@@ -109,9 +90,6 @@ function useLoadMore(args) {
|
|
|
109
90
|
var _useState = useState(false),
|
|
110
91
|
isLoadingMore = _useState[0],
|
|
111
92
|
reallySetIsLoadingMore = _useState[1];
|
|
112
|
-
// Schedule this update since it must be observed by components at the same
|
|
113
|
-
// batch as when hasNext changes. hasNext is read from the store and store
|
|
114
|
-
// updates are scheduled, so this must be scheduled too.
|
|
115
93
|
var setIsLoadingMore = function setIsLoadingMore(value) {
|
|
116
94
|
var _environment$getSched;
|
|
117
95
|
var schedule = (_environment$getSched = environment.getScheduler()) === null || _environment$getSched === void 0 ? void 0 : _environment$getSched.schedule;
|
|
@@ -1,14 +1,3 @@
|
|
|
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
|
-
*
|
|
8
|
-
* @format
|
|
9
|
-
* @oncall relay
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
1
|
'use strict';
|
|
13
2
|
|
|
14
3
|
var _require = require('../loadQuery'),
|
|
@@ -54,29 +43,14 @@ function usePreloadedQuery_REACT_CACHE(gqlQuery, preloadedQuery, options) {
|
|
|
54
43
|
process.env.NODE_ENV !== "production" ? warning(preloadedQuery.isDisposed === false, 'usePreloadedQuery(): Expected preloadedQuery to not be disposed yet. ' + 'This is because disposing the query marks it for future garbage ' + 'collection, and as such query results may no longer be present in the Relay ' + 'store. In the future, this will become a hard error.') : void 0;
|
|
55
44
|
var fallbackFetchObservable = fetchQuery(environment, operation);
|
|
56
45
|
if (source != null && environment === preloadedQuery.environment) {
|
|
57
|
-
// If the source observable exists and the environments match, reuse
|
|
58
|
-
// the source observable.
|
|
59
|
-
// If the source observable happens to be empty, we need to fall back
|
|
60
|
-
// and re-execute and de-dupe the query (at render time).
|
|
61
46
|
fetchObservable = source.ifEmpty(fallbackFetchObservable);
|
|
62
47
|
} else if (environment !== preloadedQuery.environment) {
|
|
63
|
-
// If a call to loadQuery is made with a particular environment, and that
|
|
64
|
-
// preloaded query is passed to usePreloadedQuery in a different environment
|
|
65
|
-
// context, we cannot re-use the existing preloaded query.
|
|
66
|
-
// Instead, we need to fall back and re-execute and de-dupe the query with
|
|
67
|
-
// the new environment (at render time).
|
|
68
|
-
// TODO T68036756 track occurences of this warning and turn it into a hard error
|
|
69
48
|
process.env.NODE_ENV !== "production" ? warning(false, 'usePreloadedQuery(): usePreloadedQuery was passed a preloaded query ' + 'that was created with a different environment than the one that is currently ' + 'in context. In the future, this will become a hard error.') : void 0;
|
|
70
49
|
fetchObservable = fallbackFetchObservable;
|
|
71
50
|
} else {
|
|
72
|
-
// if (source == null)
|
|
73
|
-
// If the source observable does not exist, we need to
|
|
74
|
-
// fall back and re-execute and de-dupe the query (at render time).
|
|
75
51
|
fetchObservable = fallbackFetchObservable;
|
|
76
52
|
}
|
|
77
53
|
}
|
|
78
|
-
|
|
79
|
-
// Get the query going if needed -- this may suspend.
|
|
80
54
|
var _getQueryResultOrFetc = getQueryResultOrFetchQuery(environment, operation, {
|
|
81
55
|
fetchPolicy: fetchPolicy,
|
|
82
56
|
renderPolicy: options === null || options === void 0 ? void 0 : options.UNSTABLE_renderPolicy,
|
|
@@ -86,8 +60,6 @@ function usePreloadedQuery_REACT_CACHE(gqlQuery, preloadedQuery, options) {
|
|
|
86
60
|
queryResult = _getQueryResultOrFetc[0],
|
|
87
61
|
effect = _getQueryResultOrFetc[1];
|
|
88
62
|
useEffect(effect);
|
|
89
|
-
|
|
90
|
-
// Read the query's root fragment -- this may suspend.
|
|
91
63
|
var fragmentNode = queryResult.fragmentNode,
|
|
92
64
|
fragmentRef = queryResult.fragmentRef;
|
|
93
65
|
var data = useFragmentInternal(fragmentNode, fragmentRef, 'usePreloadedQuery()', {
|
|
@@ -95,7 +67,6 @@ function usePreloadedQuery_REACT_CACHE(gqlQuery, preloadedQuery, options) {
|
|
|
95
67
|
networkCacheConfig: networkCacheConfig
|
|
96
68
|
});
|
|
97
69
|
if (process.env.NODE_ENV !== "production") {
|
|
98
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
99
70
|
useDebugValue({
|
|
100
71
|
query: preloadedQuery.name,
|
|
101
72
|
variables: preloadedQuery.variables,
|
|
@@ -1,14 +1,3 @@
|
|
|
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
|
-
*
|
|
8
|
-
* @format
|
|
9
|
-
* @oncall relay
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
1
|
'use strict';
|
|
13
2
|
|
|
14
3
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
|
|
@@ -71,7 +60,7 @@ function useRefetchableFragmentNode(fragmentNode, parentFragmentRef, componentDi
|
|
|
71
60
|
var _getRefetchMetadata = getRefetchMetadata(fragmentNode, componentDisplayName),
|
|
72
61
|
refetchableRequest = _getRefetchMetadata.refetchableRequest,
|
|
73
62
|
fragmentRefPathInResponse = _getRefetchMetadata.fragmentRefPathInResponse,
|
|
74
|
-
|
|
63
|
+
identifierInfo = _getRefetchMetadata.identifierInfo;
|
|
75
64
|
var fragmentIdentifier = getFragmentIdentifier(fragmentNode, parentFragmentRef);
|
|
76
65
|
var _useReducer = useReducer(reducer, {
|
|
77
66
|
fetchPolicy: undefined,
|
|
@@ -108,47 +97,18 @@ function useRefetchableFragmentNode(fragmentNode, parentFragmentRef, componentDi
|
|
|
108
97
|
});
|
|
109
98
|
disposeQuery();
|
|
110
99
|
} else if (refetchQuery != null && queryRef != null) {
|
|
111
|
-
// If refetch was called, we expect to have a refetchQuery and queryRef
|
|
112
|
-
// in state, since both state updates to set the refetchQuery and the
|
|
113
|
-
// queryRef occur simultaneously.
|
|
114
|
-
// In this case, we need to read the refetched query data (potentially
|
|
115
|
-
// suspending if it's in flight), and extract the new fragment ref
|
|
116
|
-
// from the query in order read the current @refetchable fragment
|
|
117
|
-
// with the updated fragment owner as the new refetchQuery.
|
|
118
|
-
|
|
119
|
-
// Before observing the refetch, record the current ID and typename
|
|
120
|
-
// so that, if we are refetching existing data on
|
|
121
|
-
// a field that implements Node, after refetching we
|
|
122
|
-
// can validate that the received data is consistent
|
|
123
100
|
var debugPreviousIDAndTypename;
|
|
124
101
|
if (process.env.NODE_ENV !== "production") {
|
|
125
|
-
debugPreviousIDAndTypename = debugFunctions.getInitialIDAndType(refetchQuery.request.variables, fragmentRefPathInResponse, environment);
|
|
102
|
+
debugPreviousIDAndTypename = debugFunctions.getInitialIDAndType(refetchQuery.request.variables, fragmentRefPathInResponse, identifierInfo === null || identifierInfo === void 0 ? void 0 : identifierInfo.identifierQueryVariableName, environment);
|
|
126
103
|
}
|
|
127
104
|
var handleQueryCompleted = function handleQueryCompleted(maybeError) {
|
|
128
105
|
onComplete && onComplete(maybeError !== null && maybeError !== void 0 ? maybeError : null);
|
|
129
106
|
};
|
|
130
|
-
|
|
131
|
-
// The queryRef.source obtained from useQueryLoader will be
|
|
132
|
-
// an observable we can consume /if/ a network request was
|
|
133
|
-
// started. Otherwise, given that QueryResource.prepare
|
|
134
|
-
// always expects an observable we fall back to a new network
|
|
135
|
-
// observable. Note however that if loadQuery did not make a network
|
|
136
|
-
// request, we don't expect to make one here, unless the state of
|
|
137
|
-
// the cache has changed between the call to refetch and this
|
|
138
|
-
// render.
|
|
139
107
|
var fetchObservable = queryRef.source != null ? queryRef.source : fetchQuery(environment, refetchQuery);
|
|
140
|
-
|
|
141
|
-
// Now wwe can we read the refetch query here using the
|
|
142
|
-
// queryRef provided from useQueryLoader. Note that the
|
|
143
|
-
// network request is started during the call to refetch,
|
|
144
|
-
// but if the refetch query is still in flight, we will suspend
|
|
145
|
-
// at this point:
|
|
146
108
|
var queryResult = profilerContext.wrapPrepareQueryResource(function () {
|
|
147
109
|
return QueryResource.prepare(refetchQuery, fetchObservable, fetchPolicy, renderPolicy, {
|
|
148
110
|
error: handleQueryCompleted,
|
|
149
111
|
complete: function complete() {
|
|
150
|
-
// Validate that the type of the object we got back matches the type
|
|
151
|
-
// of the object already in the store
|
|
152
112
|
if (process.env.NODE_ENV !== "production") {
|
|
153
113
|
debugFunctions.checkSameTypeAfterRefetch(debugPreviousIDAndTypename, environment, fragmentNode, componentDisplayName);
|
|
154
114
|
}
|
|
@@ -158,40 +118,24 @@ function useRefetchableFragmentNode(fragmentNode, parentFragmentRef, componentDi
|
|
|
158
118
|
});
|
|
159
119
|
var queryData = readFragmentInternal(environment, queryResult.fragmentNode, queryResult.fragmentRef, componentDisplayName).data;
|
|
160
120
|
!(queryData != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Relay: Expected to be able to read refetch query response. ' + "If you're seeing this, this is likely a bug in Relay.") : invariant(false) : void 0;
|
|
161
|
-
|
|
162
|
-
// After reading/fetching the refetch query, we extract from the
|
|
163
|
-
// refetch query response the new fragment ref we need to use to read
|
|
164
|
-
// the fragment. The new fragment ref will point to the refetch query
|
|
165
|
-
// as its fragment owner.
|
|
166
121
|
var refetchedFragmentRef = getValueAtPath(queryData, fragmentRefPathInResponse);
|
|
167
122
|
fragmentRef = refetchedFragmentRef;
|
|
168
123
|
if (process.env.NODE_ENV !== "production") {
|
|
169
|
-
// Validate that the id of the object we got back matches the id
|
|
170
|
-
// we queried for in the variables.
|
|
171
|
-
// We do this during render instead of onComplete to make sure we are
|
|
172
|
-
// only validating the most recent refetch.
|
|
173
124
|
debugFunctions.checkSameIDAfterRefetch(debugPreviousIDAndTypename, fragmentRef, fragmentNode, componentDisplayName);
|
|
174
125
|
}
|
|
175
126
|
}
|
|
176
|
-
|
|
177
|
-
// We read and subscribe to the fragment using useFragmentNode.
|
|
178
|
-
// If refetch was called, we read the fragment using the new computed
|
|
179
|
-
// fragment ref from the refetch query response; otherwise, we use the
|
|
180
|
-
// fragment ref passed by the caller as normal.
|
|
181
127
|
var fragmentData = useFragmentInternal(fragmentNode, fragmentRef, componentDisplayName);
|
|
182
|
-
var refetch = useRefetchFunction(componentDisplayName, dispatch, disposeQuery, fragmentData, fragmentIdentifier, fragmentNode, fragmentRefPathInResponse,
|
|
128
|
+
var refetch = useRefetchFunction(componentDisplayName, dispatch, disposeQuery, fragmentData, fragmentIdentifier, fragmentNode, fragmentRefPathInResponse, identifierInfo, loadQuery, parentFragmentRef, refetchableRequest);
|
|
183
129
|
return {
|
|
184
130
|
fragmentData: fragmentData,
|
|
185
131
|
fragmentRef: fragmentRef,
|
|
186
132
|
refetch: refetch
|
|
187
133
|
};
|
|
188
134
|
}
|
|
189
|
-
function useRefetchFunction(componentDisplayName, dispatch, disposeQuery, fragmentData, fragmentIdentifier, fragmentNode, fragmentRefPathInResponse,
|
|
135
|
+
function useRefetchFunction(componentDisplayName, dispatch, disposeQuery, fragmentData, fragmentIdentifier, fragmentNode, fragmentRefPathInResponse, identifierInfo, loadQuery, parentFragmentRef, refetchableRequest) {
|
|
190
136
|
var isMountedRef = useIsMountedRef();
|
|
191
|
-
var identifierValue = identifierField != null && fragmentData != null && typeof fragmentData === 'object' ? fragmentData[identifierField] : null;
|
|
137
|
+
var identifierValue = (identifierInfo === null || identifierInfo === void 0 ? void 0 : identifierInfo.identifierField) != null && fragmentData != null && typeof fragmentData === 'object' ? fragmentData[identifierInfo.identifierField] : null;
|
|
192
138
|
return useCallback(function (providedRefetchVariables, options) {
|
|
193
|
-
// Bail out and warn if we're trying to refetch after the component
|
|
194
|
-
// has unmounted
|
|
195
139
|
if (isMountedRef.current !== true) {
|
|
196
140
|
process.env.NODE_ENV !== "production" ? warning(false, 'Relay: Unexpected call to `refetch` on unmounted component for fragment ' + '`%s` in `%s`. It looks like some instances of your component are ' + 'still trying to fetch data but they already unmounted. ' + 'Please make sure you clear all timers, intervals, ' + 'async calls, etc that may trigger a fetch.', fragmentNode.name, componentDisplayName) : void 0;
|
|
197
141
|
return {
|
|
@@ -219,35 +163,16 @@ function useRefetchFunction(componentDisplayName, dispatch, disposeQuery, fragme
|
|
|
219
163
|
parentVariables = fragmentSelector.owner.variables;
|
|
220
164
|
fragmentVariables = fragmentSelector.variables;
|
|
221
165
|
}
|
|
222
|
-
|
|
223
|
-
// A user of `useRefetchableFragment()` may pass a subset of
|
|
224
|
-
// all variables required by the fragment when calling `refetch()`.
|
|
225
|
-
// We fill in any variables not passed by the call to `refetch()` with the
|
|
226
|
-
// variables from the original parent fragment owner.
|
|
227
166
|
var refetchVariables = (0, _objectSpread2["default"])((0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, parentVariables), fragmentVariables), providedRefetchVariables);
|
|
228
|
-
|
|
229
|
-
// If the query needs an identifier value ('id' or similar) and one
|
|
230
|
-
// was not explicitly provided, read it from the fragment data.
|
|
231
|
-
if (identifierField != null && !providedRefetchVariables.hasOwnProperty('id')) {
|
|
232
|
-
// @refetchable fragments are guaranteed to have an `id` selection
|
|
233
|
-
// if the type is Node, implements Node, or is @fetchable. Double-check
|
|
234
|
-
// that there actually is a value at runtime.
|
|
167
|
+
if (identifierInfo != null && !providedRefetchVariables.hasOwnProperty(identifierInfo.identifierQueryVariableName)) {
|
|
235
168
|
if (typeof identifierValue !== 'string') {
|
|
236
|
-
process.env.NODE_ENV !== "production" ? warning(false, 'Relay: Expected result to have a string ' + '`%s` in order to refetch, got `%s`.', identifierField, identifierValue) : void 0;
|
|
169
|
+
process.env.NODE_ENV !== "production" ? warning(false, 'Relay: Expected result to have a string ' + '`%s` in order to refetch, got `%s`.', identifierInfo.identifierField, identifierValue) : void 0;
|
|
237
170
|
}
|
|
238
|
-
refetchVariables.
|
|
171
|
+
refetchVariables[identifierInfo.identifierQueryVariableName] = identifierValue;
|
|
239
172
|
}
|
|
240
173
|
var refetchQuery = createOperationDescriptor(refetchableRequest, refetchVariables, {
|
|
241
174
|
force: true
|
|
242
175
|
});
|
|
243
|
-
|
|
244
|
-
// We call loadQuery which will start a network request if necessary
|
|
245
|
-
// and update the querRef from useQueryLoader.
|
|
246
|
-
// Note the following:
|
|
247
|
-
// - loadQuery will dispose of any previously refetched queries.
|
|
248
|
-
// - We use the variables extracted off the OperationDescriptor
|
|
249
|
-
// so that they have been filtered out to include only the
|
|
250
|
-
// variables actually declared in the query.
|
|
251
176
|
loadQuery(refetchQuery.request.variables, {
|
|
252
177
|
fetchPolicy: fetchPolicy,
|
|
253
178
|
__environment: refetchEnvironment,
|
|
@@ -264,29 +189,21 @@ function useRefetchFunction(componentDisplayName, dispatch, disposeQuery, fragme
|
|
|
264
189
|
return {
|
|
265
190
|
dispose: disposeQuery
|
|
266
191
|
};
|
|
267
|
-
},
|
|
268
|
-
// NOTE: We disable react-hooks-deps warning because:
|
|
269
|
-
// - We know fragmentRefPathInResponse is static, so it can be omitted from
|
|
270
|
-
// deps
|
|
271
|
-
// - We know fragmentNode is static, so it can be omitted from deps.
|
|
272
|
-
// - fragmentNode and parentFragmentRef are also captured by including
|
|
273
|
-
// fragmentIdentifier
|
|
274
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
275
|
-
[fragmentIdentifier, dispatch, disposeQuery, identifierValue, loadQuery]);
|
|
192
|
+
}, [fragmentIdentifier, dispatch, disposeQuery, identifierValue, loadQuery]);
|
|
276
193
|
}
|
|
277
194
|
var debugFunctions;
|
|
278
195
|
if (process.env.NODE_ENV !== "production") {
|
|
279
196
|
debugFunctions = {
|
|
280
|
-
getInitialIDAndType: function getInitialIDAndType(memoRefetchVariables, fragmentRefPathInResponse, environment) {
|
|
197
|
+
getInitialIDAndType: function getInitialIDAndType(memoRefetchVariables, fragmentRefPathInResponse, identifierQueryVariableName, environment) {
|
|
281
198
|
var _require4 = require('relay-runtime'),
|
|
282
199
|
Record = _require4.Record;
|
|
283
|
-
var id = memoRefetchVariables === null || memoRefetchVariables === void 0 ? void 0 : memoRefetchVariables
|
|
200
|
+
var id = memoRefetchVariables === null || memoRefetchVariables === void 0 ? void 0 : memoRefetchVariables[identifierQueryVariableName !== null && identifierQueryVariableName !== void 0 ? identifierQueryVariableName : 'id'];
|
|
284
201
|
if (fragmentRefPathInResponse.length !== 1 || fragmentRefPathInResponse[0] !== 'node' || id == null) {
|
|
285
202
|
return null;
|
|
286
203
|
}
|
|
287
204
|
var recordSource = environment.getStore().getSource();
|
|
288
205
|
var record = recordSource.get(id);
|
|
289
|
-
var typename = record
|
|
206
|
+
var typename = record == null ? null : Record.getType(record);
|
|
290
207
|
if (typename == null) {
|
|
291
208
|
return null;
|
|
292
209
|
}
|
|
@@ -314,7 +231,6 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
314
231
|
}
|
|
315
232
|
var _require6 = require('relay-runtime'),
|
|
316
233
|
ID_KEY = _require6.ID_KEY;
|
|
317
|
-
// $FlowExpectedError[incompatible-use]
|
|
318
234
|
var resultID = refetchedFragmentRef[ID_KEY];
|
|
319
235
|
if (resultID != null && resultID !== previousIDAndTypename.id) {
|
|
320
236
|
process.env.NODE_ENV !== "production" ? warning(false, 'Relay: Call to `refetch` returned a different id, expected ' + '`%s`, got `%s`, on `%s` in `%s`. ' + 'Please make sure the server correctly implements ' + 'unique id requirement.', resultID, previousIDAndTypename.id, fragmentNode.name, componentDisplayName) : void 0;
|
|
@@ -1,14 +1,3 @@
|
|
|
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
|
-
*
|
|
8
|
-
* @format
|
|
9
|
-
* @oncall relay
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
1
|
'use strict';
|
|
13
2
|
|
|
14
3
|
var useStaticFragmentNodeWarning = require('../useStaticFragmentNodeWarning');
|
|
@@ -24,14 +13,11 @@ function useRefetchableFragment(fragmentInput, fragmentRef) {
|
|
|
24
13
|
fragmentData = _useRefetchableFragme.fragmentData,
|
|
25
14
|
refetch = _useRefetchableFragme.refetch;
|
|
26
15
|
if (process.env.NODE_ENV !== "production") {
|
|
27
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
28
16
|
useDebugValue({
|
|
29
17
|
fragment: fragmentNode.name,
|
|
30
18
|
data: fragmentData
|
|
31
19
|
});
|
|
32
20
|
}
|
|
33
|
-
/* $FlowExpectedError[prop-missing] : Exposed options is a subset of internal
|
|
34
|
-
* options */
|
|
35
21
|
return [fragmentData, refetch];
|
|
36
22
|
}
|
|
37
23
|
module.exports = useRefetchableFragment;
|
|
@@ -1,14 +1,3 @@
|
|
|
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
|
-
*
|
|
8
|
-
* @format
|
|
9
|
-
* @oncall relay
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
1
|
'use strict';
|
|
13
2
|
|
|
14
3
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
|
|
@@ -34,7 +23,6 @@ function useBlockingPaginationFragment(fragmentInput, parentFragmentRef) {
|
|
|
34
23
|
useStaticFragmentNodeWarning(fragmentNode, "first argument of ".concat(componentDisplayName));
|
|
35
24
|
var _getPaginationMetadat = getPaginationMetadata(fragmentNode, componentDisplayName),
|
|
36
25
|
connectionPathInFragmentData = _getPaginationMetadat.connectionPathInFragmentData,
|
|
37
|
-
identifierField = _getPaginationMetadat.identifierField,
|
|
38
26
|
paginationRequest = _getPaginationMetadat.paginationRequest,
|
|
39
27
|
paginationMetadata = _getPaginationMetadat.paginationMetadata,
|
|
40
28
|
stream = _getPaginationMetadat.stream;
|
|
@@ -46,8 +34,6 @@ function useBlockingPaginationFragment(fragmentInput, parentFragmentRef) {
|
|
|
46
34
|
disableStoreUpdates = _useRefetchableFragme.disableStoreUpdates,
|
|
47
35
|
enableStoreUpdates = _useRefetchableFragme.enableStoreUpdates;
|
|
48
36
|
var fragmentIdentifier = getFragmentIdentifier(fragmentNode, fragmentRef);
|
|
49
|
-
|
|
50
|
-
// Backward pagination
|
|
51
37
|
var _useLoadMore = useLoadMore({
|
|
52
38
|
componentDisplayName: componentDisplayName,
|
|
53
39
|
connectionPathInFragmentData: connectionPathInFragmentData,
|
|
@@ -58,15 +44,12 @@ function useBlockingPaginationFragment(fragmentInput, parentFragmentRef) {
|
|
|
58
44
|
fragmentIdentifier: fragmentIdentifier,
|
|
59
45
|
fragmentNode: fragmentNode,
|
|
60
46
|
fragmentRef: fragmentRef,
|
|
61
|
-
identifierField: identifierField,
|
|
62
47
|
paginationMetadata: paginationMetadata,
|
|
63
48
|
paginationRequest: paginationRequest
|
|
64
49
|
}),
|
|
65
50
|
loadPrevious = _useLoadMore[0],
|
|
66
51
|
hasPrevious = _useLoadMore[1],
|
|
67
52
|
disposeFetchPrevious = _useLoadMore[2];
|
|
68
|
-
|
|
69
|
-
// Forward pagination
|
|
70
53
|
var _useLoadMore2 = useLoadMore({
|
|
71
54
|
componentDisplayName: componentDisplayName,
|
|
72
55
|
connectionPathInFragmentData: connectionPathInFragmentData,
|
|
@@ -77,7 +60,6 @@ function useBlockingPaginationFragment(fragmentInput, parentFragmentRef) {
|
|
|
77
60
|
fragmentIdentifier: fragmentIdentifier,
|
|
78
61
|
fragmentNode: fragmentNode,
|
|
79
62
|
fragmentRef: fragmentRef,
|
|
80
|
-
identifierField: identifierField,
|
|
81
63
|
paginationMetadata: paginationMetadata,
|
|
82
64
|
paginationRequest: paginationRequest
|
|
83
65
|
}),
|
|
@@ -92,7 +74,6 @@ function useBlockingPaginationFragment(fragmentInput, parentFragmentRef) {
|
|
|
92
74
|
}));
|
|
93
75
|
}, [disposeFetchNext, disposeFetchPrevious, refetch]);
|
|
94
76
|
return {
|
|
95
|
-
// $FlowFixMe[incompatible-cast]
|
|
96
77
|
data: fragmentData,
|
|
97
78
|
loadNext: loadNext,
|
|
98
79
|
loadPrevious: loadPrevious,
|
|
@@ -121,13 +102,7 @@ function useLoadMore(args) {
|
|
|
121
102
|
};
|
|
122
103
|
var observer = {
|
|
123
104
|
complete: promiseResolve,
|
|
124
|
-
// NOTE: loadMore is a no-op if a request is already in flight, so we
|
|
125
|
-
// can safely assume that `start` will only be called once while a
|
|
126
|
-
// request is in flight.
|
|
127
105
|
start: function start() {
|
|
128
|
-
// NOTE: We disable store updates when we suspend to ensure
|
|
129
|
-
// that higher-pri updates from the Relay store don't disrupt
|
|
130
|
-
// any Suspense timeouts passed via withSuspenseConfig.
|
|
131
106
|
disableStoreUpdates();
|
|
132
107
|
var promise = new Promise(function (resolve) {
|
|
133
108
|
promiseResolveRef.current = function () {
|
|
@@ -138,14 +113,7 @@ function useLoadMore(args) {
|
|
|
138
113
|
requestPromiseRef.current = promise;
|
|
139
114
|
setRequestPromise(promise);
|
|
140
115
|
},
|
|
141
|
-
// NOTE: Since streaming is disallowed with this hook, this means that the
|
|
142
|
-
// first payload will always contain the entire next page of items,
|
|
143
|
-
// while subsequent paylaods will contain @defer'd payloads.
|
|
144
|
-
// This allows us to unsuspend here, on the first payload, and allow
|
|
145
|
-
// descendant components to suspend on their respective @defer payloads
|
|
146
116
|
next: promiseResolve,
|
|
147
|
-
// TODO: Handle error; we probably don't want to throw an error
|
|
148
|
-
// and blow away the whole list of items.
|
|
149
117
|
error: promiseResolve
|
|
150
118
|
};
|
|
151
119
|
var _useLoadMoreFunction = useLoadMoreFunction((0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, loadMoreArgs), {}, {
|
|
@@ -155,23 +123,13 @@ function useLoadMore(args) {
|
|
|
155
123
|
loadMore = _useLoadMoreFunction[0],
|
|
156
124
|
hasMore = _useLoadMoreFunction[1],
|
|
157
125
|
disposeFetch = _useLoadMoreFunction[2];
|
|
158
|
-
|
|
159
|
-
// NOTE: To determine if we need to suspend, we check that the promise in
|
|
160
|
-
// state is the same as the promise on the ref, which ensures that we
|
|
161
|
-
// wont incorrectly suspend on other higher-pri updates before the update
|
|
162
|
-
// to suspend has committed.
|
|
163
126
|
if (requestPromise != null && requestPromise === requestPromiseRef.current) {
|
|
164
127
|
throw requestPromise;
|
|
165
128
|
}
|
|
166
129
|
useEffect(function () {
|
|
167
130
|
if (requestPromise !== requestPromiseRef.current) {
|
|
168
|
-
// NOTE: After suspense pagination has resolved, we re-enable store updates
|
|
169
|
-
// for this fragment. This may cause the component to re-render if
|
|
170
|
-
// we missed any updates to the fragment data other than the pagination update.
|
|
171
131
|
enableStoreUpdates();
|
|
172
132
|
}
|
|
173
|
-
// NOTE: We know the identity of enableStoreUpdates wont change
|
|
174
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
175
133
|
}, [requestPromise]);
|
|
176
134
|
return [loadMore, hasMore, disposeFetch];
|
|
177
135
|
}
|
|
@@ -1,27 +1,9 @@
|
|
|
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
|
-
*
|
|
8
|
-
* @format
|
|
9
|
-
* @oncall relay
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
1
|
'use strict';
|
|
13
2
|
|
|
14
3
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
|
|
15
4
|
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
|
|
16
5
|
var useLazyLoadQuery = require('./useLazyLoadQuery');
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* This hook can be used to render client-only queries.
|
|
20
|
-
* These queries are consist of queries for client-only data,
|
|
21
|
-
* schematized via local schema extensions and/or Relay resolvers.
|
|
22
|
-
*/
|
|
23
6
|
function useClientQuery(gqlQuery, variables, options) {
|
|
24
|
-
// $FlowFixMe[incompatible-type] client queries can be used with useLazyLoadQuery, but only with `store-only` policy.
|
|
25
7
|
var query = gqlQuery;
|
|
26
8
|
return useLazyLoadQuery(query, variables, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, options), {}, {
|
|
27
9
|
fetchPolicy: 'store-only'
|
|
@@ -1,14 +1,3 @@
|
|
|
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
|
-
*
|
|
8
|
-
* @format
|
|
9
|
-
* @oncall relay
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
1
|
'use strict';
|
|
13
2
|
|
|
14
3
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
|
|
@@ -27,26 +16,6 @@ var initialNullEntryPointReferenceState = {
|
|
|
27
16
|
};
|
|
28
17
|
function useLoadEntryPoint(environmentProvider, entryPoint, options) {
|
|
29
18
|
var _options$TEST_ONLY__i, _options$TEST_ONLY__i2, _options$TEST_ONLY__i3, _options$TEST_ONLY__i4;
|
|
30
|
-
/**
|
|
31
|
-
* We want to always call `entryPointReference.dispose()` for every call to
|
|
32
|
-
* `setEntryPointReference(loadEntryPoint(...))` so that no leaks of data in Relay
|
|
33
|
-
* stores will occur.
|
|
34
|
-
*
|
|
35
|
-
* However, a call to `setState(newState)` is not always followed by a commit where
|
|
36
|
-
* this value is reflected in the state. Thus, we cannot reliably clean up each ref
|
|
37
|
-
* with `useEffect(() => () => entryPointReference.dispose(), [entryPointReference])`.
|
|
38
|
-
*
|
|
39
|
-
* Instead, we keep track of each call to `loadEntryPoint` in a ref.
|
|
40
|
-
* Relying on the fact that if a state change commits, no state changes that were
|
|
41
|
-
* initiated prior to the currently committing state change will ever subsequently
|
|
42
|
-
* commit, we can safely dispose of all preloaded entry point references
|
|
43
|
-
* associated with state changes initiated prior to the currently committing state
|
|
44
|
-
* change.
|
|
45
|
-
*
|
|
46
|
-
* Finally, when the hook unmounts, we also dispose of all remaining uncommitted
|
|
47
|
-
* entry point references.
|
|
48
|
-
*/
|
|
49
|
-
|
|
50
19
|
useTrackLoadQueryInRender();
|
|
51
20
|
var initialEntryPointReferenceInternal = (_options$TEST_ONLY__i = options === null || options === void 0 ? void 0 : (_options$TEST_ONLY__i2 = options.TEST_ONLY__initialEntryPointData) === null || _options$TEST_ONLY__i2 === void 0 ? void 0 : _options$TEST_ONLY__i2.entryPointReference) !== null && _options$TEST_ONLY__i !== void 0 ? _options$TEST_ONLY__i : initialNullEntryPointReferenceState;
|
|
52
21
|
var initialEntryPointParamsInternal = (_options$TEST_ONLY__i3 = options === null || options === void 0 ? void 0 : (_options$TEST_ONLY__i4 = options.TEST_ONLY__initialEntryPointData) === null || _options$TEST_ONLY__i4 === void 0 ? void 0 : _options$TEST_ONLY__i4.entryPointParams) !== null && _options$TEST_ONLY__i3 !== void 0 ? _options$TEST_ONLY__i3 : null;
|
|
@@ -78,53 +47,17 @@ function useLoadEntryPoint(environmentProvider, entryPoint, options) {
|
|
|
78
47
|
var maybeHiddenOrFastRefresh = useRef(false);
|
|
79
48
|
useEffect(function () {
|
|
80
49
|
return function () {
|
|
81
|
-
// Attempt to detect if the component was
|
|
82
|
-
// hidden (by Offscreen API), or fast refresh occured;
|
|
83
|
-
// Only in these situations would the effect cleanup
|
|
84
|
-
// for "unmounting" run multiple times, so if
|
|
85
|
-
// we are ever able to read this ref with a value
|
|
86
|
-
// of true, it means that one of these cases
|
|
87
|
-
// has happened.
|
|
88
50
|
maybeHiddenOrFastRefresh.current = true;
|
|
89
51
|
};
|
|
90
52
|
}, []);
|
|
91
53
|
useEffect(function () {
|
|
92
54
|
if (maybeHiddenOrFastRefresh.current === true) {
|
|
93
|
-
// This block only runs if the component has previously "unmounted"
|
|
94
|
-
// due to it being hidden by the Offscreen API, or during fast refresh.
|
|
95
|
-
// At this point, the current entryPointReference will have been disposed
|
|
96
|
-
// by the previous cleanup, so instead of attempting to
|
|
97
|
-
// do our regular commit setup, which would incorrectly leave our
|
|
98
|
-
// current entryPointReference disposed, we need to load the entryPoint again
|
|
99
|
-
// and force a re-render by calling entryPointLoaderCallback again,
|
|
100
|
-
// so that the entryPointReference's queries are correctly re-retained, and
|
|
101
|
-
// potentially refetched if necessary.
|
|
102
55
|
maybeHiddenOrFastRefresh.current = false;
|
|
103
56
|
if (entryPointReference.kind !== 'NullEntryPointReference' && entryPointParams != null) {
|
|
104
57
|
entryPointLoaderCallback(entryPointParams);
|
|
105
58
|
}
|
|
106
59
|
return;
|
|
107
60
|
}
|
|
108
|
-
|
|
109
|
-
// When a new entryPointReference is committed, we iterate over all
|
|
110
|
-
// entrypoint refs in undisposedEntryPointReferences and dispose all of
|
|
111
|
-
// the refs that aren't the currently committed one. This ensures
|
|
112
|
-
// that we don't leave any dangling entrypoint references for the
|
|
113
|
-
// case that loadEntryPoint is called multiple times before commit; when
|
|
114
|
-
// this happens, multiple state updates will be scheduled, but only one
|
|
115
|
-
// will commit, meaning that we need to keep track of and dispose any
|
|
116
|
-
// query references that don't end up committing.
|
|
117
|
-
// - We are relying on the fact that sets iterate in insertion order, and we
|
|
118
|
-
// can remove items from a set as we iterate over it (i.e. no iterator
|
|
119
|
-
// invalidation issues.) Thus, it is safe to loop through
|
|
120
|
-
// undisposedEntryPointReferences until we find entryPointReference, and
|
|
121
|
-
// remove and dispose all previous references.
|
|
122
|
-
// - We are guaranteed to find entryPointReference in the set, because if a
|
|
123
|
-
// state change results in a commit, no state changes initiated prior to that
|
|
124
|
-
// one will be committed, and we are disposing and removing references
|
|
125
|
-
// associated with commits that were initiated prior to the currently
|
|
126
|
-
// committing state change. (A useEffect callback is called during the commit
|
|
127
|
-
// phase.)
|
|
128
61
|
var undisposedEntryPointReferences = undisposedEntryPointReferencesRef.current;
|
|
129
62
|
if (isMountedRef.current) {
|
|
130
63
|
var _iterator = (0, _createForOfIteratorHelper2["default"])(undisposedEntryPointReferences),
|
|
@@ -149,8 +82,6 @@ function useLoadEntryPoint(environmentProvider, entryPoint, options) {
|
|
|
149
82
|
}, [entryPointReference, entryPointParams, entryPointLoaderCallback, isMountedRef]);
|
|
150
83
|
useEffect(function () {
|
|
151
84
|
return function disposeAllRemainingEntryPointReferences() {
|
|
152
|
-
// undisposedEntryPointReferences.current is never reassigned
|
|
153
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
154
85
|
var _iterator2 = (0, _createForOfIteratorHelper2["default"])(undisposedEntryPointReferencesRef.current),
|
|
155
86
|
_step2;
|
|
156
87
|
try {
|