react-relay 18.2.0 → 19.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 (67) hide show
  1. package/ReactRelayContainerUtils.js.flow +2 -2
  2. package/ReactRelayContext.js +1 -1
  3. package/ReactRelayFragmentContainer.js.flow +5 -7
  4. package/ReactRelayLoggingContext.js.flow +21 -0
  5. package/ReactRelayPaginationContainer.js.flow +8 -8
  6. package/ReactRelayRefetchContainer.js.flow +8 -8
  7. package/ReactRelayTypes.js.flow +18 -11
  8. package/__flowtests__/ReactRelayFragmentContainer-flowtest.js.flow +1 -8
  9. package/__flowtests__/ReactRelayPaginationContainer-flowtest.js.flow +2 -5
  10. package/__flowtests__/ReactRelayRefetchContainer-flowtest.js.flow +2 -5
  11. package/buildReactRelayContainer.js.flow +3 -3
  12. package/hooks.js +1 -1
  13. package/index.js +1 -1
  14. package/index.js.flow +3 -3
  15. package/legacy.js +1 -1
  16. package/lib/ReactRelayLoggingContext.js +6 -0
  17. package/lib/index.js +2 -2
  18. package/lib/relay-hooks/legacy/FragmentResource.js +3 -3
  19. package/lib/relay-hooks/legacy/useRefetchableFragmentNode.js +1 -1
  20. package/lib/relay-hooks/loadEntryPoint.js +3 -0
  21. package/lib/relay-hooks/loadQuery.js +5 -3
  22. package/lib/relay-hooks/preloadQuery_DEPRECATED.js +7 -2
  23. package/lib/relay-hooks/readFragmentInternal.js +2 -2
  24. package/lib/relay-hooks/useFragmentInternal_CURRENT.js +11 -6
  25. package/lib/relay-hooks/useFragmentInternal_EXPERIMENTAL.js +11 -6
  26. package/lib/relay-hooks/useLoadMoreFunction.js +3 -2
  27. package/lib/relay-hooks/useLoadMoreFunction_EXPERIMENTAL.js +3 -2
  28. package/lib/relay-hooks/usePaginationFragment.js +5 -1
  29. package/lib/relay-hooks/usePrefetchableForwardPaginationFragment.js +228 -0
  30. package/lib/relay-hooks/usePrefetchableForwardPaginationFragment_EXPERIMENTAL.js +8 -8
  31. package/lib/relay-hooks/useRefetchableFragmentInternal.js +3 -3
  32. package/lib/relay-hooks/useRelayLoggingContext.js +9 -0
  33. package/package.json +3 -3
  34. package/relay-hooks/EntryPointContainer.react.js.flow +13 -17
  35. package/relay-hooks/EntryPointTypes.flow.js.flow +6 -4
  36. package/relay-hooks/MatchContainer.js.flow +1 -1
  37. package/relay-hooks/legacy/FragmentResource.js.flow +3 -6
  38. package/relay-hooks/legacy/useBlockingPaginationFragment.js.flow +2 -17
  39. package/relay-hooks/legacy/useRefetchableFragmentNode.js.flow +1 -1
  40. package/relay-hooks/loadEntryPoint.js.flow +6 -0
  41. package/relay-hooks/loadQuery.js.flow +18 -2
  42. package/relay-hooks/preloadQuery_DEPRECATED.js.flow +18 -3
  43. package/relay-hooks/readFragmentInternal.js.flow +2 -5
  44. package/relay-hooks/useEntryPointLoader.js.flow +4 -2
  45. package/relay-hooks/useFragment.js.flow +1 -0
  46. package/relay-hooks/useFragmentInternal.js.flow +2 -0
  47. package/relay-hooks/useFragmentInternal_CURRENT.js.flow +22 -5
  48. package/relay-hooks/useFragmentInternal_EXPERIMENTAL.js.flow +24 -5
  49. package/relay-hooks/useLazyLoadQuery.js.flow +4 -4
  50. package/relay-hooks/useLoadMoreFunction.js.flow +7 -7
  51. package/relay-hooks/useLoadMoreFunction_EXPERIMENTAL.js.flow +5 -7
  52. package/relay-hooks/usePaginationFragment.js.flow +6 -10
  53. package/relay-hooks/usePrefetchableForwardPaginationFragment.js.flow +436 -0
  54. package/relay-hooks/usePrefetchableForwardPaginationFragment_EXPERIMENTAL.js.flow +15 -13
  55. package/relay-hooks/usePreloadedQuery.js.flow +1 -0
  56. package/relay-hooks/useQueryLoader.js.flow +5 -1
  57. package/relay-hooks/useQueryLoader_EXPERIMENTAL.js.flow +3 -1
  58. package/relay-hooks/useRefetchableFragment.js.flow +1 -0
  59. package/relay-hooks/useRefetchableFragmentInternal.js.flow +3 -3
  60. package/relay-hooks/useRelayLoggingContext.js.flow +21 -0
  61. package/relay-hooks/useStaticFragmentNodeWarning.js.flow +1 -0
  62. package/react-relay-hooks.js +0 -4
  63. package/react-relay-hooks.min.js +0 -9
  64. package/react-relay-legacy.js +0 -4
  65. package/react-relay-legacy.min.js +0 -9
  66. package/react-relay.js +0 -4
  67. package/react-relay.min.js +0 -9
