webstudio/server/src/core/services/stack_service.ts

117 lines
3.6 KiB
TypeScript
Raw Normal View History

import { FilesChangeNotifierService, IHashesCache } from "./files_change_notifier_service";
2023-12-03 16:20:52 +03:00
import { IPipeline } from "../models/process_model";
2023-10-26 17:44:54 +03:00
import { ExecutorProgramService } from "./executor_program_service";
2023-12-03 16:20:52 +03:00
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";
2023-10-31 09:03:41 +03:00
import { TriggerService } from "./trigger_service";
2023-12-03 16:16:08 +03:00
import { Trigger } from "../../features/triggers/models/trigger_database_model";
2023-09-11 19:49:45 +03:00
export interface Iteration {
hashes: IHashesCache | null;
2023-10-27 21:22:48 +03:00
process: IPipeline;
2023-09-11 19:49:45 +03:00
result?: ExecError | SpawnError | ExecutorResult;
}
export abstract class IStackService {
abstract callStack: Iteration[];
abstract path: string;
2023-10-27 21:22:48 +03:00
abstract init(processed: IPipeline[], path: string): void;
2023-09-11 19:49:45 +03:00
}
export class StackService extends TypedEvent<Iteration[]> implements IStackService {
2023-09-11 19:49:45 +03:00
callStack: Iteration[];
path: string;
2023-10-27 21:22:48 +03:00
constructor(processed: IPipeline[], path: string) {
2023-09-11 19:49:45 +03:00
super();
this.path = path;
this.callStack = [];
this.init(processed);
}
2023-10-27 21:22:48 +03:00
public init(processed: IPipeline[]) {
2023-09-11 19:49:45 +03:00
for (let el of processed) {
el = this.commandHandler(el);
this.callStack.push({
hashes: null,
process: el,
});
}
}
2023-10-27 21:22:48 +03:00
private commandHandler(processMetaData: IPipeline) {
processMetaData.process.command = processMetaData.process.command.replace("$PATH", this.path);
2023-09-11 19:49:45 +03:00
return processMetaData;
}
public async call() {
let inc = 0;
for await (const el of this.callStack!) {
await this.execStack(inc, el);
inc += 1;
2023-11-10 12:06:40 +03:00
this.emit(this.callStack);
2023-09-11 19:49:45 +03:00
}
}
async execStack(stackNumber: number, stackLayer: Iteration): Promise<void | boolean> {
2023-09-11 19:49:45 +03:00
const executorService = new ExecutorProgramService(this.path);
executorService.call(stackLayer.process.process.type, stackLayer.process.process.command);
2023-09-11 19:49:45 +03:00
const filesChangeNotifierService = new FilesChangeNotifierService(this.path);
2023-09-11 19:49:45 +03:00
filesChangeNotifierService.call();
const result = await this.waitEvent<Result<ExecError | SpawnError, ExecutorResult>>(executorService);
2023-12-14 23:04:45 +03:00
console.log(200);
2023-09-11 19:49:45 +03:00
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);
2023-09-11 19:49:45 +03:00
triggerResult.fold(
(s) => {
2023-10-31 09:03:41 +03:00
s;
2023-09-11 19:49:45 +03:00
},
(e) => {
2023-10-31 09:03:41 +03:00
e;
2023-09-11 19:49:45 +03:00
}
);
}
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>> {
2023-11-10 12:06:40 +03:00
if (trigger !== null) {
const hashes = this.callStack[stackNumber].hashes;
2023-09-11 19:49:45 +03:00
2023-11-10 12:06:40 +03:00
if (hashes != null) {
return await new TriggerService(trigger, hashes, this.path).call();
}
throw new Error("Hashes is null");
2023-09-11 19:49:45 +03:00
}
2023-11-10 12:06:40 +03:00
return Result.ok();
2023-09-11 19:49:45 +03:00
}
}