react-relay 15.0.0 → 16.1.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 +1 -12
- package/lib/relay-hooks/InternalLogger.js +0 -11
- package/lib/relay-hooks/LRUCache.js +0 -22
- package/lib/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js +0 -18
- package/lib/relay-hooks/MatchContainer.js +0 -94
- package/lib/relay-hooks/NestedRelayEntryPointBuilderUtils.js +9 -0
- package/lib/relay-hooks/ProfilerContext.js +0 -15
- package/lib/relay-hooks/QueryResource.js +2 -68
- package/lib/relay-hooks/RelayEnvironmentProvider.js +0 -11
- package/lib/relay-hooks/SuspenseResource.js +0 -34
- package/lib/relay-hooks/{react-cache/readFragmentInternal_REACT_CACHE.js → experimental/readFragmentInternal_EXPERIMENTAL.js} +5 -29
- package/lib/relay-hooks/{react-cache/useFragmentInternal_REACT_CACHE.js → experimental/useFragmentInternal_EXPERIMENTAL.js} +35 -100
- package/lib/relay-hooks/{react-cache/useFragment_REACT_CACHE.js → experimental/useFragment_EXPERIMENTAL.js} +1 -16
- package/lib/relay-hooks/{react-cache/usePaginationFragment_REACT_CACHE.js → experimental/usePaginationFragment_EXPERIMENTAL.js} +2 -24
- package/lib/relay-hooks/{react-cache/useRefetchableFragmentInternal_REACT_CACHE.js → experimental/useRefetchableFragmentInternal_EXPERIMENTAL.js} +14 -98
- package/lib/relay-hooks/{react-cache/useRefetchableFragment_REACT_CACHE.js → experimental/useRefetchableFragment_EXPERIMENTAL.js} +1 -15
- package/lib/relay-hooks/loadEntryPoint.js +1 -24
- package/lib/relay-hooks/loadQuery.js +2 -106
- package/lib/relay-hooks/preloadQuery_DEPRECATED.js +2 -27
- package/lib/relay-hooks/prepareEntryPoint_DEPRECATED.js +0 -13
- package/lib/relay-hooks/useBlockingPaginationFragment.js +0 -42
- package/lib/relay-hooks/useClientQuery.js +0 -18
- package/lib/relay-hooks/useEntryPointLoader.js +0 -69
- package/lib/relay-hooks/useFetchTrackingRef.js +0 -26
- package/lib/relay-hooks/useFragment.js +0 -17
- package/lib/relay-hooks/useFragmentNode.js +2 -32
- package/lib/relay-hooks/useIsMountedRef.js +0 -11
- package/lib/relay-hooks/useIsOperationNodeActive.js +0 -11
- package/lib/relay-hooks/useIsParentQueryActive.js +0 -11
- package/lib/relay-hooks/useLazyLoadQuery.js +0 -18
- package/lib/relay-hooks/useLazyLoadQueryNode.js +12 -37
- package/lib/relay-hooks/useLoadMoreFunction.js +9 -34
- package/lib/relay-hooks/useMemoOperationDescriptor.js +0 -11
- package/lib/relay-hooks/useMemoVariables.js +0 -17
- package/lib/relay-hooks/useMutation.js +0 -11
- package/lib/relay-hooks/usePaginationFragment.js +1 -26
- package/lib/relay-hooks/usePreloadedQuery.js +0 -27
- package/lib/relay-hooks/useQueryLoader.js +0 -74
- package/lib/relay-hooks/useRefetchableFragment.js +0 -16
- package/lib/relay-hooks/useRefetchableFragmentNode.js +14 -97
- package/lib/relay-hooks/useRelayEnvironment.js +0 -11
- package/lib/relay-hooks/useStaticFragmentNodeWarning.js +0 -15
- package/lib/relay-hooks/useSubscribeToInvalidationState.js +0 -25
- package/lib/relay-hooks/useSubscription.js +0 -15
- package/lib/relay-hooks/useUnsafeRef_DEPRECATED.js +0 -17
- package/package.json +2 -2
- package/react-relay-hooks.js +2 -2
- package/react-relay-hooks.min.js +2 -2
- package/react-relay-legacy.js +2 -2
- package/react-relay-legacy.min.js +2 -2
- package/react-relay.js +2 -2
- package/react-relay.min.js +2 -2
- package/relay-hooks/EntryPointContainer.react.js.flow +5 -0
- package/relay-hooks/EntryPointTypes.flow.js.flow +34 -35
- package/relay-hooks/FragmentResource.js.flow +114 -26
- package/relay-hooks/HooksImplementation.js.flow +3 -1
- package/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js.flow +4 -2
- package/relay-hooks/NestedRelayEntryPointBuilderUtils.js.flow +51 -0
- package/relay-hooks/__flowtests__/EntryPointTypes/NestedEntrypoints-flowtest.js.flow +7 -5
- package/relay-hooks/__flowtests__/useBlockingPaginationFragment-flowtest.js.flow +5 -0
- package/relay-hooks/__flowtests__/usePaginationFragment-flowtest.js.flow +5 -0
- package/relay-hooks/__flowtests__/useRefetchableFragment-flowtest.js.flow +2 -0
- package/relay-hooks/{react-cache/readFragmentInternal_REACT_CACHE.js.flow → experimental/readFragmentInternal_EXPERIMENTAL.js.flow} +4 -3
- package/relay-hooks/{react-cache/useFragmentInternal_REACT_CACHE.js.flow → experimental/useFragmentInternal_EXPERIMENTAL.js.flow} +32 -14
- package/relay-hooks/{react-cache/useFragment_REACT_CACHE.js.flow → experimental/useFragment_EXPERIMENTAL.js.flow} +4 -10
- package/relay-hooks/{react-cache/usePaginationFragment_REACT_CACHE.js.flow → experimental/usePaginationFragment_EXPERIMENTAL.js.flow} +30 -59
- package/relay-hooks/{react-cache/useRefetchableFragmentInternal_REACT_CACHE.js.flow → experimental/useRefetchableFragmentInternal_EXPERIMENTAL.js.flow} +30 -23
- package/relay-hooks/experimental/useRefetchableFragment_EXPERIMENTAL.js.flow +49 -0
- package/relay-hooks/loadEntryPoint.js.flow +4 -2
- package/relay-hooks/loadQuery.js.flow +21 -1
- package/relay-hooks/prepareEntryPoint_DEPRECATED.js.flow +4 -2
- package/relay-hooks/useBlockingPaginationFragment.js.flow +10 -17
- package/relay-hooks/useClientQuery.js.flow +2 -2
- package/relay-hooks/useFragmentNode.js.flow +2 -2
- package/relay-hooks/useLazyLoadQueryNode.js.flow +17 -1
- package/relay-hooks/useLoadMoreFunction.js.flow +15 -9
- package/relay-hooks/useMutation.js.flow +26 -9
- package/relay-hooks/usePaginationFragment.js.flow +7 -15
- package/relay-hooks/useQueryLoader.js.flow +2 -8
- package/relay-hooks/useRefetchableFragment.js.flow +14 -16
- package/relay-hooks/useRefetchableFragmentNode.js.flow +33 -20
- package/lib/relay-hooks/react-cache/RelayReactCache.js +0 -32
- package/lib/relay-hooks/react-cache/getQueryResultOrFetchQuery_REACT_CACHE.js +0 -290
- package/lib/relay-hooks/react-cache/useLazyLoadQuery_REACT_CACHE.js +0 -49
- package/lib/relay-hooks/react-cache/usePreloadedQuery_REACT_CACHE.js +0 -110
- package/relay-hooks/react-cache/RelayReactCache.js.flow +0 -40
- package/relay-hooks/react-cache/getQueryResultOrFetchQuery_REACT_CACHE.js.flow +0 -430
- package/relay-hooks/react-cache/useLazyLoadQuery_REACT_CACHE.js.flow +0 -70
- package/relay-hooks/react-cache/usePreloadedQuery_REACT_CACHE.js.flow +0 -150
- package/relay-hooks/react-cache/useRefetchableFragment_REACT_CACHE.js.flow +0 -65
@@ -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_EXPERIMENTAL(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
|
@@ -517,4 +452,4 @@ function useFragmentInternal_REACT_CACHE(fragmentNode, fragmentRef, hookDisplayN
|
|
517
452
|
}
|
518
453
|
return data;
|
519
454
|
}
|
520
|
-
module.exports =
|
455
|
+
module.exports = useFragmentInternal_EXPERIMENTAL;
|
@@ -1,36 +1,21 @@
|
|
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'),
|
15
4
|
useTrackLoadQueryInRender = _require.useTrackLoadQueryInRender;
|
16
5
|
var useStaticFragmentNodeWarning = require('../useStaticFragmentNodeWarning');
|
17
|
-
var useFragmentInternal = require('./
|
6
|
+
var useFragmentInternal = require('./useFragmentInternal_EXPERIMENTAL');
|
18
7
|
var _require2 = require('react'),
|
19
8
|
useDebugValue = _require2.useDebugValue;
|
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
|
@@ -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"];
|
@@ -16,7 +5,7 @@ var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/obje
|
|
16
5
|
var useLoadMoreFunction = require('../useLoadMoreFunction');
|
17
6
|
var useRelayEnvironment = require('../useRelayEnvironment');
|
18
7
|
var useStaticFragmentNodeWarning = require('../useStaticFragmentNodeWarning');
|
19
|
-
var useRefetchableFragmentInternal = require('./
|
8
|
+
var useRefetchableFragmentInternal = require('./useRefetchableFragmentInternal_EXPERIMENTAL');
|
20
9
|
var _require = require('react'),
|
21
10
|
useCallback = _require.useCallback,
|
22
11
|
useDebugValue = _require.useDebugValue,
|
@@ -32,15 +21,12 @@ function usePaginationFragment(fragmentInput, parentFragmentRef) {
|
|
32
21
|
var _getPaginationMetadat = getPaginationMetadata(fragmentNode, componentDisplayName),
|
33
22
|
connectionPathInFragmentData = _getPaginationMetadat.connectionPathInFragmentData,
|
34
23
|
paginationRequest = _getPaginationMetadat.paginationRequest,
|
35
|
-
paginationMetadata = _getPaginationMetadat.paginationMetadata
|
36
|
-
identifierField = _getPaginationMetadat.identifierField;
|
24
|
+
paginationMetadata = _getPaginationMetadat.paginationMetadata;
|
37
25
|
var _useRefetchableFragme = useRefetchableFragmentInternal(fragmentNode, parentFragmentRef, componentDisplayName),
|
38
26
|
fragmentData = _useRefetchableFragme.fragmentData,
|
39
27
|
fragmentRef = _useRefetchableFragme.fragmentRef,
|
40
28
|
refetch = _useRefetchableFragme.refetch;
|
41
29
|
var fragmentIdentifier = getFragmentIdentifier(fragmentNode, fragmentRef);
|
42
|
-
|
43
|
-
// Backward pagination
|
44
30
|
var _useLoadMore = useLoadMore({
|
45
31
|
componentDisplayName: componentDisplayName,
|
46
32
|
connectionPathInFragmentData: connectionPathInFragmentData,
|
@@ -49,7 +35,6 @@ function usePaginationFragment(fragmentInput, parentFragmentRef) {
|
|
49
35
|
fragmentIdentifier: fragmentIdentifier,
|
50
36
|
fragmentNode: fragmentNode,
|
51
37
|
fragmentRef: fragmentRef,
|
52
|
-
identifierField: identifierField,
|
53
38
|
paginationMetadata: paginationMetadata,
|
54
39
|
paginationRequest: paginationRequest
|
55
40
|
}),
|
@@ -57,8 +42,6 @@ function usePaginationFragment(fragmentInput, parentFragmentRef) {
|
|
57
42
|
hasPrevious = _useLoadMore[1],
|
58
43
|
isLoadingPrevious = _useLoadMore[2],
|
59
44
|
disposeFetchPrevious = _useLoadMore[3];
|
60
|
-
|
61
|
-
// Forward pagination
|
62
45
|
var _useLoadMore2 = useLoadMore({
|
63
46
|
componentDisplayName: componentDisplayName,
|
64
47
|
connectionPathInFragmentData: connectionPathInFragmentData,
|
@@ -67,7 +50,6 @@ function usePaginationFragment(fragmentInput, parentFragmentRef) {
|
|
67
50
|
fragmentIdentifier: fragmentIdentifier,
|
68
51
|
fragmentNode: fragmentNode,
|
69
52
|
fragmentRef: fragmentRef,
|
70
|
-
identifierField: identifierField,
|
71
53
|
paginationMetadata: paginationMetadata,
|
72
54
|
paginationRequest: paginationRequest
|
73
55
|
}),
|
@@ -83,7 +65,6 @@ function usePaginationFragment(fragmentInput, parentFragmentRef) {
|
|
83
65
|
}));
|
84
66
|
}, [disposeFetchNext, disposeFetchPrevious, refetch]);
|
85
67
|
if (process.env.NODE_ENV !== "production") {
|
86
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
87
68
|
useDebugValue({
|
88
69
|
fragment: fragmentNode.name,
|
89
70
|
data: fragmentData,
|
@@ -109,9 +90,6 @@ function useLoadMore(args) {
|
|
109
90
|
var _useState = useState(false),
|
110
91
|
isLoadingMore = _useState[0],
|
111
92
|
reallySetIsLoadingMore = _useState[1];
|
112
|
-
// Schedule this update since it must be observed by components at the same
|
113
|
-
// batch as when hasNext changes. hasNext is read from the store and store
|
114
|
-
// updates are scheduled, so this must be scheduled too.
|
115
93
|
var setIsLoadingMore = function setIsLoadingMore(value) {
|
116
94
|
var _environment$getSched;
|
117
95
|
var schedule = (_environment$getSched = environment.getScheduler()) === null || _environment$getSched === void 0 ? void 0 : _environment$getSched.schedule;
|
@@ -1,14 +1,3 @@
|
|
1
|
-
/**
|
2
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
3
|
-
*
|
4
|
-
* This source code is licensed under the MIT license found in the
|
5
|
-
* LICENSE file in the root directory of this source tree.
|
6
|
-
*
|
7
|
-
*
|
8
|
-
* @format
|
9
|
-
* @oncall relay
|
10
|
-
*/
|
11
|
-
|
12
1
|
'use strict';
|
13
2
|
|
14
3
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
|
@@ -19,8 +8,8 @@ var _require = require('../QueryResource'),
|
|
19
8
|
var useIsMountedRef = require('../useIsMountedRef');
|
20
9
|
var useQueryLoader = require('../useQueryLoader');
|
21
10
|
var useRelayEnvironment = require('../useRelayEnvironment');
|
22
|
-
var readFragmentInternal = require('./
|
23
|
-
var useFragmentInternal = require('./
|
11
|
+
var readFragmentInternal = require('./readFragmentInternal_EXPERIMENTAL');
|
12
|
+
var useFragmentInternal = require('./useFragmentInternal_EXPERIMENTAL');
|
24
13
|
var invariant = require('invariant');
|
25
14
|
var _require2 = require('react'),
|
26
15
|
useCallback = _require2.useCallback,
|
@@ -71,7 +60,7 @@ function useRefetchableFragmentNode(fragmentNode, parentFragmentRef, componentDi
|
|
71
60
|
var _getRefetchMetadata = getRefetchMetadata(fragmentNode, componentDisplayName),
|
72
61
|
refetchableRequest = _getRefetchMetadata.refetchableRequest,
|
73
62
|
fragmentRefPathInResponse = _getRefetchMetadata.fragmentRefPathInResponse,
|
74
|
-
|
63
|
+
identifierInfo = _getRefetchMetadata.identifierInfo;
|
75
64
|
var fragmentIdentifier = getFragmentIdentifier(fragmentNode, parentFragmentRef);
|
76
65
|
var _useReducer = useReducer(reducer, {
|
77
66
|
fetchPolicy: undefined,
|
@@ -108,47 +97,18 @@ function useRefetchableFragmentNode(fragmentNode, parentFragmentRef, componentDi
|
|
108
97
|
});
|
109
98
|
disposeQuery();
|
110
99
|
} else if (refetchQuery != null && queryRef != null) {
|
111
|
-
// If refetch was called, we expect to have a refetchQuery and queryRef
|
112
|
-
// in state, since both state updates to set the refetchQuery and the
|
113
|
-
// queryRef occur simultaneously.
|
114
|
-
// In this case, we need to read the refetched query data (potentially
|
115
|
-
// suspending if it's in flight), and extract the new fragment ref
|
116
|
-
// from the query in order read the current @refetchable fragment
|
117
|
-
// with the updated fragment owner as the new refetchQuery.
|
118
|
-
|
119
|
-
// Before observing the refetch, record the current ID and typename
|
120
|
-
// so that, if we are refetching existing data on
|
121
|
-
// a field that implements Node, after refetching we
|
122
|
-
// can validate that the received data is consistent
|
123
100
|
var debugPreviousIDAndTypename;
|
124
101
|
if (process.env.NODE_ENV !== "production") {
|
125
|
-
debugPreviousIDAndTypename = debugFunctions.getInitialIDAndType(refetchQuery.request.variables, fragmentRefPathInResponse, environment);
|
102
|
+
debugPreviousIDAndTypename = debugFunctions.getInitialIDAndType(refetchQuery.request.variables, fragmentRefPathInResponse, identifierInfo === null || identifierInfo === void 0 ? void 0 : identifierInfo.identifierQueryVariableName, environment);
|
126
103
|
}
|
127
104
|
var handleQueryCompleted = function handleQueryCompleted(maybeError) {
|
128
105
|
onComplete && onComplete(maybeError !== null && maybeError !== void 0 ? maybeError : null);
|
129
106
|
};
|
130
|
-
|
131
|
-
// The queryRef.source obtained from useQueryLoader will be
|
132
|
-
// an observable we can consume /if/ a network request was
|
133
|
-
// started. Otherwise, given that QueryResource.prepare
|
134
|
-
// always expects an observable we fall back to a new network
|
135
|
-
// observable. Note however that if loadQuery did not make a network
|
136
|
-
// request, we don't expect to make one here, unless the state of
|
137
|
-
// the cache has changed between the call to refetch and this
|
138
|
-
// render.
|
139
107
|
var fetchObservable = queryRef.source != null ? queryRef.source : fetchQuery(environment, refetchQuery);
|
140
|
-
|
141
|
-
// Now wwe can we read the refetch query here using the
|
142
|
-
// queryRef provided from useQueryLoader. Note that the
|
143
|
-
// network request is started during the call to refetch,
|
144
|
-
// but if the refetch query is still in flight, we will suspend
|
145
|
-
// at this point:
|
146
108
|
var queryResult = profilerContext.wrapPrepareQueryResource(function () {
|
147
109
|
return QueryResource.prepare(refetchQuery, fetchObservable, fetchPolicy, renderPolicy, {
|
148
110
|
error: handleQueryCompleted,
|
149
111
|
complete: function complete() {
|
150
|
-
// Validate that the type of the object we got back matches the type
|
151
|
-
// of the object already in the store
|
152
112
|
if (process.env.NODE_ENV !== "production") {
|
153
113
|
debugFunctions.checkSameTypeAfterRefetch(debugPreviousIDAndTypename, environment, fragmentNode, componentDisplayName);
|
154
114
|
}
|
@@ -158,40 +118,24 @@ function useRefetchableFragmentNode(fragmentNode, parentFragmentRef, componentDi
|
|
158
118
|
});
|
159
119
|
var queryData = readFragmentInternal(environment, queryResult.fragmentNode, queryResult.fragmentRef, componentDisplayName).data;
|
160
120
|
!(queryData != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Relay: Expected to be able to read refetch query response. ' + "If you're seeing this, this is likely a bug in Relay.") : invariant(false) : void 0;
|
161
|
-
|
162
|
-
// After reading/fetching the refetch query, we extract from the
|
163
|
-
// refetch query response the new fragment ref we need to use to read
|
164
|
-
// the fragment. The new fragment ref will point to the refetch query
|
165
|
-
// as its fragment owner.
|
166
121
|
var refetchedFragmentRef = getValueAtPath(queryData, fragmentRefPathInResponse);
|
167
122
|
fragmentRef = refetchedFragmentRef;
|
168
123
|
if (process.env.NODE_ENV !== "production") {
|
169
|
-
// Validate that the id of the object we got back matches the id
|
170
|
-
// we queried for in the variables.
|
171
|
-
// We do this during render instead of onComplete to make sure we are
|
172
|
-
// only validating the most recent refetch.
|
173
124
|
debugFunctions.checkSameIDAfterRefetch(debugPreviousIDAndTypename, fragmentRef, fragmentNode, componentDisplayName);
|
174
125
|
}
|
175
126
|
}
|
176
|
-
|
177
|
-
// We read and subscribe to the fragment using useFragmentNode.
|
178
|
-
// If refetch was called, we read the fragment using the new computed
|
179
|
-
// fragment ref from the refetch query response; otherwise, we use the
|
180
|
-
// fragment ref passed by the caller as normal.
|
181
127
|
var fragmentData = useFragmentInternal(fragmentNode, fragmentRef, componentDisplayName);
|
182
|
-
var refetch = useRefetchFunction(componentDisplayName, dispatch, disposeQuery, fragmentData, fragmentIdentifier, fragmentNode, fragmentRefPathInResponse,
|
128
|
+
var refetch = useRefetchFunction(componentDisplayName, dispatch, disposeQuery, fragmentData, fragmentIdentifier, fragmentNode, fragmentRefPathInResponse, identifierInfo, loadQuery, parentFragmentRef, refetchableRequest);
|
183
129
|
return {
|
184
130
|
fragmentData: fragmentData,
|
185
131
|
fragmentRef: fragmentRef,
|
186
132
|
refetch: refetch
|
187
133
|
};
|
188
134
|
}
|
189
|
-
function useRefetchFunction(componentDisplayName, dispatch, disposeQuery, fragmentData, fragmentIdentifier, fragmentNode, fragmentRefPathInResponse,
|
135
|
+
function useRefetchFunction(componentDisplayName, dispatch, disposeQuery, fragmentData, fragmentIdentifier, fragmentNode, fragmentRefPathInResponse, identifierInfo, loadQuery, parentFragmentRef, refetchableRequest) {
|
190
136
|
var isMountedRef = useIsMountedRef();
|
191
|
-
var identifierValue = identifierField != null && fragmentData != null && typeof fragmentData === 'object' ? fragmentData[identifierField] : null;
|
137
|
+
var identifierValue = (identifierInfo === null || identifierInfo === void 0 ? void 0 : identifierInfo.identifierField) != null && fragmentData != null && typeof fragmentData === 'object' ? fragmentData[identifierInfo.identifierField] : null;
|
192
138
|
return useCallback(function (providedRefetchVariables, options) {
|
193
|
-
// Bail out and warn if we're trying to refetch after the component
|
194
|
-
// has unmounted
|
195
139
|
if (isMountedRef.current !== true) {
|
196
140
|
process.env.NODE_ENV !== "production" ? warning(false, 'Relay: Unexpected call to `refetch` on unmounted component for fragment ' + '`%s` in `%s`. It looks like some instances of your component are ' + 'still trying to fetch data but they already unmounted. ' + 'Please make sure you clear all timers, intervals, ' + 'async calls, etc that may trigger a fetch.', fragmentNode.name, componentDisplayName) : void 0;
|
197
141
|
return {
|
@@ -219,35 +163,16 @@ function useRefetchFunction(componentDisplayName, dispatch, disposeQuery, fragme
|
|
219
163
|
parentVariables = fragmentSelector.owner.variables;
|
220
164
|
fragmentVariables = fragmentSelector.variables;
|
221
165
|
}
|
222
|
-
|
223
|
-
// A user of `useRefetchableFragment()` may pass a subset of
|
224
|
-
// all variables required by the fragment when calling `refetch()`.
|
225
|
-
// We fill in any variables not passed by the call to `refetch()` with the
|
226
|
-
// variables from the original parent fragment owner.
|
227
166
|
var refetchVariables = (0, _objectSpread2["default"])((0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, parentVariables), fragmentVariables), providedRefetchVariables);
|
228
|
-
|
229
|
-
// If the query needs an identifier value ('id' or similar) and one
|
230
|
-
// was not explicitly provided, read it from the fragment data.
|
231
|
-
if (identifierField != null && !providedRefetchVariables.hasOwnProperty('id')) {
|
232
|
-
// @refetchable fragments are guaranteed to have an `id` selection
|
233
|
-
// if the type is Node, implements Node, or is @fetchable. Double-check
|
234
|
-
// that there actually is a value at runtime.
|
167
|
+
if (identifierInfo != null && !providedRefetchVariables.hasOwnProperty(identifierInfo.identifierQueryVariableName)) {
|
235
168
|
if (typeof identifierValue !== 'string') {
|
236
|
-
process.env.NODE_ENV !== "production" ? warning(false, 'Relay: Expected result to have a string ' + '`%s` in order to refetch, got `%s`.', identifierField, identifierValue) : void 0;
|
169
|
+
process.env.NODE_ENV !== "production" ? warning(false, 'Relay: Expected result to have a string ' + '`%s` in order to refetch, got `%s`.', identifierInfo.identifierField, identifierValue) : void 0;
|
237
170
|
}
|
238
|
-
refetchVariables.
|
171
|
+
refetchVariables[identifierInfo.identifierQueryVariableName] = identifierValue;
|
239
172
|
}
|
240
173
|
var refetchQuery = createOperationDescriptor(refetchableRequest, refetchVariables, {
|
241
174
|
force: true
|
242
175
|
});
|
243
|
-
|
244
|
-
// We call loadQuery which will start a network request if necessary
|
245
|
-
// and update the querRef from useQueryLoader.
|
246
|
-
// Note the following:
|
247
|
-
// - loadQuery will dispose of any previously refetched queries.
|
248
|
-
// - We use the variables extracted off the OperationDescriptor
|
249
|
-
// so that they have been filtered out to include only the
|
250
|
-
// variables actually declared in the query.
|
251
176
|
loadQuery(refetchQuery.request.variables, {
|
252
177
|
fetchPolicy: fetchPolicy,
|
253
178
|
__environment: refetchEnvironment,
|
@@ -264,29 +189,21 @@ function useRefetchFunction(componentDisplayName, dispatch, disposeQuery, fragme
|
|
264
189
|
return {
|
265
190
|
dispose: disposeQuery
|
266
191
|
};
|
267
|
-
},
|
268
|
-
// NOTE: We disable react-hooks-deps warning because:
|
269
|
-
// - We know fragmentRefPathInResponse is static, so it can be omitted from
|
270
|
-
// deps
|
271
|
-
// - We know fragmentNode is static, so it can be omitted from deps.
|
272
|
-
// - fragmentNode and parentFragmentRef are also captured by including
|
273
|
-
// fragmentIdentifier
|
274
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
275
|
-
[fragmentIdentifier, dispatch, disposeQuery, identifierValue, loadQuery]);
|
192
|
+
}, [fragmentIdentifier, dispatch, disposeQuery, identifierValue, loadQuery]);
|
276
193
|
}
|
277
194
|
var debugFunctions;
|
278
195
|
if (process.env.NODE_ENV !== "production") {
|
279
196
|
debugFunctions = {
|
280
|
-
getInitialIDAndType: function getInitialIDAndType(memoRefetchVariables, fragmentRefPathInResponse, environment) {
|
197
|
+
getInitialIDAndType: function getInitialIDAndType(memoRefetchVariables, fragmentRefPathInResponse, identifierQueryVariableName, environment) {
|
281
198
|
var _require4 = require('relay-runtime'),
|
282
199
|
Record = _require4.Record;
|
283
|
-
var id = memoRefetchVariables === null || memoRefetchVariables === void 0 ? void 0 : memoRefetchVariables
|
200
|
+
var id = memoRefetchVariables === null || memoRefetchVariables === void 0 ? void 0 : memoRefetchVariables[identifierQueryVariableName !== null && identifierQueryVariableName !== void 0 ? identifierQueryVariableName : 'id'];
|
284
201
|
if (fragmentRefPathInResponse.length !== 1 || fragmentRefPathInResponse[0] !== 'node' || id == null) {
|
285
202
|
return null;
|
286
203
|
}
|
287
204
|
var recordSource = environment.getStore().getSource();
|
288
205
|
var record = recordSource.get(id);
|
289
|
-
var typename = record
|
206
|
+
var typename = record == null ? null : Record.getType(record);
|
290
207
|
if (typename == null) {
|
291
208
|
return null;
|
292
209
|
}
|
@@ -314,7 +231,6 @@ if (process.env.NODE_ENV !== "production") {
|
|
314
231
|
}
|
315
232
|
var _require6 = require('relay-runtime'),
|
316
233
|
ID_KEY = _require6.ID_KEY;
|
317
|
-
// $FlowExpectedError[incompatible-use]
|
318
234
|
var resultID = refetchedFragmentRef[ID_KEY];
|
319
235
|
if (resultID != null && resultID !== previousIDAndTypename.id) {
|
320
236
|
process.env.NODE_ENV !== "production" ? warning(false, 'Relay: Call to `refetch` returned a different id, expected ' + '`%s`, got `%s`, on `%s` in `%s`. ' + 'Please make sure the server correctly implements ' + 'unique id requirement.', resultID, previousIDAndTypename.id, fragmentNode.name, componentDisplayName) : void 0;
|