react-relay 16.2.0 → 18.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. package/ReactRelayContainerUtils.js.flow +2 -2
  2. package/ReactRelayContext.js +1 -1
  3. package/ReactRelayContext.js.flow +1 -1
  4. package/ReactRelayFragmentContainer.js.flow +10 -8
  5. package/ReactRelayLocalQueryRenderer.js.flow +4 -1
  6. package/ReactRelayPaginationContainer.js.flow +4 -2
  7. package/ReactRelayQueryRenderer.js.flow +2 -2
  8. package/ReactRelayQueryRendererContext.js.flow +1 -1
  9. package/ReactRelayRefetchContainer.js.flow +2 -2
  10. package/ReactRelayTypes.js.flow +45 -18
  11. package/__flowtests__/ReactRelayFragmentContainer-flowtest.js.flow +2 -2
  12. package/buildReactRelayContainer.js.flow +10 -8
  13. package/getRootVariablesForFragments.js.flow +1 -0
  14. package/hooks.js +1 -1
  15. package/index.js +1 -1
  16. package/legacy.js +1 -1
  17. package/lib/ReactRelayFragmentContainer.js +2 -2
  18. package/lib/buildReactRelayContainer.js +3 -3
  19. package/lib/relay-hooks/legacy/FragmentResource.js +14 -16
  20. package/lib/relay-hooks/loadEntryPoint.js +8 -5
  21. package/lib/relay-hooks/loadQuery.js +2 -14
  22. package/lib/relay-hooks/{experimental/readFragmentInternal_EXPERIMENTAL.js → readFragmentInternal.js} +7 -5
  23. package/lib/relay-hooks/useEntryPointLoader.js +5 -8
  24. package/lib/relay-hooks/useFragment.js +7 -20
  25. package/lib/relay-hooks/useFragmentInternal.js +13 -0
  26. package/lib/relay-hooks/{experimental/useFragmentInternal_EXPERIMENTAL.js → useFragmentInternal_CURRENT.js} +12 -18
  27. package/lib/relay-hooks/useFragmentInternal_EXPERIMENTAL.js +520 -0
  28. package/lib/relay-hooks/useLazyLoadQuery.js +2 -5
  29. package/lib/relay-hooks/useLazyLoadQueryNode.js +2 -13
  30. package/lib/relay-hooks/usePaginationFragment.js +17 -13
  31. package/lib/relay-hooks/usePreloadedQuery.js +6 -9
  32. package/lib/relay-hooks/useQueryLoader.js +1 -3
  33. package/lib/relay-hooks/useRefetchableFragment.js +3 -12
  34. package/lib/relay-hooks/{experimental/useRefetchableFragmentInternal_EXPERIMENTAL.js → useRefetchableFragmentInternal.js} +7 -7
  35. package/multi-actor/ActorChange.js.flow +1 -1
  36. package/multi-actor/useRelayActorEnvironment.js.flow +1 -1
  37. package/package.json +3 -3
  38. package/react-relay-hooks.js +2 -2
  39. package/react-relay-hooks.min.js +2 -2
  40. package/react-relay-legacy.js +2 -2
  41. package/react-relay-legacy.min.js +2 -2
  42. package/react-relay.js +2 -2
  43. package/react-relay.min.js +2 -2
  44. package/relay-hooks/EntryPointTypes.flow.js.flow +49 -25
  45. package/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js.flow +22 -5
  46. package/relay-hooks/MatchContainer.js.flow +1 -1
  47. package/relay-hooks/ProfilerContext.js.flow +1 -1
  48. package/relay-hooks/__flowtests__/EntryPointTypes/ExtractQueryTypes-flowtest.js.flow +43 -0
  49. package/relay-hooks/__flowtests__/useBlockingPaginationFragment-flowtest.js.flow +21 -0
  50. package/relay-hooks/__flowtests__/usePaginationFragment-flowtest.js.flow +19 -0
  51. package/relay-hooks/__flowtests__/useRefetchableFragment-flowtest.js.flow +22 -0
  52. package/relay-hooks/legacy/FragmentResource.js.flow +13 -16
  53. package/relay-hooks/legacy/useBlockingPaginationFragment.js.flow +2 -2
  54. package/relay-hooks/legacy/useFragmentNode.js.flow +1 -1
  55. package/relay-hooks/legacy/useRefetchableFragmentNode.js.flow +2 -2
  56. package/relay-hooks/loadEntryPoint.js.flow +10 -4
  57. package/relay-hooks/loadQuery.js.flow +10 -33
  58. package/relay-hooks/prepareEntryPoint_DEPRECATED.js.flow +4 -1
  59. package/relay-hooks/{experimental/readFragmentInternal_EXPERIMENTAL.js.flow → readFragmentInternal.js.flow} +6 -4
  60. package/relay-hooks/useClientQuery.js.flow +1 -1
  61. package/relay-hooks/useEntryPointLoader.js.flow +4 -5
  62. package/relay-hooks/useFetchTrackingRef.js.flow +1 -1
  63. package/relay-hooks/useFragment.js.flow +8 -25
  64. package/relay-hooks/useFragmentInternal.js.flow +45 -0
  65. package/relay-hooks/{experimental/useFragmentInternal_EXPERIMENTAL.js.flow → useFragmentInternal_CURRENT.js.flow} +14 -5
  66. package/relay-hooks/useFragmentInternal_EXPERIMENTAL.js.flow +764 -0
  67. package/relay-hooks/useIsMountedRef.js.flow +1 -1
  68. package/relay-hooks/useIsOperationNodeActive.js.flow +1 -1
  69. package/relay-hooks/useIsParentQueryActive.js.flow +5 -2
  70. package/relay-hooks/useLazyLoadQuery.js.flow +3 -7
  71. package/relay-hooks/useLazyLoadQueryNode.js.flow +3 -19
  72. package/relay-hooks/useLoadMoreFunction.js.flow +1 -1
  73. package/relay-hooks/useMemoOperationDescriptor.js.flow +1 -1
  74. package/relay-hooks/useMemoVariables.js.flow +1 -1
  75. package/relay-hooks/useMutation.js.flow +1 -1
  76. package/relay-hooks/usePaginationFragment.js.flow +62 -50
  77. package/relay-hooks/usePreloadedQuery.js.flow +2 -6
  78. package/relay-hooks/useQueryLoader.js.flow +3 -7
  79. package/relay-hooks/useRefetchableFragment.js.flow +7 -37
  80. package/relay-hooks/{experimental/useRefetchableFragmentInternal_EXPERIMENTAL.js.flow → useRefetchableFragmentInternal.js.flow} +11 -11
  81. package/relay-hooks/useRelayEnvironment.js.flow +1 -1
  82. package/relay-hooks/useStaticFragmentNodeWarning.js.flow +3 -1
  83. package/relay-hooks/useSubscribeToInvalidationState.js.flow +1 -1
  84. package/relay-hooks/useSubscription.js.flow +1 -1
  85. package/relay-hooks/useUnsafeRef_DEPRECATED.js.flow +1 -1
  86. package/lib/relay-hooks/HooksImplementation.js +0 -15
  87. package/lib/relay-hooks/experimental/useFragment_EXPERIMENTAL.js +0 -26
  88. package/lib/relay-hooks/experimental/usePaginationFragment_EXPERIMENTAL.js +0 -127
  89. package/lib/relay-hooks/experimental/useRefetchableFragment_EXPERIMENTAL.js +0 -23
  90. package/relay-hooks/HooksImplementation.js.flow +0 -45
  91. package/relay-hooks/experimental/useFragment_EXPERIMENTAL.js.flow +0 -72
  92. package/relay-hooks/experimental/usePaginationFragment_EXPERIMENTAL.js.flow +0 -161
  93. package/relay-hooks/experimental/useRefetchableFragment_EXPERIMENTAL.js.flow +0 -49