@@ -62,6 +62,7 @@ function useLoadMoreFunction_EXPERIMENTAL(args) {
62
62
  var _getConnectionState = getConnectionState(direction, fragmentNode, fragmentData, connectionPathInFragmentData),
63
63
  cursor = _getConnectionState.cursor,
64
64
  hasMore = _getConnectionState.hasMore;
65
+ var isRequestInvalid = fragmentData == null || isParentQueryActive;
65
66
  var isMountedRef = useIsMountedRef();
66
67
  var loadMore = useCallback(function (count, options) {
67
68
  var onComplete = options === null || options === void 0 ? void 0 : options.onComplete;
@@ -72,7 +73,7 @@ function useLoadMoreFunction_EXPERIMENTAL(args) {
72
73
  };
73
74
  }
74
75
  var fragmentSelector = getSelector(fragmentNode, fragmentRef);
75
- if (fetchStatusRef.current.kind === 'fetching' || fragmentData == null || isParentQueryActive) {
76
+ if (fetchStatusRef.current.kind === 'fetching' || isRequestInvalid) {
76
77
  if (fragmentSelector == null) {
77
78
  process.env.NODE_ENV !== "production" ? warning(false, 'Relay: Unexpected fetch while using a null fragment ref ' + 'for fragment `%s` in `%s`. When fetching more items, we expect ' + "initial fragment data to be non-null. Please make sure you're " + 'passing a valid fragment ref to `%s` before paginating.', fragmentNode.name, componentDisplayName, componentDisplayName) : void 0;
78
79
  }
@@ -124,7 +125,7 @@ function useLoadMoreFunction_EXPERIMENTAL(args) {
124
125
  return {
125
126
  dispose: function dispose() {}
126
127
  };
127
- }, [environment, identifierValue, direction, cursor, isParentQueryActive, fragmentData, fragmentNode.name, fragmentRef, componentDisplayName]);
128
+ }, [environment, identifierValue, direction, cursor, isRequestInvalid, fragmentNode.name, fragmentRef, componentDisplayName]);
128
129
  return [loadMore, hasMore, forceDisposeFn];
129
130
  }
130
131
  module.exports = useLoadMoreFunction_EXPERIMENTAL;
@@ -11,6 +11,7 @@ var _require = require('react'),
11
11
  useDebugValue = _require.useDebugValue,
12
12
  useState = _require.useState;
13
13
  var _require2 = require('relay-runtime'),
14
+ RelayFeatureFlags = _require2.RelayFeatureFlags,
14
15
  getFragment = _require2.getFragment,
15
16
  getFragmentIdentifier = _require2.getFragmentIdentifier,
16
17
  getPaginationMetadata = _require2.getPaginationMetadata;
@@ -110,7 +111,10 @@ function useLoadMore(args) {
110
111
  },
111
112
  error: function error() {
112
113
  return setIsLoadingMore(false);
113
- }
114
+ },
115
+ unsubscribe: RelayFeatureFlags.ENABLE_USE_PAGINATION_IS_LOADING_FIX ? function () {
116
+ return setIsLoadingMore(false);
117
+ } : undefined
114
118
  };
