react-relay 18.2.0 → 20.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 (69) 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 +4 -5
  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 +3 -3
  24. package/lib/relay-hooks/useFragmentInternal_CURRENT.js +12 -7
  25. package/lib/relay-hooks/useFragmentInternal_EXPERIMENTAL.js +25 -10
  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 +7 -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 +20 -4
  42. package/relay-hooks/preloadQuery_DEPRECATED.js.flow +18 -3
  43. package/relay-hooks/readFragmentInternal.js.flow +6 -6
  44. package/relay-hooks/useEntryPointLoader.js.flow +5 -3
  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 +26 -6
  48. package/relay-hooks/useFragmentInternal_EXPERIMENTAL.js.flow +53 -14
  49. package/relay-hooks/useLazyLoadQuery.js.flow +62 -13
  50. package/relay-hooks/useLazyLoadQueryNode.js.flow +1 -1
  51. package/relay-hooks/useLoadMoreFunction.js.flow +7 -7
  52. package/relay-hooks/useLoadMoreFunction_EXPERIMENTAL.js.flow +5 -7
  53. package/relay-hooks/usePaginationFragment.js.flow +6 -10
  54. package/relay-hooks/usePrefetchableForwardPaginationFragment.js.flow +436 -0
  55. package/relay-hooks/usePrefetchableForwardPaginationFragment_EXPERIMENTAL.js.flow +15 -13
  56. package/relay-hooks/usePreloadedQuery.js.flow +2 -1
  57. package/relay-hooks/useQueryLoader.js.flow +6 -2
  58. package/relay-hooks/useQueryLoader_EXPERIMENTAL.js.flow +3 -1
  59. package/relay-hooks/useRefetchableFragment.js.flow +1 -0
  60. package/relay-hooks/useRefetchableFragmentInternal.js.flow +3 -3
  61. package/relay-hooks/useRelayEnvironment.js.flow +22 -0
  62. package/relay-hooks/useRelayLoggingContext.js.flow +21 -0
  63. package/relay-hooks/useStaticFragmentNodeWarning.js.flow +1 -0
  64. package/react-relay-hooks.js +0 -4
  65. package/react-relay-hooks.min.js +0 -9
  66. package/react-relay-legacy.js +0 -4
  67. package/react-relay-legacy.min.js +0 -9
  68. package/react-relay.js +0 -4
  69. package/react-relay.min.js +0 -9
@@ -7,6 +7,7 @@ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers
7
7
  var _require = require('./QueryResource'),
8
8
  getQueryResourceForEnvironment = _require.getQueryResourceForEnvironment;
9
9
  var useRelayEnvironment = require('./useRelayEnvironment');
10
+ var useRelayLoggingContext = require('./useRelayLoggingContext');
10
11
  var invariant = require('invariant');
11
12
  var _require2 = require('react'),
12
13
  useDebugValue = _require2.useDebugValue,
@@ -114,16 +115,16 @@ function getSuspendingLiveResolver(state) {
114
115
  return missingFields;
115
116
  }
116
117
  }
