react-relay 16.2.0 → 18.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.
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;