115
119
  var handleReset = function handleReset() {
116
120
  return setIsLoadingMore(false);
@@ -0,0 +1,228 @@
1
+ 'use strict';
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
4
+ var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
5
+ var useFragment = require('./useFragment');
6
+ var useLoadMoreFunction = require('./useLoadMoreFunction');
7
+ var useRefetchableFragmentInternal = require('./useRefetchableFragmentInternal');
8
+ var useRelayEnvironment = require('./useRelayEnvironment');
9
+ var useStaticFragmentNodeWarning = require('./useStaticFragmentNodeWarning');
10
+ var invariant = require('invariant');
11
+ var _require = require('react'),
12
+ useCallback = _require.useCallback,
13
+ useDebugValue = _require.useDebugValue,
14
+ useEffect = _require.useEffect,
15
+ useLayoutEffect = _require.useLayoutEffect,
16
+ useMemo = _require.useMemo,
17
+ useRef = _require.useRef,
18
+ useState = _require.useState;
19
+ var _require2 = require('relay-runtime'),
20
+ getFragment = _require2.getFragment,
21
+ getFragmentIdentifier = _require2.getFragmentIdentifier,
22
+ getPaginationMetadata = _require2.getPaginationMetadata;
23
+ var _require3 = require('relay-runtime'),
24
+ ConnectionInterface = _require3.ConnectionInterface,
25
+ RelayFeatureFlags = _require3.RelayFeatureFlags,
26
+ getSelector = _require3.getSelector,
27
+ getValueAtPath = _require3.getValueAtPath;
28
+ function usePrefetchableForwardPaginationFragment(fragmentInput, parentFragmentRef, bufferSize, initialSize, prefetchingLoadMoreOptions) {
29
+ var _fragmentInput$metada, _fragmentInput$metada2;
30
+ var minimalFetchSize = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 1;
31
+ var disablePrefetching = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false;
32
+ var fragmentNode = getFragment(fragmentInput);
33
+ useStaticFragmentNodeWarning(fragmentNode, 'first argument of usePrefetchableForwardPaginationFragment()');
34
+ var componentDisplayName = 'usePrefetchableForwardPaginationFragment()';
35
+ var _getPaginationMetadat = getPaginationMetadata(fragmentNode, componentDisplayName),
36
+ connectionPathInFragmentData = _getPaginationMetadat.connectionPathInFragmentData,
37
+ paginationRequest = _getPaginationMetadat.paginationRequest,
38
+ paginationMetadata = _getPaginationMetadat.paginationMetadata;
39
+ var _useRefetchableFragme = useRefetchableFragmentInternal(fragmentNode, parentFragmentRef, componentDisplayName),
40
+ fragmentData = _useRefetchableFragme.fragmentData,
41
+ fragmentRef = _useRefetchableFragme.fragmentRef,
42
+ refetch = _useRefetchableFragme.refetch;
43
+ var fragmentIdentifier = getFragmentIdentifier(fragmentNode, fragmentRef);
44
+ var edgeKeys = useMemo(function () {
45
+ var connection = getValueAtPath(fragmentData, connectionPathInFragmentData);
46
+ if (connection == null) {
47
+ return null;
48
+ }
49
+ var _ConnectionInterface$ = ConnectionInterface.get(),
50
+ EDGES = _ConnectionInterface$.EDGES;
51
+ return connection[EDGES];
52
+ }, [connectionPathInFragmentData, fragmentData]);
53
+ var sourceSize = edgeKeys == null ? -1 : edgeKeys.length;
54
+ var _useState = useState(initialSize != null ? initialSize : sourceSize),
55
+ _numInUse = _useState[0],
56
+ setNumInUse = _useState[1];
57
+ var numInUse = _numInUse;
58
+ if (_numInUse === -1 && sourceSize !== -1) {
59
+ numInUse = initialSize != null ? initialSize : sourceSize;
60
+ setNumInUse(numInUse);
61
+ }
62
+ var environment = useRelayEnvironment();
63
+ var _useState2 = useState(false),
64
+ isLoadingMore = _useState2[0],
65
+ reallySetIsLoadingMore = _useState2[1];
66
+ var _useState3 = useState(false),
67
+ isRefetching = _useState3[0],
68
+ setIsRefetching = _useState3[1];
69
+ var availableSizeRef = useRef(0);
70
+ var setIsLoadingMore = useCallback(function (value) {
71
+ var _environment$getSched;
72
+ var schedule = (_environment$getSched = environment.getScheduler()) === null || _environment$getSched === void 0 ? void 0 : _environment$getSched.schedule;
73
+ if (schedule) {
74
+ schedule(function () {
75
+ reallySetIsLoadingMore(value);
76
+ });
77
+ } else {
78
+ reallySetIsLoadingMore(value);
79
+ }
80
+ }, [environment]);
81
+ var isLoadingMoreRef = useRef(false);
82
+ var observer = useMemo(function () {
83
+ function setIsLoadingFalse() {
84
+ isLoadingMoreRef.current = false;
85
+ setIsLoadingMore(false);
86
+ }
87
+ return {
88
+ start: function start() {
89
+ isLoadingMoreRef.current = true;
90
+ reallySetIsLoadingMore(true);
91
+ },
92
+ complete: setIsLoadingFalse,
93
+ error: setIsLoadingFalse,
94
+ unsubscribe: RelayFeatureFlags.ENABLE_USE_PAGINATION_IS_LOADING_FIX ? setIsLoadingFalse : undefined
95
+ };
96
+ }, [setIsLoadingMore]);
97
+ var handleReset = useCallback(function () {
98
+ if (!isRefetching) {
99
+ var _environment$getSched2;
100
+ var schedule = (_environment$getSched2 = environment.getScheduler()) === null || _environment$getSched2 === void 0 ? void 0 : _environment$getSched2.schedule;
101
+ if (schedule) {
102
+ schedule(function () {
103
+ setNumInUse(-1);
104
+ });
105
+ } else {
106
+ setNumInUse(-1);
107
+ }
108
+ }
109
+ isLoadingMoreRef.current = false;
110
+ setIsLoadingMore(false);
111
+ }, [environment, isRefetching, setIsLoadingMore]);
112
+ var _useLoadMoreFunction = useLoadMoreFunction({
113
+ componentDisplayName: componentDisplayName,
114
+ connectionPathInFragmentData: connectionPathInFragmentData,
115
+ direction: 'forward',
116
+ fragmentData: fragmentData,
117
+ fragmentIdentifier: fragmentIdentifier,
118
+ fragmentNode: fragmentNode,
119
+ fragmentRef: fragmentRef,
120
+ paginationMetadata: paginationMetadata,
121
+ paginationRequest: paginationRequest,
122
+ observer: observer,
123
+ onReset: handleReset
124
+ }),
125
+ loadMore = _useLoadMoreFunction[0],
126
+ hasNext = _useLoadMoreFunction[1],
127
+ disposeFetchNext = _useLoadMoreFunction[2];
128
+ useLayoutEffect(function () {
129
+ availableSizeRef.current = sourceSize - numInUse;
130
+ }, [numInUse, sourceSize]);
131
+ var prefetchingUNSTABLE_extraVariables = prefetchingLoadMoreOptions === null || prefetchingLoadMoreOptions === void 0 ? void 0 : prefetchingLoadMoreOptions.UNSTABLE_extraVariables;
132
+ var prefetchingOnComplete = prefetchingLoadMoreOptions === null || prefetchingLoadMoreOptions === void 0 ? void 0 : prefetchingLoadMoreOptions.onComplete;
133
+ var showMore = useCallback(function (numToAdd, options) {
134
+ if (!isLoadingMoreRef.current || availableSizeRef.current >= 0) {
135
+ availableSizeRef.current -= numToAdd;
136
+ setNumInUse(function (lastNumInUse) {
137
+ return lastNumInUse + numToAdd;
138
+ });
139
+ if (!isLoadingMoreRef.current && availableSizeRef.current < 0) {
140
+ loadMore(Math.max(minimalFetchSize, Math.min(numToAdd, bufferSize - availableSizeRef.current)), options !== null && options !== void 0 ? options : {
141
+ onComplete: prefetchingOnComplete,
142
+ UNSTABLE_extraVariables: typeof prefetchingUNSTABLE_extraVariables === 'function' ? prefetchingUNSTABLE_extraVariables({
143
+ hasNext: hasNext,
144
+ data: fragmentData,
145
+ getServerEdges: function getServerEdges() {
146
+ var selector = getSelector(edgesFragment, edgeKeys);
147
+ if (selector == null) {
148
+ return [];
149
+ }
150
+ !(selector.kind === 'PluralReaderSelector') ? process.env.NODE_ENV !== "production" ? invariant(false, 'Expected a plural selector') : invariant(false) : void 0;
151
+ return selector.selectors.map(function (sel) {
152
+ return environment.lookup(sel).data;
153
+ });
154
+ }
155
+ }) : prefetchingUNSTABLE_extraVariables
156
+ });
157
+ }
158
+ }
159
+ }, [bufferSize, loadMore, minimalFetchSize, edgeKeys, fragmentData, prefetchingUNSTABLE_extraVariables, prefetchingOnComplete]);
160
+ var edgesFragment = (_fragmentInput$metada = fragmentInput.metadata) === null || _fragmentInput$metada === void 0 ? void 0 : (_fragmentInput$metada2 = _fragmentInput$metada.refetch) === null || _fragmentInput$metada2 === void 0 ? void 0 : _fragmentInput$metada2.edgesFragment;
161
+ !(edgesFragment != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'usePrefetchableForwardPaginationFragment: Expected the edge fragment to be defined, ' + 'please make sure you have added `prefetchable_pagination: true` to `@connection`') : invariant(false) : void 0;
162
+ useEffect(function () {
163
+ if (!isLoadingMoreRef.current && !isLoadingMore && !isRefetching && !disablePrefetching && hasNext && (sourceSize - numInUse < bufferSize || numInUse > sourceSize)) {
164
+ var onComplete = prefetchingOnComplete;
165
+ loadMore(Math.max(bufferSize - Math.max(sourceSize - numInUse, 0), numInUse - sourceSize, minimalFetchSize), {
166
+ onComplete: onComplete,
167
+ UNSTABLE_extraVariables: typeof prefetchingUNSTABLE_extraVariables === 'function' ? prefetchingUNSTABLE_extraVariables({
168
+ hasNext: hasNext,
169
+ data: fragmentData,
170
+ getServerEdges: function getServerEdges() {
171
+ var selector = getSelector(edgesFragment, edgeKeys);
172
+ if (selector == null) {
173
+ return [];
174
+ }
175
+ !(selector.kind === 'PluralReaderSelector') ? process.env.NODE_ENV !== "production" ? invariant(false, 'Expected a plural selector') : invariant(false) : void 0;
176
+ return selector.selectors.map(function (sel) {
177
+ return environment.lookup(sel).data;
178
+ });
179
+ }
180
+ }) : prefetchingUNSTABLE_extraVariables
181
+ });
182
+ }
183
+ }, [hasNext, bufferSize, isRefetching, loadMore, numInUse, prefetchingUNSTABLE_extraVariables, prefetchingOnComplete, sourceSize, edgeKeys, isLoadingMore, minimalFetchSize, environment, edgesFragment]);
184
+ var realNumInUse = Math.min(numInUse, sourceSize);
185
+ var derivedEdgeKeys = useMemo(function () {
186
+ var _edgeKeys$slice;
187
+ return (_edgeKeys$slice = edgeKeys === null || edgeKeys === void 0 ? void 0 : edgeKeys.slice(0, realNumInUse)) !== null && _edgeKeys$slice !== void 0 ? _edgeKeys$slice : [];
188
+ }, [edgeKeys, realNumInUse]);
189
+ var edges = useFragment(edgesFragment, derivedEdgeKeys);
190
+ var refetchPagination = useCallback(function (variables, options) {
191
+ disposeFetchNext();
192
+ setIsRefetching(true);
193
+ return refetch(variables, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, options), {}, {
194
+ onComplete: function onComplete(maybeError) {
195
+ var _environment$getSched3, _options$onComplete;
196
+ var schedule = (_environment$getSched3 = environment.getScheduler()) === null || _environment$getSched3 === void 0 ? void 0 : _environment$getSched3.schedule;
197
+ if (schedule) {
198
+ schedule(function () {
199
+ setIsRefetching(false);
200
+ setNumInUse(-1);
201
+ });
202
+ } else {
203
+ setIsRefetching(false);
204
+ setNumInUse(-1);
205
+ }
206
+ options === null || options === void 0 ? void 0 : (_options$onComplete = options.onComplete) === null || _options$onComplete === void 0 ? void 0 : _options$onComplete.call(options, maybeError);
207
+ },
208
+ __environment: undefined
209
+ }));
210
+ }, [disposeFetchNext, environment, refetch]);
211
+ if (process.env.NODE_ENV !== "production") {
212
+ useDebugValue({
213
+ fragment: fragmentNode.name,
214
+ data: fragmentData,
215
+ hasNext: hasNext,
216
+ isLoadingNext: isLoadingMore
217
+ });
218
+ }
219
+ return {
220
+ edges: edges,
221
+ data: fragmentData,
222
+ loadNext: showMore,
223
+ hasNext: hasNext || sourceSize > numInUse,
224
+ isLoadingNext: isLoadingMore && numInUse > sourceSize,
225
+ refetch: refetchPagination
226
+ };
227
+ }
228
+ module.exports = usePrefetchableForwardPaginationFragment;
@@ -22,6 +22,7 @@ var _require2 = require('relay-runtime'),
22
22
  getPaginationMetadata = _require2.getPaginationMetadata;
