@roots/bud-server
Version:
Development server for @roots/bud
93 lines (76 loc) • 1.9 kB
text/typescript
import type {Bud} from '@roots/bud-framework'
import type {Watcher as BudWatcher} from '@roots/bud-framework/services/server'
import type {FSWatcher} from 'node:fs'
import * as chokidar from '@roots/bud-support/chokidar'
import {bind} from '@roots/bud-support/decorators/bind'
import logger from '@roots/bud-support/logger'
/**
* FS Watcher
*/
export class Watcher implements BudWatcher {
/**
* Watch files
*/
public files: Set<string>
/**
* Watcher instance
*/
public instance: FSWatcher
/**
* Watch options
*/
public options: chokidar.WatchOptions
/**
* Class constructor
*
* @param app - Application instance
*/
public constructor(public _app: () => Bud) {}
/**
* App instance
*/
public get app(): Bud {
return this._app()
}
/**
* Logger
*/
public get logger(): any {
return logger.scope(`watcher`)
}
/**
* Initialize watch files
*/
public async watch(): Promise<undefined | Watcher['instance']> {
if (this.app.context.dry) return
this.files = this.app.hooks.filter(`dev.watch.files`, new Set([]))
this.options = this.app.hooks.filter(`dev.watch.options`, {
cwd: this.app.path(),
ignoreInitial: true,
})
if (this.files.size < 1) return
this.instance = chokidar
.watch([...this.files], this.options)
.on(`change`, this.watcherCallback)
.on(`add`, this.watcherCallback)
.on(`unlink`, this.watcherCallback)
this.logger.log(`watching`)
return this.instance
}
/**
* Watcher callback
*/
public watcherCallback(path: string): void {
this.logger.log(
`edit to`,
path.replace(this.app.path(), `.`),
`triggered reload`,
)
this.app.server?.appliedMiddleware?.hot?.publish({
action: `reload`,
message: `Detected file change: ${path}. Reloading window.`,
})
}
}