117
- function handlePotentialSnapshotErrorsForState(environment, state) {
118
+ function handlePotentialSnapshotErrorsForState(environment, state, loggingContext) {
118
119
  if (state.kind === 'singular') {
119
- handlePotentialSnapshotErrors(environment, state.snapshot.errorResponseFields);
120
+ handlePotentialSnapshotErrors(environment, state.snapshot.fieldErrors, loggingContext);
120
121
  } else if (state.kind === 'plural') {
121
122
  var _iterator5 = (0, _createForOfIteratorHelper2["default"])(state.snapshots),
122
123
  _step5;
123
124
  try {
124
125
  for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
125
126
  var snapshot = _step5.value;
126
- handlePotentialSnapshotErrors(environment, snapshot.errorResponseFields);
127
+ handlePotentialSnapshotErrors(environment, snapshot.fieldErrors, loggingContext);
127
128
  }
128
129
  } catch (err) {
129
130
  _iterator5.e(err);
@@ -150,7 +151,7 @@ function handleMissedUpdates(environment, state) {
150
151
  missingLiveResolverFields: currentSnapshot.missingLiveResolverFields,
151
152
  seenRecords: currentSnapshot.seenRecords,
152
153
  selector: currentSnapshot.selector,
153
- errorResponseFields: currentSnapshot.errorResponseFields
154
+ fieldErrors: currentSnapshot.fieldErrors
154
155
  };
155
156
  return [updatedData !== state.snapshot.data, {
156
157
  kind: 'singular',
@@ -173,7 +174,7 @@ function handleMissedUpdates(environment, state) {
173
174
  missingLiveResolverFields: _currentSnapshot.missingLiveResolverFields,
174
175
  seenRecords: _currentSnapshot.seenRecords,
175
176
  selector: _currentSnapshot.selector,
176
- errorResponseFields: _currentSnapshot.errorResponseFields
177
+ fieldErrors: _currentSnapshot.fieldErrors
177
178
  };
178
179
  if (_updatedData !== snapshot.data) {
179
180
  didMissUpdates = true;
@@ -198,7 +199,11 @@ function handleMissingClientEdge(environment, parentFragmentNode, parentFragment
198
199
  var queryOperationDescriptor = createOperationDescriptor(missingClientEdgeRequestInfo.request, variables, queryOptions === null || queryOptions === void 0 ? void 0 : queryOptions.networkCacheConfig);
199
200
  var QueryResource = getQueryResourceForEnvironment(environment);
200
201
  var queryResult = QueryResource.prepare(queryOperationDescriptor, fetchQueryInternal(environment, queryOperationDescriptor), queryOptions === null || queryOptions === void 0 ? void 0 : queryOptions.fetchPolicy);
201
- return [queryResult, getPromiseForActiveRequest(environment, queryOperationDescriptor.request)];
202
+ var promise = getPromiseForActiveRequest(environment, queryOperationDescriptor.request);
203
+ if (promise != null && promise.displayName == null) {
204
+ promise.displayName = missingClientEdgeRequestInfo.request.params.name;
205
+ }
206
+ return [queryResult, promise];
202
207
  }
203
208
  function subscribeToSnapshot(environment, state, setState) {
204
209
  if (state.kind === 'bailout') {
@@ -324,6 +329,10 @@ function useFragmentInternal_EXPERIMENTAL(fragmentNode, fragmentRef, hookDisplay
324
329
  }
325
330
  !(fragmentRef == null || isPlural && Array.isArray(fragmentRef) && fragmentRef.length === 0 || fragmentSelector != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Relay: Expected to receive an object where `...%s` was spread, ' + 'but the fragment reference was not found`. This is most ' + 'likely the result of:\n' + "- Forgetting to spread `%s` in `%s`'s parent's fragment.\n" + '- Conditionally fetching `%s` but unconditionally passing %s prop ' + 'to `%s`. If the parent fragment only fetches the fragment conditionally ' + '- with e.g. `@include`, `@skip`, or inside a `... on SomeType { }` ' + 'spread - then the fragment reference will not exist. ' + 'In this case, pass `null` if the conditions for evaluating the ' + 'fragment are not met (e.g. if the `@include(if)` value is false.)', fragmentNode.name, fragmentNode.name, hookDisplayName, fragmentNode.name, hookDisplayName) : invariant(false) : void 0;
326
331
  var environment = useRelayEnvironment();
332
+ var loggerContext;
333
+ if (RelayFeatureFlags.ENABLE_UI_CONTEXT_ON_RELAY_LOGGER) {
334
+ loggerContext = useRelayLoggingContext();
335
+ }
327
336
  var _useState = useState(function () {
328
337
  return getFragmentState(environment, fragmentSelector);
329
338
  }),
@@ -340,7 +349,7 @@ function useFragmentInternal_EXPERIMENTAL(fragmentNode, fragmentRef, hookDisplay
340
349
  useEffect(function () {
341
350
  committedFragmentSelectorRef.current = fragmentSelector;
342
351
  }, [fragmentSelector]);
343
- if (((_fragmentNode$metadat2 = fragmentNode.metadata) === null || _fragmentNode$metadat2 === void 0 ? void 0 : _fragmentNode$metadat2.hasClientEdges) === true) {
352
+ if (((_fragmentNode$metadat2 = fragmentNode.metadata) === null || _fragmentNode$metadat2 === void 0 ? void 0 : _fragmentNode$metadat2.hasClientEdges) === true || RelayFeatureFlags.CHECK_ALL_FRAGMENTS_FOR_MISSING_CLIENT_EDGES) {
344
353
  var _useMemo = useMemo(function () {
345
354
  var missingClientEdges = getMissingClientEdges(state);
346
355
  var clientEdgeQueries;
@@ -371,7 +380,11 @@ function useFragmentInternal_EXPERIMENTAL(fragmentNode, fragmentRef, hookDisplay
371
380
  clientEdgeQueries = _useMemo[0],
372
381
  activeRequestPromises = _useMemo[1];
373
382
  if (activeRequestPromises.length) {
374
- throw Promise.all(activeRequestPromises);
383
+ var allPromises = Promise.all(activeRequestPromises);
384
+ allPromises.displayName = "RelayClientEdge(".concat(activeRequestPromises.map(function (promise) {
385
+ return promise.displayName;
386
+ }).join(','), ")");
387
+ throw allPromises;
375
388
  }
376
389
  useEffect(function () {
377
390
  var QueryResource = getQueryResourceForEnvironment(environment);
@@ -401,9 +414,11 @@ function useFragmentInternal_EXPERIMENTAL(fragmentNode, fragmentRef, hookDisplay
401
414
  if (isMissingData(state)) {
402
415
  var suspendingLiveResolvers = getSuspendingLiveResolver(state);
403
416
  if (suspendingLiveResolvers != null && suspendingLiveResolvers.length > 0) {
404
- throw Promise.all(suspendingLiveResolvers.map(function (liveStateID) {
417
+ var promise = Promise.all(suspendingLiveResolvers.map(function (liveStateID) {
405
418
  return environment.getStore().getLiveResolverPromise(liveStateID);
406
419
  }));
420
+ promise.displayName = 'RelayLiveResolver(' + fragmentNode.name + ')';
421
+ throw promise;
407
422
  }
408
423
  if (RelayFeatureFlags.ENABLE_RELAY_OPERATION_TRACKER_SUSPENSE || environment !== previousEnvironment || !committedFragmentSelectorRef.current || !areEqualSelectors(committedFragmentSelectorRef.current, fragmentSelector)) {
409
424
  !(fragmentSelector != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'refinement, see invariants above') : invariant(false) : void 0;
@@ -414,7 +429,7 @@ function useFragmentInternal_EXPERIMENTAL(fragmentNode, fragmentRef, hookDisplay
414
429
  }
415
430
  }
416
431
  }
417
- handlePotentialSnapshotErrorsForState(environment, state);
432
+ handlePotentialSnapshotErrorsForState(environment, state, loggerContext);
418
433
  var storeSubscriptionRef = useRef(null);
419
434
  useEffect(function () {
420
435
  var storeSubscription = storeSubscriptionRef.current;
@@ -71,6 +71,7 @@ function useLoadMoreFunction_CURRENT(args) {
71
71
  disposeFetch();
72
72
  };
73
73
  }, [disposeFetch]);
74
+ var isRequestInvalid = fragmentData == null || isParentQueryActive;
74
75
  var loadMore = useCallback(function (count, options) {
75
76
  var onComplete = options === null || options === void 0 ? void 0 : options.onComplete;
76
77
  if (isMountedRef.current !== true) {
@@ -80,7 +81,7 @@ function useLoadMoreFunction_CURRENT(args) {
80
81
  };
81
82
  }
82
83
  var fragmentSelector = getSelector(fragmentNode, fragmentRef);
83
- if (isFetchingRef.current === true || fragmentData == null || isParentQueryActive) {
84
+ if (isFetchingRef.current === true || isRequestInvalid) {
84
85
  if (fragmentSelector == null) {
85
86
  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;
86
87
  }
@@ -125,7 +126,7 @@ function useLoadMoreFunction_CURRENT(args) {
125
126
  return {
126
127
  dispose: disposeFetch
127
128
  };
128
- }, [environment, identifierValue, direction, cursor, startFetch, disposeFetch, completeFetch, isFetchingRef, isParentQueryActive, fragmentData, fragmentNode.name, fragmentRef, componentDisplayName]);
129
+ }, [environment, identifierValue, direction, cursor, startFetch, disposeFetch, completeFetch, isFetchingRef, isRequestInvalid, fragmentNode.name, fragmentRef, componentDisplayName]);
129
130
  return [loadMore, hasMore, disposeFetch];
130
131
  }
131
132
  module.exports = useLoadMoreFunction;
@@ -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": "20.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": "20.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,8 @@ export type PreloadFetchPolicy =
36
36
  export type PreloadOptions = {
37
37
  +fetchKey?: string | number,
38
38
  +fetchPolicy?: ?PreloadFetchPolicy,
39
+ +includeIf?: ?boolean,
40
+ +prefetchExpiryInHours?: ?number,
39
41
  +networkCacheConfig?: ?CacheConfig,
40
42
  };
41
43
 
@@ -178,14 +180,15 @@ export type EntryPointComponent<
178
180
  TPreloadedEntryPoints = {},
179
181
  TRuntimeProps = {},
180
182
  TExtraProps = null,
181
- > = ComponentType<
182
- EntryPointProps<
183
+ TRenders: React.Node = React.Node,
184
+ > = component(
185
+ ...EntryPointProps<
183
186
  TPreloadedQueries,
184
187
  TPreloadedEntryPoints,
185
188
  TRuntimeProps,
186
189
  TExtraProps,
187
- >,
188
- >;
190
+ >
191
+ ) renders TRenders;
189
192
 
190
193
  // Return type of the `getPreloadProps(...)` of the entry point
191
194
  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');