@@ -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-b66d17d9 " ;
22
+ var ReactVersion = "18.3.0-www-classic-b794beee " ;
23
23
24
24
// This refers to a WWW module.
25
25
var warningWWW = require ( "warning" ) ;
@@ -9789,14 +9789,14 @@ function getStackByComponentStackNode(componentStack) {
9789
9789
var ReactCurrentDispatcher = ReactSharedInternals . ReactCurrentDispatcher ;
9790
9790
var ReactCurrentCache = ReactSharedInternals . ReactCurrentCache ;
9791
9791
var ReactDebugCurrentFrame = ReactSharedInternals . ReactDebugCurrentFrame ; // Linked list representing the identity of a component given the component/tag name and key.
9792
- // The name might be minified but we assume that it's going to be the same generated name. Typically
9793
- // because it's just the same compiled output in practice.
9792
+ var CLIENT_RENDERED = 4 ; // if it errors or infinitely suspends
9794
9793
9795
9794
var PENDING = 0 ;
9796
9795
var COMPLETED = 1 ;
9797
9796
var FLUSHED = 2 ;
9798
9797
var ABORTED = 3 ;
9799
9798
var ERRORED = 4 ;
9799
+ var POSTPONED = 5 ;
9800
9800
var OPEN = 0 ;
9801
9801
var CLOSING = 1 ;
9802
9802
var CLOSED = 2 ; // This is a default heuristic for how to split up the HTML content into progressive
@@ -9846,6 +9846,7 @@ function createRequest(
9846
9846
flushScheduled : false ,
9847
9847
resumableState : resumableState ,
9848
9848
renderState : renderState ,
9849
+ rootFormatContext : rootFormatContext ,
9849
9850
progressiveChunkSize :
9850
9851
progressiveChunkSize === undefined
9851
9852
? DEFAULT_PROGRESSIVE_CHUNK_SIZE
@@ -9861,6 +9862,7 @@ function createRequest(
9861
9862
clientRenderedBoundaries : [ ] ,
9862
9863
completedBoundaries : [ ] ,
9863
9864
partialBoundaries : [ ] ,
9865
+ trackedPostpones : null ,
9864
9866
onError : onError === undefined ? defaultErrorHandler : onError ,
9865
9867
onPostpone : onPostpone === undefined ? noop : onPostpone ,
9866
9868
onAllReady : onAllReady === undefined ? noop : onAllReady ,
@@ -9913,18 +9915,19 @@ function pingTask(request, task) {
9913
9915
}
9914
9916
}
9915
9917
9916
- function createSuspenseBoundary ( request , fallbackAbortableTasks ) {
9918
+ function createSuspenseBoundary ( request , fallbackAbortableTasks , keyPath ) {
9917
9919
return {
9920
+ status : PENDING ,
9918
9921
id : UNINITIALIZED_SUSPENSE_BOUNDARY_ID ,
9919
9922
rootSegmentID : - 1 ,
9920
9923
parentFlushed : false ,
9921
9924
pendingTasks : 0 ,
9922
- forceClientRender : false ,
9923
9925
completedSegments : [ ] ,
9924
9926
byteSize : 0 ,
9925
9927
fallbackAbortableTasks : fallbackAbortableTasks ,
9926
9928
errorDigest : null ,
9927
- resources : createBoundaryResources ( )
9929
+ resources : createBoundaryResources ( ) ,
9930
+ keyPath : keyPath
9928
9931
} ;
9929
9932
}
9930
9933
@@ -10117,7 +10120,11 @@ function renderSuspenseBoundary(request, task, props) {
10117
10120
var fallback = props . fallback ;
10118
10121
var content = props . children ;
10119
10122
var fallbackAbortSet = new Set ( ) ;
10120
- var newBoundary = createSuspenseBoundary ( request , fallbackAbortSet ) ;
10123
+ var newBoundary = createSuspenseBoundary (
10124
+ request ,
10125
+ fallbackAbortSet ,
10126
+ task . keyPath
10127
+ ) ;
10121
10128
var insertionIndex = parentSegment . chunks . length ; // The children of the boundary segment is actually the fallback.
10122
10129
10123
10130
var boundarySegment = createPendingSegment (
@@ -10172,16 +10179,17 @@ function renderSuspenseBoundary(request, task, props) {
10172
10179
contentRootSegment . status = COMPLETED ;
10173
10180
queueCompletedSegment ( newBoundary , contentRootSegment ) ;
10174
10181
10175
- if ( newBoundary . pendingTasks === 0 ) {
10176
- // This must have been the last segment we were waiting on. This boundary is now complete.
10182
+ if ( newBoundary . pendingTasks === 0 && newBoundary . status === PENDING ) {
10183
+ newBoundary . status = COMPLETED ; // This must have been the last segment we were waiting on. This boundary is now complete.
10177
10184
// Therefore we won't need the fallback. We early return so that we don't have to create
10178
10185
// the fallback.
10186
+
10179
10187
popComponentStackInDEV ( task ) ;
10180
10188
return ;
10181
10189
}
10182
10190
} catch ( error ) {
10183
10191
contentRootSegment . status = ERRORED ;
10184
- newBoundary . forceClientRender = true ;
10192
+ newBoundary . status = CLIENT_RENDERED ;
10185
10193
var errorDigest ;
10186
10194
10187
10195
{
@@ -11134,43 +11142,45 @@ function renderNode(request, task, node, childIndex) {
11134
11142
// (unstable) API for suspending. This implementation detail can change
11135
11143
// later, once we deprecate the old API in favor of `use`.
11136
11144
getSuspendedThenable ( )
11137
- : thrownValue ; // $FlowFixMe[method-unbinding]
11145
+ : thrownValue ;
11138
11146
11139
- if ( typeof x === "object" && x !== null && typeof x . then === "function" ) {
11140
- var wakeable = x ;
11141
- var thenableState = getThenableStateAfterSuspending ( ) ;
11142
- spawnNewSuspendedTask ( request , task , thenableState , wakeable ) ; // Restore the context. We assume that this will be restored by the inner
11143
- // functions in case nothing throws so we don't use "finally" here.
11147
+ if ( typeof x === "object" && x !== null ) {
11148
+ // $FlowFixMe[method-unbinding]
11149
+ if ( typeof x . then === "function" ) {
11150
+ var wakeable = x ;
11151
+ var thenableState = getThenableStateAfterSuspending ( ) ;
11152
+ spawnNewSuspendedTask ( request , task , thenableState , wakeable ) ; // Restore the context. We assume that this will be restored by the inner
11153
+ // functions in case nothing throws so we don't use "finally" here.
11144
11154
11145
- task . blockedSegment . formatContext = previousFormatContext ;
11146
- task . legacyContext = previousLegacyContext ;
11147
- task . context = previousContext ;
11148
- task . keyPath = previousKeyPath ; // Restore all active ReactContexts to what they were before.
11155
+ task . blockedSegment . formatContext = previousFormatContext ;
11156
+ task . legacyContext = previousLegacyContext ;
11157
+ task . context = previousContext ;
11158
+ task . keyPath = previousKeyPath ; // Restore all active ReactContexts to what they were before.
11149
11159
11150
- switchContext ( previousContext ) ;
11160
+ switchContext ( previousContext ) ;
11151
11161
11152
- {
11153
- task . componentStack = previousComponentStack ;
11162
+ {
11163
+ task . componentStack = previousComponentStack ;
11164
+ }
11165
+
11166
+ return ;
11154
11167
}
11168
+ } // Restore the context. We assume that this will be restored by the inner
11169
+ // functions in case nothing throws so we don't use "finally" here.
11155
11170
11156
- return ;
11157
- } else {
11158
- // Restore the context. We assume that this will be restored by the inner
11159
- // functions in case nothing throws so we don't use "finally" here.
11160
- task . blockedSegment . formatContext = previousFormatContext ;
11161
- task . legacyContext = previousLegacyContext ;
11162
- task . context = previousContext ;
11163
- task . keyPath = previousKeyPath ; // Restore all active ReactContexts to what they were before.
11171
+ task . blockedSegment . formatContext = previousFormatContext ;
11172
+ task . legacyContext = previousLegacyContext ;
11173
+ task . context = previousContext ;
11174
+ task . keyPath = previousKeyPath ; // Restore all active ReactContexts to what they were before.
11164
11175
11165
- switchContext ( previousContext ) ;
11176
+ switchContext ( previousContext ) ;
11166
11177
11167
- {
11168
- task . componentStack = previousComponentStack ;
11169
- } // We assume that we don't need the correct context.
11170
- // Let's terminate the rest of the tree and don't render any siblings.
11178
+ {
11179
+ task . componentStack = previousComponentStack ;
11180
+ } // We assume that we don't need the correct context.
11181
+ // Let's terminate the rest of the tree and don't render any siblings.
11171
11182
11172
- throw x ;
11173
- }
11183
+ throw x ;
11174
11184
}
11175
11185
}
11176
11186
@@ -11187,8 +11197,8 @@ function erroredTask(request, boundary, segment, error) {
11187
11197
} else {
11188
11198
boundary . pendingTasks -- ;
11189
11199
11190
- if ( ! boundary . forceClientRender ) {
11191
- boundary . forceClientRender = true ;
11200
+ if ( boundary . status !== CLIENT_RENDERED ) {
11201
+ boundary . status = CLIENT_RENDERED ;
11192
11202
boundary . errorDigest = errorDigest ;
11193
11203
11194
11204
{
@@ -11243,8 +11253,8 @@ function abortTask(task, request, error) {
11243
11253
} else {
11244
11254
boundary . pendingTasks -- ;
11245
11255
11246
- if ( ! boundary . forceClientRender ) {
11247
- boundary . forceClientRender = true ;
11256
+ if ( boundary . status !== CLIENT_RENDERED ) {
11257
+ boundary . status = CLIENT_RENDERED ;
11248
11258
boundary . errorDigest = request . onError ( error ) ;
11249
11259
11250
11260
{
@@ -11331,9 +11341,12 @@ function finishedTask(request, boundary, segment) {
11331
11341
} else {
11332
11342
boundary . pendingTasks -- ;
11333
11343
11334
- if ( boundary . forceClientRender ) ;
11344
+ if ( boundary . status === CLIENT_RENDERED ) ;
11335
11345
else if ( boundary . pendingTasks === 0 ) {
11336
- // This must have been the last segment we were waiting on. This boundary is now complete.
11346
+ if ( boundary . status === PENDING ) {
11347
+ boundary . status = COMPLETED ;
11348
+ } // This must have been the last segment we were waiting on. This boundary is now complete.
11349
+
11337
11350
if ( segment . parentFlushed ) {
11338
11351
// Our parent segment already flushed, so we need to schedule this segment to be emitted.
11339
11352
// If it is a segment that was aborted, we'll write other content instead so we don't need
@@ -11444,18 +11457,23 @@ function retryTask(request, task) {
11444
11457
// (unstable) API for suspending. This implementation detail can change
11445
11458
// later, once we deprecate the old API in favor of `use`.
11446
11459
getSuspendedThenable ( )
11447
- : thrownValue ; // $FlowFixMe[method-unbinding]
11448
-
11449
- if ( typeof x === "object" && x !== null && typeof x . then === "function" ) {
11450
- // Something suspended again, let's pick it back up later.
11451
- var ping = task . ping ;
11452
- x . then ( ping , ping ) ;
11453
- task . thenableState = getThenableStateAfterSuspending ( ) ;
11454
- } else {
11455
- task . abortSet . delete ( task ) ;
11456
- segment . status = ERRORED ;
11457
- erroredTask ( request , task . blockedBoundary , segment , x ) ;
11460
+ : thrownValue ;
11461
+
11462
+ if ( typeof x === "object" && x !== null ) {
11463
+ // $FlowFixMe[method-unbinding]
11464
+ if ( typeof x . then === "function" ) {
11465
+ // Something suspended again, let's pick it back up later.
11466
+ var ping = task . ping ;
11467
+ x . then ( ping , ping ) ;
11468
+ task . thenableState = getThenableStateAfterSuspending ( ) ;
11469
+ return ;
11470
+ }
11458
11471
}
11472
+
11473
+ task . abortSet . delete ( task ) ;
11474
+ segment . status = ERRORED ;
11475
+ erroredTask ( request , task . blockedBoundary , segment , x ) ;
11476
+ return ;
11459
11477
} finally {
11460
11478
{
11461
11479
setCurrentlyRenderingBoundaryResourcesTarget ( request . renderState , null ) ;
@@ -11545,7 +11563,11 @@ function flushSubtree(request, destination, segment) {
11545
11563
case PENDING : {
11546
11564
// We're emitting a placeholder for this segment to be filled in later.
11547
11565
// Therefore we'll need to assign it an ID - to refer to it by.
11548
- var segmentID = ( segment . id = request . nextSegmentId ++ ) ; // When this segment finally completes it won't be embedded in text since it will flush separately
11566
+ segment . id = request . nextSegmentId ++ ; // Fallthrough
11567
+ }
11568
+
11569
+ case POSTPONED : {
11570
+ var segmentID = segment . id ; // When this segment finally completes it won't be embedded in text since it will flush separately
11549
11571
11550
11572
segment . lastPushedText = false ;
11551
11573
segment . textEmbedded = false ;
@@ -11599,7 +11621,7 @@ function flushSegment(request, destination, segment) {
11599
11621
boundary . parentFlushed = true ; // This segment is a Suspense boundary. We need to decide whether to
11600
11622
// emit the content or the fallback now.
11601
11623
11602
- if ( boundary . forceClientRender ) {
11624
+ if ( boundary . status === CLIENT_RENDERED ) {
11603
11625
// Emit a client rendered suspense boundary wrapper.
11604
11626
// We never queue the inner boundary so we'll never emit its content or partial segments.
11605
11627
writeStartClientRenderedSuspenseBoundary (
@@ -11615,20 +11637,23 @@ function flushSegment(request, destination, segment) {
11615
11637
destination ,
11616
11638
request . renderState
11617
11639
) ;
11618
- } else if ( boundary . pendingTasks > 0 ) {
11619
- // This boundary is still loading. Emit a pending suspense boundary wrapper.
11640
+ } else if ( boundary . status !== COMPLETED ) {
11641
+ if ( boundary . status === PENDING ) {
11642
+ boundary . id = assignSuspenseBoundaryID (
11643
+ request . renderState ,
11644
+ request . resumableState
11645
+ ) ;
11646
+ } // This boundary is still loading. Emit a pending suspense boundary wrapper.
11620
11647
// Assign an ID to refer to the future content by.
11648
+
11621
11649
boundary . rootSegmentID = request . nextSegmentId ++ ;
11622
11650
11623
11651
if ( boundary . completedSegments . length > 0 ) {
11624
11652
// If this is at least partially complete, we can queue it to be partially emitted early.
11625
11653
request . partialBoundaries . push ( boundary ) ;
11626
11654
} /// This is the first time we should have referenced this ID.
11627
11655
11628
- var id = ( boundary . id = assignSuspenseBoundaryID (
11629
- request . renderState ,
11630
- request . resumableState
11631
- ) ) ;
11656
+ var id = boundary . id ;
11632
11657
writeStartPendingSuspenseBoundary ( destination , request . renderState , id ) ; // Flush the fallback.
11633
11658
11634
11659
flushSubtree ( request , destination , segment ) ;
@@ -11924,7 +11949,11 @@ function flushCompletedQueues(request, destination) {
11924
11949
request . flushScheduled = false ;
11925
11950
11926
11951
{
11927
- writePostamble ( destination , request . resumableState ) ;
11952
+ // We write the trailing tags but only if don't have any data to resume.
11953
+ // If we need to resume we'll write the postamble in the resume instead.
11954
+ {
11955
+ writePostamble ( destination , request . resumableState ) ;
11956
+ }
11928
11957
}
11929
11958
11930
11959
{
@@ -11940,7 +11969,7 @@ function flushCompletedQueues(request, destination) {
11940
11969
}
11941
11970
}
11942
11971
11943
- function startWork ( request ) {
11972
+ function startRender ( request ) {
11944
11973
request . flushScheduled = request . destination !== null ;
11945
11974
11946
11975
{
@@ -12019,7 +12048,7 @@ function flushResources(request) {
12019
12048
}
12020
12049
function getResumableState ( request ) {
12021
12050
return request . resumableState ;
12022
- } // Returns the state of a postponed request or null if nothing was postponed.
12051
+ }
12023
12052
12024
12053
function onError ( ) {
12025
12054
// Non-fatal errors are ignored.
@@ -12076,7 +12105,7 @@ function renderToStringImpl(
12076
12105
undefined ,
12077
12106
undefined
12078
12107
) ;
12079
- startWork ( request ) ; // If anything suspended and is still pending, we'll abort it before writing.
12108
+ startRender ( request ) ; // If anything suspended and is still pending, we'll abort it before writing.
12080
12109
// That way we write only client-rendered boundaries from the start.
12081
12110
12082
12111
abort ( request , abortReason ) ;
0 commit comments