react-relay 13.1.1 → 14.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/ReactRelayContainerUtils.js.flow +0 -2
- package/ReactRelayContext.js +1 -1
- package/ReactRelayContext.js.flow +0 -2
- package/ReactRelayFragmentContainer.js.flow +7 -6
- package/ReactRelayFragmentMockRenderer.js.flow +0 -2
- package/ReactRelayLocalQueryRenderer.js.flow +1 -3
- package/ReactRelayPaginationContainer.js.flow +13 -10
- package/ReactRelayQueryFetcher.js.flow +10 -11
- package/ReactRelayQueryRenderer.js.flow +15 -16
- package/ReactRelayQueryRendererContext.js.flow +1 -3
- package/ReactRelayRefetchContainer.js.flow +10 -7
- package/ReactRelayTestMocker.js.flow +0 -2
- package/ReactRelayTypes.js.flow +6 -8
- package/RelayContext.js.flow +0 -2
- package/__flowtests__/ReactRelayFragmentContainer-flowtest.js.flow +2 -4
- package/__flowtests__/ReactRelayPaginationContainer-flowtest.js.flow +3 -5
- package/__flowtests__/ReactRelayRefetchContainer-flowtest.js.flow +3 -5
- package/__flowtests__/RelayModern-flowtest.js.flow +2 -4
- package/__flowtests__/RelayModernFlowtest_badref.graphql.js.flow +2 -4
- package/__flowtests__/RelayModernFlowtest_notref.graphql.js.flow +2 -4
- package/__flowtests__/RelayModernFlowtest_user.graphql.js.flow +2 -4
- package/__flowtests__/RelayModernFlowtest_users.graphql.js.flow +2 -4
- package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer.graphql.js.flow +2 -2
- package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer2.graphql.js.flow +2 -2
- package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtestQuery.graphql.js.flow +3 -3
- package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtest_viewer.graphql.js.flow +3 -3
- package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtestQuery.graphql.js.flow +3 -3
- package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtest_viewer.graphql.js.flow +3 -3
- package/__flowtests__/__generated__/RelayModernFlowtest_badref.graphql.js.flow +2 -2
- package/__flowtests__/__generated__/RelayModernFlowtest_notref.graphql.js.flow +2 -2
- package/__flowtests__/__generated__/RelayModernFlowtest_user.graphql.js.flow +2 -2
- package/__flowtests__/__generated__/RelayModernFlowtest_users.graphql.js.flow +2 -2
- package/assertFragmentMap.js.flow +0 -2
- package/buildReactRelayContainer.js.flow +2 -4
- package/getRootVariablesForFragments.js.flow +0 -2
- package/hooks.js +1 -1
- package/hooks.js.flow +0 -2
- package/index.js +1 -1
- package/index.js.flow +2 -2
- package/isRelayEnvironment.js.flow +0 -2
- package/jest-react/internalAct.js.flow +25 -9
- package/legacy.js +1 -1
- package/legacy.js.flow +0 -2
- package/lib/ReactRelayContainerUtils.js +0 -1
- package/lib/ReactRelayContext.js +0 -1
- package/lib/ReactRelayFragmentContainer.js +10 -9
- package/lib/ReactRelayFragmentMockRenderer.js +0 -1
- package/lib/ReactRelayLocalQueryRenderer.js +0 -1
- package/lib/ReactRelayPaginationContainer.js +14 -11
- package/lib/ReactRelayQueryFetcher.js +2 -2
- package/lib/ReactRelayQueryRenderer.js +2 -4
- package/lib/ReactRelayQueryRendererContext.js +0 -1
- package/lib/ReactRelayRefetchContainer.js +11 -14
- package/lib/ReactRelayTestMocker.js +1 -2
- package/lib/ReactRelayTypes.js +0 -1
- package/lib/RelayContext.js +0 -1
- package/lib/assertFragmentMap.js +0 -1
- package/lib/buildReactRelayContainer.js +1 -2
- package/lib/getRootVariablesForFragments.js +1 -2
- package/lib/hooks.js +0 -1
- package/lib/index.js +3 -1
- package/lib/isRelayEnvironment.js +0 -1
- package/lib/jest-react/internalAct.js +24 -4
- package/lib/legacy.js +0 -1
- package/lib/multi-actor/useRelayActorEnvironment.js +0 -1
- package/lib/readContext.js +2 -2
- package/lib/relay-hooks/EntryPointContainer.react.js +0 -1
- package/lib/relay-hooks/EntryPointTypes.flow.js +0 -1
- package/lib/relay-hooks/FragmentResource.js +68 -29
- package/lib/relay-hooks/HooksImplementation.js +29 -0
- package/lib/relay-hooks/InternalLogger.js +0 -1
- package/lib/relay-hooks/LRUCache.js +0 -1
- package/lib/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js +0 -1
- package/lib/relay-hooks/MatchContainer.js +2 -2
- package/lib/relay-hooks/ProfilerContext.js +0 -1
- package/lib/relay-hooks/QueryResource.js +5 -168
- package/lib/relay-hooks/RelayEnvironmentProvider.js +0 -1
- package/lib/relay-hooks/SuspenseResource.js +1 -2
- package/lib/relay-hooks/loadQuery.js +1 -1
- package/lib/relay-hooks/preloadQuery_DEPRECATED.js +8 -13
- package/lib/relay-hooks/prepareEntryPoint_DEPRECATED.js +0 -1
- package/lib/relay-hooks/react-cache/RelayReactCache.js +36 -0
- package/lib/relay-hooks/react-cache/getQueryResultOrFetchQuery_REACT_CACHE.js +344 -0
- package/lib/relay-hooks/react-cache/readFragmentInternal_REACT_CACHE.js +239 -0
- package/lib/relay-hooks/react-cache/useFragmentInternal_REACT_CACHE.js +598 -0
- package/lib/relay-hooks/react-cache/useFragment_REACT_CACHE.js +50 -0
- package/lib/relay-hooks/react-cache/useLazyLoadQuery_REACT_CACHE.js +55 -0
- package/lib/relay-hooks/react-cache/usePaginationFragment_REACT_CACHE.js +150 -0
- package/lib/relay-hooks/react-cache/usePreloadedQuery_REACT_CACHE.js +124 -0
- package/lib/relay-hooks/react-cache/useRefetchableFragmentInternal_REACT_CACHE.js +367 -0
- package/lib/relay-hooks/react-cache/useRefetchableFragment_REACT_CACHE.js +45 -0
- package/lib/relay-hooks/useBlockingPaginationFragment.js +4 -3
- package/lib/relay-hooks/useClientQuery.js +33 -0
- package/lib/relay-hooks/useEntryPointLoader.js +1 -2
- package/lib/relay-hooks/useFetchTrackingRef.js +0 -1
- package/lib/relay-hooks/useFragment.js +15 -2
- package/lib/relay-hooks/useFragmentNode.js +0 -1
- package/lib/relay-hooks/useIsMountedRef.js +0 -1
- package/lib/relay-hooks/useLazyLoadQuery.js +4 -2
- package/lib/relay-hooks/useLazyLoadQueryNode.js +0 -1
- package/lib/relay-hooks/useLoadMoreFunction.js +1 -2
- package/lib/relay-hooks/useMemoOperationDescriptor.js +0 -1
- package/lib/relay-hooks/useMemoVariables.js +0 -1
- package/lib/relay-hooks/useMutation.js +5 -7
- package/lib/relay-hooks/usePaginationFragment.js +15 -3
- package/lib/relay-hooks/usePreloadedQuery.js +4 -2
- package/lib/relay-hooks/useQueryLoader.js +1 -2
- package/lib/relay-hooks/useRefetchableFragment.js +14 -2
- package/lib/relay-hooks/useRefetchableFragmentNode.js +1 -2
- package/lib/relay-hooks/useRelayEnvironment.js +0 -1
- package/lib/relay-hooks/useStaticFragmentNodeWarning.js +0 -1
- package/lib/relay-hooks/useSubscribeToInvalidationState.js +0 -1
- package/lib/relay-hooks/useSubscription.js +0 -1
- package/multi-actor/useRelayActorEnvironment.js.flow +0 -2
- package/package.json +3 -3
- 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/readContext.js.flow +1 -2
- package/relay-hooks/EntryPointContainer.react.js.flow +2 -4
- package/relay-hooks/EntryPointTypes.flow.js.flow +30 -32
- package/relay-hooks/FragmentResource.js.flow +80 -37
- package/relay-hooks/HooksImplementation.js.flow +43 -0
- package/relay-hooks/InternalLogger.js.flow +0 -2
- package/relay-hooks/LRUCache.js.flow +0 -2
- package/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js.flow +4 -6
- package/relay-hooks/MatchContainer.js.flow +11 -6
- package/relay-hooks/ProfilerContext.js.flow +0 -2
- package/relay-hooks/QueryResource.js.flow +12 -209
- package/relay-hooks/RelayEnvironmentProvider.js.flow +2 -4
- package/relay-hooks/SuspenseResource.js.flow +0 -2
- package/relay-hooks/__flowtests__/EntryPointTypes/EntryPointElementConfig-flowtest.js.flow +3 -3
- package/relay-hooks/__flowtests__/EntryPointTypes/NestedEntrypoints-flowtest.js.flow +2 -2
- package/relay-hooks/__flowtests__/__generated__/useFragmentFlowtest_user.graphql.js.flow +2 -2
- package/relay-hooks/__flowtests__/__generated__/useFragmentFlowtest_users.graphql.js.flow +2 -2
- package/relay-hooks/__flowtests__/useBlockingPaginationFragment-flowtest.js.flow +4 -6
- package/relay-hooks/__flowtests__/useFragment-flowtest.js.flow +0 -2
- package/relay-hooks/__flowtests__/usePaginationFragment-flowtest.js.flow +4 -6
- package/relay-hooks/__flowtests__/useRefetchableFragment-flowtest.js.flow +0 -2
- package/relay-hooks/__flowtests__/utils.js.flow +8 -10
- package/relay-hooks/loadQuery.js.flow +2 -1
- package/relay-hooks/preloadQuery_DEPRECATED.js.flow +11 -20
- package/relay-hooks/prepareEntryPoint_DEPRECATED.js.flow +0 -2
- package/relay-hooks/react-cache/RelayReactCache.js.flow +40 -0
- package/relay-hooks/react-cache/getQueryResultOrFetchQuery_REACT_CACHE.js.flow +430 -0
- package/relay-hooks/react-cache/readFragmentInternal_REACT_CACHE.js.flow +297 -0
- package/relay-hooks/react-cache/useFragmentInternal_REACT_CACHE.js.flow +599 -0
- package/relay-hooks/react-cache/useFragment_REACT_CACHE.js.flow +72 -0
- package/relay-hooks/react-cache/useLazyLoadQuery_REACT_CACHE.js.flow +70 -0
- package/relay-hooks/react-cache/usePaginationFragment_REACT_CACHE.js.flow +171 -0
- package/relay-hooks/react-cache/usePreloadedQuery_REACT_CACHE.js.flow +151 -0
- package/relay-hooks/react-cache/useRefetchableFragmentInternal_REACT_CACHE.js.flow +595 -0
- package/relay-hooks/react-cache/useRefetchableFragment_REACT_CACHE.js.flow +65 -0
- package/relay-hooks/useBlockingPaginationFragment.js.flow +4 -6
- package/relay-hooks/useClientQuery.js.flow +39 -0
- package/relay-hooks/useEntryPointLoader.js.flow +6 -8
- package/relay-hooks/useFetchTrackingRef.js.flow +2 -4
- package/relay-hooks/useFragment.js.flow +17 -12
- package/relay-hooks/useFragmentNode.js.flow +2 -4
- package/relay-hooks/useIsMountedRef.js.flow +1 -3
- package/relay-hooks/useLazyLoadQuery.js.flow +17 -5
- package/relay-hooks/useLazyLoadQueryNode.js.flow +2 -4
- package/relay-hooks/useLoadMoreFunction.js.flow +6 -8
- package/relay-hooks/useMemoOperationDescriptor.js.flow +0 -2
- package/relay-hooks/useMemoVariables.js.flow +0 -2
- package/relay-hooks/useMutation.js.flow +5 -7
- package/relay-hooks/usePaginationFragment.js.flow +44 -19
- package/relay-hooks/usePreloadedQuery.js.flow +14 -5
- package/relay-hooks/useQueryLoader.js.flow +4 -6
- package/relay-hooks/useRefetchableFragment.js.flow +32 -3
- package/relay-hooks/useRefetchableFragmentNode.js.flow +38 -25
- package/relay-hooks/useRelayEnvironment.js.flow +0 -2
- package/relay-hooks/useStaticFragmentNodeWarning.js.flow +0 -2
- package/relay-hooks/useSubscribeToInvalidationState.js.flow +0 -2
- package/relay-hooks/useSubscription.js.flow +14 -10
|
@@ -9,8 +9,6 @@
|
|
|
9
9
|
* @format
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
// flowlint ambiguous-object-type:error
|
|
13
|
-
|
|
14
12
|
'use strict';
|
|
15
13
|
|
|
16
14
|
import type {Cache} from './LRUCache';
|
|
@@ -24,6 +22,7 @@ import type {
|
|
|
24
22
|
RequestDescriptor,
|
|
25
23
|
Snapshot,
|
|
26
24
|
} from 'relay-runtime';
|
|
25
|
+
import type {MissingLiveResolverField} from 'relay-runtime/store/RelayStoreTypes';
|
|
27
26
|
|
|
28
27
|
const LRUCache = require('./LRUCache');
|
|
29
28
|
const {getQueryResourceForEnvironment} = require('./QueryResource');
|
|
@@ -37,21 +36,21 @@ const {
|
|
|
37
36
|
getPendingOperationsForFragment,
|
|
38
37
|
getSelector,
|
|
39
38
|
getVariablesFromFragment,
|
|
39
|
+
handlePotentialSnapshotErrors,
|
|
40
40
|
isPromise,
|
|
41
41
|
recycleNodesInto,
|
|
42
|
-
reportMissingRequiredFields,
|
|
43
42
|
} = require('relay-runtime');
|
|
44
43
|
|
|
45
44
|
export type FragmentResource = FragmentResourceImpl;
|
|
46
45
|
|
|
47
46
|
type FragmentResourceCache = Cache<
|
|
48
|
-
| {
|
|
47
|
+
| {
|
|
49
48
|
kind: 'pending',
|
|
50
49
|
pendingOperations: $ReadOnlyArray<RequestDescriptor>,
|
|
51
50
|
promise: Promise<mixed>,
|
|
52
51
|
result: FragmentResult,
|
|
53
|
-
|
|
54
|
-
| {
|
|
52
|
+
}
|
|
53
|
+
| {kind: 'done', result: FragmentResult},
|
|
55
54
|
>;
|
|
56
55
|
|
|
57
56
|
const WEAKMAP_SUPPORTED = typeof WeakMap === 'function';
|
|
@@ -62,13 +61,13 @@ interface IMap<K, V> {
|
|
|
62
61
|
|
|
63
62
|
type SingularOrPluralSnapshot = Snapshot | $ReadOnlyArray<Snapshot>;
|
|
64
63
|
|
|
65
|
-
opaque type FragmentResult: {data: mixed, ...} = {
|
|
64
|
+
opaque type FragmentResult: {data: mixed, ...} = {
|
|
66
65
|
cacheKey: string,
|
|
67
66
|
data: mixed,
|
|
68
67
|
isMissingData: boolean,
|
|
69
68
|
snapshot: SingularOrPluralSnapshot | null,
|
|
70
69
|
storeEpoch: number,
|
|
71
|
-
|
|
70
|
+
};
|
|
72
71
|
|
|
73
72
|
// TODO: Fix to not rely on LRU. If the number of active fragments exceeds this
|
|
74
73
|
// capacity, readSpec() will fail to find cached entries and break object
|
|
@@ -92,6 +91,18 @@ function hasMissingClientEdges(snapshot: SingularOrPluralSnapshot): boolean {
|
|
|
92
91
|
return (snapshot.missingClientEdges?.length ?? 0) > 0;
|
|
93
92
|
}
|
|
94
93
|
|
|
94
|
+
function missingLiveResolverFields(
|
|
95
|
+
snapshot: SingularOrPluralSnapshot,
|
|
96
|
+
): ?$ReadOnlyArray<MissingLiveResolverField> {
|
|
97
|
+
if (Array.isArray(snapshot)) {
|
|
98
|
+
return snapshot
|
|
99
|
+
.map(s => s.missingLiveResolverFields)
|
|
100
|
+
.filter(Boolean)
|
|
101
|
+
.flat();
|
|
102
|
+
}
|
|
103
|
+
return snapshot.missingLiveResolverFields;
|
|
104
|
+
}
|
|
105
|
+
|
|
95
106
|
function singularOrPluralForEach(
|
|
96
107
|
snapshot: SingularOrPluralSnapshot,
|
|
97
108
|
f: Snapshot => void,
|
|
@@ -165,7 +176,7 @@ class ClientEdgeQueryResultsCache {
|
|
|
165
176
|
}
|
|
166
177
|
}
|
|
167
178
|
|
|
168
|
-
_retain(id) {
|
|
179
|
+
_retain(id: string): {dispose: () => void} {
|
|
169
180
|
const retainCount = (this._retainCounts.get(id) ?? 0) + 1;
|
|
170
181
|
this._retainCounts.set(id, retainCount);
|
|
171
182
|
return {
|
|
@@ -288,8 +299,12 @@ class FragmentResourceImpl {
|
|
|
288
299
|
throw cachedValue.promise;
|
|
289
300
|
}
|
|
290
301
|
|
|
291
|
-
if (
|
|
292
|
-
|
|
302
|
+
if (
|
|
303
|
+
cachedValue.kind === 'done' &&
|
|
304
|
+
cachedValue.result.snapshot &&
|
|
305
|
+
!missingLiveResolverFields(cachedValue.result.snapshot)?.length
|
|
306
|
+
) {
|
|
307
|
+
this._handlePotentialSnapshotErrorsInSnapshot(
|
|
293
308
|
cachedValue.result.snapshot,
|
|
294
309
|
);
|
|
295
310
|
return cachedValue.result;
|
|
@@ -330,7 +345,7 @@ class FragmentResourceImpl {
|
|
|
330
345
|
storeEpoch,
|
|
331
346
|
);
|
|
332
347
|
if (!fragmentResult.isMissingData) {
|
|
333
|
-
this.
|
|
348
|
+
this._handlePotentialSnapshotErrorsInSnapshot(snapshot);
|
|
334
349
|
|
|
335
350
|
this._cache.set(fragmentIdentifier, {
|
|
336
351
|
kind: 'done',
|
|
@@ -352,6 +367,7 @@ class FragmentResourceImpl {
|
|
|
352
367
|
let clientEdgeRequests: ?Array<RequestDescriptor> = null;
|
|
353
368
|
if (
|
|
354
369
|
RelayFeatureFlags.ENABLE_CLIENT_EDGES &&
|
|
370
|
+
fragmentNode.metadata?.hasClientEdges === true &&
|
|
355
371
|
hasMissingClientEdges(snapshot)
|
|
356
372
|
) {
|
|
357
373
|
clientEdgeRequests = [];
|
|
@@ -384,11 +400,11 @@ class FragmentResourceImpl {
|
|
|
384
400
|
queryResults,
|
|
385
401
|
);
|
|
386
402
|
}
|
|
387
|
-
let clientEdgePromises =
|
|
403
|
+
let clientEdgePromises: Array<Promise<void>> = [];
|
|
388
404
|
if (RelayFeatureFlags.ENABLE_CLIENT_EDGES && clientEdgeRequests) {
|
|
389
405
|
clientEdgePromises = clientEdgeRequests
|
|
390
406
|
.map(request => getPromiseForActiveRequest(this._environment, request))
|
|
391
|
-
.filter(
|
|
407
|
+
.filter(Boolean);
|
|
392
408
|
}
|
|
393
409
|
|
|
394
410
|
// Finally look for operations in flight for our parent query:
|
|
@@ -404,9 +420,17 @@ class FragmentResourceImpl {
|
|
|
404
420
|
fragmentResult,
|
|
405
421
|
);
|
|
406
422
|
const parentQueryPromiseResultPromise = parentQueryPromiseResult?.promise; // for refinement
|
|
423
|
+
const missingResolverFieldPromises =
|
|
424
|
+
missingLiveResolverFields(snapshot)?.map(({liveStateID}) => {
|
|
425
|
+
const store = environment.getStore();
|
|
426
|
+
|
|
427
|
+
// $FlowFixMe[prop-missing] This is expected to be a LiveResolverStore
|
|
428
|
+
return store.getLiveResolverPromise(liveStateID);
|
|
429
|
+
}) ?? [];
|
|
407
430
|
|
|
408
431
|
if (
|
|
409
|
-
clientEdgePromises
|
|
432
|
+
clientEdgePromises.length ||
|
|
433
|
+
missingResolverFieldPromises.length ||
|
|
410
434
|
isPromise(parentQueryPromiseResultPromise)
|
|
411
435
|
) {
|
|
412
436
|
environment.__log({
|
|
@@ -416,17 +440,36 @@ class FragmentResourceImpl {
|
|
|
416
440
|
isRelayHooks: true,
|
|
417
441
|
isPromiseCached: false,
|
|
418
442
|
isMissingData: fragmentResult.isMissingData,
|
|
443
|
+
// TODO! Attach information here about missing live resolver fields
|
|
419
444
|
pendingOperations: [
|
|
420
445
|
...(parentQueryPromiseResult?.pendingOperations ?? []),
|
|
421
446
|
...(clientEdgeRequests ?? []),
|
|
422
447
|
],
|
|
423
448
|
});
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
449
|
+
let promises = [];
|
|
450
|
+
if (clientEdgePromises.length > 0) {
|
|
451
|
+
promises = promises.concat(clientEdgePromises);
|
|
452
|
+
}
|
|
453
|
+
if (missingResolverFieldPromises.length > 0) {
|
|
454
|
+
promises = promises.concat(missingResolverFieldPromises);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
if (promises.length > 0) {
|
|
458
|
+
if (parentQueryPromiseResultPromise) {
|
|
459
|
+
promises.push(parentQueryPromiseResultPromise);
|
|
460
|
+
}
|
|
461
|
+
throw Promise.all(promises);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// Note: we are re-throwing the `parentQueryPromiseResultPromise` here,
|
|
465
|
+
// because some of our suspense-related code is relying on the instance equality
|
|
466
|
+
// of thrown promises. See FragmentResource-test.js
|
|
467
|
+
if (parentQueryPromiseResultPromise) {
|
|
468
|
+
throw parentQueryPromiseResultPromise;
|
|
469
|
+
}
|
|
427
470
|
}
|
|
428
471
|
|
|
429
|
-
this.
|
|
472
|
+
this._handlePotentialSnapshotErrorsInSnapshot(snapshot);
|
|
430
473
|
return getFragmentResult(fragmentIdentifier, snapshot, storeEpoch);
|
|
431
474
|
}
|
|
432
475
|
|
|
@@ -436,7 +479,7 @@ class FragmentResourceImpl {
|
|
|
436
479
|
fragmentRef: mixed,
|
|
437
480
|
request: ConcreteRequest,
|
|
438
481
|
clientEdgeDestinationID: DataID,
|
|
439
|
-
) {
|
|
482
|
+
): {queryResult: QueryResult, requestDescriptor: RequestDescriptor} {
|
|
440
483
|
const originalVariables = getVariablesFromFragment(
|
|
441
484
|
fragmentNode,
|
|
442
485
|
fragmentRef,
|
|
@@ -462,23 +505,21 @@ class FragmentResourceImpl {
|
|
|
462
505
|
};
|
|
463
506
|
}
|
|
464
507
|
|
|
465
|
-
|
|
508
|
+
_handlePotentialSnapshotErrorsInSnapshot(snapshot: SingularOrPluralSnapshot) {
|
|
466
509
|
if (Array.isArray(snapshot)) {
|
|
467
510
|
snapshot.forEach(s => {
|
|
468
|
-
|
|
469
|
-
reportMissingRequiredFields(
|
|
470
|
-
this._environment,
|
|
471
|
-
s.missingRequiredFields,
|
|
472
|
-
);
|
|
473
|
-
}
|
|
474
|
-
});
|
|
475
|
-
} else {
|
|
476
|
-
if (snapshot.missingRequiredFields != null) {
|
|
477
|
-
reportMissingRequiredFields(
|
|
511
|
+
handlePotentialSnapshotErrors(
|
|
478
512
|
this._environment,
|
|
479
|
-
|
|
513
|
+
s.missingRequiredFields,
|
|
514
|
+
s.relayResolverErrors,
|
|
480
515
|
);
|
|
481
|
-
}
|
|
516
|
+
});
|
|
517
|
+
} else {
|
|
518
|
+
handlePotentialSnapshotErrors(
|
|
519
|
+
this._environment,
|
|
520
|
+
snapshot.missingRequiredFields,
|
|
521
|
+
snapshot.relayResolverErrors,
|
|
522
|
+
);
|
|
482
523
|
}
|
|
483
524
|
}
|
|
484
525
|
|
|
@@ -487,7 +528,7 @@ class FragmentResourceImpl {
|
|
|
487
528
|
fragmentRefs: {[string]: mixed, ...},
|
|
488
529
|
componentDisplayName: string,
|
|
489
530
|
): {[string]: FragmentResult, ...} {
|
|
490
|
-
const result = {};
|
|
531
|
+
const result: {[string]: FragmentResult} = {};
|
|
491
532
|
for (const key in fragmentNodes) {
|
|
492
533
|
result[key] = this.read(
|
|
493
534
|
fragmentNodes[key],
|
|
@@ -596,7 +637,7 @@ class FragmentResourceImpl {
|
|
|
596
637
|
|
|
597
638
|
checkMissedUpdates(
|
|
598
639
|
fragmentResult: FragmentResult,
|
|
599
|
-
): [boolean
|
|
640
|
+
): [boolean /* were updates missed? */, SingularOrPluralSnapshot | null] {
|
|
600
641
|
const environment = this._environment;
|
|
601
642
|
const renderedSnapshot = fragmentResult.snapshot;
|
|
602
643
|
if (!renderedSnapshot) {
|
|
@@ -644,9 +685,11 @@ class FragmentResourceImpl {
|
|
|
644
685
|
data: updatedData,
|
|
645
686
|
isMissingData: currentSnapshot.isMissingData,
|
|
646
687
|
missingClientEdges: currentSnapshot.missingClientEdges,
|
|
688
|
+
missingLiveResolverFields: currentSnapshot.missingLiveResolverFields,
|
|
647
689
|
seenRecords: currentSnapshot.seenRecords,
|
|
648
690
|
selector: currentSnapshot.selector,
|
|
649
691
|
missingRequiredFields: currentSnapshot.missingRequiredFields,
|
|
692
|
+
relayResolverErrors: currentSnapshot.relayResolverErrors,
|
|
650
693
|
};
|
|
651
694
|
if (updatedData !== renderData) {
|
|
652
695
|
this._cache.set(cacheKey, {
|
|
@@ -671,10 +714,10 @@ class FragmentResourceImpl {
|
|
|
671
714
|
fragmentNode: ReaderFragment,
|
|
672
715
|
fragmentOwner: RequestDescriptor,
|
|
673
716
|
fragmentResult: FragmentResult,
|
|
674
|
-
): {
|
|
717
|
+
): {
|
|
675
718
|
promise: Promise<void>,
|
|
676
719
|
pendingOperations: $ReadOnlyArray<RequestDescriptor>,
|
|
677
|
-
|
|
720
|
+
} | null {
|
|
678
721
|
const pendingOperationsResult = getPendingOperationsForFragment(
|
|
679
722
|
this._environment,
|
|
680
723
|
fragmentNode,
|
|
@@ -0,0 +1,43 @@
|
|
|
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
|
+
* @emails oncall+relay
|
|
8
|
+
* @flow strict-local
|
|
9
|
+
* @format
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
'use strict';
|
|
13
|
+
|
|
14
|
+
import typeof useFragment from './useFragment';
|
|
15
|
+
import type {UsePaginationFragmentType} from './usePaginationFragment';
|
|
16
|
+
import type {UseRefetchableFragmentType} from './useRefetchableFragment';
|
|
17
|
+
|
|
18
|
+
const warning = require('warning');
|
|
19
|
+
|
|
20
|
+
type HooksImplementation = {
|
|
21
|
+
useFragment: useFragment,
|
|
22
|
+
usePaginationFragment: UsePaginationFragmentType,
|
|
23
|
+
useRefetchableFragment: UseRefetchableFragmentType,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
let implementation: HooksImplementation | null = null;
|
|
27
|
+
|
|
28
|
+
function inject(impl: HooksImplementation): void {
|
|
29
|
+
warning(
|
|
30
|
+
implementation !== null,
|
|
31
|
+
'Relay HooksImplementation was injected twice.',
|
|
32
|
+
);
|
|
33
|
+
implementation = impl;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function get(): HooksImplementation | null {
|
|
37
|
+
return implementation;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
module.exports = {
|
|
41
|
+
inject,
|
|
42
|
+
get,
|
|
43
|
+
};
|
|
@@ -9,8 +9,6 @@
|
|
|
9
9
|
* @format
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
// flowlint ambiguous-object-type:error
|
|
13
|
-
|
|
14
12
|
'use strict';
|
|
15
13
|
|
|
16
14
|
import type {
|
|
@@ -27,13 +25,13 @@ const React = require('react');
|
|
|
27
25
|
const {useContext, useEffect, useMemo} = require('react');
|
|
28
26
|
const {stableCopy} = require('relay-runtime');
|
|
29
27
|
|
|
30
|
-
type PreloadedEntryPoint<TEntryPointComponent> = $ReadOnly<{
|
|
28
|
+
type PreloadedEntryPoint<TEntryPointComponent> = $ReadOnly<{
|
|
31
29
|
entryPoints: React.ElementConfig<TEntryPointComponent>['entryPoints'],
|
|
32
30
|
extraProps: React.ElementConfig<TEntryPointComponent>['extraProps'],
|
|
33
31
|
getComponent: () => TEntryPointComponent,
|
|
34
32
|
queries: React.ElementConfig<TEntryPointComponent>['queries'],
|
|
35
33
|
rootModuleID: string,
|
|
36
|
-
|
|
34
|
+
}>;
|
|
37
35
|
|
|
38
36
|
type EntryPointContainerProps<
|
|
39
37
|
TEntryPointParams,
|
|
@@ -42,7 +40,7 @@ type EntryPointContainerProps<
|
|
|
42
40
|
TRuntimeProps,
|
|
43
41
|
TExtraProps,
|
|
44
42
|
> = $ReadOnly<
|
|
45
|
-
$ReadOnly<{
|
|
43
|
+
$ReadOnly<{
|
|
46
44
|
entryPoint: EntryPoint<
|
|
47
45
|
TEntryPointParams,
|
|
48
46
|
EntryPointComponent<
|
|
@@ -55,7 +53,7 @@ type EntryPointContainerProps<
|
|
|
55
53
|
entryPointParams: TEntryPointParams,
|
|
56
54
|
environmentProvider?: IEnvironmentProvider<EnvironmentProviderOptions>,
|
|
57
55
|
props: TRuntimeProps,
|
|
58
|
-
|
|
56
|
+
}>,
|
|
59
57
|
>;
|
|
60
58
|
|
|
61
59
|
function stableStringify(value: mixed): string {
|
|
@@ -9,8 +9,6 @@
|
|
|
9
9
|
* @format
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
// flowlint ambiguous-object-type:error
|
|
13
|
-
|
|
14
12
|
'use strict';
|
|
15
13
|
|
|
16
14
|
const React = require('react');
|
|
@@ -87,7 +85,7 @@ const {useMemo} = React;
|
|
|
87
85
|
|
|
88
86
|
// Note: this type is intentionally non-exact, it is expected that the
|
|
89
87
|
// object may contain sibling fields.
|
|
90
|
-
type TypenameOnlyPointer = {
|
|
88
|
+
type TypenameOnlyPointer = {+__typename: string};
|
|
91
89
|
export type MatchPointer = {
|
|
92
90
|
+__fragmentPropName?: ?string,
|
|
93
91
|
+__module_component?: mixed,
|
|
@@ -95,12 +93,12 @@ export type MatchPointer = {
|
|
|
95
93
|
...
|
|
96
94
|
};
|
|
97
95
|
|
|
98
|
-
export type MatchContainerProps<TProps: {...}, TFallback: React.Node> = {
|
|
96
|
+
export type MatchContainerProps<TProps: {...}, TFallback: React.Node> = {
|
|
99
97
|
+fallback?: ?TFallback,
|
|
100
98
|
+loader: (module: mixed) => React.AbstractComponent<TProps>,
|
|
101
99
|
+match: ?MatchPointer | ?TypenameOnlyPointer,
|
|
102
100
|
+props?: TProps,
|
|
103
|
-
|
|
101
|
+
};
|
|
104
102
|
|
|
105
103
|
function MatchContainer<TProps: {...}, TFallback: React.Node | null>({
|
|
106
104
|
fallback,
|
|
@@ -149,7 +147,13 @@ function MatchContainer<TProps: {...}, TFallback: React.Node | null>({
|
|
|
149
147
|
// TODO: Perform this transformation in RelayReader so that unchanged
|
|
150
148
|
// output of subscriptions already has a stable identity.
|
|
151
149
|
if (__fragmentPropName != null && __id != null && __fragments != null) {
|
|
152
|
-
const fragProps
|
|
150
|
+
const fragProps: {
|
|
151
|
+
[string]: {
|
|
152
|
+
__fragmentOwner: $FlowFixMe,
|
|
153
|
+
__fragments: $FlowFixMe,
|
|
154
|
+
__id: string,
|
|
155
|
+
},
|
|
156
|
+
} = {};
|
|
153
157
|
fragProps[__fragmentPropName] = {__id, __fragments, __fragmentOwner};
|
|
154
158
|
return fragProps;
|
|
155
159
|
}
|
|
@@ -158,6 +162,7 @@ function MatchContainer<TProps: {...}, TFallback: React.Node | null>({
|
|
|
158
162
|
|
|
159
163
|
if (LoadedContainer != null && fragmentProps != null) {
|
|
160
164
|
// $FlowFixMe[incompatible-type]
|
|
165
|
+
// $FlowFixMe[cannot-spread-indexer]
|
|
161
166
|
return <LoadedContainer {...props} {...fragmentProps} />;
|
|
162
167
|
} else {
|
|
163
168
|
return fallback ?? null;
|
|
@@ -9,8 +9,6 @@
|
|
|
9
9
|
* @format
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
// flowlint ambiguous-object-type:error
|
|
13
|
-
|
|
14
12
|
// This contextual profiler can be used to wrap a react sub-tree. It will bind
|
|
15
13
|
// the RelayProfiler during the render phase of these components. Allows
|
|
16
14
|
// collecting metrics for a specific part of your application.
|