@@ -10,24 +10,20 @@ function format(...args: unknown[]): string {
1010 // https://nodejs.org/api/util.html#utilformatformat-args
1111 return args . map ( ( a ) => ( typeof a === "string" ? a : inspect ( a ) ) ) . join ( " " ) ;
1212}
13- let jsOutput : ReplOutput [ ] = [ ] ;
13+ let currentOutputCallback : ( ( output : ReplOutput ) => void ) | null = null ;
1414
1515// Helper function to capture console output
1616const originalConsole = self . console ;
1717self . console = {
1818 ...originalConsole ,
19- log : ( ...args : unknown [ ] ) => {
20- jsOutput . push ( { type : "stdout" , message : format ( ...args ) } ) ;
21- } ,
22- error : ( ...args : unknown [ ] ) => {
23- jsOutput . push ( { type : "stderr" , message : format ( ...args ) } ) ;
24- } ,
25- warn : ( ...args : unknown [ ] ) => {
26- jsOutput . push ( { type : "stderr" , message : format ( ...args ) } ) ;
27- } ,
28- info : ( ...args : unknown [ ] ) => {
29- jsOutput . push ( { type : "stdout" , message : format ( ...args ) } ) ;
30- } ,
19+ log : ( ...args : unknown [ ] ) =>
20+ currentOutputCallback ?.( { type : "stdout" , message : format ( ...args ) } ) ,
21+ error : ( ...args : unknown [ ] ) =>
22+ currentOutputCallback ?.( { type : "stderr" , message : format ( ...args ) } ) ,
23+ warn : ( ...args : unknown [ ] ) =>
24+ currentOutputCallback ?.( { type : "stderr" , message : format ( ...args ) } ) ,
25+ info : ( ...args : unknown [ ] ) =>
26+ currentOutputCallback ?.( { type : "stdout" , message : format ( ...args ) } ) ,
3127} ;
3228
3329async function init ( /*_interruptBuffer?: Uint8Array*/ ) : Promise < {
@@ -73,65 +69,68 @@ async function replLikeEval(code: string): Promise<unknown> {
7369 }
7470}
7571
76- async function runCode ( code : string ) : Promise < {
77- output : ReplOutput [ ] ;
72+ async function runCode (
73+ code : string ,
74+ onOutput : ( output : ReplOutput ) => void
75+ ) : Promise < {
7876 updatedFiles : Record < string , string > ;
7977} > {
78+ currentOutputCallback = onOutput ;
8079 try {
8180 const result = await replLikeEval ( code ) ;
82- jsOutput . push ( {
81+ onOutput ( {
8382 type : "return" ,
8483 message : inspect ( result ) ,
8584 } ) ;
8685 } catch ( e ) {
8786 originalConsole . log ( e ) ;
8887 // TODO: stack trace?
8988 if ( e instanceof Error ) {
90- jsOutput . push ( {
89+ onOutput ( {
9190 type : "error" ,
9291 message : `${ e . name } : ${ e . message } ` ,
9392 } ) ;
9493 } else {
95- jsOutput . push ( {
94+ onOutput ( {
9695 type : "error" ,
9796 message : `${ String ( e ) } ` ,
9897 } ) ;
9998 }
99+ } finally {
100+ currentOutputCallback = null ;
100101 }
101102
102- const output = [ ...jsOutput ] ;
103- jsOutput = [ ] ; // Clear output
104-
105- return { output, updatedFiles : { } as Record < string , string > } ;
103+ return { updatedFiles : { } as Record < string , string > } ;
106104}
107105
108106function runFile (
109107 name : string ,
110- files : Record < string , string >
111- ) : { output : ReplOutput [ ] ; updatedFiles : Record < string , string > } {
108+ files : Record < string , string > ,
109+ onOutput : ( output : ReplOutput ) => void
110+ ) : { updatedFiles : Record < string , string > } {
112111 // pyodide worker などと異なり、複数ファイルを読み込んでimportのようなことをするのには対応していません。
112+ currentOutputCallback = onOutput ;
113113 try {
114114 self . eval ( files [ name ] ) ;
115115 } catch ( e ) {
116116 originalConsole . log ( e ) ;
117117 // TODO: stack trace?
118118 if ( e instanceof Error ) {
119- jsOutput . push ( {
119+ onOutput ( {
120120 type : "error" ,
121121 message : `${ e . name } : ${ e . message } ` ,
122122 } ) ;
123123 } else {
124- jsOutput . push ( {
124+ onOutput ( {
125125 type : "error" ,
126126 message : `${ String ( e ) } ` ,
127127 } ) ;
128128 }
129+ } finally {
130+ currentOutputCallback = null ;
129131 }
130132
131- const output = [ ...jsOutput ] ;
132- jsOutput = [ ] ; // Clear output
133-
134- return { output, updatedFiles : { } as Record < string , string > } ;
133+ return { updatedFiles : { } as Record < string , string > } ;
135134}
136135
137136async function checkSyntax (
@@ -162,8 +161,6 @@ async function checkSyntax(
162161
163162async function restoreState ( commands : string [ ] ) : Promise < object > {
164163 // Re-execute all previously successful commands to restore state
165- jsOutput = [ ] ; // Clear output for restoration
166-
167164 for ( const command of commands ) {
168165 try {
169166 replLikeEval ( command ) ;
@@ -173,7 +170,6 @@ async function restoreState(commands: string[]): Promise<object> {
173170 }
174171 }
175172
176- jsOutput = [ ] ; // Clear any output from restoration
177173 return { } ;
178174}
179175
0 commit comments