import Runner from "./Runner.js"; import { watch } from "chokidar"; import { posix } from "path"; function debounce(func, wait) { let timeout = null; return function (...parameters) { if (timeout) clearTimeout(timeout); else func(...parameters); timeout = setTimeout(() => (timeout = null), wait); }; } export default class Watcher extends Runner { constructor(input, options) { super(input, options); this.watcher = null; this.watched = []; this.watched = options?.watch instanceof Array ? options.watch.map((glob) => posix.resolve(glob)) : []; } async run() { try { console.clear(); await this.build(); this.execute(); this.watch(); } catch (error) { } } async rerun() { if (!this.watcher) throw "Cannot re-run before a first run"; if (this.childProcess) { this.childProcess?.kill("SIGINT"); this.childProcess = undefined; } await this.rebuild(); // we update the list of watched files if (this.buildOutput) { this.watch(); } await this.execute(); } async rebuild() { if (!this.preserveConsole) { console.clear(); } this.dependencies.length = 0; if (this.buildOutput) { try { this.buildOutput = await this.buildContext?.rebuild(); this.outputCode = this.getOutputCode(); this.dependencies = this.retrieveDependencies(); } catch (error) { this.buildOutput = undefined; this.outputCode = ""; } } else { await this.build(); } } watch() { void this.watcher?.close(); this.watcher = watch([ ...this.dependencies, "package.json", ...this.watched, ]); this.watcher.on("change", debounce(this.rerun.bind(this), 300)); this.watcher.on("unlink", debounce(this.rerun.bind(this), 300)); } }