UNPKG

@flowlab/all

Version:

A cool library focusing on handling various flows

86 lines (71 loc) 3 kB
import { StepConfig, WorkflowDefinitionData, ConditionFunction, TaskStepConfig, ConditionStepConfig, ParallelStepConfig, SubWorkflowStepConfig, StepType } from '../types/config'; import { ConfigurationError } from '../errors'; export class WorkflowDefinition { private data: WorkflowDefinitionData; constructor(id: string, name?: string, description?: string) { if (!id) throw new ConfigurationError('Workflow definition ID is required.'); this.data = { id, name, description, steps: {}, }; } // --- Chainable Methods for Building --- addStep(config: Omit<TaskStepConfig, 'type'>): this { this._addStepInternal({ ...config, type: StepType.TASK }); return this; } addCondition(config: Omit<ConditionStepConfig, 'type'>): this { this._addStepInternal({ ...config, type: StepType.CONDITION }); return this; } addParallel(config: Omit<ParallelStepConfig, 'type'>): this { // TODO: Add validation for parallel steps structure this._addStepInternal({ ...config, type: StepType.PARALLEL }); return this; } addSubWorkflow(config: Omit<SubWorkflowStepConfig, 'type'>): this { this._addStepInternal({ ...config, type: StepType.SUB_WORKFLOW }); return this; } // TODO: Add methods for EventTrigger, EventListener etc. setStartStep(stepId: string): this { if (!this.data.steps[stepId]) { throw new ConfigurationError(`Cannot set start step: Step with ID '${stepId}' does not exist in definition '${this.data.id}'.`); } this.data.startStepId = stepId; return this; } // --- Internal Logic --- private _addStepInternal(config: StepConfig): void { if (!config.id) throw new ConfigurationError('Step ID is required.'); if (this.data.steps[config.id]) throw new ConfigurationError(`Step with ID '${config.id}' already exists in definition '${this.data.id}'.`); // TODO: Add more validation based on step type (e.g., nextStepId presence/absence) this.data.steps[config.id] = config; } // --- Accessors --- get id(): string { return this.data.id; } get name(): string | undefined { return this.data.name; } get description(): string | undefined { return this.data.description; } get startStepId(): string | undefined { return this.data.startStepId; } getStep(stepId: string): StepConfig | undefined { return this.data.steps[stepId]; } getSteps(): Readonly<Record<string, StepConfig>> { return this.data.steps; } // Get the raw data for persistence or inspection getData(): Readonly<WorkflowDefinitionData> { return this.data; } // TODO: Add a validate() method similar to Root validate(): boolean { if (!this.data.startStepId) { console.error(`[Validation Error] Workflow '${this.id}': Start step not set.`); return false; } // TODO: Check for unreachable steps, cycles (if not allowed), valid nextStepId refs etc. return true; } }