export abstract class Builder { abstract ownsFile(file_path: string): boolean; abstract getName(): string; abstract _build(): Promise; abstract dispose(): Promise; constructor( public project_dir: string, public style_dirs: string[] ) {} public ongoing_build: Promise | null = null; public build(notifier?: (message: string) => void) { if (!this.ongoing_build) { const build = this._build() .catch((err) => { console.error(err); }) .then(() => { notifier?.(this.getName()); this.ongoing_build = null; }); this.ongoing_build = build; } return this.ongoing_build; } }