import { priorityQueue , AsyncPriorityQueue } from "async" ; import { BuildResult , BuildPackage } from "../buildGraph" ; import { LeafTask } from "./leaf/leafTask" ; import { options } from "../options" ; export interface TaskExec { task : LeafTask ; resolve : ( value : BuildResult ) => void ; } ; export abstract class Task { public static createTaskQueue ( ) { return priorityQueue ( async ( taskExec ) => { taskExec . resolve ( await taskExec . task . exec ( ) ) ; } , options . concurrency ) ; } private runP ? : Promise < BuildResult > ; private isUpToDateP ? : Promise < boolean > ; protected constructor ( protected readonly node , public readonly command ) { } public get package ( ) { return this . node . pkg ; } public async run ( q ) { if ( await this . isUpToDate ( ) ) { return BuildResult . UpToDate ; } if ( ! this . runP ) { this . runP = this . runTask ( q ) ; } return this . runP ; } public async isUpToDate ( ) { if ( this . forced ) { return false ; } if ( this . isUpToDateP === undefined ) { this . isUpToDateP = this . checkIsUpToDate ( ) ; } return this . isUpToDateP ; } public toString ( ) { return `"${ this . command }" in ${ this . node . pkg . nameColored }` ; } public abstract initializeDependentTask ( ) ; public abstract get isLeaf ( ) : boolean ; public abstract matchTask ( command , options ? ) ; public abstract collectLeafTasks ( leafTasks ) ; protected abstract checkIsUpToDate ( ) ; protected abstract runTask ( q ) ; public get forced ( ) { return options . force && ( options . matchedOnly !== true || this . package . matched ) ; } } ;