@@ -1834,20 +1834,31 @@ function lanesToEventPriority(lanes) {
1834
1834
1835
1835
// Renderers that don't support hydration
1836
1836
// can re-export everything from this module.
1837
- function shim() {
1837
+ function shim$1 () {
1838
1838
throw new Error(
1839
1839
"The current renderer does not support hydration. " +
1840
1840
"This error is likely caused by a bug in React. " +
1841
1841
"Please file an issue."
1842
1842
);
1843
1843
} // Hydration (when unsupported)
1844
- var isSuspenseInstancePending = shim;
1845
- var isSuspenseInstanceFallback = shim;
1846
- var getSuspenseInstanceFallbackErrorDetails = shim;
1847
- var registerSuspenseInstanceRetry = shim;
1848
- var clearSuspenseBoundary = shim;
1849
- var clearSuspenseBoundaryFromContainer = shim;
1850
- var errorHydratingContainer = shim;
1844
+ var isSuspenseInstancePending = shim$1;
1845
+ var isSuspenseInstanceFallback = shim$1;
1846
+ var getSuspenseInstanceFallbackErrorDetails = shim$1;
1847
+ var registerSuspenseInstanceRetry = shim$1;
1848
+ var clearSuspenseBoundary = shim$1;
1849
+ var clearSuspenseBoundaryFromContainer = shim$1;
1850
+ var errorHydratingContainer = shim$1;
1851
+
1852
+ // Renderers that don't support hydration
1853
+ // can re-export everything from this module.
1854
+ function shim() {
1855
+ throw new Error(
1856
+ "The current renderer does not support Resources. " +
1857
+ "This error is likely caused by a bug in React. " +
1858
+ "Please file an issue."
1859
+ );
1860
+ } // Resources (when unsupported)
1861
+ var suspendResource = shim;
1851
1862
1852
1863
var NO_CONTEXT = {};
1853
1864
var UPDATE_SIGNAL = {};
@@ -2012,6 +2023,9 @@ function unhideInstance(instance, props) {
2012
2023
function unhideTextInstance(textInstance, text) {
2013
2024
textInstance.isHidden = false;
2014
2025
}
2026
+ function maySuspendCommit(type, props) {
2027
+ return false;
2028
+ }
2015
2029
function preloadInstance(type, props) {
2016
2030
// Return true to indicate it's already loaded
2017
2031
return true;
@@ -4296,6 +4310,13 @@ function trackUsedThenable(thenableState, thenable, index) {
4296
4310
}
4297
4311
}
4298
4312
}
4313
+ function suspendCommit() {
4314
+ // This extra indirection only exists so it can handle passing
4315
+ // noopSuspenseyCommitThenable through to throwException.
4316
+ // TODO: Factor the thenable check out of throwException
4317
+ suspendedThenable = noopSuspenseyCommitThenable;
4318
+ throw SuspenseyCommitException;
4319
+ } // This is used to track the actual thenable that suspended so it can be
4299
4320
// passed to the rest of the Suspense implementation — which, for historical
4300
4321
// reasons, expects to receive a thenable.
4301
4322
@@ -14594,16 +14615,28 @@ function preloadInstanceAndSuspendIfNeeded(
14594
14615
props,
14595
14616
renderLanes
14596
14617
) {
14597
- // Ask the renderer if this instance should suspend the commit.
14598
- {
14599
- // If this flag was set previously, we can remove it. The flag represents
14600
- // whether this particular set of props might ever need to suspend. The
14601
- // safest thing to do is for maySuspendCommit to always return true, but
14602
- // if the renderer is reasonably confident that the underlying resource
14603
- // won't be evicted, it can return false as a performance optimization.
14604
- workInProgress.flags &= ~SuspenseyCommit;
14605
- return;
14606
- } // Mark this fiber with a flag. We use this right before the commit phase to
14618
+ workInProgress.flags |= SuspenseyCommit; // Check if we're rendering at a "non-urgent" priority. This is the same
14619
+ // check that `useDeferredValue` does to determine whether it needs to
14620
+ // defer. This is partly for gradual adoption purposes (i.e. shouldn't start
14621
+ // suspending until you opt in with startTransition or Suspense) but it
14622
+ // also happens to be the desired behavior for the concrete use cases we've
14623
+ // thought of so far, like CSS loading, fonts, images, etc.
14624
+ // TODO: We may decide to expose a way to force a fallback even during a
14625
+ // sync update.
14626
+
14627
+ if (!includesOnlyNonUrgentLanes(renderLanes));
14628
+ else {
14629
+ // Preload the instance
14630
+ var isReady = preloadInstance();
14631
+
14632
+ if (!isReady) {
14633
+ if (shouldRemainOnPreviousScreen());
14634
+ else {
14635
+ // Trigger a fallback rather than block the render.
14636
+ suspendCommit();
14637
+ }
14638
+ }
14639
+ }
14607
14640
}
14608
14641
14609
14642
function scheduleRetryEffect(workInProgress, retryQueue) {
@@ -15011,6 +15044,8 @@ function completeWork(current, workInProgress, renderLanes) {
15011
15044
popHostContext(workInProgress);
15012
15045
var _type = workInProgress.type;
15013
15046
15047
+ var _maySuspend = maySuspendCommit();
15048
+
15014
15049
if (current !== null && workInProgress.stateNode != null) {
15015
15050
updateHostComponent(current, workInProgress, _type, newProps);
15016
15051
@@ -15071,7 +15106,17 @@ function completeWork(current, workInProgress, renderLanes) {
15071
15106
// will resume rendering as if the work-in-progress completed. So it must
15072
15107
// fully complete.
15073
15108
15074
- preloadInstanceAndSuspendIfNeeded(workInProgress);
15109
+ if (_maySuspend) {
15110
+ preloadInstanceAndSuspendIfNeeded(
15111
+ workInProgress,
15112
+ _type,
15113
+ newProps,
15114
+ renderLanes
15115
+ );
15116
+ } else {
15117
+ workInProgress.flags &= ~SuspenseyCommit;
15118
+ }
15119
+
15075
15120
return null;
15076
15121
}
15077
15122
@@ -18929,6 +18974,50 @@ function commitPassiveUnmountEffects(finishedWork) {
18929
18974
commitPassiveUnmountOnFiber(finishedWork);
18930
18975
resetCurrentFiber();
18931
18976
}
18977
+ function accumulateSuspenseyCommit(finishedWork) {
18978
+ accumulateSuspenseyCommitOnFiber(finishedWork);
18979
+ }
18980
+
18981
+ function recursivelyAccumulateSuspenseyCommit(parentFiber) {
18982
+ if (parentFiber.subtreeFlags & SuspenseyCommit) {
18983
+ var child = parentFiber.child;
18984
+
18985
+ while (child !== null) {
18986
+ accumulateSuspenseyCommitOnFiber(child);
18987
+ child = child.sibling;
18988
+ }
18989
+ }
18990
+ }
18991
+
18992
+ function accumulateSuspenseyCommitOnFiber(fiber) {
18993
+ switch (fiber.tag) {
18994
+ case HostHoistable: {
18995
+ recursivelyAccumulateSuspenseyCommit(fiber);
18996
+
18997
+ if (fiber.flags & SuspenseyCommit) {
18998
+ if (fiber.memoizedState !== null) {
18999
+ suspendResource();
19000
+ }
19001
+ }
19002
+
19003
+ break;
19004
+ }
19005
+
19006
+ case HostComponent: {
19007
+ recursivelyAccumulateSuspenseyCommit(fiber);
19008
+
19009
+ break;
19010
+ }
19011
+
19012
+ case HostRoot:
19013
+ case HostPortal:
19014
+ // eslint-disable-next-line-no-fallthrough
19015
+
19016
+ default: {
19017
+ recursivelyAccumulateSuspenseyCommit(fiber);
19018
+ }
19019
+ }
19020
+ }
18932
19021
18933
19022
function detachAlternateSiblings(parentFiber) {
18934
19023
// A fiber was deleted from this parent fiber, but it's still part of the
@@ -20259,6 +20348,11 @@ function commitRootWhenReady(
20259
20348
lanes
20260
20349
) {
20261
20350
if (includesOnlyNonUrgentLanes(lanes)) {
20351
+ // the suspensey resources. The renderer is responsible for accumulating
20352
+ // all the load events. This all happens in a single synchronous
20353
+ // transaction, so it track state in its own module scope.
20354
+
20355
+ accumulateSuspenseyCommit(finishedWork); // At the end, ask the renderer if it's ready to commit, or if we should
20262
20356
// suspend. If it's not ready, it will return a callback to subscribe to
20263
20357
// a ready event.
20264
20358
@@ -23649,7 +23743,7 @@ function createFiberRoot(
23649
23743
return root;
23650
23744
}
23651
23745
23652
- var ReactVersion = "18.3.0-next-175962c10-20230325 ";
23746
+ var ReactVersion = "18.3.0-next-73b6435ca-20230324 ";
23653
23747
23654
23748
// Might add PROFILE later.
23655
23749
0 commit comments