react-relay 15.0.0 → 16.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ReactRelayContext.js +1 -1
- package/ReactRelayQueryFetcher.js.flow +1 -5
- package/ReactRelayQueryRenderer.js.flow +9 -36
- package/ReactRelayTypes.js.flow +1 -0
- package/buildReactRelayContainer.js.flow +3 -1
- package/hooks.js +1 -1
- package/index.js +1 -1
- package/legacy.js +1 -1
- package/lib/ReactRelayContainerUtils.js +0 -11
- package/lib/ReactRelayContext.js +0 -11
- package/lib/ReactRelayFragmentContainer.js +6 -78
- package/lib/ReactRelayFragmentMockRenderer.js +0 -11
- package/lib/ReactRelayLocalQueryRenderer.js +0 -17
- package/lib/ReactRelayPaginationContainer.js +5 -208
- package/lib/ReactRelayQueryFetcher.js +2 -51
- package/lib/ReactRelayQueryRenderer.js +6 -94
- package/lib/ReactRelayQueryRendererContext.js +0 -11
- package/lib/ReactRelayRefetchContainer.js +5 -91
- package/lib/ReactRelayTestMocker.js +9 -85
- package/lib/ReactRelayTypes.js +0 -11
- package/lib/RelayContext.js +0 -21
- package/lib/assertFragmentMap.js +0 -15
- package/lib/buildReactRelayContainer.js +0 -19
- package/lib/getRootVariablesForFragments.js +0 -14
- package/lib/hooks.js +0 -15
- package/lib/index.js +0 -17
- package/lib/isRelayEnvironment.js +1 -18
- package/lib/jest-react/enqueueTask.js +0 -20
- package/lib/jest-react/internalAct.js +0 -38
- package/lib/legacy.js +0 -15
- package/lib/multi-actor/ActorChange.js +0 -11
- package/lib/multi-actor/index.js +0 -11
- package/lib/multi-actor/useRelayActorEnvironment.js +0 -11
- package/lib/relay-hooks/EntryPointContainer.react.js +0 -11
- package/lib/relay-hooks/EntryPointTypes.flow.js +1 -14
- package/lib/relay-hooks/FragmentResource.js +76 -132
- package/lib/relay-hooks/HooksImplementation.js +1 -12
- package/lib/relay-hooks/InternalLogger.js +0 -11
- package/lib/relay-hooks/LRUCache.js +0 -22
- package/lib/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js +0 -18
- package/lib/relay-hooks/MatchContainer.js +0 -94
- package/lib/relay-hooks/NestedRelayEntryPointBuilderUtils.js +9 -0
- package/lib/relay-hooks/ProfilerContext.js +0 -15
- package/lib/relay-hooks/QueryResource.js +2 -68
- package/lib/relay-hooks/RelayEnvironmentProvider.js +0 -11
- package/lib/relay-hooks/SuspenseResource.js +0 -34
- package/lib/relay-hooks/{react-cache/readFragmentInternal_REACT_CACHE.js → experimental/readFragmentInternal_EXPERIMENTAL.js} +5 -29
- package/lib/relay-hooks/{react-cache/useFragmentInternal_REACT_CACHE.js → experimental/useFragmentInternal_EXPERIMENTAL.js} +35 -100
- package/lib/relay-hooks/{react-cache/useFragment_REACT_CACHE.js → experimental/useFragment_EXPERIMENTAL.js} +1 -16
- package/lib/relay-hooks/{react-cache/usePaginationFragment_REACT_CACHE.js → experimental/usePaginationFragment_EXPERIMENTAL.js} +2 -24
- package/lib/relay-hooks/{react-cache/useRefetchableFragmentInternal_REACT_CACHE.js → experimental/useRefetchableFragmentInternal_EXPERIMENTAL.js} +14 -98
- package/lib/relay-hooks/{react-cache/useRefetchableFragment_REACT_CACHE.js → experimental/useRefetchableFragment_EXPERIMENTAL.js} +1 -15
- package/lib/relay-hooks/loadEntryPoint.js +1 -24
- package/lib/relay-hooks/loadQuery.js +2 -106
- package/lib/relay-hooks/preloadQuery_DEPRECATED.js +2 -27
- package/lib/relay-hooks/prepareEntryPoint_DEPRECATED.js +0 -13
- package/lib/relay-hooks/useBlockingPaginationFragment.js +0 -42
- package/lib/relay-hooks/useClientQuery.js +0 -18
- package/lib/relay-hooks/useEntryPointLoader.js +0 -69
- package/lib/relay-hooks/useFetchTrackingRef.js +0 -26
- package/lib/relay-hooks/useFragment.js +0 -17
- package/lib/relay-hooks/useFragmentNode.js +2 -32
- package/lib/relay-hooks/useIsMountedRef.js +0 -11
- package/lib/relay-hooks/useIsOperationNodeActive.js +0 -11
- package/lib/relay-hooks/useIsParentQueryActive.js +0 -11
- package/lib/relay-hooks/useLazyLoadQuery.js +0 -18
- package/lib/relay-hooks/useLazyLoadQueryNode.js +12 -37
- package/lib/relay-hooks/useLoadMoreFunction.js +9 -34
- package/lib/relay-hooks/useMemoOperationDescriptor.js +0 -11
- package/lib/relay-hooks/useMemoVariables.js +0 -17
- package/lib/relay-hooks/useMutation.js +0 -11
- package/lib/relay-hooks/usePaginationFragment.js +1 -26
- package/lib/relay-hooks/usePreloadedQuery.js +0 -27
- package/lib/relay-hooks/useQueryLoader.js +0 -74
- package/lib/relay-hooks/useRefetchableFragment.js +0 -16
- package/lib/relay-hooks/useRefetchableFragmentNode.js +14 -97
- package/lib/relay-hooks/useRelayEnvironment.js +0 -11
- package/lib/relay-hooks/useStaticFragmentNodeWarning.js +0 -15
- package/lib/relay-hooks/useSubscribeToInvalidationState.js +0 -25
- package/lib/relay-hooks/useSubscription.js +0 -15
- package/lib/relay-hooks/useUnsafeRef_DEPRECATED.js +0 -17
- package/package.json +2 -2
- package/react-relay-hooks.js +2 -2
- package/react-relay-hooks.min.js +2 -2
- package/react-relay-legacy.js +2 -2
- package/react-relay-legacy.min.js +2 -2
- package/react-relay.js +2 -2
- package/react-relay.min.js +2 -2
- package/relay-hooks/EntryPointContainer.react.js.flow +5 -0
- package/relay-hooks/EntryPointTypes.flow.js.flow +34 -35
- package/relay-hooks/FragmentResource.js.flow +114 -26
- package/relay-hooks/HooksImplementation.js.flow +3 -1
- package/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js.flow +4 -2
- package/relay-hooks/NestedRelayEntryPointBuilderUtils.js.flow +51 -0
- package/relay-hooks/__flowtests__/EntryPointTypes/NestedEntrypoints-flowtest.js.flow +7 -5
- package/relay-hooks/__flowtests__/useBlockingPaginationFragment-flowtest.js.flow +5 -0
- package/relay-hooks/__flowtests__/usePaginationFragment-flowtest.js.flow +5 -0
- package/relay-hooks/__flowtests__/useRefetchableFragment-flowtest.js.flow +2 -0
- package/relay-hooks/{react-cache/readFragmentInternal_REACT_CACHE.js.flow → experimental/readFragmentInternal_EXPERIMENTAL.js.flow} +4 -3
- package/relay-hooks/{react-cache/useFragmentInternal_REACT_CACHE.js.flow → experimental/useFragmentInternal_EXPERIMENTAL.js.flow} +32 -14
- package/relay-hooks/{react-cache/useFragment_REACT_CACHE.js.flow → experimental/useFragment_EXPERIMENTAL.js.flow} +4 -10
- package/relay-hooks/{react-cache/usePaginationFragment_REACT_CACHE.js.flow → experimental/usePaginationFragment_EXPERIMENTAL.js.flow} +30 -59
- package/relay-hooks/{react-cache/useRefetchableFragmentInternal_REACT_CACHE.js.flow → experimental/useRefetchableFragmentInternal_EXPERIMENTAL.js.flow} +30 -23
- package/relay-hooks/experimental/useRefetchableFragment_EXPERIMENTAL.js.flow +49 -0
- package/relay-hooks/loadEntryPoint.js.flow +4 -2
- package/relay-hooks/loadQuery.js.flow +21 -1
- package/relay-hooks/prepareEntryPoint_DEPRECATED.js.flow +4 -2
- package/relay-hooks/useBlockingPaginationFragment.js.flow +10 -17
- package/relay-hooks/useClientQuery.js.flow +2 -2
- package/relay-hooks/useFragmentNode.js.flow +2 -2
- package/relay-hooks/useLazyLoadQueryNode.js.flow +17 -1
- package/relay-hooks/useLoadMoreFunction.js.flow +15 -9
- package/relay-hooks/useMutation.js.flow +26 -9
- package/relay-hooks/usePaginationFragment.js.flow +7 -15
- package/relay-hooks/useQueryLoader.js.flow +2 -8
- package/relay-hooks/useRefetchableFragment.js.flow +14 -16
- package/relay-hooks/useRefetchableFragmentNode.js.flow +33 -20
- package/lib/relay-hooks/react-cache/RelayReactCache.js +0 -32
- package/lib/relay-hooks/react-cache/getQueryResultOrFetchQuery_REACT_CACHE.js +0 -290
- package/lib/relay-hooks/react-cache/useLazyLoadQuery_REACT_CACHE.js +0 -49
- package/lib/relay-hooks/react-cache/usePreloadedQuery_REACT_CACHE.js +0 -110
- package/relay-hooks/react-cache/RelayReactCache.js.flow +0 -40
- package/relay-hooks/react-cache/getQueryResultOrFetchQuery_REACT_CACHE.js.flow +0 -430
- package/relay-hooks/react-cache/useLazyLoadQuery_REACT_CACHE.js.flow +0 -70
- package/relay-hooks/react-cache/usePreloadedQuery_REACT_CACHE.js.flow +0 -150
- package/relay-hooks/react-cache/useRefetchableFragment_REACT_CACHE.js.flow +0 -65
|
@@ -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;
|