react-relay 15.0.0 → 16.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|