@@ -148,6 +148,8 @@ function doHelp() {
148148}
149149
150150async function doWatch ( ) {
151+ const { promise, resolve, reject } = Promise . withResolvers ( ) ;
152+
151153 logger . info ( `🤖 Watching entry points:\n\t${ Object . keys ( EntryPoint ) . join ( "\n\t" ) } ` ) ;
152154
153155 const entryPoints = Object . values ( EntryPoint ) ;
@@ -182,23 +184,31 @@ async function doWatch() {
182184 logger . info ( `🔓 ${ httpURL . href } ` ) ;
183185 logger . info ( `🔒 ${ httpsURL . href } ` ) ;
184186
185- return /** @type {Promise<void> } */ (
186- new Promise ( ( resolve ) => {
187- process . on ( "SIGINT" , ( ) => {
188- resolve ( ) ;
189- } ) ;
190- } )
191- ) ;
187+ let disposing = false ;
188+
189+ const delegateShutdown = ( ) => {
190+ logger . flush ( ) ;
191+ console . log ( "" ) ;
192+
193+ // We prevent multiple attempts to dispose the context
194+ // because ESBuild will repeatedly restart its internal clean-up logic.
195+ // However, sending a second SIGINT will still exit the process immediately.
196+ if ( disposing ) return ;
197+
198+ disposing = true ;
199+
200+ return buildContext . dispose ( ) . then ( resolve ) . catch ( reject ) ;
201+ } ;
202+
203+ process . on ( "SIGINT" , delegateShutdown ) ;
204+
205+ return promise ;
192206}
193207
194208async function doBuild ( ) {
195- logger . info ( `🚀 Building entry points:` ) ;
196-
197- const entryPoints = Object . entries ( EntryPoint ) . map ( ( [ entrypointID , target ] ) => {
198- logger . info ( entrypointID ) ;
209+ logger . info ( `🤖 Watching entry points:\n\t${ Object . keys ( EntryPoint ) . join ( "\n\t" ) } ` ) ;
199210
200- return target ;
201- } ) ;
211+ const entryPoints = Object . values ( EntryPoint ) ;
202212
203213 const buildOptions = createESBuildOptions ( {
204214 entryPoints,
0 commit comments