react-relay 16.0.0 → 16.2.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/ReactRelayTypes.js.flow +1 -0
- package/hooks.js +1 -1
- package/hooks.js.flow +1 -1
- package/index.js +1 -1
- package/index.js.flow +1 -1
- package/legacy.js +1 -1
- package/lib/relay-hooks/HooksImplementation.js +1 -1
- package/lib/relay-hooks/SuspenseResource.js +7 -4
- package/lib/relay-hooks/{react-cache/readFragmentInternal_REACT_CACHE.js → experimental/readFragmentInternal_EXPERIMENTAL.js} +4 -4
- package/lib/relay-hooks/{react-cache/useFragmentInternal_REACT_CACHE.js → experimental/useFragmentInternal_EXPERIMENTAL.js} +63 -29
- package/lib/relay-hooks/{react-cache/useFragment_REACT_CACHE.js → experimental/useFragment_EXPERIMENTAL.js} +1 -1
- package/lib/relay-hooks/{react-cache/usePaginationFragment_REACT_CACHE.js → experimental/usePaginationFragment_EXPERIMENTAL.js} +1 -1
- package/lib/relay-hooks/{react-cache/useRefetchableFragmentInternal_REACT_CACHE.js → experimental/useRefetchableFragmentInternal_EXPERIMENTAL.js} +2 -2
- package/lib/relay-hooks/{react-cache/useRefetchableFragment_REACT_CACHE.js → experimental/useRefetchableFragment_EXPERIMENTAL.js} +1 -1
- package/lib/relay-hooks/{FragmentResource.js → legacy/FragmentResource.js} +7 -6
- package/lib/relay-hooks/{useBlockingPaginationFragment.js → legacy/useBlockingPaginationFragment.js} +2 -2
- package/lib/relay-hooks/{useFragmentNode.js → legacy/useFragmentNode.js} +2 -2
- package/lib/relay-hooks/{useRefetchableFragmentNode.js → legacy/useRefetchableFragmentNode.js} +8 -8
- package/lib/relay-hooks/useFragment.js +1 -1
- package/lib/relay-hooks/useLazyLoadQueryNode.js +13 -3
- package/lib/relay-hooks/usePaginationFragment.js +1 -1
- package/lib/relay-hooks/useRefetchableFragment.js +1 -1
- 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/EntryPointTypes.flow.js.flow +25 -33
- package/relay-hooks/HooksImplementation.js.flow +3 -1
- package/relay-hooks/NestedRelayEntryPointBuilderUtils.js.flow +5 -11
- package/relay-hooks/SuspenseResource.js.flow +11 -8
- package/relay-hooks/__flowtests__/useBlockingPaginationFragment-flowtest.js.flow +1 -1
- package/relay-hooks/{react-cache/readFragmentInternal_REACT_CACHE.js.flow → experimental/readFragmentInternal_EXPERIMENTAL.js.flow} +4 -2
- package/relay-hooks/{react-cache/useFragmentInternal_REACT_CACHE.js.flow → experimental/useFragmentInternal_EXPERIMENTAL.js.flow} +61 -18
- package/relay-hooks/{react-cache/useFragment_REACT_CACHE.js.flow → experimental/useFragment_EXPERIMENTAL.js.flow} +10 -4
- package/relay-hooks/{react-cache/usePaginationFragment_REACT_CACHE.js.flow → experimental/usePaginationFragment_EXPERIMENTAL.js.flow} +2 -2
- package/relay-hooks/{react-cache/useRefetchableFragmentInternal_REACT_CACHE.js.flow → experimental/useRefetchableFragmentInternal_EXPERIMENTAL.js.flow} +11 -11
- package/relay-hooks/{react-cache/useRefetchableFragment_REACT_CACHE.js.flow → experimental/useRefetchableFragment_EXPERIMENTAL.js.flow} +1 -1
- package/relay-hooks/{FragmentResource.js.flow → legacy/FragmentResource.js.flow} +8 -5
- package/relay-hooks/{useBlockingPaginationFragment.js.flow → legacy/useBlockingPaginationFragment.js.flow} +13 -18
- package/relay-hooks/{useFragmentNode.js.flow → legacy/useFragmentNode.js.flow} +2 -2
- package/relay-hooks/{useRefetchableFragmentNode.js.flow → legacy/useRefetchableFragmentNode.js.flow} +12 -14
- package/relay-hooks/loadQuery.js.flow +1 -1
- package/relay-hooks/useFragment.js.flow +10 -4
- package/relay-hooks/useLazyLoadQueryNode.js.flow +18 -2
- package/relay-hooks/usePaginationFragment.js.flow +7 -9
- package/relay-hooks/useRefetchableFragment.js.flow +15 -18
- package/lib/relay-hooks/react-cache/RelayReactCache.js +0 -20
- package/lib/relay-hooks/react-cache/getQueryResultOrFetchQuery_REACT_CACHE.js +0 -255
- package/lib/relay-hooks/react-cache/useLazyLoadQuery_REACT_CACHE.js +0 -33
- package/lib/relay-hooks/react-cache/usePreloadedQuery_REACT_CACHE.js +0 -81
- 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
@@ -31,7 +31,7 @@ const useRelayEnvironment = require('../useRelayEnvironment');
|
|
31
31
|
const invariant = require('invariant');
|
32
32
|
const {useDebugValue, useEffect, useMemo, useRef, useState} = require('react');
|
33
33
|
const {
|
34
|
-
__internal: {fetchQuery: fetchQueryInternal},
|
34
|
+
__internal: {fetchQuery: fetchQueryInternal, getPromiseForActiveRequest},
|
35
35
|
RelayFeatureFlags,
|
36
36
|
areEqualSelectors,
|
37
37
|
createOperationDescriptor,
|
@@ -117,6 +117,7 @@ function handlePotentialSnapshotErrorsForState(
|
|
117
117
|
environment,
|
118
118
|
state.snapshot.missingRequiredFields,
|
119
119
|
state.snapshot.relayResolverErrors,
|
120
|
+
state.snapshot.errorResponseFields,
|
120
121
|
);
|
121
122
|
} else if (state.kind === 'plural') {
|
122
123
|
for (const snapshot of state.snapshots) {
|
@@ -124,6 +125,7 @@ function handlePotentialSnapshotErrorsForState(
|
|
124
125
|
environment,
|
125
126
|
snapshot.missingRequiredFields,
|
126
127
|
snapshot.relayResolverErrors,
|
128
|
+
snapshot.errorResponseFields,
|
127
129
|
);
|
128
130
|
}
|
129
131
|
}
|
@@ -162,6 +164,7 @@ function handleMissedUpdates(
|
|
162
164
|
selector: currentSnapshot.selector,
|
163
165
|
missingRequiredFields: currentSnapshot.missingRequiredFields,
|
164
166
|
relayResolverErrors: currentSnapshot.relayResolverErrors,
|
167
|
+
errorResponseFields: currentSnapshot.errorResponseFields,
|
165
168
|
};
|
166
169
|
return [
|
167
170
|
updatedData !== state.snapshot.data,
|
@@ -187,6 +190,7 @@ function handleMissedUpdates(
|
|
187
190
|
selector: currentSnapshot.selector,
|
188
191
|
missingRequiredFields: currentSnapshot.missingRequiredFields,
|
189
192
|
relayResolverErrors: currentSnapshot.relayResolverErrors,
|
193
|
+
errorResponseFields: currentSnapshot.errorResponseFields,
|
190
194
|
};
|
191
195
|
if (updatedData !== snapshot.data) {
|
192
196
|
didMissUpdates = true;
|
@@ -214,7 +218,7 @@ function handleMissingClientEdge(
|
|
214
218
|
parentFragmentRef: mixed,
|
215
219
|
missingClientEdgeRequestInfo: MissingClientEdgeRequestInfo,
|
216
220
|
queryOptions?: FragmentQueryOptions,
|
217
|
-
): QueryResult {
|
221
|
+
): [QueryResult, ?Promise<mixed>] {
|
218
222
|
const originalVariables = getVariablesFromFragment(
|
219
223
|
parentFragmentNode,
|
220
224
|
parentFragmentRef,
|
@@ -233,17 +237,23 @@ function handleMissingClientEdge(
|
|
233
237
|
// according to the component mount/suspense cycle; QueryResource
|
234
238
|
// already handles this by itself.
|
235
239
|
const QueryResource = getQueryResourceForEnvironment(environment);
|
236
|
-
|
240
|
+
const queryResult = QueryResource.prepare(
|
237
241
|
queryOperationDescriptor,
|
238
242
|
fetchQueryInternal(environment, queryOperationDescriptor),
|
239
243
|
queryOptions?.fetchPolicy,
|
240
244
|
);
|
245
|
+
|
246
|
+
return [
|
247
|
+
queryResult,
|
248
|
+
getPromiseForActiveRequest(environment, queryOperationDescriptor.request),
|
249
|
+
];
|
241
250
|
}
|
242
251
|
|
243
252
|
function subscribeToSnapshot(
|
244
253
|
environment: IEnvironment,
|
245
254
|
state: FragmentState,
|
246
255
|
setState: StateUpdaterFunction<FragmentState>,
|
256
|
+
hasPendingStateChanges: {current: boolean},
|
247
257
|
): () => void {
|
248
258
|
if (state.kind === 'bailout') {
|
249
259
|
return () => {};
|
@@ -264,11 +274,14 @@ function subscribeToSnapshot(
|
|
264
274
|
name: 'useFragment.subscription.missedUpdates',
|
265
275
|
hasDataChanges: dataChanged,
|
266
276
|
});
|
277
|
+
hasPendingStateChanges.current = dataChanged;
|
267
278
|
return dataChanged ? nextState : prevState;
|
268
279
|
} else {
|
269
280
|
return prevState;
|
270
281
|
}
|
271
282
|
}
|
283
|
+
|
284
|
+
hasPendingStateChanges.current = true;
|
272
285
|
return {
|
273
286
|
kind: 'singular',
|
274
287
|
snapshot: latestSnapshot,
|
@@ -297,6 +310,8 @@ function subscribeToSnapshot(
|
|
297
310
|
name: 'useFragment.subscription.missedUpdates',
|
298
311
|
hasDataChanges: dataChanged,
|
299
312
|
});
|
313
|
+
hasPendingStateChanges.current =
|
314
|
+
hasPendingStateChanges.current || dataChanged;
|
300
315
|
return dataChanged ? nextState : prevState;
|
301
316
|
} else {
|
302
317
|
return prevState;
|
@@ -304,6 +319,7 @@ function subscribeToSnapshot(
|
|
304
319
|
}
|
305
320
|
const updated = [...prevState.snapshots];
|
306
321
|
updated[index] = latestSnapshot;
|
322
|
+
hasPendingStateChanges.current = true;
|
307
323
|
return {
|
308
324
|
kind: 'plural',
|
309
325
|
snapshots: updated,
|
@@ -344,7 +360,7 @@ function getFragmentState(
|
|
344
360
|
}
|
345
361
|
|
346
362
|
// fragmentNode cannot change during the lifetime of the component, though fragmentRef may change.
|
347
|
-
function
|
363
|
+
function useFragmentInternal_EXPERIMENTAL(
|
348
364
|
fragmentNode: ReaderFragment,
|
349
365
|
fragmentRef: mixed,
|
350
366
|
hookDisplayName: string,
|
@@ -435,7 +451,7 @@ function useFragmentInternal_REACT_CACHE(
|
|
435
451
|
// The purpose of this is to detect whether we have ever committed, because we
|
436
452
|
// don't suspend on store updates, only when the component either is first trying
|
437
453
|
// to mount or when the our selector changes. The selector change in particular is
|
438
|
-
// how we suspend for pagination and
|
454
|
+
// how we suspend for pagination and refetch. Also, fragment selector can be null
|
439
455
|
// or undefined, so we use false as a special value to distinguish from all fragment
|
440
456
|
// selectors; false means that the component hasn't mounted yet.
|
441
457
|
const committedFragmentSelectorRef = useRef<false | ?ReaderSelector>(false);
|
@@ -450,27 +466,34 @@ function useFragmentInternal_REACT_CACHE(
|
|
450
466
|
// a static (constant) property of the fragment. In practice, this effect will
|
451
467
|
// always or never run for a given invocation of this hook.
|
452
468
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
453
|
-
const clientEdgeQueries = useMemo(() => {
|
469
|
+
const [clientEdgeQueries, activeRequestPromises] = useMemo(() => {
|
454
470
|
const missingClientEdges = getMissingClientEdges(state);
|
455
471
|
// eslint-disable-next-line no-shadow
|
456
472
|
let clientEdgeQueries;
|
473
|
+
const activeRequestPromises = [];
|
457
474
|
if (missingClientEdges?.length) {
|
458
475
|
clientEdgeQueries = ([]: Array<QueryResult>);
|
459
476
|
for (const edge of missingClientEdges) {
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
queryOptions,
|
467
|
-
),
|
477
|
+
const [queryResult, requestPromise] = handleMissingClientEdge(
|
478
|
+
environment,
|
479
|
+
fragmentNode,
|
480
|
+
fragmentRef,
|
481
|
+
edge,
|
482
|
+
queryOptions,
|
468
483
|
);
|
484
|
+
clientEdgeQueries.push(queryResult);
|
485
|
+
if (requestPromise != null) {
|
486
|
+
activeRequestPromises.push(requestPromise);
|
487
|
+
}
|
469
488
|
}
|
470
489
|
}
|
471
|
-
return clientEdgeQueries;
|
490
|
+
return [clientEdgeQueries, activeRequestPromises];
|
472
491
|
}, [state, environment, fragmentNode, fragmentRef, queryOptions]);
|
473
492
|
|
493
|
+
if (activeRequestPromises.length) {
|
494
|
+
throw Promise.all(activeRequestPromises);
|
495
|
+
}
|
496
|
+
|
474
497
|
// See above note
|
475
498
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
476
499
|
useEffect(() => {
|
@@ -505,6 +528,7 @@ function useFragmentInternal_REACT_CACHE(
|
|
505
528
|
// We only suspend when the component is first trying to mount or changing
|
506
529
|
// selectors, not if data becomes missing later:
|
507
530
|
if (
|
531
|
+
environment !== previousEnvironment ||
|
508
532
|
!committedFragmentSelectorRef.current ||
|
509
533
|
!areEqualSelectors(committedFragmentSelectorRef.current, fragmentSelector)
|
510
534
|
) {
|
@@ -528,6 +552,8 @@ function useFragmentInternal_REACT_CACHE(
|
|
528
552
|
// they're missing even though we are out of options for possibly fetching them:
|
529
553
|
handlePotentialSnapshotErrorsForState(environment, state);
|
530
554
|
|
555
|
+
const hasPendingStateChanges = useRef<boolean>(false);
|
556
|
+
|
531
557
|
useEffect(() => {
|
532
558
|
// Check for updates since the state was rendered
|
533
559
|
let currentState = subscribedState;
|
@@ -546,12 +572,29 @@ function useFragmentInternal_REACT_CACHE(
|
|
546
572
|
}
|
547
573
|
currentState = updatedState;
|
548
574
|
}
|
549
|
-
return subscribeToSnapshot(
|
575
|
+
return subscribeToSnapshot(
|
576
|
+
environment,
|
577
|
+
currentState,
|
578
|
+
setState,
|
579
|
+
hasPendingStateChanges,
|
580
|
+
);
|
550
581
|
}, [environment, subscribedState]);
|
551
582
|
|
583
|
+
if (hasPendingStateChanges.current) {
|
584
|
+
const updates = handleMissedUpdates(environment, state);
|
585
|
+
if (updates != null) {
|
586
|
+
const [hasStateUpdates, updatedState] = updates;
|
587
|
+
if (hasStateUpdates) {
|
588
|
+
setState(updatedState);
|
589
|
+
state = updatedState;
|
590
|
+
}
|
591
|
+
}
|
592
|
+
hasPendingStateChanges.current = false;
|
593
|
+
}
|
594
|
+
|
552
595
|
let data: ?SelectorData | Array<?SelectorData>;
|
553
596
|
if (isPlural) {
|
554
|
-
// Plural fragments require allocating an array of the
|
597
|
+
// Plural fragments require allocating an array of the snapshot data values,
|
555
598
|
// which has to be memoized to avoid triggering downstream re-renders.
|
556
599
|
//
|
557
600
|
// Note that isPlural is a constant property of the fragment and does not change
|
@@ -614,4 +657,4 @@ function useFragmentInternal_REACT_CACHE(
|
|
614
657
|
return data;
|
615
658
|
}
|
616
659
|
|
617
|
-
module.exports =
|
660
|
+
module.exports = useFragmentInternal_EXPERIMENTAL;
|
@@ -15,7 +15,7 @@ import type {Fragment, FragmentType, GraphQLTaggedNode} from 'relay-runtime';
|
|
15
15
|
|
16
16
|
const {useTrackLoadQueryInRender} = require('../loadQuery');
|
17
17
|
const useStaticFragmentNodeWarning = require('../useStaticFragmentNodeWarning');
|
18
|
-
const useFragmentInternal = require('./
|
18
|
+
const useFragmentInternal = require('./useFragmentInternal_EXPERIMENTAL');
|
19
19
|
const {useDebugValue} = require('react');
|
20
20
|
const {getFragment} = require('relay-runtime');
|
21
21
|
|
@@ -30,17 +30,23 @@ declare function useFragment<TFragmentType: FragmentType, TData>(
|
|
30
30
|
key: HasSpread<TFragmentType>,
|
31
31
|
): TData;
|
32
32
|
|
33
|
+
// if the key is nullable, return nullable value
|
34
|
+
declare function useFragment<TFragmentType: FragmentType, TData>(
|
35
|
+
fragment: Fragment<TFragmentType, TData>,
|
36
|
+
key: ?HasSpread<TFragmentType>,
|
37
|
+
): ?TData;
|
38
|
+
|
33
39
|
// if the key is a non-nullable array of keys, return non-nullable array
|
34
40
|
declare function useFragment<TFragmentType: FragmentType, TData>(
|
35
41
|
fragment: Fragment<TFragmentType, TData>,
|
36
42
|
key: $ReadOnlyArray<HasSpread<TFragmentType>>,
|
37
43
|
): TData;
|
38
44
|
|
39
|
-
// if the key is
|
45
|
+
// if the key is a nullable array of keys, return nullable array
|
40
46
|
declare function useFragment<TFragmentType: FragmentType, TData>(
|
41
47
|
fragment: Fragment<TFragmentType, TData>,
|
42
|
-
key:
|
43
|
-
):
|
48
|
+
key: ?$ReadOnlyArray<HasSpread<TFragmentType>>,
|
49
|
+
): ?TData;
|
44
50
|
|
45
51
|
function useFragment(fragment: GraphQLTaggedNode, key: mixed): mixed {
|
46
52
|
// We need to use this hook in order to be able to track if
|
@@ -13,7 +13,7 @@
|
|
13
13
|
|
14
14
|
import type {LoadMoreFn, UseLoadMoreFunctionArgs} from '../useLoadMoreFunction';
|
15
15
|
import type {ReturnType} from '../usePaginationFragment';
|
16
|
-
import type {Options} from './
|
16
|
+
import type {Options} from './useRefetchableFragmentInternal_EXPERIMENTAL';
|
17
17
|
import type {
|
18
18
|
FragmentType,
|
19
19
|
GraphQLResponse,
|
@@ -25,7 +25,7 @@ import type {
|
|
25
25
|
const useLoadMoreFunction = require('../useLoadMoreFunction');
|
26
26
|
const useRelayEnvironment = require('../useRelayEnvironment');
|
27
27
|
const useStaticFragmentNodeWarning = require('../useStaticFragmentNodeWarning');
|
28
|
-
const useRefetchableFragmentInternal = require('./
|
28
|
+
const useRefetchableFragmentInternal = require('./useRefetchableFragmentInternal_EXPERIMENTAL');
|
29
29
|
const {useCallback, useDebugValue, useState} = require('react');
|
30
30
|
const {
|
31
31
|
getFragment,
|
@@ -31,8 +31,8 @@ const {getQueryResourceForEnvironment} = require('../QueryResource');
|
|
31
31
|
const useIsMountedRef = require('../useIsMountedRef');
|
32
32
|
const useQueryLoader = require('../useQueryLoader');
|
33
33
|
const useRelayEnvironment = require('../useRelayEnvironment');
|
34
|
-
const readFragmentInternal = require('./
|
35
|
-
const useFragmentInternal = require('./
|
34
|
+
const readFragmentInternal = require('./readFragmentInternal_EXPERIMENTAL');
|
35
|
+
const useFragmentInternal = require('./useFragmentInternal_EXPERIMENTAL');
|
36
36
|
const invariant = require('invariant');
|
37
37
|
const {useCallback, useContext, useReducer} = require('react');
|
38
38
|
const {
|
@@ -55,16 +55,13 @@ export type RefetchFn<
|
|
55
55
|
// /nullable/.
|
56
56
|
// - Or, expects /a subset/ of the query variables if the provided key type is
|
57
57
|
// /non-null/.
|
58
|
-
// prettier-ignore
|
59
58
|
export type RefetchFnDynamic<
|
60
59
|
TQuery: OperationType,
|
61
|
-
TKey: ?{
|
60
|
+
TKey: ?{+$data?: mixed, ...},
|
62
61
|
TOptions = Options,
|
63
|
-
> =
|
64
|
-
|
65
|
-
|
66
|
-
TKey
|
67
|
-
>;
|
62
|
+
> = [TKey] extends [{+$data?: mixed, ...}]
|
63
|
+
? RefetchFnInexact<TQuery, TOptions>
|
64
|
+
: RefetchFnExact<TQuery, TOptions>;
|
68
65
|
|
69
66
|
export type ReturnType<
|
70
67
|
TQuery: OperationType,
|
@@ -353,6 +350,7 @@ function useRefetchableFragmentNode<
|
|
353
350
|
return {
|
354
351
|
fragmentData,
|
355
352
|
fragmentRef,
|
353
|
+
// $FlowFixMe[incompatible-return] RefetchFn not compatible with RefetchFnDynamic
|
356
354
|
refetch,
|
357
355
|
};
|
358
356
|
}
|
@@ -481,11 +479,13 @@ function useRefetchFunction<TQuery: OperationType>(
|
|
481
479
|
const refetchQuery = createOperationDescriptor(
|
482
480
|
refetchableRequest,
|
483
481
|
refetchVariables,
|
484
|
-
{
|
482
|
+
{
|
483
|
+
force: true,
|
484
|
+
},
|
485
485
|
);
|
486
486
|
|
487
487
|
// We call loadQuery which will start a network request if necessary
|
488
|
-
// and update the
|
488
|
+
// and update the queryRef from useQueryLoader.
|
489
489
|
// Note the following:
|
490
490
|
// - loadQuery will dispose of any previously refetched queries.
|
491
491
|
// - We use the variables extracted off the OperationDescriptor
|
@@ -15,7 +15,7 @@ import type {ReturnType} from '../useRefetchableFragment';
|
|
15
15
|
import type {FragmentType, RefetchableFragment, Variables} from 'relay-runtime';
|
16
16
|
|
17
17
|
const useStaticFragmentNodeWarning = require('../useStaticFragmentNodeWarning');
|
18
|
-
const useRefetchableFragmentInternal = require('./
|
18
|
+
const useRefetchableFragmentInternal = require('./useRefetchableFragmentInternal_EXPERIMENTAL');
|
19
19
|
const {useDebugValue} = require('react');
|
20
20
|
const {getFragment} = require('relay-runtime');
|
21
21
|
|
@@ -11,8 +11,8 @@
|
|
11
11
|
|
12
12
|
'use strict';
|
13
13
|
|
14
|
-
import type {Cache} from '
|
15
|
-
import type {QueryResource, QueryResult} from '
|
14
|
+
import type {Cache} from '../LRUCache';
|
15
|
+
import type {QueryResource, QueryResult} from '../QueryResource';
|
16
16
|
import type {
|
17
17
|
ConcreteRequest,
|
18
18
|
DataID,
|
@@ -24,9 +24,9 @@ import type {
|
|
24
24
|
} from 'relay-runtime';
|
25
25
|
import type {MissingLiveResolverField} from 'relay-runtime/store/RelayStoreTypes';
|
26
26
|
|
27
|
-
const LRUCache = require('
|
28
|
-
const {getQueryResourceForEnvironment} = require('
|
29
|
-
const SuspenseResource = require('
|
27
|
+
const LRUCache = require('../LRUCache');
|
28
|
+
const {getQueryResourceForEnvironment} = require('../QueryResource');
|
29
|
+
const SuspenseResource = require('../SuspenseResource');
|
30
30
|
const invariant = require('invariant');
|
31
31
|
const {
|
32
32
|
__internal: {fetchQuery, getPromiseForActiveRequest},
|
@@ -566,6 +566,7 @@ class FragmentResourceImpl {
|
|
566
566
|
this._environment,
|
567
567
|
s.missingRequiredFields,
|
568
568
|
s.relayResolverErrors,
|
569
|
+
s.errorResponseFields,
|
569
570
|
);
|
570
571
|
});
|
571
572
|
} else {
|
@@ -573,6 +574,7 @@ class FragmentResourceImpl {
|
|
573
574
|
this._environment,
|
574
575
|
snapshot.missingRequiredFields,
|
575
576
|
snapshot.relayResolverErrors,
|
577
|
+
snapshot.errorResponseFields,
|
576
578
|
);
|
577
579
|
}
|
578
580
|
}
|
@@ -776,6 +778,7 @@ class FragmentResourceImpl {
|
|
776
778
|
selector: currentSnapshot.selector,
|
777
779
|
missingRequiredFields: currentSnapshot.missingRequiredFields,
|
778
780
|
relayResolverErrors: currentSnapshot.relayResolverErrors,
|
781
|
+
errorResponseFields: currentSnapshot.errorResponseFields,
|
779
782
|
};
|
780
783
|
if (updatedData !== renderData) {
|
781
784
|
const result = getFragmentResult(
|
@@ -11,9 +11,9 @@
|
|
11
11
|
|
12
12
|
'use strict';
|
13
13
|
|
14
|
-
import type {
|
15
|
-
import type {LoadMoreFn, UseLoadMoreFunctionArgs} from './useLoadMoreFunction';
|
14
|
+
import type {LoadMoreFn, UseLoadMoreFunctionArgs} from '../useLoadMoreFunction';
|
16
15
|
import type {Options} from './useRefetchableFragmentNode';
|
16
|
+
import type {RefetchableFragment} from 'relay-runtime';
|
17
17
|
import type {
|
18
18
|
Disposable,
|
19
19
|
FragmentType,
|
@@ -22,9 +22,9 @@ import type {
|
|
22
22
|
Variables,
|
23
23
|
} from 'relay-runtime';
|
24
24
|
|
25
|
-
const useLoadMoreFunction = require('
|
25
|
+
const useLoadMoreFunction = require('../useLoadMoreFunction');
|
26
|
+
const useStaticFragmentNodeWarning = require('../useStaticFragmentNodeWarning');
|
26
27
|
const useRefetchableFragmentNode = require('./useRefetchableFragmentNode');
|
27
|
-
const useStaticFragmentNodeWarning = require('./useStaticFragmentNodeWarning');
|
28
28
|
const invariant = require('invariant');
|
29
29
|
const {useCallback, useEffect, useRef, useState} = require('react');
|
30
30
|
const {
|
@@ -34,15 +34,12 @@ const {
|
|
34
34
|
} = require('relay-runtime');
|
35
35
|
|
36
36
|
type RefetchVariables<TVariables, TKey> =
|
37
|
-
// NOTE: This
|
37
|
+
// NOTE: This type ensures that the type of the variables is either:
|
38
38
|
// - nullable if the provided ref type is non-nullable
|
39
39
|
// - non-nullable if the provided ref type is nullable, and the caller need to provide the full set of variables
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
& (<TFragmentType>(?{ +$fragmentSpreads: TFragmentType, ... }) => TVariables),
|
44
|
-
TKey,
|
45
|
-
>;
|
40
|
+
[+key: TKey] extends [+key: {+$fragmentSpreads: mixed, ...}]
|
41
|
+
? Partial<TVariables>
|
42
|
+
: TVariables;
|
46
43
|
|
47
44
|
type RefetchFnBase<TVars, TOptions> = (
|
48
45
|
vars: TVars,
|
@@ -55,15 +52,12 @@ type RefetchFn<TVariables, TKey, TOptions = Options> = RefetchFnBase<
|
|
55
52
|
>;
|
56
53
|
|
57
54
|
type ReturnType<TVariables, TData, TKey> = {
|
58
|
-
// NOTE: This
|
55
|
+
// NOTE: This rtpw ensures that the type of the returned data is either:
|
59
56
|
// - nullable if the provided ref type is nullable
|
60
57
|
// - non-nullable if the provided ref type is non-nullable
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
& (<TFragmentType>(?{ +$fragmentSpreads: TFragmentType, ... }) => ?TData),
|
65
|
-
TKey,
|
66
|
-
>,
|
58
|
+
data: [+key: TKey] extends [+key: {+$fragmentSpreads: mixed, ...}]
|
59
|
+
? TData
|
60
|
+
: ?TData,
|
67
61
|
loadNext: LoadMoreFn<TVariables>,
|
68
62
|
loadPrevious: LoadMoreFn<TVariables>,
|
69
63
|
hasNext: boolean,
|
@@ -162,6 +156,7 @@ function useBlockingPaginationFragment<
|
|
162
156
|
|
163
157
|
return {
|
164
158
|
// $FlowFixMe[incompatible-cast]
|
159
|
+
// $FlowFixMe[incompatible-return]
|
165
160
|
data: (fragmentData: TData),
|
166
161
|
loadNext,
|
167
162
|
loadPrevious,
|
@@ -13,9 +13,9 @@
|
|
13
13
|
|
14
14
|
import type {ReaderFragment} from 'relay-runtime';
|
15
15
|
|
16
|
+
const useRelayEnvironment = require('../useRelayEnvironment');
|
17
|
+
const useUnsafeRef_DEPRECATED = require('../useUnsafeRef_DEPRECATED');
|
16
18
|
const {getFragmentResourceForEnvironment} = require('./FragmentResource');
|
17
|
-
const useRelayEnvironment = require('./useRelayEnvironment');
|
18
|
-
const useUnsafeRef_DEPRECATED = require('./useUnsafeRef_DEPRECATED');
|
19
19
|
const {useEffect, useState} = require('react');
|
20
20
|
const {RelayFeatureFlags, getFragmentIdentifier} = require('relay-runtime');
|
21
21
|
const warning = require('warning');
|
package/relay-hooks/{useRefetchableFragmentNode.js.flow → legacy/useRefetchableFragmentNode.js.flow}
RENAMED
@@ -11,8 +11,8 @@
|
|
11
11
|
|
12
12
|
'use strict';
|
13
13
|
|
14
|
-
import type {
|
15
|
-
import type {
|
14
|
+
import type {LoaderFn} from '../useQueryLoader';
|
15
|
+
import type {RefetchableIdentifierInfo} from 'relay-runtime';
|
16
16
|
import type {
|
17
17
|
ConcreteRequest,
|
18
18
|
Disposable,
|
@@ -26,13 +26,13 @@ import type {
|
|
26
26
|
VariablesOf,
|
27
27
|
} from 'relay-runtime';
|
28
28
|
|
29
|
+
const ProfilerContext = require('../ProfilerContext');
|
30
|
+
const {getQueryResourceForEnvironment} = require('../QueryResource');
|
31
|
+
const useIsMountedRef = require('../useIsMountedRef');
|
32
|
+
const useQueryLoader = require('../useQueryLoader');
|
33
|
+
const useRelayEnvironment = require('../useRelayEnvironment');
|
29
34
|
const {getFragmentResourceForEnvironment} = require('./FragmentResource');
|
30
|
-
const ProfilerContext = require('./ProfilerContext');
|
31
|
-
const {getQueryResourceForEnvironment} = require('./QueryResource');
|
32
35
|
const useFragmentNode = require('./useFragmentNode');
|
33
|
-
const useIsMountedRef = require('./useIsMountedRef');
|
34
|
-
const useQueryLoader = require('./useQueryLoader');
|
35
|
-
const useRelayEnvironment = require('./useRelayEnvironment');
|
36
36
|
const invariant = require('invariant');
|
37
37
|
const {useCallback, useContext, useReducer} = require('react');
|
38
38
|
const {
|
@@ -55,16 +55,13 @@ export type RefetchFn<
|
|
55
55
|
// /nullable/.
|
56
56
|
// - Or, expects /a subset/ of the query variables if the provided key type is
|
57
57
|
// /non-null/.
|
58
|
-
// prettier-ignore
|
59
58
|
export type RefetchFnDynamic<
|
60
59
|
TQuery: OperationType,
|
61
|
-
TKey: ?{
|
60
|
+
TKey: ?{+$data?: mixed, ...},
|
62
61
|
TOptions = Options,
|
63
|
-
> =
|
64
|
-
|
65
|
-
|
66
|
-
TKey
|
67
|
-
>;
|
62
|
+
> = [TKey] extends [{+$data?: mixed, ...}]
|
63
|
+
? RefetchFnInexact<TQuery, TOptions>
|
64
|
+
: RefetchFnExact<TQuery, TOptions>;
|
68
65
|
|
69
66
|
export type ReturnType<
|
70
67
|
TQuery: OperationType,
|
@@ -363,6 +360,7 @@ function useRefetchableFragmentNode<
|
|
363
360
|
return {
|
364
361
|
fragmentData,
|
365
362
|
fragmentRef,
|
363
|
+
// $FlowFixMe[incompatible-return] RefetchFn not compatible with RefetchFnDynamic
|
366
364
|
refetch,
|
367
365
|
disableStoreUpdates,
|
368
366
|
enableStoreUpdates,
|
@@ -62,7 +62,7 @@ type QueryType<T> = T extends Query<infer V, infer D, infer RR>
|
|
62
62
|
variables: V,
|
63
63
|
response: D,
|
64
64
|
rawResponse?: $NonMaybeType<RR>,
|
65
|
-
}
|
65
|
+
} // $FlowFixMe[deprecated-type]
|
66
66
|
: $Call<<T>(PreloadableConcreteRequest<T>) => T, T>;
|
67
67
|
|
68
68
|
declare function loadQuery<
|
@@ -14,8 +14,8 @@
|
|
14
14
|
import type {Fragment, FragmentType, GraphQLTaggedNode} from 'relay-runtime';
|
15
15
|
|
16
16
|
const HooksImplementation = require('./HooksImplementation');
|
17
|
+
const useFragmentNode = require('./legacy/useFragmentNode');
|
17
18
|
const {useTrackLoadQueryInRender} = require('./loadQuery');
|
18
|
-
const useFragmentNode = require('./useFragmentNode');
|
19
19
|
const useStaticFragmentNodeWarning = require('./useStaticFragmentNodeWarning');
|
20
20
|
const {useDebugValue} = require('react');
|
21
21
|
const {getFragment} = require('relay-runtime');
|
@@ -31,17 +31,23 @@ declare function useFragment<TFragmentType: FragmentType, TData>(
|
|
31
31
|
key: HasSpread<TFragmentType>,
|
32
32
|
): TData;
|
33
33
|
|
34
|
+
// if the key is nullable, return nullable value
|
35
|
+
declare function useFragment<TFragmentType: FragmentType, TData>(
|
36
|
+
fragment: Fragment<TFragmentType, TData>,
|
37
|
+
key: ?HasSpread<TFragmentType>,
|
38
|
+
): ?TData;
|
39
|
+
|
34
40
|
// if the key is a non-nullable array of keys, return non-nullable array
|
35
41
|
declare function useFragment<TFragmentType: FragmentType, TData>(
|
36
42
|
fragment: Fragment<TFragmentType, TData>,
|
37
43
|
key: $ReadOnlyArray<HasSpread<TFragmentType>>,
|
38
44
|
): TData;
|
39
45
|
|
40
|
-
// if the key is
|
46
|
+
// if the key is a nullable array of keys, return nullable array
|
41
47
|
declare function useFragment<TFragmentType: FragmentType, TData>(
|
42
48
|
fragment: Fragment<TFragmentType, TData>,
|
43
|
-
key:
|
44
|
-
):
|
49
|
+
key: ?$ReadOnlyArray<HasSpread<TFragmentType>>,
|
50
|
+
): ?TData;
|
45
51
|
|
46
52
|
function useFragment_LEGACY(fragment: GraphQLTaggedNode, key: mixed): mixed {
|
47
53
|
// We need to use this hook in order to be able to track if
|
@@ -19,14 +19,16 @@ import type {
|
|
19
19
|
OperationType,
|
20
20
|
RenderPolicy,
|
21
21
|
} from 'relay-runtime';
|
22
|
+
import type {ReaderFragment} from 'relay-runtime/util/ReaderNode';
|
22
23
|
|
24
|
+
const HooksImplementation = require('./HooksImplementation');
|
25
|
+
const useFragmentNode = require('./legacy/useFragmentNode');
|
23
26
|
const ProfilerContext = require('./ProfilerContext');
|
24
27
|
const {
|
25
28
|
getQueryCacheIdentifier,
|
26
29
|
getQueryResourceForEnvironment,
|
27
30
|
} = require('./QueryResource');
|
28
31
|
const useFetchTrackingRef = require('./useFetchTrackingRef');
|
29
|
-
const useFragmentNode = require('./useFragmentNode');
|
30
32
|
const useRelayEnvironment = require('./useRelayEnvironment');
|
31
33
|
const React = require('react');
|
32
34
|
|
@@ -125,7 +127,7 @@ function useLazyLoadQueryNode<TQuery: OperationType>({
|
|
125
127
|
});
|
126
128
|
|
127
129
|
const {fragmentNode, fragmentRef} = preparedQueryResult;
|
128
|
-
const
|
130
|
+
const data = useFragmentNodeImpl(
|
129
131
|
fragmentNode,
|
130
132
|
fragmentRef,
|
131
133
|
componentDisplayName,
|
@@ -133,4 +135,18 @@ function useLazyLoadQueryNode<TQuery: OperationType>({
|
|
133
135
|
return data;
|
134
136
|
}
|
135
137
|
|
138
|
+
function useFragmentNodeImpl(
|
139
|
+
fragment: ReaderFragment,
|
140
|
+
key: mixed,
|
141
|
+
componentDisplayName: string,
|
142
|
+
): mixed {
|
143
|
+
const impl = HooksImplementation.get();
|
144
|
+
if (impl && impl.useFragment__internal) {
|
145
|
+
return impl.useFragment__internal(fragment, key, componentDisplayName);
|
146
|
+
} else {
|
147
|
+
const {data} = useFragmentNode<mixed>(fragment, key, componentDisplayName);
|
148
|
+
return data;
|
149
|
+
}
|
150
|
+
}
|
151
|
+
|
136
152
|
module.exports = useLazyLoadQueryNode;
|