@@ -83,33 +83,25 @@ export function diff(
8383 ( isHydrating = oldVNode . _flags & MODE_HYDRATE ) &&
8484 oldVNode . _component . _excess
8585 ) {
86- let startMarker = oldVNode . _component . _excess [ 0 ] ;
87- if (
88- startMarker &&
89- startMarker . nodeType == 8 &&
90- startMarker . data . startsWith ( '$s' )
91- ) {
92- // Deferred restoration: re-scan current DOM from the stored start marker.
93- // This ensures we always hydrate against the most up-to-date DOM state,
94- // even if a streaming SSR patcher replaced the content between markers.
95- excessDomChildren = [ ] ;
96- let depth = 1 ;
97- let node = startMarker . nextSibling ;
98- while ( node && depth > 0 ) {
86+ let excess = oldVNode . _component . _excess ;
87+ excessDomChildren = [ ] ;
88+ if ( excess . nodeType == 8 ) {
89+ // Re-scan DOM from stored start marker for streamed hydration
90+ for (
91+ let depth = 1 , node = excess . nextSibling ;
92+ node && depth > 0 ;
93+ node = node . nextSibling
94+ ) {
9995 if ( node . nodeType == 8 ) {
10096 if ( node . data . startsWith ( '$s' ) ) depth ++ ;
101- else if ( node . data . startsWith ( '/$s' ) ) {
102- if ( -- depth == 0 ) break ;
103- }
97+ else if ( node . data . startsWith ( '/$s' ) && ! -- depth ) break ;
10498 }
10599 excessDomChildren . push ( node ) ;
106- node = node . nextSibling ;
107100 }
108- oldDom = excessDomChildren [ 0 ] ;
109101 } else {
110- excessDomChildren = oldVNode . _component . _excess ;
111- oldDom = excessDomChildren [ 0 ] ;
102+ excessDomChildren . push ( excess ) ;
112103 }
104+ oldDom = excessDomChildren [ 0 ] ;
113105 oldVNode . _component . _excess = NULL ;
114106 }
115107
@@ -335,33 +327,25 @@ export function diff(
335327 if ( isHydrating || excessDomChildren != NULL ) {
336328 if ( e . then ) {
337329 let commentMarkersToFind = 0 ,
338- done ,
339330 startMarker ;
340331
341332 newVNode . _flags |= isHydrating
342333 ? MODE_HYDRATE | MODE_SUSPENDED
343334 : MODE_SUSPENDED ;
344335
345336 for ( let i = 0 ; i < excessDomChildren . length ; i ++ ) {
346- const child = excessDomChildren [ i ] ;
347- if ( child == NULL || done ) continue ;
348-
349- // When we encounter a $s boundary marker we are opening a
350- // suspended region. Track nesting depth to find the matching
351- // close marker. We null out ALL nodes in the region so the
352- // parent diff doesn't try to remove them; the children will be
353- // re-scanned from the stored start marker on resume.
337+ let child = excessDomChildren [ i ] ;
338+ if ( child == NULL ) continue ;
339+
354340 if ( child . nodeType == 8 ) {
355341 if ( child . data . startsWith ( '$s' ) ) {
356- if ( ! commentMarkersToFind ) {
357- // Store outermost start marker for deferred restoration
358- startMarker = child ;
359- }
342+ if ( ! commentMarkersToFind ) startMarker = child ;
360343 commentMarkersToFind ++ ;
361344 } else if ( child . data . startsWith ( '/$s' ) ) {
362345 if ( -- commentMarkersToFind == 0 ) {
363- done = true ;
364- oldDom = excessDomChildren [ i ] ;
346+ oldDom = child ;
347+ excessDomChildren [ i ] = NULL ;
348+ break ;
365349 }
366350 }
367351 excessDomChildren [ i ] = NULL ;
@@ -370,18 +354,16 @@ export function diff(
370354 }
371355 }
372356
373- if ( done ) {
374- // Store only the start marker; children are re-scanned on resume
375- // so we always hydrate against the current DOM state.
376- // TODO: consider just storing in _dom and getting rid of _excess altogether?
377- newVNode . _component . _excess = [ startMarker ] ;
357+ if ( startMarker ) {
358+ // Store start marker directly; children re-scanned on resume
359+ newVNode . _component . _excess = startMarker ;
378360 } else {
379361 while ( oldDom && oldDom . nodeType == 8 && oldDom . nextSibling ) {
380362 oldDom = oldDom . nextSibling ;
381363 }
382364
383365 excessDomChildren [ excessDomChildren . indexOf ( oldDom ) ] = NULL ;
384- newVNode . _component . _excess = [ oldDom ] ;
366+ newVNode . _component . _excess = oldDom ;
385367 }
386368
387369 newVNode . _dom = oldDom ;
0 commit comments