@@ -26,6 +26,41 @@ export function renderToPipeableStream(vnode, options, context) {
2626 const controller = new AbortController ( ) ;
2727 const stream = new PassThrough ( ) ;
2828 let waitingForDrain = null ;
29+ let shellReadyCalled = false ;
30+ let allReadyCalled = false ;
31+ let errored = false ;
32+ let shellReadyScheduled = false ;
33+
34+ function callOnShellReady ( ) {
35+ if ( shellReadyCalled || errored ) return ;
36+ shellReadyCalled = true ;
37+ options . onShellReady && options . onShellReady ( ) ;
38+ }
39+
40+ function callOnAllReady ( ) {
41+ if ( allReadyCalled || errored ) return ;
42+ allReadyCalled = true ;
43+ options . onAllReady && options . onAllReady ( ) ;
44+ }
45+
46+ function callOnError ( error ) {
47+ if ( errored ) return ;
48+ errored = true ;
49+ if ( options . onError ) {
50+ options . onError ( error ) ;
51+ } else {
52+ throw error ;
53+ }
54+ }
55+
56+ function scheduleOnShellReady ( ) {
57+ if ( shellReadyCalled || shellReadyScheduled || errored ) return ;
58+ shellReadyScheduled = true ;
59+ Promise . resolve ( ) . then ( ( ) => {
60+ shellReadyScheduled = false ;
61+ callOnShellReady ( ) ;
62+ } ) ;
63+ }
2964
3065 /**
3166 * @returns {Promise<void> }
@@ -59,33 +94,29 @@ export function renderToPipeableStream(vnode, options, context) {
5994 return waitingForDrain ;
6095 }
6196
62- renderToChunks ( vnode , {
63- context,
64- abortSignal : controller . signal ,
65- async onWrite ( s ) {
66- if ( stream . destroyed || stream . writableEnded ) return ;
67- if ( ! stream . write ( encoder . encode ( s ) ) ) {
68- await waitForDrain ( ) ;
69- }
70- }
71- } )
97+ Promise . resolve ( )
98+ . then ( ( ) =>
99+ renderToChunks ( vnode , {
100+ context,
101+ abortSignal : controller . signal ,
102+ async onWrite ( s ) {
103+ scheduleOnShellReady ( ) ;
104+ if ( stream . destroyed || stream . writableEnded ) return ;
105+ if ( ! stream . write ( encoder . encode ( s ) ) ) {
106+ await waitForDrain ( ) ;
107+ }
108+ }
109+ } )
110+ )
72111 . then ( ( ) => {
73- options . onAllReady && options . onAllReady ( ) ;
112+ callOnAllReady ( ) ;
74113 stream . end ( ) ;
75114 } )
76115 . catch ( ( error ) => {
77116 stream . destroy ( ) ;
78- if ( options . onError ) {
79- options . onError ( error ) ;
80- } else {
81- throw error ;
82- }
117+ callOnError ( error ) ;
83118 } ) ;
84119
85- Promise . resolve ( ) . then ( ( ) => {
86- options . onShellReady && options . onShellReady ( ) ;
87- } ) ;
88-
89120 return {
90121 /**
91122 * @param {unknown } [reason]
0 commit comments