@@ -32,38 +32,52 @@ export class ProcessWrap {
3232 } ;
3333 } ) ;
3434
35- this . _isReady = promise . then ( ( webcontainerProcess ) => {
36- this . _webcontainerProcess = webcontainerProcess ;
37- this . _writer = webcontainerProcess . input . getWriter ( ) ;
35+ this . _isReady = new Promise ( ( resolve , reject ) => {
36+ const timeout = setTimeout ( ( ) => {
37+ console . error (
38+ "WebContainer process startup timed out in 30s, TODO remove this log message" ,
39+ ) ;
3840
39- webcontainerProcess . exit . then ( setDone ) ;
41+ reject ( new Error ( "WebContainer process startup timed out in 30s" ) ) ;
42+ } , 30_000 ) ;
4043
41- const reader = this . _webcontainerProcess . output . getReader ( ) ;
44+ promise . then ( ( webcontainerProcess ) => {
45+ clearTimeout ( timeout ) ;
4246
43- const read = async ( ) => {
44- while ( true ) {
45- const { done, value } = await reader . read ( ) ;
47+ this . _webcontainerProcess = webcontainerProcess ;
48+ this . _writer = webcontainerProcess . input . getWriter ( ) ;
4649
47- if ( isExitted && ! done ) {
48- console . warn (
49- `[webcontainer-test]: Closed process keeps writing to output. Closing reader forcefully. \n` +
50- ` Received: "${ value } ".` ,
51- ) ;
52- await reader . cancel ( ) ;
53- break ;
54- }
50+ webcontainerProcess . exit . then ( setDone ) ;
51+
52+ const reader = this . _webcontainerProcess . output . getReader ( ) ;
53+
54+ const read = async ( ) => {
55+ while ( true ) {
56+ const { done, value } = await reader . read ( ) ;
5557
56- // webcontainer process never reaches here, but for future-proofing let's exit
57- if ( done ) {
58- break ;
58+ if ( isExitted && ! done ) {
59+ console . warn (
60+ `[webcontainer-test]: Closed process keeps writing to output. Closing reader forcefully. \n` +
61+ ` Received: "${ value } ".` ,
62+ ) ;
63+ await reader . cancel ( ) ;
64+ break ;
65+ }
66+
67+ // webcontainer process never reaches here, but for future-proofing let's exit
68+ if ( done ) {
69+ break ;
70+ }
71+
72+ this . _output += value ;
73+ this . _listeners . forEach ( ( fn ) => fn ( value ) ) ;
5974 }
75+ } ;
6076
61- this . _output += value ;
62- this . _listeners . forEach ( ( fn ) => fn ( value ) ) ;
63- }
64- } ;
77+ void read ( ) ;
6578
66- void read ( ) ;
79+ resolve ( ) ;
80+ } ) ;
6781 } ) ;
6882 }
6983
@@ -147,9 +161,23 @@ export class ProcessWrap {
147161 exit = async ( ) => {
148162 await this . _isReady ;
149163
150- this . _webcontainerProcess . kill ( ) ;
151- this . _listeners . splice ( 0 ) ;
164+ // eslint-disable-next-line no-async-promise-executor -- async in promise is completely fine
165+ return new Promise < void > ( async ( resolve , reject ) => {
166+ const timeout = setTimeout ( ( ) => {
167+ console . error (
168+ "WebContainer process teardown timed out in 30s, TODO remove this log message" ,
169+ ) ;
170+
171+ reject ( new Error ( "WebContainer process teardown timed out in 30s" ) ) ;
172+ } , 30_000 ) ;
152173
153- return this . isDone ;
174+ this . _webcontainerProcess . kill ( ) ;
175+ this . _listeners . splice ( 0 ) ;
176+
177+ await this . isDone ;
178+
179+ clearTimeout ( timeout ) ;
180+ resolve ( ) ;
181+ } ) ;
154182 } ;
155183}
0 commit comments