@@ -37,46 +37,45 @@ async function init({ id }: WorkerRequest["init"]) {
3737 } satisfies WorkerResponse [ "init" ] ) ;
3838}
3939
40- async function runCode ( { id, payload } : WorkerRequest [ "runCode" ] ) {
41- let { code } = payload ;
42- try {
43- let result : unknown ;
44-
45- // eval()の中でconst,letを使って変数を作成した場合、
46- // 次に実行するコマンドはスコープ外扱いでありアクセスできなくなってしまうので、
47- // varに置き換えている
48- if ( code . trim ( ) . startsWith ( "const " ) ) {
49- code = "var " + code . trim ( ) . slice ( 6 ) ;
50- } else if ( code . trim ( ) . startsWith ( "let " ) ) {
51- code = "var " + code . trim ( ) . slice ( 4 ) ;
52- }
53- // eval()の中でclassを作成した場合も同様
54- const classRegExp = / ^ \s * c l a s s \s + ( \w + ) / ;
55- if ( classRegExp . test ( code ) ) {
56- code = code . replace ( classRegExp , "var $1 = class $1" ) ;
57- }
40+ async function replLikeEval ( code : string ) : Promise < unknown > {
41+ // eval()の中でconst,letを使って変数を作成した場合、
42+ // 次に実行するコマンドはスコープ外扱いでありアクセスできなくなってしまうので、
43+ // varに置き換えている
44+ if ( code . trim ( ) . startsWith ( "const " ) ) {
45+ code = "var " + code . trim ( ) . slice ( 6 ) ;
46+ } else if ( code . trim ( ) . startsWith ( "let " ) ) {
47+ code = "var " + code . trim ( ) . slice ( 4 ) ;
48+ }
49+ // eval()の中でclassを作成した場合も同様
50+ const classRegExp = / ^ \s * c l a s s \s + ( \w + ) / ;
51+ if ( classRegExp . test ( code ) ) {
52+ code = code . replace ( classRegExp , "var $1 = class $1" ) ;
53+ }
5854
59- if ( code . trim ( ) . startsWith ( "{" ) && code . trim ( ) . endsWith ( "}" ) ) {
60- // オブジェクトは ( ) で囲わなければならない
61- try {
62- result = self . eval ( `(${ code } )` ) ;
63- } catch ( e ) {
64- if ( e instanceof SyntaxError ) {
65- // オブジェクトではなくブロックだった場合、再度普通に実行
66- result = self . eval ( code ) ;
67- } else {
68- throw e ;
69- }
55+ if ( code . trim ( ) . startsWith ( "{" ) && code . trim ( ) . endsWith ( "}" ) ) {
56+ // オブジェクトは ( ) で囲わなければならない
57+ try {
58+ return self . eval ( `(${ code } )` ) ;
59+ } catch ( e ) {
60+ if ( e instanceof SyntaxError ) {
61+ // オブジェクトではなくブロックだった場合、再度普通に実行
62+ return self . eval ( code ) ;
63+ } else {
64+ throw e ;
7065 }
71- } else if ( / ^ \s * a w a i t \W / . test ( code ) ) {
72- // promiseをawaitする場合は、promiseの部分だけをevalし、それを外からawaitする
73- result = await self . eval ( code . trim ( ) . slice ( 5 ) ) ;
74- } else {
75- // Execute code directly with eval in the worker global scope
76- // This will preserve variables across calls
77- result = self . eval ( code ) ;
7866 }
67+ } else if ( / ^ \s * a w a i t \W / . test ( code ) ) {
68+ // promiseをawaitする場合は、promiseの部分だけをevalし、それを外からawaitする
69+ return await self . eval ( code . trim ( ) . slice ( 5 ) ) ;
70+ } else {
71+ return self . eval ( code ) ;
72+ }
73+ }
7974
75+ async function runCode ( { id, payload } : WorkerRequest [ "runCode" ] ) {
76+ const { code } = payload ;
77+ try {
78+ const result = await replLikeEval ( code ) ;
8079 jsOutput . push ( {
8180 type : "return" ,
8281 message : inspect ( result ) ,
@@ -110,8 +109,6 @@ function runFile({ id, payload }: WorkerRequest["runFile"]) {
110109 const { name, files } = payload ;
111110 // pyodide worker などと異なり、複数ファイルを読み込んでimportのようなことをするのには対応していません。
112111 try {
113- // Execute code directly with eval in the worker global scope
114- // This will preserve variables across calls
115112 self . eval ( files [ name ] ) ;
116113 } catch ( e ) {
117114 originalConsole . log ( e ) ;
@@ -183,7 +180,7 @@ async function restoreState({ id, payload }: WorkerRequest["restoreState"]) {
183180
184181 for ( const command of commands ) {
185182 try {
186- self . eval ( command ) ;
183+ replLikeEval ( command ) ;
187184 } catch ( e ) {
188185 // If restoration fails, we still continue with other commands
189186 originalConsole . error ( "Failed to restore command:" , command , e ) ;
0 commit comments