116 lines
3.6 KiB
TypeScript
116 lines
3.6 KiB
TypeScript
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<Iteration[]> 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<void | boolean> {
|
|
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<Result<ExecError | SpawnError, ExecutorResult>>(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<T>(stream: TypedEvent<T>): Promise<T> {
|
|
const promise = new Promise<T>((resolve, reject) => {
|
|
const addListener = () => {
|
|
stream.on((e) => {
|
|
const event = e as Result<ExecError | SpawnError, ExecutorResult>;
|
|
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<Result<boolean, boolean>> {
|
|
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();
|
|
}
|
|
}
|