import { Options as ExecaOptions, ExecaChildProcess } from 'execa';
import { Blueprint, Predicates } from 'optimal';
import { Debugger } from '@boost/debug';
import { Event } from '@boost/event';
import Context from './Context';
import Task, { TaskAction } from './Task';
import CoreTool from './Tool';
import { AggregatedResponse } from './Executor';
import { PoolExecutorOptions } from './executors/Pool';
export interface CommandOptions {
    shell?: boolean;
    task?: Task<any>;
    wrap?: (process: ExecaChildProcess) => void;
}
export default abstract class Routine<Ctx extends Context, Tool extends CoreTool<any>, Options extends object = {}> extends Task<Ctx> {
    debug: Debugger;
    key: string;
    onCommand: Event<[string]>;
    onCommandData: Event<[string, string]>;
    options: Required<Options>;
    parent: Routine<Ctx, Tool> | null;
    routines: Routine<Ctx, Tool>[];
    tasks: Task<Ctx>[];
    tool: Tool;
    constructor(key: string, title: string, options?: Options);
    /**
     * Define an optimal blueprint in which to validate and build the
     * options passed to the constructor.
     */
    blueprint(preds: Predicates): Blueprint<Required<Options>>;
    /**
     * Called once the routine has been configured and is ready to execute.
     */
    bootstrap(): void;
    /**
     * Configure the routine after it has been instantiated.
     */
    configure(parent: Routine<Ctx, Tool>): this;
    /**
     * Execute the current routine and return a new value.
     */
    execute(context: Ctx, value: any): Promise<any>;
    /**
     * Execute a command with the given arguments and pass the results through a promise.
     */
    executeCommand(command: string, args: string[], options?: ExecaOptions & CommandOptions): Promise<ExecaChildProcess>;
    /**
     * Execute routines in parallel.
     */
    parallelizeRoutines<T>(value?: T, routines?: Routine<Ctx, Tool>[]): Promise<any[]>;
    /**
     * Execute tasks in parallel.
     */
    parallelizeTasks<T>(value?: T, tasks?: Task<Ctx>[]): Promise<any[]>;
    /**
     * Add a new routine within this routine.
     */
    pipe(routine: Routine<Ctx, Tool>): this;
    /**
     * Execute routines in a pool.
     */
    poolRoutines<T, R = any>(value?: T, options?: Partial<PoolExecutorOptions>, routines?: Routine<Ctx, Tool>[]): Promise<AggregatedResponse<R>>;
    /**
     * Execute tasks in a pool.
     */
    poolTasks<T, R = any>(value?: T, options?: Partial<PoolExecutorOptions>, tasks?: Task<Ctx>[]): Promise<AggregatedResponse<R>>;
    /**
     * Execute routines in sequential (serial) order.
     */
    serializeRoutines<T>(value?: T, routines?: Routine<Ctx, Tool>[]): Promise<any>;
    /**
     * Execute tasks in sequential (serial) order.
     */
    serializeTasks<T>(value?: T, tasks?: Task<Ctx>[]): Promise<any>;
    /**
     * Execute routines in sync.
     */
    synchronizeRoutines<T, R = any>(value?: T, routines?: Routine<Ctx, Tool>[]): Promise<AggregatedResponse<R>>;
    /**
     * Execute tasks in sync.
     */
    synchronizeTasks<T, R = any>(value?: T, tasks?: Task<Ctx>[]): Promise<AggregatedResponse<R>>;
    /**
     * Define an individual task.
     */
    task(title: string, action: TaskAction<Ctx>, scope?: any): Task<Ctx>;
}
//# sourceMappingURL=Routine.d.ts.map