react-relay 15.0.0 → 16.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 (119) hide show
  1. package/ReactRelayContext.js +1 -1
  2. package/ReactRelayQueryFetcher.js.flow +1 -5
  3. package/ReactRelayQueryRenderer.js.flow +9 -36
  4. package/ReactRelayTypes.js.flow +1 -0
  5. package/buildReactRelayContainer.js.flow +3 -1
  6. package/hooks.js +1 -1
  7. package/index.js +1 -1
  8. package/legacy.js +1 -1
  9. package/lib/ReactRelayContainerUtils.js +0 -11
  10. package/lib/ReactRelayContext.js +0 -11
  11. package/lib/ReactRelayFragmentContainer.js +6 -78
  12. package/lib/ReactRelayFragmentMockRenderer.js +0 -11
  13. package/lib/ReactRelayLocalQueryRenderer.js +0 -17
  14. package/lib/ReactRelayPaginationContainer.js +5 -208
  15. package/lib/ReactRelayQueryFetcher.js +2 -51
  16. package/lib/ReactRelayQueryRenderer.js +6 -94
  17. package/lib/ReactRelayQueryRendererContext.js +0 -11
  18. package/lib/ReactRelayRefetchContainer.js +5 -91
  19. package/lib/ReactRelayTestMocker.js +9 -85
  20. package/lib/ReactRelayTypes.js +0 -11
  21. package/lib/RelayContext.js +0 -21
  22. package/lib/assertFragmentMap.js +0 -15
  23. package/lib/buildReactRelayContainer.js +0 -19
  24. package/lib/getRootVariablesForFragments.js +0 -14
  25. package/lib/hooks.js +0 -15
  26. package/lib/index.js +0 -17
  27. package/lib/isRelayEnvironment.js +1 -18
  28. package/lib/jest-react/enqueueTask.js +0 -20
  29. package/lib/jest-react/internalAct.js +0 -38
  30. package/lib/legacy.js +0 -15
  31. package/lib/multi-actor/ActorChange.js +0 -11
  32. package/lib/multi-actor/index.js +0 -11
  33. package/lib/multi-actor/useRelayActorEnvironment.js +0 -11
  34. package/lib/relay-hooks/EntryPointContainer.react.js +0 -11
  35. package/lib/relay-hooks/EntryPointTypes.flow.js +1 -14
  36. package/lib/relay-hooks/FragmentResource.js +76 -132
  37. package/lib/relay-hooks/HooksImplementation.js +0 -11
  38. package/lib/relay-hooks/InternalLogger.js +0 -11
  39. package/lib/relay-hooks/LRUCache.js +0 -22
  40. package/lib/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js +0 -18
  41. package/lib/relay-hooks/MatchContainer.js +0 -94
  42. package/lib/relay-hooks/NestedRelayEntryPointBuilderUtils.js +9 -0
  43. package/lib/relay-hooks/ProfilerContext.js +0 -15
  44. package/lib/relay-hooks/QueryResource.js +2 -68
  45. package/lib/relay-hooks/RelayEnvironmentProvider.js +0 -11
  46. package/lib/relay-hooks/SuspenseResource.js +0 -34
  47. package/lib/relay-hooks/loadEntryPoint.js +1 -24
  48. package/lib/relay-hooks/loadQuery.js +2 -106
  49. package/lib/relay-hooks/preloadQuery_DEPRECATED.js +2 -27
  50. package/lib/relay-hooks/prepareEntryPoint_DEPRECATED.js +0 -13
  51. package/lib/relay-hooks/react-cache/RelayReactCache.js +0 -12
  52. package/lib/relay-hooks/react-cache/getQueryResultOrFetchQuery_REACT_CACHE.js +1 -36
  53. package/lib/relay-hooks/react-cache/readFragmentInternal_REACT_CACHE.js +3 -27
  54. package/lib/relay-hooks/react-cache/useFragmentInternal_REACT_CACHE.js +34 -99
  55. package/lib/relay-hooks/react-cache/useFragment_REACT_CACHE.js +0 -15
  56. package/lib/relay-hooks/react-cache/useLazyLoadQuery_REACT_CACHE.js +0 -16
  57. package/lib/relay-hooks/react-cache/usePaginationFragment_REACT_CACHE.js +1 -23
  58. package/lib/relay-hooks/react-cache/usePreloadedQuery_REACT_CACHE.js +0 -29
  59. package/lib/relay-hooks/react-cache/useRefetchableFragmentInternal_REACT_CACHE.js +12 -96
  60. package/lib/relay-hooks/react-cache/useRefetchableFragment_REACT_CACHE.js +0 -14
  61. package/lib/relay-hooks/useBlockingPaginationFragment.js +0 -42
  62. package/lib/relay-hooks/useClientQuery.js +0 -18
  63. package/lib/relay-hooks/useEntryPointLoader.js +0 -69
  64. package/lib/relay-hooks/useFetchTrackingRef.js +0 -26
  65. package/lib/relay-hooks/useFragment.js +0 -17
  66. package/lib/relay-hooks/useFragmentNode.js +2 -32
  67. package/lib/relay-hooks/useIsMountedRef.js +0 -11
  68. package/lib/relay-hooks/useIsOperationNodeActive.js +0 -11
  69. package/lib/relay-hooks/useIsParentQueryActive.js +0 -11
  70. package/lib/relay-hooks/useLazyLoadQuery.js +0 -18
  71. package/lib/relay-hooks/useLazyLoadQueryNode.js +0 -35
  72. package/lib/relay-hooks/useLoadMoreFunction.js +9 -34
  73. package/lib/relay-hooks/useMemoOperationDescriptor.js +0 -11
  74. package/lib/relay-hooks/useMemoVariables.js +0 -17
  75. package/lib/relay-hooks/useMutation.js +0 -11
  76. package/lib/relay-hooks/usePaginationFragment.js +1 -26
  77. package/lib/relay-hooks/usePreloadedQuery.js +0 -27
  78. package/lib/relay-hooks/useQueryLoader.js +0 -74
  79. package/lib/relay-hooks/useRefetchableFragment.js +0 -16
  80. package/lib/relay-hooks/useRefetchableFragmentNode.js +14 -97
  81. package/lib/relay-hooks/useRelayEnvironment.js +0 -11
  82. package/lib/relay-hooks/useStaticFragmentNodeWarning.js +0 -15
  83. package/lib/relay-hooks/useSubscribeToInvalidationState.js +0 -25
  84. package/lib/relay-hooks/useSubscription.js +0 -15
  85. package/lib/relay-hooks/useUnsafeRef_DEPRECATED.js +0 -17
  86. package/package.json +2 -2
  87. package/react-relay-hooks.js +2 -2
  88. package/react-relay-hooks.min.js +2 -2
  89. package/react-relay-legacy.js +2 -2
  90. package/react-relay-legacy.min.js +2 -2
  91. package/react-relay.js +2 -2
  92. package/react-relay.min.js +2 -2
  93. package/relay-hooks/EntryPointContainer.react.js.flow +5 -0
  94. package/relay-hooks/EntryPointTypes.flow.js.flow +20 -19
  95. package/relay-hooks/FragmentResource.js.flow +114 -26
  96. package/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js.flow +4 -2
  97. package/relay-hooks/NestedRelayEntryPointBuilderUtils.js.flow +51 -0
  98. package/relay-hooks/__flowtests__/EntryPointTypes/NestedEntrypoints-flowtest.js.flow +7 -5
  99. package/relay-hooks/__flowtests__/useBlockingPaginationFragment-flowtest.js.flow +5 -0
  100. package/relay-hooks/__flowtests__/usePaginationFragment-flowtest.js.flow +5 -0
  101. package/relay-hooks/__flowtests__/useRefetchableFragment-flowtest.js.flow +2 -0
  102. package/relay-hooks/loadEntryPoint.js.flow +4 -2
  103. package/relay-hooks/loadQuery.js.flow +21 -1
  104. package/relay-hooks/prepareEntryPoint_DEPRECATED.js.flow +4 -2
  105. package/relay-hooks/react-cache/readFragmentInternal_REACT_CACHE.js.flow +2 -1
  106. package/relay-hooks/react-cache/useFragmentInternal_REACT_CACHE.js.flow +28 -10
  107. package/relay-hooks/react-cache/useFragment_REACT_CACHE.js.flow +3 -9
  108. package/relay-hooks/react-cache/usePaginationFragment_REACT_CACHE.js.flow +28 -57
  109. package/relay-hooks/react-cache/useRefetchableFragmentInternal_REACT_CACHE.js.flow +19 -12
  110. package/relay-hooks/react-cache/useRefetchableFragment_REACT_CACHE.js.flow +15 -31
  111. package/relay-hooks/useBlockingPaginationFragment.js.flow +2 -4
  112. package/relay-hooks/useClientQuery.js.flow +2 -2
  113. package/relay-hooks/useFragmentNode.js.flow +2 -2
  114. package/relay-hooks/useLoadMoreFunction.js.flow +15 -9
  115. package/relay-hooks/useMutation.js.flow +26 -9
  116. package/relay-hooks/usePaginationFragment.js.flow +2 -8
  117. package/relay-hooks/useQueryLoader.js.flow +2 -8
  118. package/relay-hooks/useRefetchableFragment.js.flow +3 -2
  119. package/relay-hooks/useRefetchableFragmentNode.js.flow +28 -13