23
23
  var _require3 = require('relay-runtime'),
24
24
  ConnectionInterface = _require3.ConnectionInterface,
25
+ RelayFeatureFlags = _require3.RelayFeatureFlags,
25
26
  getSelector = _require3.getSelector,
26
27
  getValueAtPath = _require3.getValueAtPath;
27
28
  function usePrefetchableForwardPaginationFragment_EXPERIMENTAL(fragmentInput, parentFragmentRef, bufferSize, initialSize, prefetchingLoadMoreOptions) {
@@ -78,19 +79,18 @@ function usePrefetchableForwardPaginationFragment_EXPERIMENTAL(fragmentInput, pa
78
79
  }, [environment]);
79
80
  var isLoadingMoreRef = useRef(false);
80
81
  var observer = useMemo(function () {
82
+ function setIsLoadingFalse() {
83
+ isLoadingMoreRef.current = false;
84
+ setIsLoadingMore(false);
85
+ }
81
86
  return {
82
87
  start: function start() {
83
88
  isLoadingMoreRef.current = true;
84
89
  reallySetIsLoadingMore(true);
85
90
  },
86
- complete: function complete() {
87
- isLoadingMoreRef.current = false;
88
- setIsLoadingMore(false);
89
- },
90
- error: function error() {
91
- isLoadingMoreRef.current = false;
92
- setIsLoadingMore(false);
93
- }
91
+ complete: setIsLoadingFalse,
92
+ error: setIsLoadingFalse,
93
+ unsubscribe: RelayFeatureFlags.ENABLE_USE_PAGINATION_IS_LOADING_FIX ? setIsLoadingFalse : undefined
94
94
  };
95
95
  }, [setIsLoadingMore]);
