@@ -101,10 +101,7 @@ interface CompileProps {
101101 codes : Code [ ] ;
102102}
103103export interface CompileResultWithOutput extends CompileResult {
104- compilerOutput : ReplOutput [ ] ;
105- compilerError : ReplOutput [ ] ;
106- programOutput : ReplOutput [ ] ;
107- programError : ReplOutput [ ] ;
104+ output : ReplOutput [ ] ;
108105}
109106
110107export async function compileAndRun (
@@ -136,12 +133,41 @@ export async function compileAndRun(
136133 throw new Error ( `HTTP error! status: ${ response . status } ` ) ;
137134 }
138135
139- // Read the ndjson response line by line
140- const text = await response . text ( ) ;
141- const lines = text . trim ( ) . split ( "\n" ) ;
142- const ndjsonResults : CompileNdjsonResult [ ] = lines
143- . filter ( ( line ) => line . trim ( ) . length > 0 )
144- . map ( ( line ) => JSON . parse ( line ) as CompileNdjsonResult ) ;
136+ // Read the ndjson response as a stream
137+ const reader = response . body ?. getReader ( ) ;
138+ if ( ! reader ) {
139+ throw new Error ( "Response body is not readable" ) ;
140+ }
141+
142+ const decoder = new TextDecoder ( ) ;
143+ let buffer = "" ;
144+ const ndjsonResults : CompileNdjsonResult [ ] = [ ] ;
145+
146+ try {
147+ while ( true ) {
148+ const { done, value } = await reader . read ( ) ;
149+ if ( done ) break ;
150+
151+ buffer += decoder . decode ( value , { stream : true } ) ;
152+ const lines = buffer . split ( "\n" ) ;
153+
154+ // Keep the last incomplete line in the buffer
155+ buffer = lines . pop ( ) || "" ;
156+
157+ for ( const line of lines ) {
158+ if ( line . trim ( ) . length > 0 ) {
159+ ndjsonResults . push ( JSON . parse ( line ) as CompileNdjsonResult ) ;
160+ }
161+ }
162+ }
163+
164+ // Process any remaining data in the buffer
165+ if ( buffer . trim ( ) . length > 0 ) {
166+ ndjsonResults . push ( JSON . parse ( buffer ) as CompileNdjsonResult ) ;
167+ }
168+ } finally {
169+ reader . releaseLock ( ) ;
170+ }
145171
146172 // Merge ndjson results into a CompileResult (same logic as Rust merge_compile_result)
147173 const result : CompileResult = {
@@ -157,6 +183,9 @@ export async function compileAndRun(
157183 url : "" ,
158184 } ;
159185
186+ // Build output array in the order messages are received
187+ const output : ReplOutput [ ] = [ ] ;
188+
160189 for ( const r of ndjsonResults ) {
161190 switch ( r . type ) {
162191 case "Control" :
@@ -165,18 +194,42 @@ export async function compileAndRun(
165194 case "CompilerMessageS" :
166195 result . compiler_output += r . data ;
167196 result . compiler_message += r . data ;
197+ // Add to output in order
198+ if ( r . data . trim ( ) ) {
199+ for ( const line of r . data . trim ( ) . split ( "\n" ) ) {
200+ output . push ( { type : "stdout" , message : line } ) ;
201+ }
202+ }
168203 break ;
169204 case "CompilerMessageE" :
170205 result . compiler_error += r . data ;
171206 result . compiler_message += r . data ;
207+ // Add to output in order
208+ if ( r . data . trim ( ) ) {
209+ for ( const line of r . data . trim ( ) . split ( "\n" ) ) {
210+ output . push ( { type : "error" , message : line } ) ;
211+ }
212+ }
172213 break ;
173214 case "StdOut" :
174215 result . program_output += r . data ;
175216 result . program_message += r . data ;
217+ // Add to output in order
218+ if ( r . data . trim ( ) ) {
219+ for ( const line of r . data . trim ( ) . split ( "\n" ) ) {
220+ output . push ( { type : "stdout" , message : line } ) ;
221+ }
222+ }
176223 break ;
177224 case "StdErr" :
178225 result . program_error += r . data ;
179226 result . program_message += r . data ;
227+ // Add to output in order
228+ if ( r . data . trim ( ) ) {
229+ for ( const line of r . data . trim ( ) . split ( "\n" ) ) {
230+ output . push ( { type : "stderr" , message : line } ) ;
231+ }
232+ }
180233 break ;
181234 case "ExitCode" :
182235 result . status += r . data ;
@@ -192,29 +245,6 @@ export async function compileAndRun(
192245
193246 return {
194247 ...result ,
195- compilerOutput : result . compiler_output . trim ( )
196- ? result . compiler_output
197- . trim ( )
198- . split ( "\n" )
199- . map ( ( line ) => ( { type : "stdout" as const , message : line } ) )
200- : [ ] ,
201- compilerError : result . compiler_error . trim ( )
202- ? result . compiler_error
203- . trim ( )
204- . split ( "\n" )
205- . map ( ( line ) => ( { type : "error" as const , message : line } ) )
206- : [ ] ,
207- programOutput : result . program_output . trim ( )
208- ? result . program_output
209- . trim ( )
210- . split ( "\n" )
211- . map ( ( line ) => ( { type : "stdout" as const , message : line } ) )
212- : [ ] ,
213- programError : result . program_error . trim ( )
214- ? result . program_error
215- . trim ( )
216- . split ( "\n" )
217- . map ( ( line ) => ( { type : "error" as const , message : line } ) )
218- : [ ] ,
248+ output,
219249 } ;
220250}
0 commit comments