@@ -13,9 +13,7 @@
13
13
 
14
14
  import type {Fragment, FragmentType, GraphQLTaggedNode} from 'relay-runtime';
15
15
 
16
- const HooksImplementation = require('./HooksImplementation');
17
- const useFragmentNode = require('./legacy/useFragmentNode');
18
- const {useTrackLoadQueryInRender} = require('./loadQuery');
16
+ const useFragmentInternal = require('./useFragmentInternal');
19
17
  const useStaticFragmentNodeWarning = require('./useStaticFragmentNodeWarning');
20
18
  const {useDebugValue} = require('react');
21
19
  const {getFragment} = require('relay-runtime');
@@ -26,54 +24,39 @@ type HasSpread<TFragmentType> = {
26
24
  };
27
25
 
28
26
  // if the key is non-nullable, return non-nullable value
29
- declare function useFragment<TFragmentType: FragmentType, TData>(
27
+ declare hook useFragment<TFragmentType: FragmentType, TData>(
30
28
  fragment: Fragment<TFragmentType, TData>,
31
29
  key: HasSpread<TFragmentType>,
32
30
  ): TData;
33
31
 
34
32
  // if the key is nullable, return nullable value
35
- declare function useFragment<TFragmentType: FragmentType, TData>(
33
+ declare hook useFragment<TFragmentType: FragmentType, TData>(
36
34
  fragment: Fragment<TFragmentType, TData>,
37
35
  key: ?HasSpread<TFragmentType>,
38
36
  ): ?TData;
39
37
 
40
38
  // if the key is a non-nullable array of keys, return non-nullable array
41
- declare function useFragment<TFragmentType: FragmentType, TData>(
39
+ declare hook useFragment<TFragmentType: FragmentType, TData>(
42
40
  fragment: Fragment<TFragmentType, TData>,
43
41
  key: $ReadOnlyArray<HasSpread<TFragmentType>>,
44
42
  ): TData;
45
43
 
46
44
  // if the key is a nullable array of keys, return nullable array
47
- declare function useFragment<TFragmentType: FragmentType, TData>(
45
+ declare hook useFragment<TFragmentType: FragmentType, TData>(
48
46
  fragment: Fragment<TFragmentType, TData>,
49
47
  key: ?$ReadOnlyArray<HasSpread<TFragmentType>>,
50
48
  ): ?TData;
51
49
 
52
- function useFragment_LEGACY(fragment: GraphQLTaggedNode, key: mixed): mixed {
53
- // We need to use this hook in order to be able to track if
54
- // loadQuery was called during render
55
- useTrackLoadQueryInRender();
56
-
50
+ hook useFragment(fragment: GraphQLTaggedNode, key: mixed): mixed {
57
51
  const fragmentNode = getFragment(fragment);
58
52
  useStaticFragmentNodeWarning(fragmentNode, 'first argument of useFragment()');
59
- const {data} = useFragmentNode<mixed>(fragmentNode, key, 'useFragment()');
53
+ const data = useFragmentInternal(fragmentNode, key, 'useFragment()');
60
54
  if (__DEV__) {
61
55
  // eslint-disable-next-line react-hooks/rules-of-hooks
56
+ // $FlowFixMe[react-rule-hook]
62
57
  useDebugValue({fragment: fragmentNode.name, data});
63
58
  }
64
59
  return data;
65
60
  }
66
61
 
67
- function useFragment(fragment: GraphQLTaggedNode, key: mixed): mixed {
68
- const impl = HooksImplementation.get();
69
- if (impl) {
70
- // $FlowFixMe This is safe because impl.useFragment has the type of useFragment...
71
- return impl.useFragment(fragment, key);
72
- // (i.e. type declared above, but not the supertype used in this function definition)
73
- } else {
74
- // eslint-disable-next-line react-hooks/rules-of-hooks
75
- return useFragment_LEGACY(fragment, key);
76
- }
77
- }
78
-
79
62
  module.exports = useFragment;
@@ -0,0 +1,45 @@
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
+ * @flow strict-local
8
+ * @format
9
+ * @oncall relay
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ import type {FragmentQueryOptions} from './useFragmentInternal_EXPERIMENTAL';
15
+ import type {ReaderFragment, SelectorData} from 'relay-runtime';
16
+
17
+ import useFragmentInternal_CURRENT from './useFragmentInternal_CURRENT';
18
+ import useFragmentInternal_EXPERIMENTAL from './useFragmentInternal_EXPERIMENTAL';
19
+ import {RelayFeatureFlags} from 'relay-runtime';
20
+
21
+ hook useFragmentInternal(
22
+ fragmentNode: ReaderFragment,
23
+ fragmentRef: mixed,
24
+ hookDisplayName: string,
25
+ queryOptions?: FragmentQueryOptions,
26
+ ): ?SelectorData | Array<?SelectorData> {
27
+ if (RelayFeatureFlags.ENABLE_USE_FRAGMENT_EXPERIMENTAL) {
28
+ // $FlowFixMe[react-rule-hook] - the condition is static
29
+ return useFragmentInternal_EXPERIMENTAL(
30
+ fragmentNode,
31
+ fragmentRef,
32
+ hookDisplayName,
33
+ queryOptions,
34
+ );
35
+ }
36
+ // $FlowFixMe[react-rule-hook] - the condition is static
37
+ return useFragmentInternal_CURRENT(
38
+ fragmentNode,
39
+ fragmentRef,
40
+ hookDisplayName,
41
+ queryOptions,
42
+ );
43
+ }
44
+
45
+ module.exports = useFragmentInternal;
@@ -11,7 +11,7 @@
11
11
 
12
12
  'use strict';
13
13
 
14
- import type {QueryResult} from '../QueryResource';
14
+ import type {QueryResult} from './QueryResource';
15
15
  import type {
16
16
  CacheConfig,
17
17
  FetchPolicy,
@@ -26,8 +26,8 @@ import type {
26
26
  MissingLiveResolverField,
27
27
  } from 'relay-runtime/store/RelayStoreTypes';
28
28
 
29
- const {getQueryResourceForEnvironment} = require('../QueryResource');
30
- const useRelayEnvironment = require('../useRelayEnvironment');
29
+ const {getQueryResourceForEnvironment} = require('./QueryResource');
30
+ const useRelayEnvironment = require('./useRelayEnvironment');
31
31
  const invariant = require('invariant');
32
32
  const {useDebugValue, useEffect, useMemo, useRef, useState} = require('react');
33
33
  const {
@@ -118,6 +118,7 @@ function handlePotentialSnapshotErrorsForState(
118
118
  state.snapshot.missingRequiredFields,
119
119
  state.snapshot.relayResolverErrors,
120
120
  state.snapshot.errorResponseFields,
121
+ state.snapshot.selector.node.metadata?.throwOnFieldError ?? false,
121
122
  );
122
123
  } else if (state.kind === 'plural') {
123
124
  for (const snapshot of state.snapshots) {
@@ -126,6 +127,7 @@ function handlePotentialSnapshotErrorsForState(
126
127
  snapshot.missingRequiredFields,
127
128
  snapshot.relayResolverErrors,
128
129
  snapshot.errorResponseFields,
130
+ snapshot.selector.node.metadata?.throwOnFieldError ?? false,
129
131
  );
130
132
  }
131
133
  }
@@ -360,7 +362,7 @@ function getFragmentState(
360
362
  }
361
363
 
362
364
  // fragmentNode cannot change during the lifetime of the component, though fragmentRef may change.
363
- function useFragmentInternal_EXPERIMENTAL(
365
+ hook useFragmentInternal(
364
366
  fragmentNode: ReaderFragment,
365
367
  fragmentRef: mixed,
366
368
  hookDisplayName: string,
@@ -466,6 +468,7 @@ function useFragmentInternal_EXPERIMENTAL(
466
468
  // a static (constant) property of the fragment. In practice, this effect will
467
469
  // always or never run for a given invocation of this hook.
468
470
  // eslint-disable-next-line react-hooks/rules-of-hooks
471
+ // $FlowFixMe[react-rule-hook]
469
472
  const [clientEdgeQueries, activeRequestPromises] = useMemo(() => {
470
473
  const missingClientEdges = getMissingClientEdges(state);
471
474
  // eslint-disable-next-line no-shadow
@@ -496,6 +499,7 @@ function useFragmentInternal_EXPERIMENTAL(
496
499
 
497
500
  // See above note
498
501
  // eslint-disable-next-line react-hooks/rules-of-hooks
502
+ // $FlowFixMe[react-rule-hook]
499
503
  useEffect(() => {
500
504
  const QueryResource = getQueryResourceForEnvironment(environment);
501
505
  if (clientEdgeQueries?.length) {
@@ -528,8 +532,10 @@ function useFragmentInternal_EXPERIMENTAL(
528
532
  // We only suspend when the component is first trying to mount or changing
529
533
  // selectors, not if data becomes missing later:
530
534
  if (
535
+ RelayFeatureFlags.ENABLE_RELAY_OPERATION_TRACKER_SUSPENSE ||
531
536
  environment !== previousEnvironment ||
532
537
  !committedFragmentSelectorRef.current ||
538
+ // $FlowFixMe[react-rule-unsafe-ref]
533
539
  !areEqualSelectors(committedFragmentSelectorRef.current, fragmentSelector)
534
540
  ) {
535
541
  invariant(fragmentSelector != null, 'refinement, see invariants above');
@@ -589,6 +595,7 @@ function useFragmentInternal_EXPERIMENTAL(
589
595
  state = updatedState;
590
596
  }
591
597
  }
598
+ // $FlowFixMe[react-rule-unsafe-ref]
592
599
  hasPendingStateChanges.current = false;
593
600
  }
594
601
 
@@ -601,6 +608,7 @@ function useFragmentInternal_EXPERIMENTAL(
601
608
  // for a particular useFragment invocation site
602
609
  const fragmentRefIsNullish = fragmentRef == null; // for less sensitive memoization
603
610
  // eslint-disable-next-line react-hooks/rules-of-hooks
611
+ // $FlowFixMe[react-rule-hook]
604
612
  data = useMemo(() => {
605
613
  if (state.kind === 'bailout') {
606
614
  // Bailout state can happen if the fragmentRef is a plural array that is empty or has no
@@ -651,10 +659,11 @@ function useFragmentInternal_EXPERIMENTAL(
651
659
 
652
660
  if (__DEV__) {
653
661
  // eslint-disable-next-line react-hooks/rules-of-hooks
662
+ // $FlowFixMe[react-rule-hook]
654
663
  useDebugValue({fragment: fragmentNode.name, data});
655
664
  }
656
665
 
657
666
  return data;
658
667
  }
659
668
 
660
- module.exports = useFragmentInternal_EXPERIMENTAL;
669
+ module.exports = useFragmentInternal;