@@ -1,14 +1,3 @@
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
- *
8
- * @format
9
- * @oncall relay
10
- */
11
-
12
1
  'use strict';
13
2
 
14
3
  var _require = require('../loadQuery'),
@@ -26,8 +15,6 @@ function useLazyLoadQuery_REACT_CACHE(gqlQuery, variables, options) {
26
15
  var queryOperationDescriptor = useMemoOperationDescriptor(gqlQuery, variables, (_options$networkCache = options === null || options === void 0 ? void 0 : options.networkCacheConfig) !== null && _options$networkCache !== void 0 ? _options$networkCache : {
27
16
  force: true
28
17
  });
29
-
30
- // Get the query going if needed -- this may suspend.
31
18
  var _getQueryResultOrFetc = getQueryResultOrFetchQuery(environment, queryOperationDescriptor, {
32
19
  fetchPolicy: options === null || options === void 0 ? void 0 : options.fetchPolicy,
33
20
  renderPolicy: options === null || options === void 0 ? void 0 : options.UNSTABLE_renderPolicy,
@@ -36,11 +23,8 @@ function useLazyLoadQuery_REACT_CACHE(gqlQuery, variables, options) {
36
23
  queryResult = _getQueryResultOrFetc[0],
37
24
  effect = _getQueryResultOrFetc[1];
38
25
  useEffect(effect);
39
-
40
- // Read the query's root fragment -- this may suspend.
41
26
  var fragmentNode = queryResult.fragmentNode,
42
27
  fragmentRef = queryResult.fragmentRef;
43
- // $FlowExpectedError[incompatible-return] Is this a fixable incompatible-return?
44
28
  return useFragmentInternal(fragmentNode, fragmentRef, 'useLazyLoadQuery()', {
45
29
  fetchPolicy: options === null || options === void 0 ? void 0 : options.fetchPolicy,
46
30
  networkCacheConfig: options === null || options === void 0 ? void 0 : options.networkCacheConfig
@@ -1,14 +1,3 @@
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
- *
8
- * @format
9
- * @oncall relay
10
- */
11
-
12
1
  'use strict';
13
2
 
14
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
@@ -32,15 +21,12 @@ function usePaginationFragment(fragmentInput, parentFragmentRef) {
32
21
  var _getPaginationMetadat = getPaginationMetadata(fragmentNode, componentDisplayName),
33
22
  connectionPathInFragmentData = _getPaginationMetadat.connectionPathInFragmentData,
34
23
  paginationRequest = _getPaginationMetadat.paginationRequest,
35
- paginationMetadata = _getPaginationMetadat.paginationMetadata,
36
- identifierField = _getPaginationMetadat.identifierField;
24
+ paginationMetadata = _getPaginationMetadat.paginationMetadata;
37
25
  var _useRefetchableFragme = useRefetchableFragmentInternal(fragmentNode, parentFragmentRef, componentDisplayName),
38
26
  fragmentData = _useRefetchableFragme.fragmentData,
39
27
  fragmentRef = _useRefetchableFragme.fragmentRef,
40
28
  refetch = _useRefetchableFragme.refetch;
41
29
  var fragmentIdentifier = getFragmentIdentifier(fragmentNode, fragmentRef);
42
-
43
- // Backward pagination
44
30
  var _useLoadMore = useLoadMore({
45
31
  componentDisplayName: componentDisplayName,
46
32
  connectionPathInFragmentData: connectionPathInFragmentData,
@@ -49,7 +35,6 @@ function usePaginationFragment(fragmentInput, parentFragmentRef) {
49
35
  fragmentIdentifier: fragmentIdentifier,
50
36
  fragmentNode: fragmentNode,
51
37
  fragmentRef: fragmentRef,
52
- identifierField: identifierField,
53
38
  paginationMetadata: paginationMetadata,
54
39
  paginationRequest: paginationRequest
55
40
  }),
@@ -57,8 +42,6 @@ function usePaginationFragment(fragmentInput, parentFragmentRef) {
57
42
  hasPrevious = _useLoadMore[1],
58
43
  isLoadingPrevious = _useLoadMore[2],
59
44
  disposeFetchPrevious = _useLoadMore[3];
60
-
61
- // Forward pagination
62
45
  var _useLoadMore2 = useLoadMore({
63
46
  componentDisplayName: componentDisplayName,
64
47
  connectionPathInFragmentData: connectionPathInFragmentData,
@@ -67,7 +50,6 @@ function usePaginationFragment(fragmentInput, parentFragmentRef) {
67
50
  fragmentIdentifier: fragmentIdentifier,
68
51
  fragmentNode: fragmentNode,
69
52
  fragmentRef: fragmentRef,
70
- identifierField: identifierField,
71
53
  paginationMetadata: paginationMetadata,
72
54
  paginationRequest: paginationRequest
73
55
  }),
@@ -83,7 +65,6 @@ function usePaginationFragment(fragmentInput, parentFragmentRef) {
83
65
  }));
84
66
  }, [disposeFetchNext, disposeFetchPrevious, refetch]);
85
67
  if (process.env.NODE_ENV !== "production") {
86
- // eslint-disable-next-line react-hooks/rules-of-hooks
87
68
  useDebugValue({
88
69
  fragment: fragmentNode.name,
89
70
  data: fragmentData,
@@ -109,9 +90,6 @@ function useLoadMore(args) {
109
90
  var _useState = useState(false),
110
91
  isLoadingMore = _useState[0],
111
92
  reallySetIsLoadingMore = _useState[1];
112
- // Schedule this update since it must be observed by components at the same
113
- // batch as when hasNext changes. hasNext is read from the store and store
114
- // updates are scheduled, so this must be scheduled too.
115
93
  var setIsLoadingMore = function setIsLoadingMore(value) {
116
94
  var _environment$getSched;
117
95
  var schedule = (_environment$getSched = environment.getScheduler()) === null || _environment$getSched === void 0 ? void 0 : _environment$getSched.schedule;
@@ -1,14 +1,3 @@
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
- *
8
- * @format
9
- * @oncall relay
10
- */
11
-
12
1
  'use strict';
13
2
 
14
3
  var _require = require('../loadQuery'),
@@ -54,29 +43,14 @@ function usePreloadedQuery_REACT_CACHE(gqlQuery, preloadedQuery, options) {
54
43
  process.env.NODE_ENV !== "production" ? warning(preloadedQuery.isDisposed === false, 'usePreloadedQuery(): Expected preloadedQuery to not be disposed yet. ' + 'This is because disposing the query marks it for future garbage ' + 'collection, and as such query results may no longer be present in the Relay ' + 'store. In the future, this will become a hard error.') : void 0;
55
44
  var fallbackFetchObservable = fetchQuery(environment, operation);
56
45
  if (source != null && environment === preloadedQuery.environment) {
57
- // If the source observable exists and the environments match, reuse
58
- // the source observable.
59
- // If the source observable happens to be empty, we need to fall back
60
- // and re-execute and de-dupe the query (at render time).
61
46
  fetchObservable = source.ifEmpty(fallbackFetchObservable);
62
47
  } else if (environment !== preloadedQuery.environment) {
63
- // If a call to loadQuery is made with a particular environment, and that
64
- // preloaded query is passed to usePreloadedQuery in a different environment
65
- // context, we cannot re-use the existing preloaded query.
66
- // Instead, we need to fall back and re-execute and de-dupe the query with
67
- // the new environment (at render time).
68
- // TODO T68036756 track occurences of this warning and turn it into a hard error
69
48
  process.env.NODE_ENV !== "production" ? warning(false, 'usePreloadedQuery(): usePreloadedQuery was passed a preloaded query ' + 'that was created with a different environment than the one that is currently ' + 'in context. In the future, this will become a hard error.') : void 0;
70
49
  fetchObservable = fallbackFetchObservable;
71
50
  } else {
72
- // if (source == null)
73
- // If the source observable does not exist, we need to
74
- // fall back and re-execute and de-dupe the query (at render time).
75
51
  fetchObservable = fallbackFetchObservable;
76
52
  }
77
53
  }
78
-
79
- // Get the query going if needed -- this may suspend.
80
54
  var _getQueryResultOrFetc = getQueryResultOrFetchQuery(environment, operation, {
81
55
  fetchPolicy: fetchPolicy,
82
56
  renderPolicy: options === null || options === void 0 ? void 0 : options.UNSTABLE_renderPolicy,
@@ -86,8 +60,6 @@ function usePreloadedQuery_REACT_CACHE(gqlQuery, preloadedQuery, options) {
86
60
  queryResult = _getQueryResultOrFetc[0],
87
61
  effect = _getQueryResultOrFetc[1];
88
62
  useEffect(effect);
89
-
90
- // Read the query's root fragment -- this may suspend.
91
63
  var fragmentNode = queryResult.fragmentNode,
92
64
  fragmentRef = queryResult.fragmentRef;
93
65
  var data = useFragmentInternal(fragmentNode, fragmentRef, 'usePreloadedQuery()', {
@@ -95,7 +67,6 @@ function usePreloadedQuery_REACT_CACHE(gqlQuery, preloadedQuery, options) {
95
67
  networkCacheConfig: networkCacheConfig
96
68
  });
97
69
  if (process.env.NODE_ENV !== "production") {
98
- // eslint-disable-next-line react-hooks/rules-of-hooks
99
70
  useDebugValue({
100
71
  query: preloadedQuery.name,
101
72
  variables: preloadedQuery.variables,
@@ -1,14 +1,3 @@
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
- *
8
- * @format
9
- * @oncall relay
10
- */
11
-
12
1
  'use strict';
13
2
 
14
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
@@ -71,7 +60,7 @@ function useRefetchableFragmentNode(fragmentNode, parentFragmentRef, componentDi
71
60
  var _getRefetchMetadata = getRefetchMetadata(fragmentNode, componentDisplayName),
72
61
  refetchableRequest = _getRefetchMetadata.refetchableRequest,
73
62
  fragmentRefPathInResponse = _getRefetchMetadata.fragmentRefPathInResponse,
74
- identifierField = _getRefetchMetadata.identifierField;
63
+ identifierInfo = _getRefetchMetadata.identifierInfo;
75
64
  var fragmentIdentifier = getFragmentIdentifier(fragmentNode, parentFragmentRef);
76
65
  var _useReducer = useReducer(reducer, {
77
66
  fetchPolicy: undefined,
@@ -108,47 +97,18 @@ function useRefetchableFragmentNode(fragmentNode, parentFragmentRef, componentDi
108
97
  });
109
98
  disposeQuery();
110
99
  } else if (refetchQuery != null && queryRef != null) {
111
- // If refetch was called, we expect to have a refetchQuery and queryRef
112
- // in state, since both state updates to set the refetchQuery and the
113
- // queryRef occur simultaneously.
114
- // In this case, we need to read the refetched query data (potentially
115
- // suspending if it's in flight), and extract the new fragment ref
116
- // from the query in order read the current @refetchable fragment
117
- // with the updated fragment owner as the new refetchQuery.
118
-
119
- // Before observing the refetch, record the current ID and typename
120
- // so that, if we are refetching existing data on
121
- // a field that implements Node, after refetching we
122
- // can validate that the received data is consistent
123
100
  var debugPreviousIDAndTypename;
124
101
  if (process.env.NODE_ENV !== "production") {
125
- debugPreviousIDAndTypename = debugFunctions.getInitialIDAndType(refetchQuery.request.variables, fragmentRefPathInResponse, environment);
102
+ debugPreviousIDAndTypename = debugFunctions.getInitialIDAndType(refetchQuery.request.variables, fragmentRefPathInResponse, identifierInfo === null || identifierInfo === void 0 ? void 0 : identifierInfo.identifierQueryVariableName, environment);
126
103
  }
127
104
  var handleQueryCompleted = function handleQueryCompleted(maybeError) {
128
105
  onComplete && onComplete(maybeError !== null && maybeError !== void 0 ? maybeError : null);
129
106
  };
130
-
131
- // The queryRef.source obtained from useQueryLoader will be
132
- // an observable we can consume /if/ a network request was
133
- // started. Otherwise, given that QueryResource.prepare
134
- // always expects an observable we fall back to a new network
135
- // observable. Note however that if loadQuery did not make a network
136
- // request, we don't expect to make one here, unless the state of
137
- // the cache has changed between the call to refetch and this
138
- // render.
139
107
  var fetchObservable = queryRef.source != null ? queryRef.source : fetchQuery(environment, refetchQuery);
140
-
141
- // Now wwe can we read the refetch query here using the
142
- // queryRef provided from useQueryLoader. Note that the
143
- // network request is started during the call to refetch,
144
- // but if the refetch query is still in flight, we will suspend
145
- // at this point:
146
108
  var queryResult = profilerContext.wrapPrepareQueryResource(function () {
147
109
  return QueryResource.prepare(refetchQuery, fetchObservable, fetchPolicy, renderPolicy, {
148
110
  error: handleQueryCompleted,
149
111
  complete: function complete() {
150
- // Validate that the type of the object we got back matches the type
151
- // of the object already in the store
152
112
  if (process.env.NODE_ENV !== "production") {
153
113
  debugFunctions.checkSameTypeAfterRefetch(debugPreviousIDAndTypename, environment, fragmentNode, componentDisplayName);
154
114
  }
@@ -158,40 +118,24 @@ function useRefetchableFragmentNode(fragmentNode, parentFragmentRef, componentDi
158
118
  });
159
119
  var queryData = readFragmentInternal(environment, queryResult.fragmentNode, queryResult.fragmentRef, componentDisplayName).data;
160
120
  !(queryData != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Relay: Expected to be able to read refetch query response. ' + "If you're seeing this, this is likely a bug in Relay.") : invariant(false) : void 0;
161
-
162
- // After reading/fetching the refetch query, we extract from the
163
- // refetch query response the new fragment ref we need to use to read
164
- // the fragment. The new fragment ref will point to the refetch query
165
- // as its fragment owner.
166
121
  var refetchedFragmentRef = getValueAtPath(queryData, fragmentRefPathInResponse);
167
122
  fragmentRef = refetchedFragmentRef;
168
123
  if (process.env.NODE_ENV !== "production") {
169
- // Validate that the id of the object we got back matches the id
170
- // we queried for in the variables.
171
- // We do this during render instead of onComplete to make sure we are
172
- // only validating the most recent refetch.
173
124
  debugFunctions.checkSameIDAfterRefetch(debugPreviousIDAndTypename, fragmentRef, fragmentNode, componentDisplayName);
174
125
  }
175
126
  }
176
-
177
- // We read and subscribe to the fragment using useFragmentNode.
178
- // If refetch was called, we read the fragment using the new computed
179
- // fragment ref from the refetch query response; otherwise, we use the
180
- // fragment ref passed by the caller as normal.
181
127
  var fragmentData = useFragmentInternal(fragmentNode, fragmentRef, componentDisplayName);
182
- var refetch = useRefetchFunction(componentDisplayName, dispatch, disposeQuery, fragmentData, fragmentIdentifier, fragmentNode, fragmentRefPathInResponse, identifierField, loadQuery, parentFragmentRef, refetchableRequest);
128
+ var refetch = useRefetchFunction(componentDisplayName, dispatch, disposeQuery, fragmentData, fragmentIdentifier, fragmentNode, fragmentRefPathInResponse, identifierInfo, loadQuery, parentFragmentRef, refetchableRequest);
183
129
  return {
184
130
  fragmentData: fragmentData,
185
131
  fragmentRef: fragmentRef,
186
132
  refetch: refetch
187
133
  };
188
134
  }
189
- function useRefetchFunction(componentDisplayName, dispatch, disposeQuery, fragmentData, fragmentIdentifier, fragmentNode, fragmentRefPathInResponse, identifierField, loadQuery, parentFragmentRef, refetchableRequest) {
135
+ function useRefetchFunction(componentDisplayName, dispatch, disposeQuery, fragmentData, fragmentIdentifier, fragmentNode, fragmentRefPathInResponse, identifierInfo, loadQuery, parentFragmentRef, refetchableRequest) {
190
136
  var isMountedRef = useIsMountedRef();
191
- var identifierValue = identifierField != null && fragmentData != null && typeof fragmentData === 'object' ? fragmentData[identifierField] : null;
137
+ var identifierValue = (identifierInfo === null || identifierInfo === void 0 ? void 0 : identifierInfo.identifierField) != null && fragmentData != null && typeof fragmentData === 'object' ? fragmentData[identifierInfo.identifierField] : null;
192
138
  return useCallback(function (providedRefetchVariables, options) {
193
- // Bail out and warn if we're trying to refetch after the component
194
- // has unmounted
195
139
  if (isMountedRef.current !== true) {
196
140
  process.env.NODE_ENV !== "production" ? warning(false, 'Relay: Unexpected call to `refetch` on unmounted component for fragment ' + '`%s` in `%s`. It looks like some instances of your component are ' + 'still trying to fetch data but they already unmounted. ' + 'Please make sure you clear all timers, intervals, ' + 'async calls, etc that may trigger a fetch.', fragmentNode.name, componentDisplayName) : void 0;
197
141
  return {
@@ -219,35 +163,16 @@ function useRefetchFunction(componentDisplayName, dispatch, disposeQuery, fragme
219
163
  parentVariables = fragmentSelector.owner.variables;
220
164
  fragmentVariables = fragmentSelector.variables;
221
165
  }
222
-
223
- // A user of `useRefetchableFragment()` may pass a subset of
224
- // all variables required by the fragment when calling `refetch()`.
225
- // We fill in any variables not passed by the call to `refetch()` with the
226
- // variables from the original parent fragment owner.
227
166
  var refetchVariables = (0, _objectSpread2["default"])((0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, parentVariables), fragmentVariables), providedRefetchVariables);
228
-
229
- // If the query needs an identifier value ('id' or similar) and one
230
- // was not explicitly provided, read it from the fragment data.
231
- if (identifierField != null && !providedRefetchVariables.hasOwnProperty('id')) {
232
- // @refetchable fragments are guaranteed to have an `id` selection
233
- // if the type is Node, implements Node, or is @fetchable. Double-check
234
- // that there actually is a value at runtime.
167
+ if (identifierInfo != null && !providedRefetchVariables.hasOwnProperty(identifierInfo.identifierQueryVariableName)) {
235
168
  if (typeof identifierValue !== 'string') {
236
- process.env.NODE_ENV !== "production" ? warning(false, 'Relay: Expected result to have a string ' + '`%s` in order to refetch, got `%s`.', identifierField, identifierValue) : void 0;
169
+ process.env.NODE_ENV !== "production" ? warning(false, 'Relay: Expected result to have a string ' + '`%s` in order to refetch, got `%s`.', identifierInfo.identifierField, identifierValue) : void 0;
237
170
  }
238
- refetchVariables.id = identifierValue;
171
+ refetchVariables[identifierInfo.identifierQueryVariableName] = identifierValue;
239
172
  }
240
173
  var refetchQuery = createOperationDescriptor(refetchableRequest, refetchVariables, {
241
174
  force: true
242
175
  });
243
-
244
- // We call loadQuery which will start a network request if necessary
245
- // and update the querRef from useQueryLoader.
246
- // Note the following:
247
- // - loadQuery will dispose of any previously refetched queries.
248
- // - We use the variables extracted off the OperationDescriptor
249
- // so that they have been filtered out to include only the
250
- // variables actually declared in the query.
251
176
  loadQuery(refetchQuery.request.variables, {
252
177
  fetchPolicy: fetchPolicy,
253
178
  __environment: refetchEnvironment,
@@ -264,29 +189,21 @@ function useRefetchFunction(componentDisplayName, dispatch, disposeQuery, fragme
264
189
  return {
265
190
  dispose: disposeQuery
266
191
  };
267
- },
268
- // NOTE: We disable react-hooks-deps warning because:
269
- // - We know fragmentRefPathInResponse is static, so it can be omitted from
270
- // deps
271
- // - We know fragmentNode is static, so it can be omitted from deps.
272
- // - fragmentNode and parentFragmentRef are also captured by including
273
- // fragmentIdentifier
274
- // eslint-disable-next-line react-hooks/exhaustive-deps
275
- [fragmentIdentifier, dispatch, disposeQuery, identifierValue, loadQuery]);
192
+ }, [fragmentIdentifier, dispatch, disposeQuery, identifierValue, loadQuery]);
276
193
  }
277
194
  var debugFunctions;
278
195
  if (process.env.NODE_ENV !== "production") {
279
196
  debugFunctions = {
280
- getInitialIDAndType: function getInitialIDAndType(memoRefetchVariables, fragmentRefPathInResponse, environment) {
197
+ getInitialIDAndType: function getInitialIDAndType(memoRefetchVariables, fragmentRefPathInResponse, identifierQueryVariableName, environment) {
281
198
  var _require4 = require('relay-runtime'),
282
199
  Record = _require4.Record;
283
- var id = memoRefetchVariables === null || memoRefetchVariables === void 0 ? void 0 : memoRefetchVariables.id;
200
+ var id = memoRefetchVariables === null || memoRefetchVariables === void 0 ? void 0 : memoRefetchVariables[identifierQueryVariableName !== null && identifierQueryVariableName !== void 0 ? identifierQueryVariableName : 'id'];
284
201
  if (fragmentRefPathInResponse.length !== 1 || fragmentRefPathInResponse[0] !== 'node' || id == null) {
285
202
  return null;
286
203
  }
287
204
  var recordSource = environment.getStore().getSource();
288
205
  var record = recordSource.get(id);
289
- var typename = record && Record.getType(record);
206
+ var typename = record == null ? null : Record.getType(record);
290
207
  if (typename == null) {
291
208
  return null;
292
209
  }
@@ -314,7 +231,6 @@ if (process.env.NODE_ENV !== "production") {
314
231
  }
315
232
  var _require6 = require('relay-runtime'),
316
233
  ID_KEY = _require6.ID_KEY;
317
- // $FlowExpectedError[incompatible-use]
318
234
  var resultID = refetchedFragmentRef[ID_KEY];
319
235
  if (resultID != null && resultID !== previousIDAndTypename.id) {
320
236
  process.env.NODE_ENV !== "production" ? warning(false, 'Relay: Call to `refetch` returned a different id, expected ' + '`%s`, got `%s`, on `%s` in `%s`. ' + 'Please make sure the server correctly implements ' + 'unique id requirement.', resultID, previousIDAndTypename.id, fragmentNode.name, componentDisplayName) : void 0;
@@ -1,14 +1,3 @@
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
- *
8
- * @format
9
- * @oncall relay
10
- */
11
-
12
1
  'use strict';
13
2
 
14
3
  var useStaticFragmentNodeWarning = require('../useStaticFragmentNodeWarning');
@@ -24,14 +13,11 @@ function useRefetchableFragment(fragmentInput, fragmentRef) {
24
13
  fragmentData = _useRefetchableFragme.fragmentData,
25
14
  refetch = _useRefetchableFragme.refetch;
26
15
  if (process.env.NODE_ENV !== "production") {
27
- // eslint-disable-next-line react-hooks/rules-of-hooks
28
16
  useDebugValue({
29
17
  fragment: fragmentNode.name,
30
18
  data: fragmentData
31
19
  });
32
20
  }
33
- /* $FlowExpectedError[prop-missing] : Exposed options is a subset of internal
34
- * options */
35
21
  return [fragmentData, refetch];
36
22
  }
37
23
  module.exports = useRefetchableFragment;
@@ -1,14 +1,3 @@
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
- *
8
- * @format
9
- * @oncall relay
10
- */
11
-
12
1
  'use strict';
13
2
 
14
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
@@ -34,7 +23,6 @@ function useBlockingPaginationFragment(fragmentInput, parentFragmentRef) {
34
23
  useStaticFragmentNodeWarning(fragmentNode, "first argument of ".concat(componentDisplayName));
35
24
  var _getPaginationMetadat = getPaginationMetadata(fragmentNode, componentDisplayName),
36
25
  connectionPathInFragmentData = _getPaginationMetadat.connectionPathInFragmentData,
37
- identifierField = _getPaginationMetadat.identifierField,
38
26
  paginationRequest = _getPaginationMetadat.paginationRequest,
39
27
  paginationMetadata = _getPaginationMetadat.paginationMetadata,
40
28
  stream = _getPaginationMetadat.stream;
@@ -46,8 +34,6 @@ function useBlockingPaginationFragment(fragmentInput, parentFragmentRef) {
46
34
  disableStoreUpdates = _useRefetchableFragme.disableStoreUpdates,
47
35
  enableStoreUpdates = _useRefetchableFragme.enableStoreUpdates;
48
36
  var fragmentIdentifier = getFragmentIdentifier(fragmentNode, fragmentRef);
49
-
50
- // Backward pagination
51
37
  var _useLoadMore = useLoadMore({
52
38
  componentDisplayName: componentDisplayName,
53
39
  connectionPathInFragmentData: connectionPathInFragmentData,
@@ -58,15 +44,12 @@ function useBlockingPaginationFragment(fragmentInput, parentFragmentRef) {
58
44
  fragmentIdentifier: fragmentIdentifier,
59
45
  fragmentNode: fragmentNode,
60
46
  fragmentRef: fragmentRef,
61
- identifierField: identifierField,
62
47
  paginationMetadata: paginationMetadata,
63
48
  paginationRequest: paginationRequest
64
49
  }),
65
50
  loadPrevious = _useLoadMore[0],
66
51
  hasPrevious = _useLoadMore[1],
67
52
  disposeFetchPrevious = _useLoadMore[2];
68
-
69
- // Forward pagination
70
53
  var _useLoadMore2 = useLoadMore({
71
54
  componentDisplayName: componentDisplayName,
72
55
  connectionPathInFragmentData: connectionPathInFragmentData,
@@ -77,7 +60,6 @@ function useBlockingPaginationFragment(fragmentInput, parentFragmentRef) {
77
60
  fragmentIdentifier: fragmentIdentifier,
78
61
  fragmentNode: fragmentNode,
79
62
  fragmentRef: fragmentRef,
80
- identifierField: identifierField,
81
63
  paginationMetadata: paginationMetadata,
82
64
  paginationRequest: paginationRequest
83
65
  }),
@@ -92,7 +74,6 @@ function useBlockingPaginationFragment(fragmentInput, parentFragmentRef) {
92
74
  }));
93
75
  }, [disposeFetchNext, disposeFetchPrevious, refetch]);
94
76
  return {
95
- // $FlowFixMe[incompatible-cast]
96
77
  data: fragmentData,
97
78
  loadNext: loadNext,
98
79
  loadPrevious: loadPrevious,
@@ -121,13 +102,7 @@ function useLoadMore(args) {
121
102
  };
122
103
  var observer = {
123
104
  complete: promiseResolve,
124
- // NOTE: loadMore is a no-op if a request is already in flight, so we
125
- // can safely assume that `start` will only be called once while a
126
- // request is in flight.
127
105
  start: function start() {
128
- // NOTE: We disable store updates when we suspend to ensure
129
- // that higher-pri updates from the Relay store don't disrupt
130
- // any Suspense timeouts passed via withSuspenseConfig.
131
106
  disableStoreUpdates();
132
107
  var promise = new Promise(function (resolve) {
133
108
  promiseResolveRef.current = function () {
@@ -138,14 +113,7 @@ function useLoadMore(args) {
138
113
  requestPromiseRef.current = promise;
139
114
  setRequestPromise(promise);
140
115
  },
141
- // NOTE: Since streaming is disallowed with this hook, this means that the
142
- // first payload will always contain the entire next page of items,
143
- // while subsequent paylaods will contain @defer'd payloads.
144
- // This allows us to unsuspend here, on the first payload, and allow
145
- // descendant components to suspend on their respective @defer payloads
146
116
  next: promiseResolve,
147
- // TODO: Handle error; we probably don't want to throw an error
148
- // and blow away the whole list of items.
149
117
  error: promiseResolve
150
118
  };
151
119
  var _useLoadMoreFunction = useLoadMoreFunction((0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, loadMoreArgs), {}, {
@@ -155,23 +123,13 @@ function useLoadMore(args) {
155
123
  loadMore = _useLoadMoreFunction[0],
156
124
  hasMore = _useLoadMoreFunction[1],
157
125
  disposeFetch = _useLoadMoreFunction[2];
158
-
159
- // NOTE: To determine if we need to suspend, we check that the promise in
160
- // state is the same as the promise on the ref, which ensures that we
161
- // wont incorrectly suspend on other higher-pri updates before the update
162
- // to suspend has committed.
163
126
  if (requestPromise != null && requestPromise === requestPromiseRef.current) {
164
127
  throw requestPromise;
165
128
  }
166
129
  useEffect(function () {
167
130
  if (requestPromise !== requestPromiseRef.current) {
168
- // NOTE: After suspense pagination has resolved, we re-enable store updates
169
- // for this fragment. This may cause the component to re-render if
170
- // we missed any updates to the fragment data other than the pagination update.
171
131
  enableStoreUpdates();
172
132
  }
173
- // NOTE: We know the identity of enableStoreUpdates wont change
174
- // eslint-disable-next-line react-hooks/exhaustive-deps
175
133
  }, [requestPromise]);
176
134
  return [loadMore, hasMore, disposeFetch];
177
135
  }
@@ -1,27 +1,9 @@
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
- *
8
- * @format
9
- * @oncall relay
10
- */
11
-
12
1
  'use strict';
13
2
 
14
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
15
4
  var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
16
5
  var useLazyLoadQuery = require('./useLazyLoadQuery');
17
-
18
- /**
19
- * This hook can be used to render client-only queries.
20
- * These queries are consist of queries for client-only data,
21
- * schematized via local schema extensions and/or Relay resolvers.
22
- */
23
6
  function useClientQuery(gqlQuery, variables, options) {
24
- // $FlowFixMe[incompatible-type] client queries can be used with useLazyLoadQuery, but only with `store-only` policy.
25
7
  var query = gqlQuery;
26
8
  return useLazyLoadQuery(query, variables, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, options), {}, {
27
9
  fetchPolicy: 'store-only'
@@ -1,14 +1,3 @@
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
- *
8
- * @format
9
- * @oncall relay
10
- */
11
-
12
1
  'use strict';
13
2
 
14
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
@@ -27,26 +16,6 @@ var initialNullEntryPointReferenceState = {
27
16
  };
28
17
  function useLoadEntryPoint(environmentProvider, entryPoint, options) {
29
18
  var _options$TEST_ONLY__i, _options$TEST_ONLY__i2, _options$TEST_ONLY__i3, _options$TEST_ONLY__i4;
30
- /**
31
- * We want to always call `entryPointReference.dispose()` for every call to
32
- * `setEntryPointReference(loadEntryPoint(...))` so that no leaks of data in Relay
33
- * stores will occur.
34
- *
35
- * However, a call to `setState(newState)` is not always followed by a commit where
36
- * this value is reflected in the state. Thus, we cannot reliably clean up each ref
37
- * with `useEffect(() => () => entryPointReference.dispose(), [entryPointReference])`.
38
- *
39
- * Instead, we keep track of each call to `loadEntryPoint` in a ref.
40
- * Relying on the fact that if a state change commits, no state changes that were
41
- * initiated prior to the currently committing state change will ever subsequently
42
- * commit, we can safely dispose of all preloaded entry point references
43
- * associated with state changes initiated prior to the currently committing state
44
- * change.
45
- *
46
- * Finally, when the hook unmounts, we also dispose of all remaining uncommitted
47
- * entry point references.
48
- */
49
-
50
19
  useTrackLoadQueryInRender();
51
20
  var initialEntryPointReferenceInternal = (_options$TEST_ONLY__i = options === null || options === void 0 ? void 0 : (_options$TEST_ONLY__i2 = options.TEST_ONLY__initialEntryPointData) === null || _options$TEST_ONLY__i2 === void 0 ? void 0 : _options$TEST_ONLY__i2.entryPointReference) !== null && _options$TEST_ONLY__i !== void 0 ? _options$TEST_ONLY__i : initialNullEntryPointReferenceState;
52
21
  var initialEntryPointParamsInternal = (_options$TEST_ONLY__i3 = options === null || options === void 0 ? void 0 : (_options$TEST_ONLY__i4 = options.TEST_ONLY__initialEntryPointData) === null || _options$TEST_ONLY__i4 === void 0 ? void 0 : _options$TEST_ONLY__i4.entryPointParams) !== null && _options$TEST_ONLY__i3 !== void 0 ? _options$TEST_ONLY__i3 : null;
@@ -78,53 +47,17 @@ function useLoadEntryPoint(environmentProvider, entryPoint, options) {
78
47
  var maybeHiddenOrFastRefresh = useRef(false);
79
48
  useEffect(function () {
80
49
  return function () {
81
- // Attempt to detect if the component was
82
- // hidden (by Offscreen API), or fast refresh occured;
83
- // Only in these situations would the effect cleanup
84
- // for "unmounting" run multiple times, so if
85
- // we are ever able to read this ref with a value
86
- // of true, it means that one of these cases
87
- // has happened.
88
50
  maybeHiddenOrFastRefresh.current = true;
89
51
  };
90
52
  }, []);
91
53
  useEffect(function () {
92
54
  if (maybeHiddenOrFastRefresh.current === true) {
93
- // This block only runs if the component has previously "unmounted"
94
- // due to it being hidden by the Offscreen API, or during fast refresh.
95
- // At this point, the current entryPointReference will have been disposed
96
- // by the previous cleanup, so instead of attempting to
97
- // do our regular commit setup, which would incorrectly leave our
98
- // current entryPointReference disposed, we need to load the entryPoint again
99
- // and force a re-render by calling entryPointLoaderCallback again,
100
- // so that the entryPointReference's queries are correctly re-retained, and
101
- // potentially refetched if necessary.
102
55
  maybeHiddenOrFastRefresh.current = false;
103
56
  if (entryPointReference.kind !== 'NullEntryPointReference' && entryPointParams != null) {
104
57
  entryPointLoaderCallback(entryPointParams);
105
58
  }
106
59
  return;
107
60
  }
108
-
109
- // When a new entryPointReference is committed, we iterate over all
110
- // entrypoint refs in undisposedEntryPointReferences and dispose all of
111
- // the refs that aren't the currently committed one. This ensures
112
- // that we don't leave any dangling entrypoint references for the
113
- // case that loadEntryPoint is called multiple times before commit; when
114
- // this happens, multiple state updates will be scheduled, but only one
115
- // will commit, meaning that we need to keep track of and dispose any
116
- // query references that don't end up committing.
117
- // - We are relying on the fact that sets iterate in insertion order, and we
118
- // can remove items from a set as we iterate over it (i.e. no iterator
119
- // invalidation issues.) Thus, it is safe to loop through
120
- // undisposedEntryPointReferences until we find entryPointReference, and
121
- // remove and dispose all previous references.
122
- // - We are guaranteed to find entryPointReference in the set, because if a
123
- // state change results in a commit, no state changes initiated prior to that
124
- // one will be committed, and we are disposing and removing references
125
- // associated with commits that were initiated prior to the currently
126
- // committing state change. (A useEffect callback is called during the commit
127
- // phase.)
128
61
  var undisposedEntryPointReferences = undisposedEntryPointReferencesRef.current;
129
62
  if (isMountedRef.current) {
130
63
  var _iterator = (0, _createForOfIteratorHelper2["default"])(undisposedEntryPointReferences),
@@ -149,8 +82,6 @@ function useLoadEntryPoint(environmentProvider, entryPoint, options) {
149
82
  }, [entryPointReference, entryPointParams, entryPointLoaderCallback, isMountedRef]);
150
83
  useEffect(function () {
151
84
  return function disposeAllRemainingEntryPointReferences() {
152
- // undisposedEntryPointReferences.current is never reassigned
153
- // eslint-disable-next-line react-hooks/exhaustive-deps
154
85
  var _iterator2 = (0, _createForOfIteratorHelper2["default"])(undisposedEntryPointReferencesRef.current),
155
86
  _step2;
156
87
  try {