@@ -19,7 +19,7 @@ if (__DEV__) {
19
19
var React = require ( "react" ) ;
20
20
var ReactDOM = require ( "react-dom" ) ;
21
21
22
- var ReactVersion = "18.3.0-www-classic-8314963c " ;
22
+ var ReactVersion = "18.3.0-www-classic-87fc393f " ;
23
23
24
24
// This refers to a WWW module.
25
25
var warningWWW = require ( "warning" ) ;
@@ -9994,7 +9994,7 @@ function pingTask(request, task) {
9994
9994
}
9995
9995
}
9996
9996
9997
- function createSuspenseBoundary ( request , fallbackAbortableTasks , keyPath ) {
9997
+ function createSuspenseBoundary ( request , fallbackAbortableTasks ) {
9998
9998
return {
9999
9999
status : PENDING ,
10000
10000
rootSegmentID : - 1 ,
@@ -10005,7 +10005,8 @@ function createSuspenseBoundary(request, fallbackAbortableTasks, keyPath) {
10005
10005
fallbackAbortableTasks : fallbackAbortableTasks ,
10006
10006
errorDigest : null ,
10007
10007
resources : createBoundaryResources ( ) ,
10008
- keyPath : keyPath
10008
+ trackedContentKeyPath : null ,
10009
+ trackedFallbackNode : null
10009
10010
} ;
10010
10011
}
10011
10012
@@ -10271,7 +10272,12 @@ function renderSuspenseBoundary(request, someTask, keyPath, props) {
10271
10272
var fallback = props . fallback ;
10272
10273
var content = props . children ;
10273
10274
var fallbackAbortSet = new Set ( ) ;
10274
- var newBoundary = createSuspenseBoundary ( request , fallbackAbortSet , keyPath ) ;
10275
+ var newBoundary = createSuspenseBoundary ( request , fallbackAbortSet ) ;
10276
+
10277
+ if ( request . trackedPostpones !== null ) {
10278
+ newBoundary . trackedContentKeyPath = keyPath ;
10279
+ }
10280
+
10275
10281
var insertionIndex = parentSegment . chunks . length ; // The children of the boundary segment is actually the fallback.
10276
10282
10277
10283
var boundarySegment = createPendingSegment (
@@ -10363,6 +10369,25 @@ function renderSuspenseBoundary(request, someTask, keyPath, props) {
10363
10369
task . blockedBoundary = parentBoundary ;
10364
10370
task . blockedSegment = parentSegment ;
10365
10371
task . keyPath = prevKeyPath ;
10372
+ }
10373
+
10374
+ var fallbackKeyPath = [ keyPath [ 0 ] , "Suspense Fallback" , keyPath [ 2 ] ] ;
10375
+ var trackedPostpones = request . trackedPostpones ;
10376
+
10377
+ if ( trackedPostpones !== null ) {
10378
+ // We create a detached replay node to track any postpones inside the fallback.
10379
+ var fallbackReplayNode = [ fallbackKeyPath [ 1 ] , fallbackKeyPath [ 2 ] , [ ] , null ] ;
10380
+ trackedPostpones . workingMap . set ( fallbackKeyPath , fallbackReplayNode ) ;
10381
+
10382
+ if ( newBoundary . status === POSTPONED ) {
10383
+ // This must exist now.
10384
+ var boundaryReplayNode = trackedPostpones . workingMap . get ( keyPath ) ;
10385
+ boundaryReplayNode [ 4 ] = fallbackReplayNode ;
10386
+ } else {
10387
+ // We might not inject it into the postponed tree, unless the content actually
10388
+ // postpones too. We need to keep track of it until that happpens.
10389
+ newBoundary . trackedFallbackNode = fallbackReplayNode ;
10390
+ }
10366
10391
} // We create suspended task for the fallback because we don't want to actually work
10367
10392
// on it yet in case we finish the main content, so we queue for later.
10368
10393
@@ -10373,8 +10398,8 @@ function renderSuspenseBoundary(request, someTask, keyPath, props) {
10373
10398
- 1 ,
10374
10399
parentBoundary ,
10375
10400
boundarySegment ,
10376
- fallbackAbortSet , // TODO: Should distinguish key path of fallback and primary tasks
10377
- keyPath ,
10401
+ fallbackAbortSet ,
10402
+ fallbackKeyPath ,
10378
10403
task . formatContext ,
10379
10404
task . legacyContext ,
10380
10405
task . context ,
@@ -10397,19 +10422,18 @@ function replaySuspenseBoundary(
10397
10422
props ,
10398
10423
id ,
10399
10424
childNodes ,
10400
- childSlots
10425
+ childSlots ,
10426
+ fallbackNodes ,
10427
+ fallbackSlots
10401
10428
) {
10402
10429
pushBuiltInComponentStackInDEV ( task , "Suspense" ) ;
10403
10430
var prevKeyPath = task . keyPath ;
10404
10431
var previousReplaySet = task . replay ;
10405
10432
var parentBoundary = task . blockedBoundary ;
10406
10433
var content = props . children ;
10434
+ var fallback = props . fallback ;
10407
10435
var fallbackAbortSet = new Set ( ) ;
10408
- var resumedBoundary = createSuspenseBoundary (
10409
- request ,
10410
- fallbackAbortSet ,
10411
- task . keyPath
10412
- ) ;
10436
+ var resumedBoundary = createSuspenseBoundary ( request , fallbackAbortSet ) ;
10413
10437
resumedBoundary . parentFlushed = true ; // We restore the same id of this boundary as was used during prerender.
10414
10438
10415
10439
resumedBoundary . rootSegmentID = id ; // We can reuse the current context and task to render the content immediately without
@@ -10438,14 +10462,6 @@ function replaySuspenseBoundary(
10438
10462
renderNode ( request , task , content , - 1 ) ;
10439
10463
}
10440
10464
10441
- if (
10442
- resumedBoundary . pendingTasks === 0 &&
10443
- resumedBoundary . status === PENDING
10444
- ) {
10445
- resumedBoundary . status = COMPLETED ;
10446
- request . completedBoundaries . push ( resumedBoundary ) ;
10447
- }
10448
-
10449
10465
if ( task . replay . pendingTasks === 1 && task . replay . nodes . length > 0 ) {
10450
10466
throw new Error (
10451
10467
"Couldn't find all resumable slots by key/index during replaying. " +
@@ -10454,6 +10470,19 @@ function replaySuspenseBoundary(
10454
10470
}
10455
10471
10456
10472
task . replay . pendingTasks -- ;
10473
+
10474
+ if (
10475
+ resumedBoundary . pendingTasks === 0 &&
10476
+ resumedBoundary . status === PENDING
10477
+ ) {
10478
+ resumedBoundary . status = COMPLETED ;
10479
+ request . completedBoundaries . push ( resumedBoundary ) ; // This must have been the last segment we were waiting on. This boundary is now complete.
10480
+ // Therefore we won't need the fallback. We early return so that we don't have to create
10481
+ // the fallback.
10482
+
10483
+ popComponentStackInDEV ( task ) ;
10484
+ return ;
10485
+ }
10457
10486
} catch ( error ) {
10458
10487
resumedBoundary . status = CLIENT_RENDERED ;
10459
10488
var errorDigest ;
@@ -10484,7 +10513,66 @@ function replaySuspenseBoundary(
10484
10513
task . blockedBoundary = parentBoundary ;
10485
10514
task . replay = previousReplaySet ;
10486
10515
task . keyPath = prevKeyPath ;
10487
- } // TODO: Should this be in the finally?
10516
+ }
10517
+
10518
+ var fallbackKeyPath = [ keyPath [ 0 ] , "Suspense Fallback" , keyPath [ 2 ] ] ;
10519
+ var suspendedFallbackTask ; // We create suspended task for the fallback because we don't want to actually work
10520
+ // on it yet in case we finish the main content, so we queue for later.
10521
+
10522
+ if ( typeof fallbackSlots === "number" ) {
10523
+ // Resuming directly in the fallback.
10524
+ var resumedSegment = createPendingSegment (
10525
+ request ,
10526
+ 0 ,
10527
+ null ,
10528
+ task . formatContext ,
10529
+ false ,
10530
+ false
10531
+ ) ;
10532
+ resumedSegment . id = fallbackSlots ;
10533
+ resumedSegment . parentFlushed = true ;
10534
+ suspendedFallbackTask = createRenderTask (
10535
+ request ,
10536
+ null ,
10537
+ fallback ,
10538
+ - 1 ,
10539
+ parentBoundary ,
10540
+ resumedSegment ,
10541
+ fallbackAbortSet ,
10542
+ fallbackKeyPath ,
10543
+ task . formatContext ,
10544
+ task . legacyContext ,
10545
+ task . context ,
10546
+ task . treeContext
10547
+ ) ;
10548
+ } else {
10549
+ var fallbackReplay = {
10550
+ nodes : fallbackNodes ,
10551
+ slots : fallbackSlots ,
10552
+ pendingTasks : 0
10553
+ } ;
10554
+ suspendedFallbackTask = createReplayTask (
10555
+ request ,
10556
+ null ,
10557
+ fallbackReplay ,
10558
+ fallback ,
10559
+ - 1 ,
10560
+ parentBoundary ,
10561
+ fallbackAbortSet ,
10562
+ fallbackKeyPath ,
10563
+ task . formatContext ,
10564
+ task . legacyContext ,
10565
+ task . context ,
10566
+ task . treeContext
10567
+ ) ;
10568
+ }
10569
+
10570
+ {
10571
+ suspendedFallbackTask . componentStack = task . componentStack ;
10572
+ } // TODO: This should be queued at a separate lower priority queue so that we only work
10573
+ // on preparing fallbacks if we don't have any more main content to task on.
10574
+
10575
+ request . pingedTasks . push ( suspendedFallbackTask ) ; // TODO: Should this be in the finally?
10488
10576
10489
10577
popComponentStackInDEV ( task ) ;
10490
10578
}
@@ -11392,9 +11480,11 @@ function replayElement(
11392
11480
task ,
11393
11481
keyPath ,
11394
11482
props ,
11395
- node [ 4 ] ,
11483
+ node [ 5 ] ,
11396
11484
node [ 2 ] ,
11397
- node [ 3 ]
11485
+ node [ 3 ] ,
11486
+ node [ 4 ] === null ? [ ] : node [ 4 ] [ 2 ] ,
11487
+ node [ 4 ] === null ? null : node [ 4 ] [ 3 ]
11398
11488
) ;
11399
11489
} // We finished rendering this node, so now we can consume this
11400
11490
// slot. This must happen after in case we rerender this task.
@@ -12104,11 +12194,7 @@ function abortRemainingSuspenseBoundary(
12104
12194
error ,
12105
12195
errorDigest
12106
12196
) {
12107
- var resumedBoundary = createSuspenseBoundary (
12108
- request ,
12109
- new Set ( ) ,
12110
- null // The keyPath doesn't matter at this point so we don't bother rebuilding it.
12111
- ) ;
12197
+ var resumedBoundary = createSuspenseBoundary ( request , new Set ( ) ) ;
12112
12198
resumedBoundary . parentFlushed = true ; // We restore the same id of this boundary as was used during prerender.
12113
12199
12114
12200
resumedBoundary . rootSegmentID = rootSegmentID ;
@@ -12163,7 +12249,7 @@ function abortRemainingReplayNodes(
12163
12249
) ;
12164
12250
} else {
12165
12251
var boundaryNode = node ;
12166
- var rootSegmentID = boundaryNode [ 4 ] ;
12252
+ var rootSegmentID = boundaryNode [ 5 ] ;
12167
12253
abortRemainingSuspenseBoundary (
12168
12254
request ,
12169
12255
rootSegmentID ,
@@ -12950,9 +13036,7 @@ function flushCompletedQueues(request, destination) {
12950
13036
destination ,
12951
13037
request . resumableState ,
12952
13038
request . renderState ,
12953
- request . allPendingTasks === 0 &&
12954
- ( request . trackedPostpones === null ||
12955
- request . trackedPostpones . workingMap . size === 0 )
13039
+ request . allPendingTasks === 0 && request . trackedPostpones === null
12956
13040
) ;
12957
13041
}
12958
13042
0 commit comments