96
96
  var handleReset = useCallback(function () {
@@ -55,7 +55,7 @@ function reducer(state, action) {
55
55
  }
56
56
  }
57
57
  }
58
- function useRefetchableFragmentNode(fragmentNode, parentFragmentRef, componentDisplayName) {
58
+ function useRefetchableFragmentInternal(fragmentNode, parentFragmentRef, componentDisplayName) {
59
59
  var parentEnvironment = useRelayEnvironment();
60
60
  var _getRefetchMetadata = getRefetchMetadata(fragmentNode, componentDisplayName),
61
61
  refetchableRequest = _getRefetchMetadata.refetchableRequest,
@@ -226,7 +226,7 @@ if (process.env.NODE_ENV !== "production") {
226
226
  }
227
227
  },
228
228
  checkSameIDAfterRefetch: function checkSameIDAfterRefetch(previousIDAndTypename, refetchedFragmentRef, fragmentNode, componentDisplayName) {
229
- if (previousIDAndTypename == null) {
229
+ if (previousIDAndTypename == null || refetchedFragmentRef == null) {
230
230
  return;
231
231
  }
232
232
  var _require6 = require('relay-runtime'),
@@ -238,4 +238,4 @@ if (process.env.NODE_ENV !== "production") {
238
238
  }
239
239
  };
240
240
  }
241
- module.exports = useRefetchableFragmentNode;
241
+ module.exports = useRefetchableFragmentInternal;
@@ -0,0 +1,9 @@
1
+ 'use strict';
2
+
3
+ var ReactRelayLoggingContext = require('./../ReactRelayLoggingContext');
4
+ var _require = require('react'),
5
+ useContext = _require.useContext;
6
+ function useRelayLoggingContext() {
7
+ return useContext(ReactRelayLoggingContext);
8
+ }
9
+ module.exports = useRelayLoggingContext;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "react-relay",
3
3
  "description": "A framework for building GraphQL-driven React applications.",
4
- "version": "18.2.0",
4
+ "version": "19.0.0",
5
5
  "keywords": [
6
6
  "graphql",
7
7
  "relay",
@@ -20,10 +20,10 @@
20
20
  "fbjs": "^3.0.2",
21
21
  "invariant": "^2.2.4",
22
22
  "nullthrows": "^1.1.1",
23
- "relay-runtime": "18.2.0"
23
+ "relay-runtime": "19.0.0"
24
24
  },
25
25
  "peerDependencies": {
26
- "react": "^16.9.0 || ^17 || ^18"
26
+ "react": "^16.9.0 || ^17 || ^18 || ^19"
27
27
  },
28
28
  "directories": {
29
29
  "": "./"
@@ -22,29 +22,25 @@ const React = require('react');
22
22
  const {useContext, useEffect} = require('react');
23
23
  const warning = require('warning');
24
24
 
25
- function EntryPointContainer<
25
+ component EntryPointContainer<
26
26
  // $FlowFixMe[unsupported-variance-annotation]
27
- +TPreloadedQueries: {...},
27
+ TRuntimeProps: {...},
28
+ TRenders: React.Node,
28
29
  // $FlowFixMe[unsupported-variance-annotation]
29
- +TPreloadedNestedEntryPoints: {...},
30
- // $FlowFixMe[unsupported-variance-annotation]
31
- +TRuntimeProps: {...},
32
- // $FlowFixMe[unsupported-variance-annotation]
33
- +TExtraProps,
34
- // $FlowFixMe[unsupported-variance-annotation]
35
- +TEntryPointComponent: EntryPointComponent<
36
- TPreloadedQueries,
37
- TPreloadedNestedEntryPoints,
30
+ TEntryPointComponent: EntryPointComponent<
31
+ // $FlowExpectedErrors[unclear-type] Use any to accept all kinds of EntryPointComponent
32
+ any,
33
+ // $FlowExpectedErrors[unclear-type] Use any to accept all kinds of EntryPointComponent
34
+ any,
38
35
  TRuntimeProps,
39
- TExtraProps,
36
+ // $FlowExpectedErrors[unclear-type] Use any to accept all kinds of EntryPointComponent
37
+ any,
38
+ TRenders,
40
39
  >,
41
- >({
42
- entryPointReference,
43
- props,
44
- }: $ReadOnly<{
40
+ >(
45
41
  entryPointReference: PreloadedEntryPoint<TEntryPointComponent>,
46
42
  props: TRuntimeProps,
47
- }>): React.MixedElement {
43
+ ) renders TRenders {
48
44
  warning(
49
45
  entryPointReference.isDisposed === false,
50
46
  '<EntryPointContainer>: Expected entryPointReference to not be disposed ' +
@@ -36,6 +36,7 @@ export type PreloadFetchPolicy =
36
36
  export type PreloadOptions = {
37
37
  +fetchKey?: string | number,
38
38
  +fetchPolicy?: ?PreloadFetchPolicy,
39
+ +includeIf?: ?boolean,
39
40
  +networkCacheConfig?: ?CacheConfig,
40
41
  };
41
42
 
@@ -178,14 +179,15 @@ export type EntryPointComponent<
178
179
  TPreloadedEntryPoints = {},
179
180
  TRuntimeProps = {},
180
181
  TExtraProps = null,
181
- > = ComponentType<
182
- EntryPointProps<
182
+ TRenders: React.Node = React.Node,
183
+ > = component(
184
+ ...EntryPointProps<
183
185
  TPreloadedQueries,
184
186
  TPreloadedEntryPoints,
185
187
  TRuntimeProps,
186
188
  TExtraProps,
187
- >,
188
- >;
189
+ >
190
+ ) renders TRenders;
189
191
 
190
192
  // Return type of the `getPreloadProps(...)` of the entry point
191
193
  export type PreloadProps<
@@ -95,7 +95,7 @@ export type MatchPointer = {
95
95
 
96
96
  export type MatchContainerProps<TProps: {...}, TFallback: React.Node> = {
97
97
  +fallback?: ?TFallback,
98
- +loader: (module: mixed) => React.ComponentType<TProps>,
98
+ +loader: (module: mixed) => component(...TProps),
99
99
  +match: ?MatchPointer | ?TypenameOnlyPointer,
100
100
  +props?: TProps,
101
101
  };
@@ -558,13 +558,10 @@ class FragmentResourceImpl {
558
558
  _throwOrLogErrorsInSnapshot(snapshot: SingularOrPluralSnapshot) {
559
559
  if (Array.isArray(snapshot)) {
560
560
  snapshot.forEach(s => {
561
- handlePotentialSnapshotErrors(this._environment, s.errorResponseFields);
561
+ handlePotentialSnapshotErrors(this._environment, s.fieldErrors);
562
562
  });
563
563
  } else {
564
- handlePotentialSnapshotErrors(
565
- this._environment,
566
- snapshot.errorResponseFields,
567
- );
564
+ handlePotentialSnapshotErrors(this._environment, snapshot.fieldErrors);
568
565
  }
569
566
  }
570
567
 
@@ -763,7 +760,7 @@ class FragmentResourceImpl {
763
760
  missingLiveResolverFields: currentSnapshot.missingLiveResolverFields,
764
761
  seenRecords: currentSnapshot.seenRecords,
765
762
  selector: currentSnapshot.selector,
766
- errorResponseFields: currentSnapshot.errorResponseFields,
763
+ fieldErrors: currentSnapshot.fieldErrors,
767
764
  };
768
765
  if (updatedData !== renderData) {
769
766
  const result = getFragmentResult(
@@ -14,13 +14,7 @@
14
14
  import type {LoadMoreFn, UseLoadMoreFunctionArgs} from '../useLoadMoreFunction';
15
15
  import type {Options} from './useRefetchableFragmentNode';
16
16
  import type {RefetchableFragment} from 'relay-runtime';
17
- import type {
18
- Disposable,
19
- FragmentType,
20
- GraphQLResponse,
21
- Observer,
22
- Variables,
23
- } from 'relay-runtime';
17
+ import type {Disposable, FragmentType, Variables} from 'relay-runtime';
24
18
 
25
19
  const useLoadMoreFunction = require('../useLoadMoreFunction');
26
20
  const useStaticFragmentNodeWarning = require('../useStaticFragmentNodeWarning');
@@ -169,16 +163,7 @@ hook useBlockingPaginationFragment<
169
163
  hook useLoadMore<TVariables: Variables>(args: {
170
164
  disableStoreUpdates: () => void,
171
165
  enableStoreUpdates: () => void,
172
- ...$Exact<
173
- $Diff<
174
- UseLoadMoreFunctionArgs,
175
- {
176
- observer: Observer<GraphQLResponse>,
177
- onReset: () => void,
178
- ...
179
- },
180
- >,
181
- >,
166
+ ...$Exact<Omit<UseLoadMoreFunctionArgs, 'observer' | 'onReset'>>,
182
167
  }): [LoadMoreFn<TVariables>, boolean, () => void] {
183
168
  const {disableStoreUpdates, enableStoreUpdates, ...loadMoreArgs} = args;
184
169
  const [requestPromise, setRequestPromise] = useState<null | Promise<mixed>>(
@@ -592,7 +592,7 @@ if (__DEV__) {
592
592
  fragmentNode: ReaderFragment,
593
593
  componentDisplayName: string,
594
594
  ): void {
595
- if (previousIDAndTypename == null) {
595
+ if (previousIDAndTypename == null || refetchedFragmentRef == null) {
596
596
  return;
597
597
  }
598
598
  const {ID_KEY} = require('relay-runtime');
@@ -62,6 +62,12 @@ function loadEntryPoint<
62
62
  const {environmentProviderOptions, options, parameters, variables} =
63
63
  query;
64
64
 
65
+ // $FlowFixMe[prop-missing] Exists for types that wrap EntryPoint
66
+ if (options?.includeIf === false) {
67
+ // don't preload this query since the includeIf is false
68
+ return;
69
+ }
70
+
65
71
  const environment = environmentProvider.getEnvironment(
66
72
  environmentProviderOptions,
67
73
  );
@@ -28,6 +28,7 @@ import type {
28
28
  RequestIdentifier,
29
29
  RequestParameters,
30
30
  } from 'relay-runtime';
31
+ import type {OperationAvailability} from 'relay-runtime/store/RelayStoreTypes';
31
32
 
32
33
  const invariant = require('invariant');
33
34
  const {
@@ -130,6 +131,7 @@ function loadQuery<
130
131
  let didMakeNetworkRequest = false;
131
132
  const makeNetworkRequest = (
132
133
  params: RequestParameters,
134
+ checkOperation?: () => OperationAvailability,
133
135
  ): Observable<GraphQLResponse> => {
134
136
  // N.B. this function is called synchronously or not at all
135
137
  // didMakeNetworkRequest is safe to rely on in the returned value
@@ -160,7 +162,16 @@ function loadQuery<
160
162
  'raw-network-request-' + getRequestIdentifier(params, variables);
161
163
  const observable = fetchQueryDeduped(environment, identifier, () => {
162
164
  const network = environment.getNetwork();
163
- return network.execute(params, variables, networkCacheConfig);
165
+ return network.execute(
166
+ params,
167
+ variables,
168
+ networkCacheConfig,
169
+ undefined,
170
+ undefined,
171
+ undefined,
172
+ undefined,
173
+ checkOperation,
174
+ );
164
175
  });
165
176
 
166
177
  const {unsubscribe} = observable.subscribe({
@@ -247,13 +258,18 @@ function loadQuery<
247
258
  // then we do nothing.
248
259
  const shouldFetch =
249
260
  fetchPolicy !== 'store-or-network' ||
261
+ // environment.check can trigger store updates through missing field handlers,
262
+ // short circuiting the check avoids unnecessary updates
250
263
  environment.check(operation).status !== 'available';
251
264
 
252
265
  if (shouldFetch) {
253
266
  executeDeduped(operation, () => {
254
267
  // N.B. Since we have the operation synchronously available here,
255
268
  // we can immediately fetch and execute the operation.
256
- const networkObservable = makeNetworkRequest(concreteRequest.params);
269
+ const networkObservable = makeNetworkRequest(
270
+ concreteRequest.params,
271
+ () => environment.check(operation),
272
+ );
257
273
  const executeObservable = executeWithNetworkSource(
258
274
  operation,
259
275
  networkObservable,
@@ -24,6 +24,7 @@ import type {
24
24
  GraphQLResponse,
25
25
  GraphQLTaggedNode,
26
26
  IEnvironment,
27
+ OperationAvailability,
27
28
  OperationType,
28
29
  Subscription,
29
30
  } from 'relay-runtime';
@@ -167,12 +168,17 @@ function preloadQueryDeduped<TQuery: OperationType>(
167
168
  }`;
168
169
  const prevQueryEntry = pendingQueries.get(cacheKey);
169
170
 
170
- const availability =
171
- fetchPolicy === STORE_OR_NETWORK_DEFAULT && query != null && query != null
171
+ function checkOperation(): OperationAvailability {
172
+ return query != null
172
173
  ? environment.check(
173
174
  createOperationDescriptor(query, variables, networkCacheConfig),
174
175
  )
175
176
  : {status: 'missing'};
177
+ }
178
+ const availability =
179
+ fetchPolicy === STORE_OR_NETWORK_DEFAULT
180
+ ? checkOperation()
181
+ : {status: 'missing'};
176
182
 
177
183
  let nextQueryEntry: ?PendingQueryEntry;
178
184
  if (availability.status === 'available' && query != null) {
@@ -203,7 +209,16 @@ function preloadQueryDeduped<TQuery: OperationType>(
203
209
  }
204
210
  } else if (prevQueryEntry == null || prevQueryEntry.kind !== 'network') {
205
211
  // Should fetch but we're not already fetching: fetch!
206
- const source = network.execute(params, variables, networkCacheConfig, null);
212
+ const source = network.execute(
213
+ params,
214
+ variables,
215
+ networkCacheConfig,
216
+ null,
217
+ undefined,
218
+ undefined,
219
+ undefined,
220
+ checkOperation,
221
+ );
207
222
  const subject = new ReplaySubject<GraphQLResponse>();
208
223
  nextQueryEntry = {
209
224
  cacheKey,
@@ -83,13 +83,10 @@ function handlePotentialSnapshotErrorsForState(
83
83
  state: FragmentState,
84
84
  ): void {
85
85
  if (state.kind === 'singular') {
86
- handlePotentialSnapshotErrors(
87
- environment,
88
- state.snapshot.errorResponseFields,
89
- );
86
+ handlePotentialSnapshotErrors(environment, state.snapshot.fieldErrors);
90
87
  } else if (state.kind === 'plural') {
91
88
  for (const snapshot of state.snapshots) {
92
- handlePotentialSnapshotErrors(environment, snapshot.errorResponseFields);
89
+ handlePotentialSnapshotErrors(environment, snapshot.fieldErrors);
93
90
  }
94
91
  }
95
92
  }