UNPKG

yoonite-saga

Version:

> Orchestration de workflows transactionnels avec gestion de compensation (pattern Saga)

93 lines (79 loc) 2.29 kB
import { SagaConfig } from "./types/config.type"; import { Compensation, Condition, Invoke } from "./types/invoke.type"; import { SagaStep } from "./types/saga-step.type"; import { Workflow } from "./types/workflow.type"; export class SagaBuilder { index: number | null = null; steps: Workflow = []; debug: boolean; constructor(config: SagaConfig = {}) { this.debug = config.debug || false; } // -------------------- // Describe a new step // -------------------- step(name: string): SagaBuilder { this.index = this.index === null ? 0 : this.index + 1; const step: SagaStep = { name, validate: null, condition: null, invokes: [], withCompensation: null, debug: this.debug, }; this.steps = [...this.steps, step]; return this; } // -------------------- // Stack a function to execute for this workflow // -------------------- invoke(name: string | Invoke, fn?: Invoke): SagaBuilder { const realFn = typeof name === "string" ? fn : name; const realName = typeof name === "string" ? name : `Anonymous invoke`; const step = this.steps[this.index]; // Transform function into InvokeAction if (typeof realFn === "function") { step.invokes.push({ name: realName, validate: null, condition: null, action: realFn, withCompensation: null, }); } else { step.invokes.push(realFn); } return this; } // -------------------- // Add a validation step // -------------------- validate(dto): SagaBuilder { const step = this.steps[this.index]; step.validate = dto; return this; } // -------------------- // Add a condition to step execution // -------------------- condition(fn: Condition): SagaBuilder { const step = this.steps[this.index]; step.condition = fn; return this; } // -------------------- // Add a compensate function to execute if an error occured into step // -------------------- withCompensation(fn: Compensation): SagaBuilder { const step = this.steps[this.index]; step.withCompensation = fn; return this; } // -------------------- // Return workflow steps // -------------------- build(): Workflow { return this.steps; } }