@@ -83,7 +83,24 @@ export function diff(
8383 ( isHydrating = oldVNode . _flags & MODE_HYDRATE ) &&
8484 oldVNode . _component . _excess
8585 ) {
86- excessDomChildren = oldVNode . _component . _excess ;
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+ ) {
95+ if ( node . nodeType == 8 ) {
96+ if ( node . data . startsWith ( '$s' ) ) depth ++ ;
97+ else if ( node . data . startsWith ( '/$s' ) && ! -- depth ) break ;
98+ }
99+ excessDomChildren . push ( node ) ;
100+ }
101+ } else {
102+ excessDomChildren . push ( excess ) ;
103+ }
87104 oldDom = excessDomChildren [ 0 ] ;
88105 oldVNode . _component . _excess = NULL ;
89106 }
@@ -310,52 +327,43 @@ export function diff(
310327 if ( isHydrating || excessDomChildren != NULL ) {
311328 if ( e . then ) {
312329 let commentMarkersToFind = 0 ,
313- done ;
330+ startMarker ;
314331
315332 newVNode . _flags |= isHydrating
316333 ? MODE_HYDRATE | MODE_SUSPENDED
317334 : MODE_SUSPENDED ;
318335
319- newVNode . _component . _excess = [ ] ;
320336 for ( let i = 0 ; i < excessDomChildren . length ; i ++ ) {
321- const child = excessDomChildren [ i ] ;
322- if ( child == NULL || done ) continue ;
323-
324- // When we encounter a boundary with $s we are opening
325- // a boundary, this implies that we need to bump
326- // the amount of markers we need to find before closing
327- // the outer boundary.
328- // We exclude the open and closing marker from
329- // the future excessDomChildren but any nested one
330- // needs to be included for future suspensions.
337+ let child = excessDomChildren [ i ] ;
338+ if ( child == NULL ) continue ;
339+
331340 if ( child . nodeType == 8 ) {
332- if ( child . data == '$s' ) {
333- if ( commentMarkersToFind ) {
334- newVNode . _component . _excess . push ( child ) ;
335- }
341+ if ( child . data . startsWith ( '$s' ) ) {
342+ if ( ! commentMarkersToFind ) startMarker = child ;
336343 commentMarkersToFind ++ ;
337- } else if ( child . data == '/$s' ) {
338- commentMarkersToFind -- ;
339- if ( commentMarkersToFind ) {
340- newVNode . _component . _excess . push ( child ) ;
344+ } else if ( child . data . startsWith ( '/$s' ) ) {
345+ if ( -- commentMarkersToFind == 0 ) {
346+ oldDom = child ;
347+ excessDomChildren [ i ] = NULL ;
348+ break ;
341349 }
342- done = commentMarkersToFind == 0 ;
343- oldDom = excessDomChildren [ i ] ;
344350 }
345351 excessDomChildren [ i ] = NULL ;
346352 } else if ( commentMarkersToFind ) {
347- newVNode . _component . _excess . push ( child ) ;
348353 excessDomChildren [ i ] = NULL ;
349354 }
350355 }
351356
352- if ( ! done ) {
357+ if ( startMarker ) {
358+ // Store start marker directly; children re-scanned on resume
359+ newVNode . _component . _excess = startMarker ;
360+ } else {
353361 while ( oldDom && oldDom . nodeType == 8 && oldDom . nextSibling ) {
354362 oldDom = oldDom . nextSibling ;
355363 }
356364
357365 excessDomChildren [ excessDomChildren . indexOf ( oldDom ) ] = NULL ;
358- newVNode . _component . _excess = [ oldDom ] ;
366+ newVNode . _component . _excess = oldDom ;
359367 }
360368
361369 newVNode . _dom = oldDom ;
0 commit comments