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 _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
|
|
@@ -20,10 +9,7 @@ var _require = require('relay-runtime'),
|
|
|
20
9
|
createOperationDescriptor = _require.createOperationDescriptor,
|
|
21
10
|
getRequest = _require.getRequest,
|
|
22
11
|
getRequestIdentifier = _require.getRequestIdentifier;
|
|
23
|
-
|
|
24
|
-
// Expire results by this delay after they resolve.
|
|
25
|
-
var DEFAULT_PREFETCH_TIMEOUT = 30 * 1000; // 30 seconds
|
|
26
|
-
|
|
12
|
+
var DEFAULT_PREFETCH_TIMEOUT = 30 * 1000;
|
|
27
13
|
var WEAKMAP_SUPPORTED = typeof WeakMap === 'function';
|
|
28
14
|
var STORE_OR_NETWORK_DEFAULT = 'store-or-network';
|
|
29
15
|
var pendingQueriesByEnvironment = WEAKMAP_SUPPORTED ? new WeakMap() : new Map();
|
|
@@ -33,7 +19,7 @@ function preloadQuery(environment, preloadableRequest, variables, options, envir
|
|
|
33
19
|
_pendingQueries = new Map();
|
|
34
20
|
pendingQueriesByEnvironment.set(environment, _pendingQueries);
|
|
35
21
|
}
|
|
36
|
-
var pendingQueries = _pendingQueries;
|
|
22
|
+
var pendingQueries = _pendingQueries;
|
|
37
23
|
var queryEntry = preloadQueryDeduped(environment, pendingQueries, preloadableRequest, variables, options);
|
|
38
24
|
var source = queryEntry.kind === 'network' ? Observable.create(function (sink) {
|
|
39
25
|
var subscription;
|
|
@@ -52,8 +38,6 @@ function preloadQuery(environment, preloadableRequest, variables, options, envir
|
|
|
52
38
|
return;
|
|
53
39
|
}
|
|
54
40
|
setTimeout(function () {
|
|
55
|
-
// Clear the cache entry after the default timeout
|
|
56
|
-
// null-check for Flow
|
|
57
41
|
if (queryEntry != null) {
|
|
58
42
|
cleanup(pendingQueries, queryEntry);
|
|
59
43
|
}
|
|
@@ -115,15 +99,12 @@ function preloadQueryDeduped(environment, pendingQueries, preloadableRequest, va
|
|
|
115
99
|
};
|
|
116
100
|
if (!environment.isServer() && prevQueryEntry == null) {
|
|
117
101
|
setTimeout(function () {
|
|
118
|
-
// Clear the cache entry after the default timeout
|
|
119
|
-
// null-check for Flow
|
|
120
102
|
if (nextQueryEntry != null) {
|
|
121
103
|
cleanup(pendingQueries, nextQueryEntry);
|
|
122
104
|
}
|
|
123
105
|
}, DEFAULT_PREFETCH_TIMEOUT);
|
|
124
106
|
}
|
|
125
107
|
} else if (prevQueryEntry == null || prevQueryEntry.kind !== 'network') {
|
|
126
|
-
// Should fetch but we're not already fetching: fetch!
|
|
127
108
|
var source = network.execute(params, variables, networkCacheConfig, null);
|
|
128
109
|
var subject = new ReplaySubject();
|
|
129
110
|
nextQueryEntry = {
|
|
@@ -144,8 +125,6 @@ function preloadQueryDeduped(environment, pendingQueries, preloadableRequest, va
|
|
|
144
125
|
return;
|
|
145
126
|
}
|
|
146
127
|
setTimeout(function () {
|
|
147
|
-
// Clear the cache entry after the default timeout
|
|
148
|
-
// null-check for Flow
|
|
149
128
|
if (nextQueryEntry != null) {
|
|
150
129
|
cleanup(pendingQueries, nextQueryEntry);
|
|
151
130
|
}
|
|
@@ -169,10 +148,6 @@ function preloadQueryDeduped(environment, pendingQueries, preloadableRequest, va
|
|
|
169
148
|
return nextQueryEntry;
|
|
170
149
|
}
|
|
171
150
|
function cleanup(pendingQueries, entry) {
|
|
172
|
-
// Reload the entry by its cache key and only invalidate if its the identical
|
|
173
|
-
// entry instance. This ensures that if the same query/variables are fetched
|
|
174
|
-
// successively that a timeout/expiration from an earlier fetch doesn't clear
|
|
175
|
-
// a subsequent fetch.
|
|
176
151
|
var currentEntry = pendingQueries.get(entry.cacheKey);
|
|
177
152
|
if (currentEntry != null && currentEntry === entry) {
|
|
178
153
|
if (currentEntry.kind === 'network') {
|
|
@@ -1,21 +1,8 @@
|
|
|
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 preloadQuery = require('./preloadQuery_DEPRECATED');
|
|
15
4
|
function prepareEntryPoint(environmentProvider, entryPoint, entryPointParams) {
|
|
16
|
-
// Start loading the code for the entrypoint
|
|
17
5
|
if (entryPoint.root.getModuleIfRequired() == null) {
|
|
18
|
-
// $FlowFixMe[unused-promise]
|
|
19
6
|
entryPoint.root.load();
|
|
20
7
|
}
|
|
21
8
|
var preloadProps = entryPoint.getPreloadProps(entryPointParams);
|
|
@@ -1,18 +1,6 @@
|
|
|
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 invariant = require('invariant');
|
|
15
|
-
// $FlowFixMe[prop-missing] These exist in experimental builds but aren't in React's types yet.
|
|
16
4
|
var _require = require('react'),
|
|
17
5
|
unstable_getCacheForType = _require.unstable_getCacheForType,
|
|
18
6
|
unstable_getCacheSignal = _require.unstable_getCacheSignal;
|
|
@@ -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"];
|
|
@@ -102,15 +91,9 @@ function getQueryResultOrFetchQuery_REACT_CACHE(environment, queryOperationDescr
|
|
|
102
91
|
currentEntry = makeInitialCacheEntry();
|
|
103
92
|
cache.set(environment, cacheKey, currentEntry);
|
|
104
93
|
}
|
|
105
|
-
// $FlowExpectedError[prop-missing] Extra properties are passed in -- this is fine
|
|
106
94
|
var newStatus = updater(currentEntry);
|
|
107
|
-
// $FlowExpectedError[cannot-spread-inexact] Flow cannot understand that this is valid...
|
|
108
95
|
cache.set(environment, cacheKey, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, currentEntry), newStatus));
|
|
109
|
-
// ... but we can because QueryCacheEntry spreads QueryCacheEntryStatus, so spreading
|
|
110
|
-
// a QueryCacheEntryStatus into a QueryCacheEntry will result in a valid QueryCacheEntry.
|
|
111
96
|
}
|
|
112
|
-
|
|
113
|
-
// Initiate a query to fetch the data if needed:
|
|
114
97
|
if (RelayFeatureFlags.USE_REACT_CACHE_LEGACY_TIMEOUTS) {
|
|
115
98
|
var _entry;
|
|
116
99
|
if (initialEntry === undefined) {
|
|
@@ -144,13 +127,7 @@ function getQueryResultOrFetchQuery_REACT_CACHE(environment, queryOperationDescr
|
|
|
144
127
|
_entry.suspenseResource.temporaryRetain(environment);
|
|
145
128
|
} else {
|
|
146
129
|
if (initialEntry === undefined) {
|
|
147
|
-
// This is the behavior we eventually want: We retain the query until the
|
|
148
|
-
// presiding Cache component unmounts, at which point the AbortSignal
|
|
149
|
-
// will be triggered.
|
|
150
130
|
onCacheMiss(environment, queryOperationDescriptor, fetchPolicy, renderPolicy, updateCache, options === null || options === void 0 ? void 0 : options.fetchObservable);
|
|
151
|
-
|
|
152
|
-
// Since this is the first time rendering, retain the query. React will
|
|
153
|
-
// trigger the abort signal when this cache entry is no longer needed.
|
|
154
131
|
var retention = environment.retain(queryOperationDescriptor);
|
|
155
132
|
var dispose = function dispose() {
|
|
156
133
|
retention.dispose();
|
|
@@ -162,7 +139,7 @@ function getQueryResultOrFetchQuery_REACT_CACHE(environment, queryOperationDescr
|
|
|
162
139
|
});
|
|
163
140
|
}
|
|
164
141
|
}
|
|
165
|
-
var entry = cache.get(environment, cacheKey);
|
|
142
|
+
var entry = cache.get(environment, cacheKey);
|
|
166
143
|
!(entry !== undefined) ? process.env.NODE_ENV !== "production" ? invariant(false, 'An entry should have been created by onCacheMiss. This is a bug in Relay.') : invariant(false) : void 0;
|
|
167
144
|
switch (entry.status) {
|
|
168
145
|
case 'pending':
|
|
@@ -175,8 +152,6 @@ function getQueryResultOrFetchQuery_REACT_CACHE(environment, queryOperationDescr
|
|
|
175
152
|
!false ? process.env.NODE_ENV !== "production" ? invariant(false, 'switch statement should be exhaustive') : invariant(false) : void 0;
|
|
176
153
|
}
|
|
177
154
|
function onCacheMiss(environment, operation, fetchPolicy, renderPolicy, updateCache, customFetchObservable) {
|
|
178
|
-
// NB: Besides checking if the data is available, calling `check` will write missing
|
|
179
|
-
// data to the store using any missing data handlers specified in the environment.
|
|
180
155
|
var queryAvailability = environment.check(operation);
|
|
181
156
|
var queryStatus = queryAvailability.status;
|
|
182
157
|
var hasFullQuery = queryStatus === 'available';
|
|
@@ -240,11 +215,8 @@ function executeOperationAndKeepUpToDate(environment, operation, updateCache, cu
|
|
|
240
215
|
var promise = new Promise(function (r) {
|
|
241
216
|
resolvePromise = r;
|
|
242
217
|
});
|
|
243
|
-
// $FlowExpectedError[prop-missing] Expando to annotate Promises.
|
|
244
218
|
promise.displayName = 'Relay(' + operation.request.node.operation.name + ')';
|
|
245
219
|
var isFirstPayload = true;
|
|
246
|
-
|
|
247
|
-
// FIXME We may still need to cancel network requests for live queries.
|
|
248
220
|
var fetchObservable = customFetchObservable !== null && customFetchObservable !== void 0 ? customFetchObservable : fetchQueryInternal(environment, operation);
|
|
249
221
|
fetchObservable.subscribe({
|
|
250
222
|
start: function start(subscription) {},
|
|
@@ -257,15 +229,12 @@ function executeOperationAndKeepUpToDate(environment, operation, updateCache, cu
|
|
|
257
229
|
};
|
|
258
230
|
});
|
|
259
231
|
} else {
|
|
260
|
-
// TODO:T92030819 Remove this warning and actually throw the network error
|
|
261
|
-
// To complete this task we need to have a way of precisely tracking suspendable points
|
|
262
232
|
process.env.NODE_ENV !== "production" ? warning(false, 'getQueryResultOrFetchQuery: An incremental payload for query `%` returned an error: `%`:`%`.', operation.request.node.operation.name, _error.message, _error.stack) : void 0;
|
|
263
233
|
}
|
|
264
234
|
resolvePromise();
|
|
265
235
|
isFirstPayload = false;
|
|
266
236
|
},
|
|
267
237
|
next: function next(response) {
|
|
268
|
-
// Stop suspending on the first payload because of streaming, defer, etc.
|
|
269
238
|
updateCache(function (_existing) {
|
|
270
239
|
return {
|
|
271
240
|
status: 'resolved',
|
|
@@ -276,10 +245,6 @@ function executeOperationAndKeepUpToDate(environment, operation, updateCache, cu
|
|
|
276
245
|
isFirstPayload = false;
|
|
277
246
|
}
|
|
278
247
|
});
|
|
279
|
-
|
|
280
|
-
// If the above subscription yields a value synchronously, then one of the updates
|
|
281
|
-
// above will have already happened and we'll now be in a resolved or rejected state.
|
|
282
|
-
// But in the usual case, we save the promise to the entry here:
|
|
283
248
|
updateCache(function (existing) {
|
|
284
249
|
return existing.status === 'pending' ? {
|
|
285
250
|
status: 'pending',
|
|
@@ -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"];
|
|
@@ -19,6 +8,7 @@ var _require = require('../QueryResource'),
|
|
|
19
8
|
var invariant = require('invariant');
|
|
20
9
|
var _require2 = require('relay-runtime'),
|
|
21
10
|
fetchQueryInternal = _require2.__internal.fetchQuery,
|
|
11
|
+
RelayFeatureFlags = _require2.RelayFeatureFlags,
|
|
22
12
|
createOperationDescriptor = _require2.createOperationDescriptor,
|
|
23
13
|
getPendingOperationsForFragment = _require2.getPendingOperationsForFragment,
|
|
24
14
|
getSelector = _require2.getSelector,
|
|
@@ -95,14 +85,9 @@ function handlePotentialSnapshotErrorsForState(environment, state) {
|
|
|
95
85
|
function handleMissingClientEdge(environment, parentFragmentNode, parentFragmentRef, missingClientEdgeRequestInfo, queryOptions) {
|
|
96
86
|
var originalVariables = getVariablesFromFragment(parentFragmentNode, parentFragmentRef);
|
|
97
87
|
var variables = (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, originalVariables), {}, {
|
|
98
|
-
id: missingClientEdgeRequestInfo.clientEdgeDestinationID
|
|
88
|
+
id: missingClientEdgeRequestInfo.clientEdgeDestinationID
|
|
99
89
|
});
|
|
100
|
-
|
|
101
90
|
var queryOperationDescriptor = createOperationDescriptor(missingClientEdgeRequestInfo.request, variables, queryOptions === null || queryOptions === void 0 ? void 0 : queryOptions.networkCacheConfig);
|
|
102
|
-
// This may suspend. We don't need to do anything with the results; all we're
|
|
103
|
-
// doing here is started the query if needed and retaining and releasing it
|
|
104
|
-
// according to the component mount/suspense cycle; QueryResource
|
|
105
|
-
// already handles this by itself.
|
|
106
91
|
var QueryResource = getQueryResourceForEnvironment(environment);
|
|
107
92
|
return QueryResource.prepare(queryOperationDescriptor, fetchQueryInternal(environment, queryOperationDescriptor), queryOptions === null || queryOptions === void 0 ? void 0 : queryOptions.fetchPolicy);
|
|
108
93
|
}
|
|
@@ -133,8 +118,6 @@ function getFragmentState(environment, fragmentSelector) {
|
|
|
133
118
|
};
|
|
134
119
|
}
|
|
135
120
|
}
|
|
136
|
-
|
|
137
|
-
// fragmentNode cannot change during the lifetime of the component, though fragmentRef may change.
|
|
138
121
|
function readFragmentInternal_REACT_CACHE(environment, fragmentNode, fragmentRef, hookDisplayName, queryOptions, fragmentKey) {
|
|
139
122
|
var _fragmentNode$metadat, _fragmentNode$metadat2;
|
|
140
123
|
var fragmentSelector = getSelector(fragmentNode, fragmentRef);
|
|
@@ -146,9 +129,6 @@ function readFragmentInternal_REACT_CACHE(environment, fragmentNode, fragmentRef
|
|
|
146
129
|
}
|
|
147
130
|
!(fragmentRef == null || isPlural && Array.isArray(fragmentRef) && fragmentRef.length === 0 || fragmentSelector != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Relay: Expected to receive an object where `...%s` was spread, ' + 'but the fragment reference was not found`. This is most ' + 'likely the result of:\n' + "- Forgetting to spread `%s` in `%s`'s parent's fragment.\n" + '- Conditionally fetching `%s` but unconditionally passing %s prop ' + 'to `%s`. If the parent fragment only fetches the fragment conditionally ' + '- with e.g. `@include`, `@skip`, or inside a `... on SomeType { }` ' + 'spread - then the fragment reference will not exist. ' + 'In this case, pass `null` if the conditions for evaluating the ' + 'fragment are not met (e.g. if the `@include(if)` value is false.)', fragmentNode.name, fragmentNode.name, hookDisplayName, fragmentNode.name, fragmentKey == null ? 'a fragment reference' : "the `".concat(fragmentKey, "`"), hookDisplayName) : invariant(false) : void 0;
|
|
148
131
|
var state = getFragmentState(environment, fragmentSelector);
|
|
149
|
-
|
|
150
|
-
// Handle the queries for any missing client edges; this may suspend.
|
|
151
|
-
// FIXME handle client edges in parallel.
|
|
152
132
|
var clientEdgeQueries = null;
|
|
153
133
|
if (((_fragmentNode$metadat2 = fragmentNode.metadata) === null || _fragmentNode$metadat2 === void 0 ? void 0 : _fragmentNode$metadat2.hasClientEdges) === true) {
|
|
154
134
|
var missingClientEdges = getMissingClientEdges(state);
|
|
@@ -169,16 +149,12 @@ function readFragmentInternal_REACT_CACHE(environment, fragmentNode, fragmentRef
|
|
|
169
149
|
}
|
|
170
150
|
}
|
|
171
151
|
if (isMissingData(state)) {
|
|
172
|
-
// Suspend if an active operation bears on this fragment, either the
|
|
173
|
-
// fragment's owner or some other mutation etc. that could affect it:
|
|
174
152
|
!(fragmentSelector != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'refinement, see invariants above') : invariant(false) : void 0;
|
|
175
153
|
var fragmentOwner = fragmentSelector.kind === 'PluralReaderSelector' ? fragmentSelector.selectors[0].owner : fragmentSelector.owner;
|
|
176
154
|
var pendingOperationsResult = getPendingOperationsForFragment(environment, fragmentNode, fragmentOwner);
|
|
177
155
|
if (pendingOperationsResult) {
|
|
178
156
|
throw pendingOperationsResult.promise;
|
|
179
157
|
}
|
|
180
|
-
// Report required fields only if we're not suspending, since that means
|
|
181
|
-
// they're missing even though we are out of options for possibly fetching them:
|
|
182
158
|
handlePotentialSnapshotErrorsForState(environment, state);
|
|
183
159
|
}
|
|
184
160
|
var data;
|
|
@@ -191,7 +167,7 @@ function readFragmentInternal_REACT_CACHE(environment, fragmentNode, fragmentRef
|
|
|
191
167
|
return s.data;
|
|
192
168
|
});
|
|
193
169
|
}
|
|
194
|
-
if (process.env.NODE_ENV !== "production") {
|
|
170
|
+
if (RelayFeatureFlags.LOG_MISSING_RECORDS_IN_PROD || process.env.NODE_ENV !== "production") {
|
|
195
171
|
if (fragmentRef != null && (data === undefined || Array.isArray(data) && data.length > 0 && data.every(function (d) {
|
|
196
172
|
return d === undefined;
|
|
197
173
|
}))) {
|
|
@@ -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,6 +16,7 @@ var _require2 = require('react'),
|
|
|
27
16
|
useState = _require2.useState;
|
|
28
17
|
var _require3 = require('relay-runtime'),
|
|
29
18
|
fetchQueryInternal = _require3.__internal.fetchQuery,
|
|
19
|
+
RelayFeatureFlags = _require3.RelayFeatureFlags,
|
|
30
20
|
areEqualSelectors = _require3.areEqualSelectors,
|
|
31
21
|
createOperationDescriptor = _require3.createOperationDescriptor,
|
|
32
22
|
getPendingOperationsForFragment = _require3.getPendingOperationsForFragment,
|
|
@@ -140,22 +130,14 @@ function handlePotentialSnapshotErrorsForState(environment, state) {
|
|
|
140
130
|
}
|
|
141
131
|
}
|
|
142
132
|
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Check for updates to the store that occurred concurrently with rendering the given `state` value,
|
|
146
|
-
* returning a new (updated) state if there were updates or null if there were no changes.
|
|
147
|
-
*/
|
|
148
133
|
function handleMissedUpdates(environment, state) {
|
|
149
134
|
if (state.kind === 'bailout') {
|
|
150
135
|
return null;
|
|
151
136
|
}
|
|
152
|
-
// FIXME this is invalid if we've just switched environments.
|
|
153
137
|
var currentEpoch = environment.getStore().getEpoch();
|
|
154
138
|
if (currentEpoch === state.epoch) {
|
|
155
139
|
return null;
|
|
156
140
|
}
|
|
157
|
-
// The store has updated since we rendered (without us being subscribed yet),
|
|
158
|
-
// so check for any updates to the data we're rendering:
|
|
159
141
|
if (state.kind === 'singular') {
|
|
160
142
|
var currentSnapshot = environment.lookup(state.snapshot.selector);
|
|
161
143
|
var updatedData = recycleNodesInto(state.snapshot.data, currentSnapshot.data);
|
|
@@ -207,14 +189,9 @@ function handleMissedUpdates(environment, state) {
|
|
|
207
189
|
function handleMissingClientEdge(environment, parentFragmentNode, parentFragmentRef, missingClientEdgeRequestInfo, queryOptions) {
|
|
208
190
|
var originalVariables = getVariablesFromFragment(parentFragmentNode, parentFragmentRef);
|
|
209
191
|
var variables = (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, originalVariables), {}, {
|
|
210
|
-
id: missingClientEdgeRequestInfo.clientEdgeDestinationID
|
|
192
|
+
id: missingClientEdgeRequestInfo.clientEdgeDestinationID
|
|
211
193
|
});
|
|
212
|
-
|
|
213
194
|
var queryOperationDescriptor = createOperationDescriptor(missingClientEdgeRequestInfo.request, variables, queryOptions === null || queryOptions === void 0 ? void 0 : queryOptions.networkCacheConfig);
|
|
214
|
-
// This may suspend. We don't need to do anything with the results; all we're
|
|
215
|
-
// doing here is started the query if needed and retaining and releasing it
|
|
216
|
-
// according to the component mount/suspense cycle; QueryResource
|
|
217
|
-
// already handles this by itself.
|
|
218
195
|
var QueryResource = getQueryResourceForEnvironment(environment);
|
|
219
196
|
return QueryResource.prepare(queryOperationDescriptor, fetchQueryInternal(environment, queryOperationDescriptor), queryOptions === null || queryOptions === void 0 ? void 0 : queryOptions.fetchPolicy);
|
|
220
197
|
}
|
|
@@ -224,11 +201,19 @@ function subscribeToSnapshot(environment, state, setState) {
|
|
|
224
201
|
} else if (state.kind === 'singular') {
|
|
225
202
|
var disposable = environment.subscribe(state.snapshot, function (latestSnapshot) {
|
|
226
203
|
setState(function (prevState) {
|
|
227
|
-
// In theory a setState from a subscription could be batched together
|
|
228
|
-
// with a setState to change the fragment selector. Guard against this
|
|
229
|
-
// by bailing out of the state update if the selector has changed.
|
|
230
204
|
if (prevState.kind !== 'singular' || prevState.snapshot.selector !== latestSnapshot.selector) {
|
|
231
|
-
|
|
205
|
+
var updates = handleMissedUpdates(environment, prevState);
|
|
206
|
+
if (updates != null) {
|
|
207
|
+
var dataChanged = updates[0],
|
|
208
|
+
nextState = updates[1];
|
|
209
|
+
environment.__log({
|
|
210
|
+
name: 'useFragment.subscription.missedUpdates',
|
|
211
|
+
hasDataChanges: dataChanged
|
|
212
|
+
});
|
|
213
|
+
return dataChanged ? nextState : prevState;
|
|
214
|
+
} else {
|
|
215
|
+
return prevState;
|
|
216
|
+
}
|
|
232
217
|
}
|
|
233
218
|
return {
|
|
234
219
|
kind: 'singular',
|
|
@@ -245,11 +230,19 @@ function subscribeToSnapshot(environment, state, setState) {
|
|
|
245
230
|
return environment.subscribe(snapshot, function (latestSnapshot) {
|
|
246
231
|
setState(function (prevState) {
|
|
247
232
|
var _prevState$snapshots$;
|
|
248
|
-
// In theory a setState from a subscription could be batched together
|
|
249
|
-
// with a setState to change the fragment selector. Guard against this
|
|
250
|
-
// by bailing out of the state update if the selector has changed.
|
|
251
233
|
if (prevState.kind !== 'plural' || ((_prevState$snapshots$ = prevState.snapshots[index]) === null || _prevState$snapshots$ === void 0 ? void 0 : _prevState$snapshots$.selector) !== latestSnapshot.selector) {
|
|
252
|
-
|
|
234
|
+
var updates = handleMissedUpdates(environment, prevState);
|
|
235
|
+
if (updates != null) {
|
|
236
|
+
var dataChanged = updates[0],
|
|
237
|
+
nextState = updates[1];
|
|
238
|
+
environment.__log({
|
|
239
|
+
name: 'useFragment.subscription.missedUpdates',
|
|
240
|
+
hasDataChanges: dataChanged
|
|
241
|
+
});
|
|
242
|
+
return dataChanged ? nextState : prevState;
|
|
243
|
+
} else {
|
|
244
|
+
return prevState;
|
|
245
|
+
}
|
|
253
246
|
}
|
|
254
247
|
var updated = (0, _toConsumableArray2["default"])(prevState.snapshots);
|
|
255
248
|
updated[index] = latestSnapshot;
|
|
@@ -283,8 +276,6 @@ function getFragmentState(environment, fragmentSelector) {
|
|
|
283
276
|
kind: 'bailout'
|
|
284
277
|
};
|
|
285
278
|
} else if (fragmentSelector.kind === 'PluralReaderSelector') {
|
|
286
|
-
// Note that if fragmentRef is an empty array, fragmentSelector will be null so we'll hit the above case.
|
|
287
|
-
// Null is returned by getSelector if fragmentRef has no non-null items.
|
|
288
279
|
return {
|
|
289
280
|
kind: 'plural',
|
|
290
281
|
snapshots: fragmentSelector.selectors.map(function (s) {
|
|
@@ -300,20 +291,18 @@ function getFragmentState(environment, fragmentSelector) {
|
|
|
300
291
|
};
|
|
301
292
|
}
|
|
302
293
|
}
|
|
303
|
-
|
|
304
|
-
// fragmentNode cannot change during the lifetime of the component, though fragmentRef may change.
|
|
305
|
-
function useFragmentInternal_REACT_CACHE(fragmentNode, fragmentRef, hookDisplayName, queryOptions, fragmentKey) {
|
|
294
|
+
function useFragmentInternal_REACT_CACHE(fragmentNode, fragmentRef, hookDisplayName, queryOptions) {
|
|
306
295
|
var _fragmentNode$metadat, _fragmentNode$metadat2;
|
|
307
296
|
var fragmentSelector = useMemo(function () {
|
|
308
297
|
return getSelector(fragmentNode, fragmentRef);
|
|
309
298
|
}, [fragmentNode, fragmentRef]);
|
|
310
299
|
var isPlural = (fragmentNode === null || fragmentNode === void 0 ? void 0 : (_fragmentNode$metadat = fragmentNode.metadata) === null || _fragmentNode$metadat === void 0 ? void 0 : _fragmentNode$metadat.plural) === true;
|
|
311
300
|
if (isPlural) {
|
|
312
|
-
!(fragmentRef == null || Array.isArray(fragmentRef)) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Relay: Expected fragment pointer%s for fragment `%s` to be ' + 'an array, instead got `%s`. Remove `@relay(plural: true)` ' + 'from fragment `%s` to allow the prop to be an object.',
|
|
301
|
+
!(fragmentRef == null || Array.isArray(fragmentRef)) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Relay: Expected fragment pointer%s for fragment `%s` to be ' + 'an array, instead got `%s`. Remove `@relay(plural: true)` ' + 'from fragment `%s` to allow the prop to be an object.', fragmentNode.name, typeof fragmentRef, fragmentNode.name) : invariant(false) : void 0;
|
|
313
302
|
} else {
|
|
314
|
-
!!Array.isArray(fragmentRef) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Relay: Expected fragment pointer%s for fragment `%s` not to be ' + 'an array, instead got `%s`. Add `@relay(plural: true)` ' + 'to fragment `%s` to allow the prop to be an array.',
|
|
303
|
+
!!Array.isArray(fragmentRef) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Relay: Expected fragment pointer%s for fragment `%s` not to be ' + 'an array, instead got `%s`. Add `@relay(plural: true)` ' + 'to fragment `%s` to allow the prop to be an array.', fragmentNode.name, typeof fragmentRef, fragmentNode.name) : invariant(false) : void 0;
|
|
315
304
|
}
|
|
316
|
-
!(fragmentRef == null || isPlural && Array.isArray(fragmentRef) && fragmentRef.length === 0 || fragmentSelector != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Relay: Expected to receive an object where `...%s` was spread, ' + 'but the fragment reference was not found`. This is most ' + 'likely the result of:\n' + "- Forgetting to spread `%s` in `%s`'s parent's fragment.\n" + '- Conditionally fetching `%s` but unconditionally passing %s prop ' + 'to `%s`. If the parent fragment only fetches the fragment conditionally ' + '- with e.g. `@include`, `@skip`, or inside a `... on SomeType { }` ' + 'spread - then the fragment reference will not exist. ' + 'In this case, pass `null` if the conditions for evaluating the ' + 'fragment are not met (e.g. if the `@include(if)` value is false.)', fragmentNode.name, fragmentNode.name, hookDisplayName, fragmentNode.name,
|
|
305
|
+
!(fragmentRef == null || isPlural && Array.isArray(fragmentRef) && fragmentRef.length === 0 || fragmentSelector != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Relay: Expected to receive an object where `...%s` was spread, ' + 'but the fragment reference was not found`. This is most ' + 'likely the result of:\n' + "- Forgetting to spread `%s` in `%s`'s parent's fragment.\n" + '- Conditionally fetching `%s` but unconditionally passing %s prop ' + 'to `%s`. If the parent fragment only fetches the fragment conditionally ' + '- with e.g. `@include`, `@skip`, or inside a `... on SomeType { }` ' + 'spread - then the fragment reference will not exist. ' + 'In this case, pass `null` if the conditions for evaluating the ' + 'fragment are not met (e.g. if the `@include(if)` value is false.)', fragmentNode.name, fragmentNode.name, hookDisplayName, fragmentNode.name, hookDisplayName) : invariant(false) : void 0;
|
|
317
306
|
var environment = useRelayEnvironment();
|
|
318
307
|
var _useState = useState(function () {
|
|
319
308
|
return getFragmentState(environment, fragmentSelector);
|
|
@@ -321,14 +310,9 @@ function useFragmentInternal_REACT_CACHE(fragmentNode, fragmentRef, hookDisplayN
|
|
|
321
310
|
_state = _useState[0],
|
|
322
311
|
setState = _useState[1];
|
|
323
312
|
var state = _state;
|
|
324
|
-
|
|
325
|
-
// This copy of the state we only update when something requires us to
|
|
326
|
-
// unsubscribe and re-subscribe, namely a changed environment or
|
|
327
|
-
// fragment selector.
|
|
328
313
|
var _useState2 = useState(state),
|
|
329
314
|
_subscribedState = _useState2[0],
|
|
330
315
|
setSubscribedState = _useState2[1];
|
|
331
|
-
// FIXME since this is used as an effect dependency, it needs to be memoized.
|
|
332
316
|
var subscribedState = _subscribedState;
|
|
333
317
|
var _useState3 = useState(fragmentSelector),
|
|
334
318
|
previousFragmentSelector = _useState3[0],
|
|
@@ -337,40 +321,21 @@ function useFragmentInternal_REACT_CACHE(fragmentNode, fragmentRef, hookDisplayN
|
|
|
337
321
|
previousEnvironment = _useState4[0],
|
|
338
322
|
setPreviousEnvironment = _useState4[1];
|
|
339
323
|
if (!areEqualSelectors(fragmentSelector, previousFragmentSelector) || environment !== previousEnvironment) {
|
|
340
|
-
// Enqueue setState to record the new selector and state
|
|
341
324
|
setPreviousFragmentSelector(fragmentSelector);
|
|
342
325
|
setPreviousEnvironment(environment);
|
|
343
326
|
var newState = getFragmentState(environment, fragmentSelector);
|
|
344
327
|
setState(newState);
|
|
345
|
-
setSubscribedState(newState);
|
|
346
|
-
// But render with the latest state w/o waiting for the setState. Otherwise
|
|
347
|
-
// the component would render the wrong information temporarily (including
|
|
348
|
-
// possibly incorrectly triggering some warnings below).
|
|
328
|
+
setSubscribedState(newState);
|
|
349
329
|
state = newState;
|
|
350
330
|
subscribedState = newState;
|
|
351
331
|
}
|
|
352
|
-
|
|
353
|
-
// The purpose of this is to detect whether we have ever committed, because we
|
|
354
|
-
// don't suspend on store updates, only when the component either is first trying
|
|
355
|
-
// to mount or when the our selector changes. The selector change in particular is
|
|
356
|
-
// how we suspend for pagination and refetech. Also, fragment selector can be null
|
|
357
|
-
// or undefined, so we use false as a special value to distinguish from all fragment
|
|
358
|
-
// selectors; false means that the component hasn't mounted yet.
|
|
359
332
|
var committedFragmentSelectorRef = useRef(false);
|
|
360
333
|
useEffect(function () {
|
|
361
334
|
committedFragmentSelectorRef.current = fragmentSelector;
|
|
362
335
|
}, [fragmentSelector]);
|
|
363
|
-
|
|
364
|
-
// Handle the queries for any missing client edges; this may suspend.
|
|
365
|
-
// FIXME handle client edges in parallel.
|
|
366
336
|
if (((_fragmentNode$metadat2 = fragmentNode.metadata) === null || _fragmentNode$metadat2 === void 0 ? void 0 : _fragmentNode$metadat2.hasClientEdges) === true) {
|
|
367
|
-
// The fragment is validated to be static (in useFragment) and hasClientEdges is
|
|
368
|
-
// a static (constant) property of the fragment. In practice, this effect will
|
|
369
|
-
// always or never run for a given invocation of this hook.
|
|
370
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
371
337
|
var clientEdgeQueries = useMemo(function () {
|
|
372
338
|
var missingClientEdges = getMissingClientEdges(state);
|
|
373
|
-
// eslint-disable-next-line no-shadow
|
|
374
339
|
var clientEdgeQueries;
|
|
375
340
|
if (missingClientEdges !== null && missingClientEdges !== void 0 && missingClientEdges.length) {
|
|
376
341
|
clientEdgeQueries = [];
|
|
@@ -389,9 +354,6 @@ function useFragmentInternal_REACT_CACHE(fragmentNode, fragmentRef, hookDisplayN
|
|
|
389
354
|
}
|
|
390
355
|
return clientEdgeQueries;
|
|
391
356
|
}, [state, environment, fragmentNode, fragmentRef, queryOptions]);
|
|
392
|
-
|
|
393
|
-
// See above note
|
|
394
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
395
357
|
useEffect(function () {
|
|
396
358
|
var QueryResource = getQueryResourceForEnvironment(environment);
|
|
397
359
|
if (clientEdgeQueries !== null && clientEdgeQueries !== void 0 && clientEdgeQueries.length) {
|
|
@@ -426,19 +388,13 @@ function useFragmentInternal_REACT_CACHE(fragmentNode, fragmentRef, hookDisplayN
|
|
|
426
388
|
}, [environment, clientEdgeQueries]);
|
|
427
389
|
}
|
|
428
390
|
if (isMissingData(state)) {
|
|
429
|
-
// Suspend if a Live Resolver within this fragment is in a suspended state:
|
|
430
391
|
var suspendingLiveResolvers = getSuspendingLiveResolver(state);
|
|
431
392
|
if (suspendingLiveResolvers != null && suspendingLiveResolvers.length > 0) {
|
|
432
393
|
throw Promise.all(suspendingLiveResolvers.map(function (_ref) {
|
|
433
394
|
var liveStateID = _ref.liveStateID;
|
|
434
|
-
// $FlowFixMe[prop-missing] This is expected to be a LiveResolverStore
|
|
435
395
|
return environment.getStore().getLiveResolverPromise(liveStateID);
|
|
436
396
|
}));
|
|
437
397
|
}
|
|
438
|
-
// Suspend if an active operation bears on this fragment, either the
|
|
439
|
-
// fragment's owner or some other mutation etc. that could affect it.
|
|
440
|
-
// We only suspend when the component is first trying to mount or changing
|
|
441
|
-
// selectors, not if data becomes missing later:
|
|
442
398
|
if (!committedFragmentSelectorRef.current || !areEqualSelectors(committedFragmentSelectorRef.current, fragmentSelector)) {
|
|
443
399
|
!(fragmentSelector != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'refinement, see invariants above') : invariant(false) : void 0;
|
|
444
400
|
var fragmentOwner = fragmentSelector.kind === 'PluralReaderSelector' ? fragmentSelector.selectors[0].owner : fragmentSelector.owner;
|
|
@@ -447,24 +403,14 @@ function useFragmentInternal_REACT_CACHE(fragmentNode, fragmentRef, hookDisplayN
|
|
|
447
403
|
throw pendingOperationsResult.promise;
|
|
448
404
|
}
|
|
449
405
|
}
|
|
450
|
-
// Report required fields only if we're not suspending, since that means
|
|
451
|
-
// they're missing even though we are out of options for possibly fetching them:
|
|
452
|
-
handlePotentialSnapshotErrorsForState(environment, state);
|
|
453
406
|
}
|
|
407
|
+
handlePotentialSnapshotErrorsForState(environment, state);
|
|
454
408
|
useEffect(function () {
|
|
455
|
-
// Check for updates since the state was rendered
|
|
456
409
|
var currentState = subscribedState;
|
|
457
410
|
var updates = handleMissedUpdates(environment, subscribedState);
|
|
458
411
|
if (updates !== null) {
|
|
459
412
|
var didMissUpdates = updates[0],
|
|
460
413
|
updatedState = updates[1];
|
|
461
|
-
// TODO: didMissUpdates only checks for changes to snapshot data, but it's possible
|
|
462
|
-
// that other snapshot properties may have changed that should also trigger a re-render,
|
|
463
|
-
// such as changed missing resolver fields, missing client edges, etc.
|
|
464
|
-
// A potential alternative is for handleMissedUpdates() to recycle the entire state
|
|
465
|
-
// value, and return the new (recycled) state only if there was some change. In that
|
|
466
|
-
// case the code would always setState if something in the snapshot changed, in addition
|
|
467
|
-
// to using the latest snapshot to subscribe.
|
|
468
414
|
if (didMissUpdates) {
|
|
469
415
|
setState(updatedState);
|
|
470
416
|
}
|
|
@@ -474,17 +420,9 @@ function useFragmentInternal_REACT_CACHE(fragmentNode, fragmentRef, hookDisplayN
|
|
|
474
420
|
}, [environment, subscribedState]);
|
|
475
421
|
var data;
|
|
476
422
|
if (isPlural) {
|
|
477
|
-
|
|
478
|
-
// which has to be memoized to avoid triggering downstream re-renders.
|
|
479
|
-
//
|
|
480
|
-
// Note that isPlural is a constant property of the fragment and does not change
|
|
481
|
-
// for a particular useFragment invocation site
|
|
482
|
-
var fragmentRefIsNullish = fragmentRef == null; // for less sensitive memoization
|
|
483
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
423
|
+
var fragmentRefIsNullish = fragmentRef == null;
|
|
484
424
|
data = useMemo(function () {
|
|
485
425
|
if (state.kind === 'bailout') {
|
|
486
|
-
// Bailout state can happen if the fragmentRef is a plural array that is empty or has no
|
|
487
|
-
// non-null entries. In that case, the compatible behavior is to return [] instead of null.
|
|
488
426
|
return fragmentRefIsNullish ? null : [];
|
|
489
427
|
} else {
|
|
490
428
|
!(state.kind === 'plural') ? process.env.NODE_ENV !== "production" ? invariant(false, 'Expected state to be plural because fragment is plural') : invariant(false) : void 0;
|
|
@@ -494,14 +432,12 @@ function useFragmentInternal_REACT_CACHE(fragmentNode, fragmentRef, hookDisplayN
|
|
|
494
432
|
}
|
|
495
433
|
}, [state, fragmentRefIsNullish]);
|
|
496
434
|
} else if (state.kind === 'bailout') {
|
|
497
|
-
// This case doesn't allocate a new object so it doesn't have to be memoized
|
|
498
435
|
data = null;
|
|
499
436
|
} else {
|
|
500
|
-
// This case doesn't allocate a new object so it doesn't have to be memoized
|
|
501
437
|
!(state.kind === 'singular') ? process.env.NODE_ENV !== "production" ? invariant(false, 'Expected state to be singular because fragment is singular') : invariant(false) : void 0;
|
|
502
438
|
data = state.snapshot.data;
|
|
503
439
|
}
|
|
504
|
-
if (process.env.NODE_ENV !== "production") {
|
|
440
|
+
if (RelayFeatureFlags.LOG_MISSING_RECORDS_IN_PROD || process.env.NODE_ENV !== "production") {
|
|
505
441
|
if (fragmentRef != null && (data === undefined || Array.isArray(data) && data.length > 0 && data.every(function (d) {
|
|
506
442
|
return d === undefined;
|
|
507
443
|
}))) {
|
|
@@ -509,7 +445,6 @@ function useFragmentInternal_REACT_CACHE(fragmentNode, fragmentRef, hookDisplayN
|
|
|
509
445
|
}
|
|
510
446
|
}
|
|
511
447
|
if (process.env.NODE_ENV !== "production") {
|
|
512
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
513
448
|
useDebugValue({
|
|
514
449
|
fragment: fragmentNode.name,
|
|
515
450
|
data: data
|
|
@@ -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'),
|
|
@@ -20,17 +9,13 @@ var _require2 = require('react'),
|
|
|
20
9
|
var _require3 = require('relay-runtime'),
|
|
21
10
|
getFragment = _require3.getFragment;
|
|
22
11
|
function useFragment(fragment, key) {
|
|
23
|
-
// We need to use this hook in order to be able to track if
|
|
24
|
-
// loadQuery was called during render
|
|
25
12
|
useTrackLoadQueryInRender();
|
|
26
13
|
var fragmentNode = getFragment(fragment);
|
|
27
14
|
if (process.env.NODE_ENV !== "production") {
|
|
28
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
29
15
|
useStaticFragmentNodeWarning(fragmentNode, 'first argument of useFragment()');
|
|
30
16
|
}
|
|
31
17
|
var data = useFragmentInternal(fragmentNode, key, 'useFragment()');
|
|
32
18
|
if (process.env.NODE_ENV !== "production") {
|
|
33
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
34
19
|
useDebugValue({
|
|
35
20
|
fragment: fragmentNode.name,
|
|
36
21
|
data: data
|