@@ -17,6 +17,7 @@ import { EnvLoader, EnvParser } from '@adonisjs/env'
17
17
import { run } from './run.js'
18
18
import { watch } from './watch.js'
19
19
import type { DevServerOptions } from './types.js'
20
+ import type { Watcher } from '@poppinss/chokidar-ts'
20
21
21
22
/**
22
23
* Instance of CLIUI
@@ -43,6 +44,9 @@ export class DevServer {
43
44
#httpServerProcess?: ExecaChildProcess < string >
44
45
#isMetaFileWithReloadsEnabled: picomatch . Matcher
45
46
#isMetaFileWithReloadsDisabled: picomatch . Matcher
47
+ #watcher?: ReturnType < Watcher [ 'watch' ] >
48
+ #onError?: ( error : any ) => any
49
+ #onClose?: ( exitCode : number ) => any
46
50
47
51
/**
48
52
* Getting reference to colors library from logger
@@ -136,7 +140,7 @@ export class DevServer {
136
140
/**
137
141
* Starts the HTTP server
138
142
*/
139
- #startHTTPServer( port : string ) {
143
+ #startHTTPServer( port : string , mode : 'blocking' | 'nonblocking' ) {
140
144
this . #httpServerProcess = run ( this . #cwd, {
141
145
script : this . #scriptFile,
142
146
env : { PORT : port , ...this . #options. env } ,
@@ -159,15 +163,20 @@ export class DevServer {
159
163
}
160
164
} )
161
165
162
- this . #httpServerProcess. on ( 'error' , ( error ) => {
163
- this . #logger. warning ( 'unable to connect to underlying HTTP server process' )
164
- this . #logger. fatal ( error )
165
- } )
166
-
167
- this . #httpServerProcess. on ( 'close' , ( exitCode ) => {
168
- this . #logger. warning ( `underlying HTTP server closed with status code "${ exitCode } "` )
169
- this . #logger. info ( 'watching file system and waiting for application to recover' )
170
- } )
166
+ this . #httpServerProcess
167
+ . then ( ( result ) => {
168
+ this . #logger. warning ( `underlying HTTP server closed with status code "${ result . exitCode } "` )
169
+ if ( mode === 'nonblocking' ) {
170
+ this . #onClose?.( result . exitCode )
171
+ this . #watcher?. close ( )
172
+ }
173
+ } )
174
+ . catch ( ( error ) => {
175
+ this . #logger. warning ( 'unable to connect to underlying HTTP server process' )
176
+ this . #logger. fatal ( error )
177
+ this . #onError?.( error )
178
+ this . #watcher?. close ( )
179
+ } )
171
180
}
172
181
173
182
/**
@@ -179,7 +188,7 @@ export class DevServer {
179
188
this . #httpServerProcess. kill ( 'SIGKILL' )
180
189
}
181
190
182
- this . #startHTTPServer( port )
191
+ this . #startHTTPServer( port , 'blocking' )
183
192
}
184
193
185
194
/**
@@ -190,39 +199,67 @@ export class DevServer {
190
199
return this
191
200
}
192
201
202
+ /**
203
+ * Add listener to get notified when dev server is
204
+ * closed
205
+ */
206
+ onClose ( callback : ( exitCode : number ) => any ) : this {
207
+ this . #onClose = callback
208
+ return this
209
+ }
210
+
211
+ /**
212
+ * Add listener to get notified when dev server exists
213
+ * with an error
214
+ */
215
+ onError ( callback : ( error : any ) => any ) : this {
216
+ this . #onError = callback
217
+ return this
218
+ }
219
+
193
220
/**
194
221
* Start the development server
195
222
*/
196
223
async start ( ) {
197
224
this . #clearScreen( )
198
225
this . #logger. info ( 'starting HTTP server...' )
199
- this . #startHTTPServer( String ( await this . #getPort( ) ) )
226
+ this . #startHTTPServer( String ( await this . #getPort( ) ) , 'nonblocking' )
200
227
}
201
228
202
229
/**
203
230
* Start the development server in watch mode
204
231
*/
205
232
async startAndWatch ( ts : typeof tsStatic , options ?: { poll : boolean } ) {
206
- const port = String ( await this . #getPort( ) )
207
-
208
233
this . #isWatching = true
209
234
this . #clearScreen( )
210
235
236
+ const port = String ( await this . #getPort( ) )
237
+
211
238
this . #logger. info ( 'starting HTTP server...' )
212
- this . #startHTTPServer( port )
239
+ this . #startHTTPServer( port , 'blocking' )
213
240
214
241
const output = watch ( this . #cwd, ts , options || { } )
215
242
if ( ! output ) {
243
+ this . #onClose?.( 1 )
216
244
return
217
245
}
218
246
247
+ this . #watcher = output . chokidar
248
+
219
249
/**
220
250
* Notify the watcher is ready
221
251
*/
222
252
output . watcher . on ( 'watcher:ready' , ( ) => {
223
253
this . #logger. info ( 'watching file system for changes...' )
224
254
} )
225
255
256
+ output . chokidar . on ( 'error' , ( error ) => {
257
+ this . #logger. warning ( 'file system watcher failure' )
258
+ this . #logger. fatal ( error )
259
+ this . #onError?.( error )
260
+ output . chokidar . close ( )
261
+ } )
262
+
226
263
/**
227
264
* Changes in TypeScript source file
228
265
*/
0 commit comments