@@ -21,11 +21,27 @@ declare global {
2121self . stdout = {
2222 write ( str : string ) {
2323 stdoutBuffer += str ;
24+ // If buffer contains newlines, flush complete lines immediately
25+ if ( stdoutBuffer . includes ( "\n" ) ) {
26+ const lines = stdoutBuffer . split ( "\n" ) ;
27+ for ( let i = 0 ; i < lines . length - 1 ; i ++ ) {
28+ currentOutputCallback ?.( { type : "stdout" , message : lines [ i ] } ) ;
29+ }
30+ stdoutBuffer = lines [ lines . length - 1 ] ;
31+ }
2432 } ,
2533} ;
2634self . stderr = {
2735 write ( str : string ) {
2836 stderrBuffer += str ;
37+ // If buffer contains newlines, flush complete lines immediately
38+ if ( stderrBuffer . includes ( "\n" ) ) {
39+ const lines = stderrBuffer . split ( "\n" ) ;
40+ for ( let i = 0 ; i < lines . length - 1 ; i ++ ) {
41+ currentOutputCallback ?.( { type : "stderr" , message : lines [ i ] } ) ;
42+ }
43+ stderrBuffer = lines [ lines . length - 1 ] ;
44+ }
2945 } ,
3046} ;
3147
@@ -55,30 +71,14 @@ async function init(/*_interruptBuffer?: Uint8Array*/): Promise<{
5571}
5672
5773function flushOutput ( ) {
58- if ( ! currentOutputCallback ) return ;
59-
60- if ( stdoutBuffer ) {
61- const lines = stdoutBuffer . split ( "\n" ) ;
62- for ( let i = 0 ; i < lines . length - 1 ; i ++ ) {
63- currentOutputCallback ( { type : "stdout" , message : lines [ i ] } ) ;
64- }
65- stdoutBuffer = lines [ lines . length - 1 ] ;
66- }
67- // Final flush if there's remaining non-empty text
74+ // Flush any remaining non-empty text without newlines
6875 if ( stdoutBuffer && stdoutBuffer . trim ( ) ) {
69- currentOutputCallback ( { type : "stdout" , message : stdoutBuffer } ) ;
76+ currentOutputCallback ?. ( { type : "stdout" , message : stdoutBuffer } ) ;
7077 }
7178 stdoutBuffer = "" ;
7279
73- if ( stderrBuffer ) {
74- const lines = stderrBuffer . split ( "\n" ) ;
75- for ( let i = 0 ; i < lines . length - 1 ; i ++ ) {
76- currentOutputCallback ( { type : "stderr" , message : lines [ i ] } ) ;
77- }
78- stderrBuffer = lines [ lines . length - 1 ] ;
79- }
8080 if ( stderrBuffer && stderrBuffer . trim ( ) ) {
81- currentOutputCallback ( { type : "stderr" , message : stderrBuffer } ) ;
81+ currentOutputCallback ?. ( { type : "stderr" , message : stderrBuffer } ) ;
8282 }
8383 stderrBuffer = "" ;
8484}
@@ -120,9 +120,6 @@ async function runCode(
120120
121121 const result = rubyVM . eval ( code ) ;
122122
123- // Flush any buffered output
124- flushOutput ( ) ;
125-
126123 const resultStr = await result . callAsync ( "inspect" ) ;
127124
128125 // Add result to output if it's not nil and not empty
@@ -132,13 +129,14 @@ async function runCode(
132129 } ) ;
133130 } catch ( e ) {
134131 console . log ( e ) ;
135- flushOutput ( ) ;
136132
137133 onOutput ( {
138134 type : "error" ,
139135 message : formatRubyError ( e , false ) ,
140136 } ) ;
141137 } finally {
138+ // Flush any buffered output
139+ flushOutput ( ) ;
142140 currentOutputCallback = null ;
143141 }
144142
@@ -177,18 +175,16 @@ async function runFile(
177175
178176 // Run the specified file
179177 rubyVM . eval ( `load ${ JSON . stringify ( name ) } ` ) ;
180-
181- // Flush any buffered output
182- flushOutput ( ) ;
183178 } catch ( e ) {
184179 console . log ( e ) ;
185- flushOutput ( ) ;
186180
187181 onOutput ( {
188182 type : "error" ,
189183 message : formatRubyError ( e , true ) ,
190184 } ) ;
191185 } finally {
186+ // Flush any buffered output
187+ flushOutput ( ) ;
192188 currentOutputCallback = null ;
193189 }
194190
0 commit comments