react-relay 20.1.1 → 21.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ReactRelayContext.js +1 -1
- package/ReactRelayContext.js.flow +2 -2
- package/ReactRelayFragmentContainer.js.flow +8 -9
- package/ReactRelayLocalQueryRenderer.js.flow +11 -3
- package/ReactRelayLoggingContext.js.flow +3 -3
- package/ReactRelayPaginationContainer.js.flow +31 -24
- package/ReactRelayQueryFetcher.js.flow +1 -1
- package/ReactRelayQueryRenderer.js.flow +2 -2
- package/ReactRelayQueryRendererContext.js.flow +2 -2
- package/ReactRelayRefetchContainer.js.flow +17 -14
- package/ReactRelayTestMocker.js.flow +10 -10
- package/ReactRelayTypes.js.flow +18 -20
- package/RelayContext.js.flow +3 -3
- package/__flowtests__/ReactRelayFragmentContainer-flowtest.js.flow +11 -11
- package/__flowtests__/ReactRelayPaginationContainer-flowtest.js.flow +5 -5
- package/__flowtests__/ReactRelayRefetchContainer-flowtest.js.flow +5 -5
- package/__flowtests__/RelayModern-flowtest.js.flow +24 -27
- package/__flowtests__/RelayModernFlowtest_users.graphql.js.flow +1 -1
- package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer.graphql.js.flow +3 -4
- package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer2.graphql.js.flow +3 -4
- package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtestQuery.graphql.js.flow +9 -10
- package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtest_viewer.graphql.js.flow +4 -5
- package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtestQuery.graphql.js.flow +9 -10
- package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtest_viewer.graphql.js.flow +4 -5
- package/__flowtests__/__generated__/RelayModernFlowtest_badref.graphql.js.flow +3 -4
- package/__flowtests__/__generated__/RelayModernFlowtest_notref.graphql.js.flow +3 -4
- package/__flowtests__/__generated__/RelayModernFlowtest_user.graphql.js.flow +3 -4
- package/__flowtests__/__generated__/RelayModernFlowtest_users.graphql.js.flow +5 -6
- package/buildReactRelayContainer.js.flow +4 -4
- package/getRootVariablesForFragments.js.flow +1 -1
- package/hooks.js +1 -1
- package/hooks.js.flow +23 -8
- package/index.js +1 -1
- package/index.js.flow +40 -14
- package/isRelayEnvironment.js.flow +1 -1
- package/jest-react/internalAct.js.flow +1 -1
- package/legacy.js +1 -1
- package/legacy.js.flow +32 -13
- package/lib/ReactRelayFragmentContainer.js +1 -1
- package/lib/ReactRelayPaginationContainer.js +8 -8
- package/lib/ReactRelayRefetchContainer.js +8 -8
- package/lib/ReactRelayTestMocker.js +5 -5
- package/lib/hooks.js +18 -8
- package/lib/index.js +30 -14
- package/lib/legacy.js +26 -13
- package/lib/relay-hooks/legacy/useBlockingPaginationFragment.js +5 -5
- package/lib/relay-hooks/legacy/useRefetchableFragmentNode.js +34 -34
- package/lib/relay-hooks/loadEntryPoint.js +2 -2
- package/lib/relay-hooks/loadQuery.js +14 -14
- package/lib/relay-hooks/preloadQuery_DEPRECATED.js +10 -10
- package/lib/relay-hooks/readFragmentInternal.js +6 -6
- package/lib/relay-hooks/rsc/serverFetchQuery.js +20 -0
- package/lib/relay-hooks/rsc/serverPreloadQuery.js +31 -0
- package/lib/relay-hooks/rsc/serverReadFragment.js +15 -0
- package/lib/relay-hooks/rsc/useQueryFromServer.js +62 -0
- package/lib/relay-hooks/useFragmentInternal_CURRENT.js +49 -25
- package/lib/relay-hooks/useFragmentInternal_EXPERIMENTAL.js +81 -44
- package/lib/relay-hooks/useLazyLoadQueryNode.js +32 -19
- package/lib/relay-hooks/useMutation.js +6 -14
- package/lib/relay-hooks/useMutationAction_EXPERIMENTAL.js +26 -0
- package/lib/relay-hooks/usePreloadedQuery.js +52 -47
- package/lib/relay-hooks/useQueryLoader.js +2 -2
- package/lib/relay-hooks/useQueryLoader_EXPERIMENTAL.js +2 -2
- package/lib/relay-hooks/useRefetchableFragmentInternal.js +31 -31
- package/lib/rsc-client_EXPERIMENTAL.js +7 -0
- package/lib/rsc_EXPERIMENTAL.js +43 -0
- package/multi-actor/ActorChange.js.flow +1 -1
- package/package.json +3 -2
- package/relay-hooks/EntryPointContainer.react.js.flow +6 -6
- package/relay-hooks/EntryPointTypes.flow.js.flow +61 -67
- package/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js.flow +23 -21
- package/relay-hooks/MatchContainer.js.flow +12 -6
- package/relay-hooks/NestedRelayEntryPointBuilderUtils.js.flow +3 -9
- package/relay-hooks/QueryResource.js.flow +6 -6
- package/relay-hooks/RelayEnvironmentProvider.js.flow +2 -2
- package/relay-hooks/__flowtests__/EntryPointTypes/EntryPointElementConfig-flowtest.js.flow +6 -6
- package/relay-hooks/__flowtests__/EntryPointTypes/ExtractQueryTypes-flowtest.js.flow +48 -1
- package/relay-hooks/__flowtests__/EntryPointTypes/NestedEntrypoints-flowtest.js.flow +9 -9
- package/relay-hooks/__flowtests__/__generated__/useFragmentFlowtest_user.graphql.js.flow +3 -4
- package/relay-hooks/__flowtests__/__generated__/useFragmentFlowtest_users.graphql.js.flow +5 -6
- package/relay-hooks/__flowtests__/useBlockingPaginationFragment-flowtest.js.flow +27 -32
- package/relay-hooks/__flowtests__/useFragment-flowtest.js.flow +25 -25
- package/relay-hooks/__flowtests__/usePaginationFragment-flowtest.js.flow +26 -32
- package/relay-hooks/__flowtests__/useRefetchableFragment-flowtest.js.flow +23 -30
- package/relay-hooks/__flowtests__/utils.js.flow +4 -4
- package/relay-hooks/getConnectionState.js.flow +2 -2
- package/relay-hooks/legacy/FragmentResource.js.flow +13 -13
- package/relay-hooks/legacy/useBlockingPaginationFragment.js.flow +24 -25
- package/relay-hooks/legacy/useFragmentNode.js.flow +4 -4
- package/relay-hooks/legacy/useRefetchableFragmentNode.js.flow +79 -81
- package/relay-hooks/loadEntryPoint.js.flow +15 -13
- package/relay-hooks/loadQuery.js.flow +18 -18
- package/relay-hooks/preloadQuery_DEPRECATED.js.flow +16 -13
- package/relay-hooks/prepareEntryPoint_DEPRECATED.js.flow +7 -7
- package/relay-hooks/readFragmentInternal.js.flow +9 -9
- package/relay-hooks/rsc/serverFetchQuery.js.flow +31 -0
- package/relay-hooks/rsc/serverPreloadQuery.js.flow +69 -0
- package/relay-hooks/rsc/serverReadFragment.js.flow +33 -0
- package/relay-hooks/rsc/useQueryFromServer.js.flow +135 -0
- package/relay-hooks/useClientQuery.js.flow +2 -2
- package/relay-hooks/useEntryPointLoader.js.flow +11 -11
- package/relay-hooks/useFragment.js.flow +7 -7
- package/relay-hooks/useFragmentInternal.js.flow +1 -1
- package/relay-hooks/useFragmentInternal_CURRENT.js.flow +54 -22
- package/relay-hooks/useFragmentInternal_EXPERIMENTAL.js.flow +95 -46
- package/relay-hooks/useIsOperationNodeActive.js.flow +1 -1
- package/relay-hooks/useIsParentQueryActive.js.flow +1 -1
- package/relay-hooks/useLazyLoadQuery.js.flow +10 -3
- package/relay-hooks/useLazyLoadQueryNode.js.flow +67 -28
- package/relay-hooks/useLoadMoreFunction.js.flow +7 -6
- package/relay-hooks/useLoadMoreFunction_EXPERIMENTAL.js.flow +5 -5
- package/relay-hooks/useMemoVariables.js.flow +1 -1
- package/relay-hooks/useMutation.js.flow +8 -16
- package/relay-hooks/useMutationAction_EXPERIMENTAL.js.flow +68 -0
- package/relay-hooks/usePaginationFragment.js.flow +15 -11
- package/relay-hooks/usePrefetchableForwardPaginationFragment.js.flow +19 -18
- package/relay-hooks/usePrefetchableForwardPaginationFragment_EXPERIMENTAL.js.flow +19 -18
- package/relay-hooks/usePreloadedQuery.js.flow +119 -85
- package/relay-hooks/useQueryLoader.js.flow +27 -23
- package/relay-hooks/useQueryLoader_EXPERIMENTAL.js.flow +10 -10
- package/relay-hooks/useRefetchableFragment.js.flow +16 -11
- package/relay-hooks/useRefetchableFragmentInternal.js.flow +77 -79
- package/relay-hooks/useRelayLoggingContext.js.flow +1 -1
- package/relay-hooks/useSubscribeToInvalidationState.js.flow +1 -1
- package/relay-hooks/useSubscription.js.flow +1 -1
- package/rsc-client_EXPERIMENTAL.js +10 -0
- package/rsc-client_EXPERIMENTAL.js.flow +23 -0
- package/rsc_EXPERIMENTAL.js +10 -0
- package/rsc_EXPERIMENTAL.js.flow +90 -0
|
@@ -47,10 +47,10 @@ type FragmentQueryOptions = {
|
|
|
47
47
|
networkCacheConfig?: ?CacheConfig,
|
|
48
48
|
};
|
|
49
49
|
|
|
50
|
-
type FragmentState =
|
|
50
|
+
type FragmentState = Readonly<
|
|
51
51
|
| {kind: 'bailout'}
|
|
52
52
|
| {kind: 'singular', snapshot: Snapshot, epoch: number}
|
|
53
|
-
| {kind: 'plural', snapshots:
|
|
53
|
+
| {kind: 'plural', snapshots: ReadonlyArray<Snapshot>, epoch: number},
|
|
54
54
|
>;
|
|
55
55
|
|
|
56
56
|
type StateUpdaterFunction<T> = ((T) => T) => void;
|
|
@@ -67,7 +67,7 @@ function isMissingData(state: FragmentState): boolean {
|
|
|
67
67
|
|
|
68
68
|
function getMissingClientEdges(
|
|
69
69
|
state: FragmentState,
|
|
70
|
-
):
|
|
70
|
+
): ReadonlyArray<MissingClientEdgeRequestInfo> | null {
|
|
71
71
|
if (state.kind === 'bailout') {
|
|
72
72
|
return null;
|
|
73
73
|
} else if (state.kind === 'singular') {
|
|
@@ -88,7 +88,7 @@ function getMissingClientEdges(
|
|
|
88
88
|
|
|
89
89
|
function getSuspendingLiveResolver(
|
|
90
90
|
state: FragmentState,
|
|
91
|
-
):
|
|
91
|
+
): ReadonlyArray<DataID> | null {
|
|
92
92
|
if (state.kind === 'bailout') {
|
|
93
93
|
return null;
|
|
94
94
|
} else if (state.kind === 'singular') {
|
|
@@ -110,7 +110,7 @@ function getSuspendingLiveResolver(
|
|
|
110
110
|
function handlePotentialSnapshotErrorsForState(
|
|
111
111
|
environment: IEnvironment,
|
|
112
112
|
state: FragmentState,
|
|
113
|
-
loggingContext:
|
|
113
|
+
loggingContext: unknown | void,
|
|
114
114
|
): void {
|
|
115
115
|
if (state.kind === 'singular') {
|
|
116
116
|
handlePotentialSnapshotErrors(
|
|
@@ -155,19 +155,19 @@ function handleMissedUpdates(
|
|
|
155
155
|
);
|
|
156
156
|
const updatedCurrentSnapshot: Snapshot = {
|
|
157
157
|
data: updatedData,
|
|
158
|
+
fieldErrors: currentSnapshot.fieldErrors,
|
|
158
159
|
isMissingData: currentSnapshot.isMissingData,
|
|
159
160
|
missingClientEdges: currentSnapshot.missingClientEdges,
|
|
160
161
|
missingLiveResolverFields: currentSnapshot.missingLiveResolverFields,
|
|
161
162
|
seenRecords: currentSnapshot.seenRecords,
|
|
162
163
|
selector: currentSnapshot.selector,
|
|
163
|
-
fieldErrors: currentSnapshot.fieldErrors,
|
|
164
164
|
};
|
|
165
165
|
return [
|
|
166
166
|
updatedData !== state.snapshot.data,
|
|
167
167
|
{
|
|
168
|
+
epoch: currentEpoch,
|
|
168
169
|
kind: 'singular',
|
|
169
170
|
snapshot: updatedCurrentSnapshot,
|
|
170
|
-
epoch: currentEpoch,
|
|
171
171
|
},
|
|
172
172
|
];
|
|
173
173
|
} else {
|
|
@@ -179,12 +179,12 @@ function handleMissedUpdates(
|
|
|
179
179
|
const updatedData = recycleNodesInto(snapshot.data, currentSnapshot.data);
|
|
180
180
|
const updatedCurrentSnapshot: Snapshot = {
|
|
181
181
|
data: updatedData,
|
|
182
|
+
fieldErrors: currentSnapshot.fieldErrors,
|
|
182
183
|
isMissingData: currentSnapshot.isMissingData,
|
|
183
184
|
missingClientEdges: currentSnapshot.missingClientEdges,
|
|
184
185
|
missingLiveResolverFields: currentSnapshot.missingLiveResolverFields,
|
|
185
186
|
seenRecords: currentSnapshot.seenRecords,
|
|
186
187
|
selector: currentSnapshot.selector,
|
|
187
|
-
fieldErrors: currentSnapshot.fieldErrors,
|
|
188
188
|
};
|
|
189
189
|
if (updatedData !== snapshot.data) {
|
|
190
190
|
didMissUpdates = true;
|
|
@@ -198,9 +198,9 @@ function handleMissedUpdates(
|
|
|
198
198
|
return [
|
|
199
199
|
didMissUpdates,
|
|
200
200
|
{
|
|
201
|
+
epoch: currentEpoch,
|
|
201
202
|
kind: 'plural',
|
|
202
203
|
snapshots: currentSnapshots,
|
|
203
|
-
epoch: currentEpoch,
|
|
204
204
|
},
|
|
205
205
|
];
|
|
206
206
|
}
|
|
@@ -209,10 +209,10 @@ function handleMissedUpdates(
|
|
|
209
209
|
function handleMissingClientEdge(
|
|
210
210
|
environment: IEnvironment,
|
|
211
211
|
parentFragmentNode: ReaderFragment,
|
|
212
|
-
parentFragmentRef:
|
|
212
|
+
parentFragmentRef: unknown,
|
|
213
213
|
missingClientEdgeRequestInfo: MissingClientEdgeRequestInfo,
|
|
214
214
|
queryOptions?: FragmentQueryOptions,
|
|
215
|
-
): [QueryResult, ?Promise<
|
|
215
|
+
): [QueryResult, ?Promise<unknown>] {
|
|
216
216
|
const originalVariables = getVariablesFromFragment(
|
|
217
217
|
parentFragmentNode,
|
|
218
218
|
parentFragmentRef,
|
|
@@ -265,8 +265,8 @@ function subscribeToSnapshot(
|
|
|
265
265
|
if (updates != null) {
|
|
266
266
|
const [dataChanged, nextState] = updates;
|
|
267
267
|
environment.__log({
|
|
268
|
-
name: 'useFragment.subscription.missedUpdates',
|
|
269
268
|
hasDataChanges: dataChanged,
|
|
269
|
+
name: 'useFragment.subscription.missedUpdates',
|
|
270
270
|
});
|
|
271
271
|
hasPendingStateChanges.current = dataChanged;
|
|
272
272
|
return dataChanged ? nextState : prevState;
|
|
@@ -277,9 +277,9 @@ function subscribeToSnapshot(
|
|
|
277
277
|
|
|
278
278
|
hasPendingStateChanges.current = true;
|
|
279
279
|
return {
|
|
280
|
+
epoch: environment.getStore().getEpoch(),
|
|
280
281
|
kind: 'singular',
|
|
281
282
|
snapshot: latestSnapshot,
|
|
282
|
-
epoch: environment.getStore().getEpoch(),
|
|
283
283
|
};
|
|
284
284
|
});
|
|
285
285
|
});
|
|
@@ -301,8 +301,8 @@ function subscribeToSnapshot(
|
|
|
301
301
|
if (updates != null) {
|
|
302
302
|
const [dataChanged, nextState] = updates;
|
|
303
303
|
environment.__log({
|
|
304
|
-
name: 'useFragment.subscription.missedUpdates',
|
|
305
304
|
hasDataChanges: dataChanged,
|
|
305
|
+
name: 'useFragment.subscription.missedUpdates',
|
|
306
306
|
});
|
|
307
307
|
hasPendingStateChanges.current =
|
|
308
308
|
hasPendingStateChanges.current || dataChanged;
|
|
@@ -315,9 +315,9 @@ function subscribeToSnapshot(
|
|
|
315
315
|
updated[index] = latestSnapshot;
|
|
316
316
|
hasPendingStateChanges.current = true;
|
|
317
317
|
return {
|
|
318
|
+
epoch: environment.getStore().getEpoch(),
|
|
318
319
|
kind: 'plural',
|
|
319
320
|
snapshots: updated,
|
|
320
|
-
epoch: environment.getStore().getEpoch(),
|
|
321
321
|
};
|
|
322
322
|
});
|
|
323
323
|
}),
|
|
@@ -340,15 +340,15 @@ function getFragmentState(
|
|
|
340
340
|
// Note that if fragmentRef is an empty array, fragmentSelector will be null so we'll hit the above case.
|
|
341
341
|
// Null is returned by getSelector if fragmentRef has no non-null items.
|
|
342
342
|
return {
|
|
343
|
+
epoch: environment.getStore().getEpoch(),
|
|
343
344
|
kind: 'plural',
|
|
344
345
|
snapshots: fragmentSelector.selectors.map(s => environment.lookup(s)),
|
|
345
|
-
epoch: environment.getStore().getEpoch(),
|
|
346
346
|
};
|
|
347
347
|
} else {
|
|
348
348
|
return {
|
|
349
|
+
epoch: environment.getStore().getEpoch(),
|
|
349
350
|
kind: 'singular',
|
|
350
351
|
snapshot: environment.lookup(fragmentSelector),
|
|
351
|
-
epoch: environment.getStore().getEpoch(),
|
|
352
352
|
};
|
|
353
353
|
}
|
|
354
354
|
}
|
|
@@ -356,7 +356,7 @@ function getFragmentState(
|
|
|
356
356
|
// fragmentNode cannot change during the lifetime of the component, though fragmentRef may change.
|
|
357
357
|
hook useFragmentInternal(
|
|
358
358
|
fragmentNode: ReaderFragment,
|
|
359
|
-
fragmentRef:
|
|
359
|
+
fragmentRef: unknown,
|
|
360
360
|
hookDisplayName: string,
|
|
361
361
|
queryOptions?: FragmentQueryOptions,
|
|
362
362
|
): ?SelectorData | Array<?SelectorData> {
|
|
@@ -478,7 +478,7 @@ hook useFragmentInternal(
|
|
|
478
478
|
let clientEdgeQueries;
|
|
479
479
|
const activeRequestPromises = [];
|
|
480
480
|
if (missingClientEdges?.length) {
|
|
481
|
-
clientEdgeQueries =
|
|
481
|
+
clientEdgeQueries = [] as Array<QueryResult>;
|
|
482
482
|
for (const edge of missingClientEdges) {
|
|
483
483
|
const [queryResult, requestPromise] = handleMissingClientEdge(
|
|
484
484
|
environment,
|
|
@@ -497,6 +497,18 @@ hook useFragmentInternal(
|
|
|
497
497
|
}, [state, environment, fragmentNode, fragmentRef, queryOptions]);
|
|
498
498
|
|
|
499
499
|
if (activeRequestPromises.length) {
|
|
500
|
+
invariant(fragmentSelector != null, 'refinement, see invariants above');
|
|
501
|
+
const fragmentOwner =
|
|
502
|
+
fragmentSelector.kind === 'PluralReaderSelector'
|
|
503
|
+
? fragmentSelector.selectors[0].owner
|
|
504
|
+
: fragmentSelector.owner;
|
|
505
|
+
environment.__log({
|
|
506
|
+
name: 'suspense.client_edge',
|
|
507
|
+
fragment: fragmentNode,
|
|
508
|
+
fragmentOwner,
|
|
509
|
+
// $FlowFixMe[react-rule-unsafe-ref]
|
|
510
|
+
isMount: committedFragmentSelectorRef.current === false,
|
|
511
|
+
});
|
|
500
512
|
throw Promise.all(activeRequestPromises);
|
|
501
513
|
}
|
|
502
514
|
|
|
@@ -524,6 +536,19 @@ hook useFragmentInternal(
|
|
|
524
536
|
// Suspend if a Live Resolver within this fragment is in a suspended state:
|
|
525
537
|
const suspendingLiveResolvers = getSuspendingLiveResolver(state);
|
|
526
538
|
if (suspendingLiveResolvers != null && suspendingLiveResolvers.length > 0) {
|
|
539
|
+
invariant(fragmentSelector != null, 'refinement, see invariants above');
|
|
540
|
+
const fragmentOwner =
|
|
541
|
+
fragmentSelector.kind === 'PluralReaderSelector'
|
|
542
|
+
? fragmentSelector.selectors[0].owner
|
|
543
|
+
: fragmentSelector.owner;
|
|
544
|
+
environment.__log({
|
|
545
|
+
name: 'suspense.resolver',
|
|
546
|
+
fragment: fragmentNode,
|
|
547
|
+
fragmentOwner,
|
|
548
|
+
// $FlowFixMe[react-rule-unsafe-ref]
|
|
549
|
+
isMount: committedFragmentSelectorRef.current === false,
|
|
550
|
+
suspendingLiveResolvers,
|
|
551
|
+
});
|
|
527
552
|
throw Promise.all(
|
|
528
553
|
suspendingLiveResolvers.map(liveStateID => {
|
|
529
554
|
// $FlowFixMe[prop-missing] This is expected to be a RelayModernStore
|
|
@@ -538,8 +563,7 @@ hook useFragmentInternal(
|
|
|
538
563
|
if (
|
|
539
564
|
RelayFeatureFlags.ENABLE_RELAY_OPERATION_TRACKER_SUSPENSE ||
|
|
540
565
|
environment !== previousEnvironment ||
|
|
541
|
-
|
|
542
|
-
!committedFragmentSelectorRef.current ||
|
|
566
|
+
committedFragmentSelectorRef.current === false ||
|
|
543
567
|
// $FlowFixMe[react-rule-unsafe-ref]
|
|
544
568
|
!areEqualSelectors(committedFragmentSelectorRef.current, fragmentSelector)
|
|
545
569
|
) {
|
|
@@ -554,6 +578,14 @@ hook useFragmentInternal(
|
|
|
554
578
|
fragmentOwner,
|
|
555
579
|
);
|
|
556
580
|
if (pendingOperationsResult) {
|
|
581
|
+
environment.__log({
|
|
582
|
+
name: 'suspense.missing_data',
|
|
583
|
+
fragment: fragmentNode,
|
|
584
|
+
fragmentOwner,
|
|
585
|
+
// $FlowFixMe[react-rule-unsafe-ref]
|
|
586
|
+
isMount: committedFragmentSelectorRef.current === false,
|
|
587
|
+
pendingOperations: pendingOperationsResult.pendingOperations,
|
|
588
|
+
});
|
|
557
589
|
throw pendingOperationsResult.promise;
|
|
558
590
|
}
|
|
559
591
|
}
|
|
@@ -667,7 +699,7 @@ hook useFragmentInternal(
|
|
|
667
699
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
668
700
|
// $FlowFixMe[react-rule-hook]
|
|
669
701
|
// $FlowFixMe[react-rule-hook-conditional]
|
|
670
|
-
useDebugValue({fragment: fragmentNode.name
|
|
702
|
+
useDebugValue({data, fragment: fragmentNode.name});
|
|
671
703
|
}
|
|
672
704
|
|
|
673
705
|
return data;
|
|
@@ -47,7 +47,7 @@ export type FragmentQueryOptions = {
|
|
|
47
47
|
networkCacheConfig?: ?CacheConfig,
|
|
48
48
|
};
|
|
49
49
|
|
|
50
|
-
type FragmentState =
|
|
50
|
+
type FragmentState = Readonly<
|
|
51
51
|
| {kind: 'bailout', environment: IEnvironment}
|
|
52
52
|
| {
|
|
53
53
|
kind: 'singular',
|
|
@@ -58,7 +58,7 @@ type FragmentState = $ReadOnly<
|
|
|
58
58
|
}
|
|
59
59
|
| {
|
|
60
60
|
kind: 'plural',
|
|
61
|
-
snapshots:
|
|
61
|
+
snapshots: ReadonlyArray<Snapshot>,
|
|
62
62
|
epoch: number,
|
|
63
63
|
selector: ReaderSelector,
|
|
64
64
|
environment: IEnvironment,
|
|
@@ -79,7 +79,7 @@ function isMissingData(state: FragmentState): boolean {
|
|
|
79
79
|
|
|
80
80
|
function getMissingClientEdges(
|
|
81
81
|
state: FragmentState,
|
|
82
|
-
):
|
|
82
|
+
): ReadonlyArray<MissingClientEdgeRequestInfo> | null {
|
|
83
83
|
if (state.kind === 'bailout') {
|
|
84
84
|
return null;
|
|
85
85
|
} else if (state.kind === 'singular') {
|
|
@@ -100,7 +100,7 @@ function getMissingClientEdges(
|
|
|
100
100
|
|
|
101
101
|
function getSuspendingLiveResolver(
|
|
102
102
|
state: FragmentState,
|
|
103
|
-
):
|
|
103
|
+
): ReadonlyArray<DataID> | null {
|
|
104
104
|
if (state.kind === 'bailout') {
|
|
105
105
|
return null;
|
|
106
106
|
} else if (state.kind === 'singular') {
|
|
@@ -122,7 +122,7 @@ function getSuspendingLiveResolver(
|
|
|
122
122
|
function handlePotentialSnapshotErrorsForState(
|
|
123
123
|
environment: IEnvironment,
|
|
124
124
|
state: FragmentState,
|
|
125
|
-
loggingContext:
|
|
125
|
+
loggingContext: unknown | void,
|
|
126
126
|
): void {
|
|
127
127
|
if (state.kind === 'singular') {
|
|
128
128
|
handlePotentialSnapshotErrors(
|
|
@@ -167,21 +167,21 @@ function handleMissedUpdates(
|
|
|
167
167
|
);
|
|
168
168
|
const updatedCurrentSnapshot: Snapshot = {
|
|
169
169
|
data: updatedData,
|
|
170
|
+
fieldErrors: currentSnapshot.fieldErrors,
|
|
170
171
|
isMissingData: currentSnapshot.isMissingData,
|
|
171
172
|
missingClientEdges: currentSnapshot.missingClientEdges,
|
|
172
173
|
missingLiveResolverFields: currentSnapshot.missingLiveResolverFields,
|
|
173
174
|
seenRecords: currentSnapshot.seenRecords,
|
|
174
175
|
selector: currentSnapshot.selector,
|
|
175
|
-
fieldErrors: currentSnapshot.fieldErrors,
|
|
176
176
|
};
|
|
177
177
|
return [
|
|
178
178
|
updatedData !== state.snapshot.data,
|
|
179
179
|
{
|
|
180
|
-
|
|
181
|
-
snapshot: updatedCurrentSnapshot,
|
|
180
|
+
environment: state.environment,
|
|
182
181
|
epoch: currentEpoch,
|
|
182
|
+
kind: 'singular',
|
|
183
183
|
selector: state.selector,
|
|
184
|
-
|
|
184
|
+
snapshot: updatedCurrentSnapshot,
|
|
185
185
|
},
|
|
186
186
|
];
|
|
187
187
|
} else {
|
|
@@ -193,12 +193,12 @@ function handleMissedUpdates(
|
|
|
193
193
|
const updatedData = recycleNodesInto(snapshot.data, currentSnapshot.data);
|
|
194
194
|
const updatedCurrentSnapshot: Snapshot = {
|
|
195
195
|
data: updatedData,
|
|
196
|
+
fieldErrors: currentSnapshot.fieldErrors,
|
|
196
197
|
isMissingData: currentSnapshot.isMissingData,
|
|
197
198
|
missingClientEdges: currentSnapshot.missingClientEdges,
|
|
198
199
|
missingLiveResolverFields: currentSnapshot.missingLiveResolverFields,
|
|
199
200
|
seenRecords: currentSnapshot.seenRecords,
|
|
200
201
|
selector: currentSnapshot.selector,
|
|
201
|
-
fieldErrors: currentSnapshot.fieldErrors,
|
|
202
202
|
};
|
|
203
203
|
if (updatedData !== snapshot.data) {
|
|
204
204
|
didMissUpdates = true;
|
|
@@ -212,22 +212,22 @@ function handleMissedUpdates(
|
|
|
212
212
|
return [
|
|
213
213
|
didMissUpdates,
|
|
214
214
|
{
|
|
215
|
-
|
|
216
|
-
snapshots: currentSnapshots,
|
|
215
|
+
environment: state.environment,
|
|
217
216
|
epoch: currentEpoch,
|
|
217
|
+
kind: 'plural',
|
|
218
218
|
selector: state.selector,
|
|
219
|
-
|
|
219
|
+
snapshots: currentSnapshots,
|
|
220
220
|
},
|
|
221
221
|
];
|
|
222
222
|
}
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
-
type PromiseWithDisplayName = Promise<
|
|
225
|
+
type PromiseWithDisplayName = Promise<unknown> & {displayName?: string};
|
|
226
226
|
|
|
227
227
|
function handleMissingClientEdge(
|
|
228
228
|
environment: IEnvironment,
|
|
229
229
|
parentFragmentNode: ReaderFragment,
|
|
230
|
-
parentFragmentRef:
|
|
230
|
+
parentFragmentRef: unknown,
|
|
231
231
|
missingClientEdgeRequestInfo: MissingClientEdgeRequestInfo,
|
|
232
232
|
queryOptions?: FragmentQueryOptions,
|
|
233
233
|
): [QueryResult, ?PromiseWithDisplayName] {
|
|
@@ -291,8 +291,8 @@ function subscribeToSnapshot(
|
|
|
291
291
|
if (updates != null) {
|
|
292
292
|
const [dataChanged, updatedState] = updates;
|
|
293
293
|
environment.__log({
|
|
294
|
-
name: 'useFragment.subscription.missedUpdates',
|
|
295
294
|
hasDataChanges: dataChanged,
|
|
295
|
+
name: 'useFragment.subscription.missedUpdates',
|
|
296
296
|
});
|
|
297
297
|
nextState = dataChanged ? updatedState : prevState;
|
|
298
298
|
} else {
|
|
@@ -300,11 +300,11 @@ function subscribeToSnapshot(
|
|
|
300
300
|
}
|
|
301
301
|
} else {
|
|
302
302
|
nextState = {
|
|
303
|
-
|
|
304
|
-
snapshot: latestSnapshot,
|
|
303
|
+
environment: state.environment,
|
|
305
304
|
epoch: environment.getStore().getEpoch(),
|
|
305
|
+
kind: 'singular',
|
|
306
306
|
selector: state.selector,
|
|
307
|
-
|
|
307
|
+
snapshot: latestSnapshot,
|
|
308
308
|
};
|
|
309
309
|
}
|
|
310
310
|
return nextState;
|
|
@@ -333,8 +333,8 @@ function subscribeToSnapshot(
|
|
|
333
333
|
if (updates != null) {
|
|
334
334
|
const [dataChanged, updatedState] = updates;
|
|
335
335
|
environment.__log({
|
|
336
|
-
name: 'useFragment.subscription.missedUpdates',
|
|
337
336
|
hasDataChanges: dataChanged,
|
|
337
|
+
name: 'useFragment.subscription.missedUpdates',
|
|
338
338
|
});
|
|
339
339
|
nextState = dataChanged ? updatedState : prevState;
|
|
340
340
|
} else {
|
|
@@ -344,11 +344,11 @@ function subscribeToSnapshot(
|
|
|
344
344
|
const updated = [...prevState.snapshots];
|
|
345
345
|
updated[index] = latestSnapshot;
|
|
346
346
|
nextState = {
|
|
347
|
-
|
|
348
|
-
snapshots: updated,
|
|
347
|
+
environment: state.environment,
|
|
349
348
|
epoch: environment.getStore().getEpoch(),
|
|
349
|
+
kind: 'plural',
|
|
350
350
|
selector: state.selector,
|
|
351
|
-
|
|
351
|
+
snapshots: updated,
|
|
352
352
|
};
|
|
353
353
|
}
|
|
354
354
|
return nextState;
|
|
@@ -368,24 +368,24 @@ function getFragmentState(
|
|
|
368
368
|
fragmentSelector: ?ReaderSelector,
|
|
369
369
|
): FragmentState {
|
|
370
370
|
if (fragmentSelector == null) {
|
|
371
|
-
return {kind: 'bailout'
|
|
371
|
+
return {environment, kind: 'bailout'};
|
|
372
372
|
} else if (fragmentSelector.kind === 'PluralReaderSelector') {
|
|
373
373
|
// Note that if fragmentRef is an empty array, fragmentSelector will be null so we'll hit the above case.
|
|
374
374
|
// Null is returned by getSelector if fragmentRef has no non-null items.
|
|
375
375
|
return {
|
|
376
|
-
|
|
377
|
-
snapshots: fragmentSelector.selectors.map(s => environment.lookup(s)),
|
|
376
|
+
environment,
|
|
378
377
|
epoch: environment.getStore().getEpoch(),
|
|
378
|
+
kind: 'plural',
|
|
379
379
|
selector: fragmentSelector,
|
|
380
|
-
|
|
380
|
+
snapshots: fragmentSelector.selectors.map(s => environment.lookup(s)),
|
|
381
381
|
};
|
|
382
382
|
} else {
|
|
383
383
|
return {
|
|
384
|
-
|
|
385
|
-
snapshot: environment.lookup(fragmentSelector),
|
|
384
|
+
environment,
|
|
386
385
|
epoch: environment.getStore().getEpoch(),
|
|
386
|
+
kind: 'singular',
|
|
387
387
|
selector: fragmentSelector,
|
|
388
|
-
|
|
388
|
+
snapshot: environment.lookup(fragmentSelector),
|
|
389
389
|
};
|
|
390
390
|
}
|
|
391
391
|
}
|
|
@@ -393,7 +393,7 @@ function getFragmentState(
|
|
|
393
393
|
// fragmentNode cannot change during the lifetime of the component, though fragmentRef may change.
|
|
394
394
|
hook useFragmentInternal_EXPERIMENTAL(
|
|
395
395
|
fragmentNode: ReaderFragment,
|
|
396
|
-
fragmentRef:
|
|
396
|
+
fragmentRef: unknown,
|
|
397
397
|
hookDisplayName: string,
|
|
398
398
|
queryOptions?: FragmentQueryOptions,
|
|
399
399
|
): ?SelectorData | Array<?SelectorData> {
|
|
@@ -501,7 +501,7 @@ hook useFragmentInternal_EXPERIMENTAL(
|
|
|
501
501
|
let clientEdgeQueries;
|
|
502
502
|
const activeRequestPromises: Array<PromiseWithDisplayName> = [];
|
|
503
503
|
if (missingClientEdges?.length) {
|
|
504
|
-
clientEdgeQueries =
|
|
504
|
+
clientEdgeQueries = [] as Array<QueryResult>;
|
|
505
505
|
for (const edge of missingClientEdges) {
|
|
506
506
|
const [queryResult, requestPromise] = handleMissingClientEdge(
|
|
507
507
|
environment,
|
|
@@ -520,6 +520,18 @@ hook useFragmentInternal_EXPERIMENTAL(
|
|
|
520
520
|
}, [state, environment, fragmentNode, fragmentRef, queryOptions]);
|
|
521
521
|
|
|
522
522
|
if (activeRequestPromises.length) {
|
|
523
|
+
invariant(fragmentSelector != null, 'refinement, see invariants above');
|
|
524
|
+
const fragmentOwner =
|
|
525
|
+
fragmentSelector.kind === 'PluralReaderSelector'
|
|
526
|
+
? fragmentSelector.selectors[0].owner
|
|
527
|
+
: fragmentSelector.owner;
|
|
528
|
+
environment.__log({
|
|
529
|
+
name: 'suspense.client_edge',
|
|
530
|
+
fragment: fragmentNode,
|
|
531
|
+
fragmentOwner,
|
|
532
|
+
// $FlowFixMe[react-rule-unsafe-ref]
|
|
533
|
+
isMount: committedFragmentSelectorRef.current === false,
|
|
534
|
+
});
|
|
523
535
|
const allPromises = Promise.all(activeRequestPromises);
|
|
524
536
|
// $FlowExpectedError[prop-missing] Expando to annotate Promises.
|
|
525
537
|
allPromises.displayName = `RelayClientEdge(${activeRequestPromises
|
|
@@ -552,6 +564,19 @@ hook useFragmentInternal_EXPERIMENTAL(
|
|
|
552
564
|
// Suspend if a Live Resolver within this fragment is in a suspended state:
|
|
553
565
|
const suspendingLiveResolvers = getSuspendingLiveResolver(state);
|
|
554
566
|
if (suspendingLiveResolvers != null && suspendingLiveResolvers.length > 0) {
|
|
567
|
+
invariant(fragmentSelector != null, 'refinement, see invariants above');
|
|
568
|
+
const fragmentOwner =
|
|
569
|
+
fragmentSelector.kind === 'PluralReaderSelector'
|
|
570
|
+
? fragmentSelector.selectors[0].owner
|
|
571
|
+
: fragmentSelector.owner;
|
|
572
|
+
environment.__log({
|
|
573
|
+
name: 'suspense.resolver',
|
|
574
|
+
fragment: fragmentNode,
|
|
575
|
+
fragmentOwner,
|
|
576
|
+
// $FlowFixMe[react-rule-unsafe-ref]
|
|
577
|
+
isMount: committedFragmentSelectorRef.current === false,
|
|
578
|
+
suspendingLiveResolvers,
|
|
579
|
+
});
|
|
555
580
|
const promise = Promise.all(
|
|
556
581
|
suspendingLiveResolvers.map(liveStateID => {
|
|
557
582
|
// $FlowFixMe[prop-missing] This is expected to be a RelayModernStore
|
|
@@ -569,8 +594,7 @@ hook useFragmentInternal_EXPERIMENTAL(
|
|
|
569
594
|
if (
|
|
570
595
|
RelayFeatureFlags.ENABLE_RELAY_OPERATION_TRACKER_SUSPENSE ||
|
|
571
596
|
environment !== previousEnvironment ||
|
|
572
|
-
|
|
573
|
-
!committedFragmentSelectorRef.current ||
|
|
597
|
+
committedFragmentSelectorRef.current === false ||
|
|
574
598
|
// $FlowFixMe[react-rule-unsafe-ref]
|
|
575
599
|
!areEqualSelectors(committedFragmentSelectorRef.current, fragmentSelector)
|
|
576
600
|
) {
|
|
@@ -585,6 +609,14 @@ hook useFragmentInternal_EXPERIMENTAL(
|
|
|
585
609
|
fragmentOwner,
|
|
586
610
|
);
|
|
587
611
|
if (pendingOperationsResult) {
|
|
612
|
+
environment.__log({
|
|
613
|
+
name: 'suspense.missing_data',
|
|
614
|
+
fragment: fragmentNode,
|
|
615
|
+
fragmentOwner,
|
|
616
|
+
// $FlowFixMe[react-rule-unsafe-ref]
|
|
617
|
+
isMount: committedFragmentSelectorRef.current === false,
|
|
618
|
+
pendingOperations: pendingOperationsResult.pendingOperations,
|
|
619
|
+
});
|
|
588
620
|
throw pendingOperationsResult.promise;
|
|
589
621
|
}
|
|
590
622
|
}
|
|
@@ -608,15 +640,20 @@ hook useFragmentInternal_EXPERIMENTAL(
|
|
|
608
640
|
// or detaches (<Activity> going hidden), and then re-subscribes when the component
|
|
609
641
|
// re-attaches (<Activity> going visible). These cases wouldn't fire the
|
|
610
642
|
// "update" effect because the state and environment don't change.
|
|
611
|
-
const storeSubscriptionRef = useRef<
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
643
|
+
const storeSubscriptionRef = useRef<
|
|
644
|
+
| {
|
|
645
|
+
kind: 'initialized',
|
|
646
|
+
dispose: () => void,
|
|
647
|
+
selector: ?ReaderSelector,
|
|
648
|
+
environment: IEnvironment,
|
|
649
|
+
}
|
|
650
|
+
| {kind: 'missed-updates'}
|
|
651
|
+
| {kind: 'uninitialized'},
|
|
652
|
+
>({kind: 'uninitialized'});
|
|
616
653
|
// $FlowFixMe[react-rule-hook] - the condition is static
|
|
617
654
|
useEffect(() => {
|
|
618
655
|
const storeSubscription = storeSubscriptionRef.current;
|
|
619
|
-
if (storeSubscription
|
|
656
|
+
if (storeSubscription.kind === 'initialized') {
|
|
620
657
|
if (
|
|
621
658
|
state.environment === storeSubscription.environment &&
|
|
622
659
|
state.selector === storeSubscription.selector
|
|
@@ -626,6 +663,7 @@ hook useFragmentInternal_EXPERIMENTAL(
|
|
|
626
663
|
} else {
|
|
627
664
|
// The selector has changed, so we need to dispose of the previous subscription
|
|
628
665
|
storeSubscription.dispose();
|
|
666
|
+
storeSubscriptionRef.current = {kind: 'uninitialized'};
|
|
629
667
|
}
|
|
630
668
|
}
|
|
631
669
|
if (state.kind === 'bailout') {
|
|
@@ -650,7 +688,11 @@ hook useFragmentInternal_EXPERIMENTAL(
|
|
|
650
688
|
// to using the latest snapshot to subscribe.
|
|
651
689
|
if (didMissUpdates) {
|
|
652
690
|
setState(updatedState);
|
|
691
|
+
storeSubscriptionRef.current = {kind: 'missed-updates'};
|
|
653
692
|
// We missed updates, we're going to render again anyway so wait until then to subscribe
|
|
693
|
+
// Setting the ref to kind: missed-updates ensures the second useEffect (simulating the
|
|
694
|
+
// setup/teardown part of the crud effect) will not set up the subscription w the stale
|
|
695
|
+
// state
|
|
654
696
|
return;
|
|
655
697
|
}
|
|
656
698
|
stateForSubscription = updatedState;
|
|
@@ -662,23 +704,30 @@ hook useFragmentInternal_EXPERIMENTAL(
|
|
|
662
704
|
);
|
|
663
705
|
storeSubscriptionRef.current = {
|
|
664
706
|
dispose,
|
|
665
|
-
selector: state.selector,
|
|
666
707
|
environment: state.environment,
|
|
708
|
+
kind: 'initialized',
|
|
709
|
+
selector: state.selector,
|
|
667
710
|
};
|
|
668
711
|
}, [state]);
|
|
669
712
|
// $FlowFixMe[react-rule-hook] - the condition is static
|
|
670
713
|
useEffect(() => {
|
|
671
|
-
if (
|
|
714
|
+
if (
|
|
715
|
+
storeSubscriptionRef.current.kind === 'uninitialized' &&
|
|
716
|
+
state.kind !== 'bailout'
|
|
717
|
+
) {
|
|
672
718
|
const dispose = subscribeToSnapshot(state.environment, state, setState);
|
|
673
719
|
storeSubscriptionRef.current = {
|
|
674
720
|
dispose,
|
|
675
|
-
selector: state.selector,
|
|
676
721
|
environment: state.environment,
|
|
722
|
+
kind: 'initialized',
|
|
723
|
+
selector: state.selector,
|
|
677
724
|
};
|
|
678
725
|
}
|
|
679
726
|
return () => {
|
|
680
|
-
storeSubscriptionRef.current
|
|
681
|
-
|
|
727
|
+
if (storeSubscriptionRef.current.kind === 'initialized') {
|
|
728
|
+
storeSubscriptionRef.current.dispose();
|
|
729
|
+
}
|
|
730
|
+
storeSubscriptionRef.current = {kind: 'uninitialized'};
|
|
682
731
|
};
|
|
683
732
|
// NOTE: this intentionally has no dependencies, see above comment about
|
|
684
733
|
// simulating a CRUD effect
|
|
@@ -747,7 +796,7 @@ hook useFragmentInternal_EXPERIMENTAL(
|
|
|
747
796
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
748
797
|
// $FlowFixMe[react-rule-hook]
|
|
749
798
|
// $FlowFixMe[react-rule-hook-conditional]
|
|
750
|
-
useDebugValue({fragment: fragmentNode.name
|
|
799
|
+
useDebugValue({data, fragment: fragmentNode.name});
|
|
751
800
|
}
|
|
752
801
|
|
|
753
802
|
return data;
|
|
@@ -25,7 +25,7 @@ const {useEffect, useState, useMemo} = React;
|
|
|
25
25
|
|
|
26
26
|
hook useIsOperationNodeActive(
|
|
27
27
|
fragmentNode: ReaderFragment,
|
|
28
|
-
fragmentRef:
|
|
28
|
+
fragmentRef: unknown,
|
|
29
29
|
): boolean {
|
|
30
30
|
const environment = useRelayEnvironment();
|
|
31
31
|
const observable = useMemo(() => {
|
|
@@ -18,7 +18,7 @@ const useStaticFragmentNodeWarning = require('./useStaticFragmentNodeWarning');
|
|
|
18
18
|
const {getFragment} = require('relay-runtime');
|
|
19
19
|
|
|
20
20
|
hook useIsParentQueryActive<
|
|
21
|
-
TKey
|
|
21
|
+
TKey extends ?{+$data?: unknown, +$fragmentSpreads: FragmentType, ...},
|
|
22
22
|
>(
|
|
23
23
|
fragmentInput: GraphQLTaggedNode,
|
|
24
24
|
fragmentRef: TKey,
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
'use strict';
|
|
13
13
|
|
|
14
|
+
import type {LazyLoadQueryNodeParamsWithQuery} from './useLazyLoadQueryNode';
|
|
14
15
|
import type {
|
|
15
16
|
CacheConfig,
|
|
16
17
|
FetchPolicy,
|
|
@@ -29,7 +30,10 @@ const {
|
|
|
29
30
|
// This separate type export is only needed as long as we are injecting
|
|
30
31
|
// a separate hooks implementation in ./HooksImplementation -- it can
|
|
31
32
|
// be removed after we stop doing that.
|
|
32
|
-
export type UseLazyLoadQueryHookType = hook <
|
|
33
|
+
export type UseLazyLoadQueryHookType = hook <
|
|
34
|
+
TVariables extends Variables,
|
|
35
|
+
TData,
|
|
36
|
+
>(
|
|
33
37
|
gqlQuery: Query<TVariables, TData>,
|
|
34
38
|
variables: TVariables,
|
|
35
39
|
options?: Options,
|
|
@@ -85,7 +89,7 @@ type Options = {
|
|
|
85
89
|
* @returns - `data`: Object that contains data which has been read out from the Relay store; the object matches the shape of specified query.
|
|
86
90
|
* - The Flow type for data will also match this shape, and contain types derived from the GraphQL Schema. For example, the type of `data` above is: `{| user: ?{| name: ?string |} |}`.
|
|
87
91
|
*/
|
|
88
|
-
hook useLazyLoadQuery<TVariables
|
|
92
|
+
hook useLazyLoadQuery<TVariables extends Variables, TData>(
|
|
89
93
|
/**
|
|
90
94
|
* GraphQL query specified using a `graphql` template literal.
|
|
91
95
|
*/
|
|
@@ -108,7 +112,10 @@ hook useLazyLoadQuery<TVariables: Variables, TData>(
|
|
|
108
112
|
? options.networkCacheConfig
|
|
109
113
|
: {force: true},
|
|
110
114
|
);
|
|
111
|
-
const data = useLazyLoadQueryNode
|
|
115
|
+
const data = useLazyLoadQueryNode<
|
|
116
|
+
$FlowFixMe,
|
|
117
|
+
LazyLoadQueryNodeParamsWithQuery,
|
|
118
|
+
>({
|
|
112
119
|
componentDisplayName: 'useLazyLoadQuery()',
|
|
113
120
|
fetchKey: options?.fetchKey,
|
|
114
121
|
fetchObservable: fetchQuery(environment, query),
|