import { FilesChangeNotifierService, IHashesCache } from "./files_change_notifier_service"; import { IPipeline } from "../models/process_model"; import { ExecutorProgramService } from "./executor_program_service"; import { EXEC_EVENT, ExecError, SpawnError } from "../models/exec_error_model"; import { TypedEvent } from "../helpers/typed_event"; import { Result } from "../helpers/result"; import { ExecutorResult } from "../models/executor_result"; import { delay } from "../helpers/delay"; import { TriggerService } from "./trigger_service"; import { Trigger } from "../../features/triggers/models/trigger_database_model"; export interface Iteration { hashes: IHashesCache | null; process: IPipeline; result?: ExecError | SpawnError | ExecutorResult; } export abstract class IStackService { abstract callStack: Iteration[]; abstract path: string; abstract init(processed: IPipeline[], path: string): void; } export class StackService extends TypedEvent implements IStackService { callStack: Iteration[]; path: string; constructor(processed: IPipeline[], path: string) { super(); this.path = path; this.callStack = []; this.init(processed); } public init(processed: IPipeline[]) { for (let el of processed) { el = this.commandHandler(el); this.callStack.push({ hashes: null, process: el, }); } } private commandHandler(processMetaData: IPipeline) { processMetaData.process.command = processMetaData.process.command.replace("$PATH", this.path); return processMetaData; } public async call() { let inc = 0; for await (const el of this.callStack!) { await this.execStack(inc, el); inc += 1; this.emit(this.callStack); } } async execStack(stackNumber: number, stackLayer: Iteration): Promise { const executorService = new ExecutorProgramService(this.path); executorService.call(stackLayer.process.process.type, stackLayer.process.process.command); const filesChangeNotifierService = new FilesChangeNotifierService(this.path); filesChangeNotifierService.call(); const result = await this.waitEvent>(executorService); console.log(200); await delay(100); if (result.isSuccess()) { this.callStack[stackNumber].result = result.value; this.callStack[stackNumber].hashes = filesChangeNotifierService.hashes; const triggerResult = await this.triggerExec(stackLayer.process.trigger, stackNumber); triggerResult.fold( (s) => { s; }, (e) => { e; } ); } filesChangeNotifierService.cancel(); return; } public waitEvent(stream: TypedEvent): Promise { const promise = new Promise((resolve, reject) => { const addListener = () => { stream.on((e) => { const event = e as Result; event.fold( (s) => { if (s.event === EXEC_EVENT.END) { resolve(e); } }, (e) => { reject(e); } ); }); }; addListener(); }); return promise; } private async triggerExec(trigger: Trigger | null, stackNumber: number): Promise> { if (trigger !== null) { const hashes = this.callStack[stackNumber].hashes; if (hashes != null) { return await new TriggerService(trigger, hashes, this.path).call(); } throw new Error("Hashes is null"); } return Result.ok(); } }