298
import {processTransitionCallbacks} from './ReactFiberTracingMarkerComponent';
299
import {
300
SuspenseException,
301
+ SuspenseActionException,
302
SuspenseyCommitException,
303
getSuspendedThenable,
304
isThenableResolved,
347
// The lanes we're rendering
348
let workInProgressRootRenderLanes: Lanes = NoLanes;
349
349
-opaque type SuspendedReason = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
350
+opaque type SuspendedReason = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
351
const NotSuspended: SuspendedReason = 0;
352
const SuspendedOnError: SuspendedReason = 1;
353
const SuspendedOnData: SuspendedReason = 2;
357
const SuspendedOnDeprecatedThrowPromise: SuspendedReason = 6;
358
const SuspendedAndReadyToContinue: SuspendedReason = 7;
359
const SuspendedOnHydration: SuspendedReason = 8;
360
+const SuspendedOnAction: SuspendedReason = 9;
361
362
// When this is true, the work-in-progress fiber just suspended (or errored) and
363
// we've yet to unwind the stack. In some cases, we may yield to the main thread
640
}
641
642
export function isWorkLoopSuspendedOnData(): boolean {
641
- return workInProgressSuspendedReason === SuspendedOnData;
643
+ return (
644
+ workInProgressSuspendedReason === SuspendedOnData ||
645
+ workInProgressSuspendedReason === SuspendedOnAction
646
+ );
647
}
648
649
export function getCurrentTime(): number {
772
if (
773
// Suspended render phase
774
(root === workInProgressRoot &&
770
- workInProgressSuspendedReason === SuspendedOnData) ||
775
+ (workInProgressSuspendedReason === SuspendedOnData ||
776
+ workInProgressSuspendedReason === SuspendedOnAction)) ||
777
// Suspended commit phase
778
root.cancelPendingCommit !== null
779
) {
1821
resetCurrentFiber();
1822
}
1823
1818
- if (thrownValue === SuspenseException) {
1824
+ if (
1825
+ thrownValue === SuspenseException ||
1826
+ thrownValue === SuspenseActionException
1827
+ ) {
1828
// This is a special type of exception used for Suspense. For historical
1829
// reasons, the rest of the Suspense implementation expects the thrown value
1830
// to be a thenable, because before `use` existed that was the (unstable)
1845
!includesNonIdleWork(workInProgressRootSkippedLanes) &&
1846
!includesNonIdleWork(workInProgressRootInterleavedUpdatedLanes)
1847
? // Suspend work loop until data resolves
1839
- SuspendedOnData
1848
+ thrownValue === SuspenseActionException
1849
+ ? SuspendedOnAction
1850
+ : SuspendedOnData
1851
: // Don't suspend work loop, except to check if the data has
1852
// immediately resolved (i.e. in a microtask). Otherwise, trigger the
1853
// nearest Suspense fallback.
1914
break;
1915
}
1916
case SuspendedOnData:
1917
+ case SuspendedOnAction:
1918
case SuspendedOnImmediate:
1919
case SuspendedOnDeprecatedThrowPromise:
1920
case SuspendedAndReadyToContinue: {
2197
}
2198
case SuspendedOnImmediate:
2199
case SuspendedOnData:
2200
+ case SuspendedOnAction:
2201
case SuspendedOnDeprecatedThrowPromise: {
2202
if (getSuspenseHandler() === null) {
2203
didSuspendInShell = true;
2361
);
2362
break;
2363
}
2351
- case SuspendedOnData: {
2364
+ case SuspendedOnData:
2365
+ case SuspendedOnAction: {
2366
const thenable: Thenable<mixed> = (thrownValue: any);
2367
if (isThenableResolved(thenable)) {
2368
// The data resolved. Try rendering the component again.
2380
const onResolution = () => {
2381
// Check if the root is still suspended on this promise.
2382
if (
2369
- workInProgressSuspendedReason === SuspendedOnData &&
2383
+ (workInProgressSuspendedReason === SuspendedOnData ||
2384
+ workInProgressSuspendedReason === SuspendedOnAction) &&
2385
workInProgressRoot === root
2386
) {
2387
// Mark the root as ready to continue rendering.
2829
// can prerender the siblings.
2830
if (
2831
suspendedReason === SuspendedOnData ||
2832
+ suspendedReason === SuspendedOnAction ||
2833
suspendedReason === SuspendedOnImmediate ||
2834
suspendedReason === SuspendedOnDeprecatedThrowPromise
2835
) {