@spfn/workflow 0.1.0-alpha.2 → 0.1.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -145,7 +145,7 @@ type InferWorkflowInput<T> = T extends WorkflowDef<string, infer TInput> ? TInpu
|
|
|
145
145
|
/**
|
|
146
146
|
* Workflow builder with fluent API and type inference
|
|
147
147
|
*/
|
|
148
|
-
declare class WorkflowBuilder<TName extends string, TInput = void, TResults extends Record<string, unknown> =
|
|
148
|
+
declare class WorkflowBuilder<TName extends string, TInput = void, TResults extends Record<string, unknown> = {}> {
|
|
149
149
|
private readonly _name;
|
|
150
150
|
private _inputSchema?;
|
|
151
151
|
private _steps;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/builder/workflow-builder.ts","../src/entities/schema.ts","../src/entities/workflow-execution.entity.ts","../src/entities/workflow-step-execution.entity.ts","../src/engine/types.ts","../src/engine/workflow-engine.ts","../src/notification/providers.ts","../src/config/workflow-router.ts"],"names":["text","integer","jsonb","timestamp","timestamps","index","workflow"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Workflow Builder\n *\n * Fluent API for defining workflows\n */\n\nimport type { TSchema, Static } from '@sinclair/typebox';\nimport type { JobDef, InferJobInput, InferJobOutput } from '@spfn/core/job';\nimport type {\n WorkflowDef,\n WorkflowStepDef,\n StepMapper,\n NotifyConfig,\n} from './types';\n\n/**\n * Workflow builder with fluent API and type inference\n */\nexport class WorkflowBuilder<\n TName extends string,\n TInput = void,\n TResults extends Record<string, unknown> = Record<string, never>\n>\n{\n private readonly _name: TName;\n private _inputSchema?: TSchema;\n private _steps: WorkflowStepDef[] = [];\n private _resumable: boolean = false;\n private _rollbackEnabled: boolean = true;\n private _notifyConfigs: NotifyConfig[] = [];\n\n constructor(name: TName)\n {\n this._name = name;\n }\n\n /**\n * Define input schema\n */\n input<TSchema extends import('@sinclair/typebox').TSchema>(\n schema: TSchema\n ): WorkflowBuilder<TName, Static<TSchema>, TResults>\n {\n const builder = new WorkflowBuilder<TName, Static<TSchema>, TResults>(this._name);\n builder._inputSchema = schema;\n builder._steps = this._steps;\n builder._resumable = this._resumable;\n builder._rollbackEnabled = this._rollbackEnabled;\n builder._notifyConfigs = [...this._notifyConfigs];\n return builder;\n }\n\n /**\n * Add a sequential step\n */\n pipe<\n TJob extends JobDef<any, any>,\n TStepName extends string = TJob['name']\n >(\n job: TJob,\n mapper: StepMapper<TInput, TResults, InferJobInput<TJob>>\n ): WorkflowBuilder<\n TName,\n TInput,\n TResults & { [K in TStepName]: InferJobOutput<TJob> }\n >\n {\n const stepName = job.name as TStepName;\n\n const step: WorkflowStepDef = {\n name: stepName,\n job: job as JobDef<unknown, unknown>,\n mapper: mapper as StepMapper<unknown, Record<string, unknown>, unknown>,\n type: 'sequential',\n };\n\n const builder = new WorkflowBuilder<\n TName,\n TInput,\n TResults & { [K in TStepName]: InferJobOutput<TJob> }\n >(this._name);\n builder._inputSchema = this._inputSchema;\n builder._steps = [...this._steps, step];\n builder._resumable = this._resumable;\n builder._rollbackEnabled = this._rollbackEnabled;\n builder._notifyConfigs = [...this._notifyConfigs];\n\n return builder;\n }\n\n /**\n * Add parallel steps\n */\n parallel<\n TParallel extends Record<string, [JobDef<any, any>, StepMapper<TInput, TResults, any>]>\n >(\n steps: TParallel\n ): WorkflowBuilder<\n TName,\n TInput,\n TResults & { [K in keyof TParallel]: InferJobOutput<TParallel[K][0]> }\n >\n {\n const parallelGroup = `parallel_${this._steps.length}`;\n const parallelSteps: WorkflowStepDef[] = [];\n\n for (const [name, [job, mapper]] of Object.entries(steps))\n {\n parallelSteps.push({\n name,\n job: job as JobDef<unknown, unknown>,\n mapper: mapper as StepMapper<unknown, Record<string, unknown>, unknown>,\n type: 'parallel',\n parallelGroup,\n });\n }\n\n const builder = new WorkflowBuilder<\n TName,\n TInput,\n TResults & { [K in keyof TParallel]: InferJobOutput<TParallel[K][0]> }\n >(this._name);\n builder._inputSchema = this._inputSchema;\n builder._steps = [...this._steps, ...parallelSteps];\n builder._resumable = this._resumable;\n builder._rollbackEnabled = this._rollbackEnabled;\n builder._notifyConfigs = [...this._notifyConfigs];\n\n return builder;\n }\n\n /**\n * Enable/disable resumable (restart from failure point)\n */\n resumable(enabled: boolean = true): this\n {\n this._resumable = enabled;\n return this;\n }\n\n /**\n * Enable/disable rollback on failure\n */\n rollback(enabled: boolean = true): this\n {\n this._rollbackEnabled = enabled;\n return this;\n }\n\n /**\n * Configure notifications (chainable — each call adds a separate config)\n */\n notify(config: NotifyConfig): this\n {\n this._notifyConfigs.push(config);\n return this;\n }\n\n /**\n * Build the workflow definition\n */\n build(): WorkflowDef<TName, TInput>\n {\n return {\n name: this._name,\n inputSchema: this._inputSchema,\n steps: this._steps,\n resumable: this._resumable,\n rollbackEnabled: this._rollbackEnabled,\n notifyConfigs: this._notifyConfigs,\n _input: undefined as unknown as TInput,\n };\n }\n}\n\n/**\n * Create a new workflow definition\n *\n * @example\n * ```typescript\n * const provisionTenant = workflow('provision-tenant')\n * .input(Type.Object({\n * tenantId: Type.String(),\n * plan: Type.String(),\n * }))\n * .resumable(true)\n * .pipe(createPodIdentity, (ctx) => ({\n * tenantId: ctx.input.tenantId,\n * }))\n * .parallel({\n * appRepo: [createAppRepo, (ctx) => ({ tenantId: ctx.input.tenantId })],\n * gitopsRepo: [createGitopsRepo, (ctx) => ({ tenantId: ctx.input.tenantId })],\n * })\n * .pipe(notifyComplete, (ctx) => ({\n * appRepoUrl: ctx.results.appRepo.repoUrl,\n * gitopsRepoUrl: ctx.results.gitopsRepo.repoUrl,\n * }))\n * .build();\n * ```\n */\nexport function workflow<TName extends string>(name: TName): WorkflowBuilder<TName>\n{\n return new WorkflowBuilder(name);\n}\n","/**\n * @spfn/workflow - Database Schema Definition\n *\n * Defines the 'spfn_workflow' PostgreSQL schema for all workflow-related tables\n */\n\nimport { createSchema } from '@spfn/core/db';\n\n/**\n * Workflow schema for all workflow execution tables\n * Tables: executions, step_executions\n */\nexport const workflowSchema = createSchema('@spfn/workflow');\n","/**\n * Workflow Execution Entity\n *\n * Stores the state of workflow executions\n */\n\nimport { text, integer, timestamp, jsonb, index } from 'drizzle-orm/pg-core';\nimport { timestamps } from '@spfn/core/db';\nimport type { WorkflowStatus } from '../types';\nimport { workflowSchema } from './schema';\n\nexport const workflowExecutions = workflowSchema.table(\n 'executions',\n {\n id: text('id').primaryKey().$defaultFn(() => crypto.randomUUID()),\n\n /**\n * Workflow name (identifier)\n */\n workflowName: text('workflow_name').notNull(),\n\n /**\n * Execution status\n */\n status: text('status').$type<WorkflowStatus>().notNull().default('pending'),\n\n /**\n * Input data (JSON)\n */\n input: jsonb('input'),\n\n /**\n * Current step index\n */\n currentStep: integer('current_step').notNull().default(0),\n\n /**\n * Error message (if failed)\n */\n error: text('error'),\n\n /**\n * Completed timestamp\n */\n completedAt: timestamp('completed_at', { withTimezone: true }),\n\n ...timestamps(),\n },\n (table) => [\n index('wf_exec_workflow_name_idx').on(table.workflowName),\n index('wf_exec_status_idx').on(table.status),\n index('wf_exec_created_at_idx').on(table.createdAt),\n index('wf_exec_workflow_status_idx').on(table.workflowName, table.status),\n ]\n);\n\nexport type WorkflowExecution = typeof workflowExecutions.$inferSelect;\nexport type NewWorkflowExecution = typeof workflowExecutions.$inferInsert;\n","/**\n * Workflow Step Execution Entity\n *\n * Stores the state of individual step executions within a workflow\n */\n\nimport { text, integer, timestamp, jsonb, index } from 'drizzle-orm/pg-core';\nimport { timestamps } from '@spfn/core/db';\nimport type { WorkflowStepStatus } from '../types';\nimport { workflowExecutions } from './workflow-execution.entity';\nimport { workflowSchema } from './schema';\n\nexport const workflowStepExecutions = workflowSchema.table(\n 'step_executions',\n {\n id: text('id').primaryKey().$defaultFn(() => crypto.randomUUID()),\n\n /**\n * Parent workflow execution ID\n */\n executionId: text('execution_id')\n .notNull()\n .references(() => workflowExecutions.id, { onDelete: 'cascade' }),\n\n /**\n * Step name (job name)\n */\n stepName: text('step_name').notNull(),\n\n /**\n * Step index in the workflow\n */\n stepIndex: integer('step_index').notNull(),\n\n /**\n * Step execution status\n */\n status: text('status').$type<WorkflowStepStatus>().notNull().default('pending'),\n\n /**\n * Step output data (JSON or URL reference for large data)\n */\n output: jsonb('output'),\n\n /**\n * Error message (if failed)\n */\n error: text('error'),\n\n /**\n * Started timestamp\n */\n startedAt: timestamp('started_at', { withTimezone: true }),\n\n /**\n * Completed timestamp\n */\n completedAt: timestamp('completed_at', { withTimezone: true }),\n\n ...timestamps(),\n },\n (table) => [\n index('wf_step_exec_execution_id_idx').on(table.executionId),\n index('wf_step_exec_status_idx').on(table.status),\n index('wf_step_exec_exec_step_idx').on(table.executionId, table.stepIndex),\n ]\n);\n\nexport type WorkflowStepExecution = typeof workflowStepExecutions.$inferSelect;\nexport type NewWorkflowStepExecution = typeof workflowStepExecutions.$inferInsert;\n","/**\n * Workflow Engine Types\n */\n\nimport type { WorkflowDef, WorkflowEvent } from '../builder';\nimport type { WorkflowExecution, WorkflowStepExecution } from '../entities';\n\n/**\n * Logger interface for workflow engine\n */\nexport interface WorkflowLogger\n{\n info(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n debug(message: string, ...args: unknown[]): void;\n}\n\n/**\n * Default console logger\n */\nexport const defaultLogger: WorkflowLogger = {\n info: (message, ...args) => console.log(message, ...args),\n error: (message, ...args) => console.error(message, ...args),\n warn: (message, ...args) => console.warn(message, ...args),\n debug: (message, ...args) => console.debug(message, ...args),\n};\n\n/**\n * Workflow engine configuration\n */\nexport interface WorkflowEngineConfig\n{\n /**\n * Database instance (drizzle)\n */\n db: unknown;\n\n /**\n * Storage for large outputs (optional)\n */\n storage?: OutputStorage;\n\n /**\n * Large output threshold in bytes (default: 1MB)\n */\n largeOutputThreshold?: number;\n\n /**\n * Custom logger (optional, defaults to console)\n */\n logger?: WorkflowLogger;\n\n /**\n * Enable input schema validation (default: true)\n */\n validateInput?: boolean;\n}\n\n/**\n * Output storage interface for large data\n */\nexport interface OutputStorage\n{\n /**\n * Upload data and return URL reference\n */\n upload(data: unknown): Promise<string>;\n\n /**\n * Download data from URL reference\n */\n download(url: string): Promise<unknown>;\n}\n\n/**\n * Execution result from start()\n */\nexport interface ExecutionResult\n{\n /**\n * Execution ID\n */\n id: string;\n\n /**\n * Workflow name\n */\n workflowName: string;\n\n /**\n * Initial status\n */\n status: 'pending';\n}\n\n/**\n * Execution status with details\n */\nexport interface ExecutionStatus extends WorkflowExecution\n{\n /**\n * Step executions\n */\n steps: WorkflowStepExecution[];\n}\n\n/**\n * Cancel options\n */\nexport interface CancelOptions\n{\n /**\n * Execute rollback after cancel\n */\n rollback?: boolean;\n}\n\n/**\n * List filter options\n */\nexport interface ListOptions\n{\n /**\n * Filter by workflow name\n */\n workflowName?: string;\n\n /**\n * Filter by status\n */\n status?: string;\n\n /**\n * Limit results\n */\n limit?: number;\n\n /**\n * Offset for pagination\n */\n offset?: number;\n}\n\n/**\n * Workflow engine interface\n */\nexport interface WorkflowEngine<TWorkflows extends WorkflowDef<string, unknown>[]>\n{\n /**\n * Start a workflow execution\n */\n start<TName extends TWorkflows[number]['name']>(\n name: TName,\n input: ExtractWorkflowInput<TWorkflows, TName>\n ): Promise<ExecutionResult>;\n\n /**\n * Get execution status\n */\n get(executionId: string): Promise<ExecutionStatus | null>;\n\n /**\n * Get step output\n */\n getStepOutput(executionId: string, stepName: string): Promise<unknown>;\n\n /**\n * List executions\n */\n list(options?: ListOptions): Promise<ExecutionStatus[]>;\n\n /**\n * Retry failed execution\n */\n retry(executionId: string): Promise<ExecutionResult>;\n\n /**\n * Cancel execution\n */\n cancel(executionId: string, options?: CancelOptions): Promise<void>;\n\n /**\n * Subscribe to execution events\n */\n subscribe(\n executionId: string,\n callback: (event: WorkflowEvent) => void\n ): () => void;\n}\n\n/**\n * Extract input type from workflow by name\n */\nexport type ExtractWorkflowInput<\n TWorkflows extends WorkflowDef<string, unknown>[],\n TName extends string\n> = TWorkflows extends (infer W)[]\n ? W extends WorkflowDef<TName, infer TInput>\n ? TInput\n : never\n : never;\n","/**\n * Workflow Engine Implementation\n *\n * Orchestrates workflow execution using @spfn/core Job and Events\n */\n\nimport { eq, and, desc, inArray } from 'drizzle-orm';\nimport { Value } from '@sinclair/typebox/value';\nimport type { WorkflowDef, WorkflowEvent, WorkflowStepDef } from '../builder';\nimport type { WorkflowStatus, WorkflowStepStatus } from '../types';\nimport {\n workflowExecutions,\n workflowStepExecutions,\n type WorkflowExecution,\n type WorkflowStepExecution,\n} from '../entities';\nimport {\n defaultLogger,\n type WorkflowEngineConfig,\n type WorkflowEngine,\n type WorkflowLogger,\n type ExecutionResult,\n type ExecutionStatus,\n type CancelOptions,\n type ListOptions,\n type ExtractWorkflowInput,\n} from './types';\n\n/**\n * Default large output threshold (1MB)\n */\nconst DEFAULT_LARGE_OUTPUT_THRESHOLD = 1024 * 1024;\n\n/**\n * Internal workflow engine implementation\n */\nclass WorkflowEngineImpl<TWorkflows extends WorkflowDef[]>\n implements WorkflowEngine<TWorkflows>\n{\n private config: WorkflowEngineConfig;\n private workflows: Map<string, WorkflowDef>;\n private subscribers: Map<string, Set<(event: WorkflowEvent) => void>>;\n private logger: WorkflowLogger;\n /** Track executions currently being processed to prevent race conditions */\n private processingExecutions: Set<string>;\n\n constructor(\n workflows: TWorkflows,\n config: WorkflowEngineConfig\n )\n {\n this.config = config;\n this.workflows = new Map();\n this.subscribers = new Map();\n this.logger = config.logger ?? defaultLogger;\n this.processingExecutions = new Set();\n\n // Register workflows\n for (const wf of workflows)\n {\n this.workflows.set(wf.name, wf);\n }\n }\n\n /**\n * Get database instance\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private get db(): any\n {\n return this.config.db;\n }\n\n /**\n * Start a workflow execution\n */\n async start<TName extends TWorkflows[number]['name']>(\n name: TName,\n input: ExtractWorkflowInput<TWorkflows, TName>\n ): Promise<ExecutionResult>\n {\n const workflow = this.workflows.get(name);\n if (!workflow)\n {\n throw new Error(`Workflow '${name}' not found`);\n }\n\n // Validate input against schema if enabled (default: true)\n if (this.config.validateInput !== false && workflow.inputSchema)\n {\n if (!Value.Check(workflow.inputSchema, input))\n {\n const errors = [...Value.Errors(workflow.inputSchema, input)];\n const errorMessages = errors.map(e => `${e.path}: ${e.message}`).join(', ');\n throw new Error(`Invalid workflow input: ${errorMessages}`);\n }\n }\n\n // Create execution and steps in a transaction for atomicity\n const execution = await this.db.transaction(async (tx: typeof this.db) =>\n {\n // Create execution record\n const [exec] = await tx\n .insert(workflowExecutions)\n .values({\n workflowName: name,\n status: 'pending' as WorkflowStatus,\n input: input as Record<string, unknown>,\n currentStep: 0,\n })\n .returning() as WorkflowExecution[];\n\n // Create step execution records\n const stepRecords = workflow.steps.map((step, index) => ({\n executionId: exec.id,\n stepName: step.name,\n stepIndex: index,\n status: 'pending' as WorkflowStepStatus,\n }));\n\n if (stepRecords.length > 0)\n {\n await tx\n .insert(workflowStepExecutions)\n .values(stepRecords);\n }\n\n return exec;\n });\n\n // Emit started event\n this.emitEvent({\n type: 'started',\n workflowName: name,\n executionId: execution.id,\n input: input as unknown,\n timestamp: new Date(),\n });\n\n // Start first step (async, don't await)\n this.executeNextStep(execution.id, workflow, input as Record<string, unknown>)\n .catch((error) =>\n {\n this.logger.error(`[Workflow:${name}] Execution error:`, error);\n });\n\n return {\n id: execution.id,\n workflowName: name,\n status: 'pending',\n };\n }\n\n /**\n * Execute steps iteratively until completion or failure\n */\n private async executeNextStep(\n executionId: string,\n workflow: WorkflowDef,\n input: Record<string, unknown>\n ): Promise<void>\n {\n while (true)\n {\n // Get current execution state\n const execution = await this.getExecution(executionId);\n if (!execution || (execution.status !== 'pending' && execution.status !== 'running'))\n {\n return;\n }\n\n // Update status to running\n if (execution.status === 'pending')\n {\n await this.updateExecutionStatus(executionId, 'running');\n }\n\n // Get completed results\n const results = await this.getCompletedResults(executionId);\n\n // Find next pending steps\n const pendingSteps = execution.steps.filter(s => s.status === 'pending');\n if (pendingSteps.length === 0)\n {\n // All steps completed\n await this.completeExecution(executionId);\n return;\n }\n\n // Get the next step(s) to execute\n const currentStepIndex = Math.min(...pendingSteps.map(s => s.stepIndex));\n\n // Update currentStep in execution record\n await this.db\n .update(workflowExecutions)\n .set({ currentStep: currentStepIndex, updatedAt: new Date() })\n .where(eq(workflowExecutions.id, executionId));\n\n // Check if this is a parallel group\n const stepDef = workflow.steps[currentStepIndex];\n if (stepDef.type === 'parallel')\n {\n // Execute all parallel steps concurrently.\n // Wait for ALL steps to complete before handling failures\n // to prevent rollback from racing with still-running steps.\n const parallelSteps = workflow.steps.filter(\n s => s.parallelGroup === stepDef.parallelGroup\n );\n const errors = await Promise.all(\n parallelSteps.map(step =>\n this.executeStep(executionId, workflow, step, input, results)\n )\n );\n\n // Handle failure after all parallel steps have settled\n const firstError = errors.find(e => e !== null);\n if (firstError)\n {\n await this.handleStepFailure(executionId, workflow, firstError);\n return;\n }\n }\n else\n {\n // Execute sequential step\n const error = await this.executeStep(executionId, workflow, stepDef, input, results);\n if (error)\n {\n await this.handleStepFailure(executionId, workflow, error);\n return;\n }\n }\n }\n }\n\n /**\n * Execute a single step\n *\n * Returns the error message if the step failed, or null if successful.\n */\n private async executeStep(\n executionId: string,\n workflow: WorkflowDef,\n step: WorkflowStepDef,\n input: Record<string, unknown>,\n results: Record<string, unknown>\n ): Promise<string | null>\n {\n const stepExecution = await this.getStepExecution(executionId, step.name);\n if (!stepExecution || stepExecution.status !== 'pending')\n {\n return null;\n }\n\n // Update step status to running\n await this.updateStepStatus(stepExecution.id, 'running');\n\n this.emitEvent({\n type: 'step.started',\n workflowName: workflow.name,\n executionId,\n stepName: step.name,\n stepIndex: stepExecution.stepIndex,\n timestamp: new Date(),\n });\n\n try\n {\n // Map input using the mapper function\n const context = {\n input,\n results,\n execution: {\n id: executionId,\n workflowName: workflow.name,\n startedAt: new Date(),\n },\n };\n\n const stepInput = step.mapper(context);\n\n // Execute the job\n const output = await step.job.run(stepInput);\n\n // Store output (handle large data)\n const storedOutput = await this.storeOutput(output);\n\n // Update step as completed\n await this.updateStepStatus(stepExecution.id, 'completed', storedOutput);\n\n this.emitEvent({\n type: 'step.completed',\n workflowName: workflow.name,\n executionId,\n stepName: step.name,\n stepIndex: stepExecution.stepIndex,\n output: storedOutput,\n timestamp: new Date(),\n });\n\n return null;\n }\n catch (error)\n {\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n // Update step as failed\n await this.updateStepStatus(stepExecution.id, 'failed', undefined, errorMessage);\n\n this.emitEvent({\n type: 'step.failed',\n workflowName: workflow.name,\n executionId,\n stepName: step.name,\n stepIndex: stepExecution.stepIndex,\n error: errorMessage,\n timestamp: new Date(),\n });\n\n return errorMessage;\n }\n }\n\n /**\n * Handle step failure - rollback if enabled\n */\n private async handleStepFailure(\n executionId: string,\n workflow: WorkflowDef,\n error: string\n ): Promise<void>\n {\n // Update execution status\n await this.db\n .update(workflowExecutions)\n .set({\n status: 'failed' as WorkflowStatus,\n error,\n updatedAt: new Date(),\n })\n .where(eq(workflowExecutions.id, executionId));\n\n this.emitEvent({\n type: 'failed',\n workflowName: workflow.name,\n executionId,\n error,\n timestamp: new Date(),\n });\n\n // Execute rollback if enabled\n if (workflow.rollbackEnabled)\n {\n await this.executeRollback(executionId, workflow);\n }\n }\n\n /**\n * Execute rollback in reverse order\n */\n private async executeRollback(\n executionId: string,\n workflow: WorkflowDef\n ): Promise<void>\n {\n await this.updateExecutionStatus(executionId, 'compensating');\n\n const execution = await this.getExecution(executionId);\n if (!execution) return;\n\n // Get completed steps in reverse order\n const completedSteps = execution.steps\n .filter(s => s.status === 'completed')\n .sort((a, b) => b.stepIndex - a.stepIndex);\n\n for (const stepExecution of completedSteps)\n {\n const stepDef = workflow.steps.find(s => s.name === stepExecution.stepName);\n if (!stepDef || !stepDef.job.compensate)\n {\n continue;\n }\n\n try\n {\n const input = execution.input as Record<string, unknown>;\n const output = await this.resolveOutput(stepExecution.output);\n\n await stepDef.job.compensate(input, output);\n\n await this.updateStepStatus(stepExecution.id, 'compensated');\n }\n catch (compensateError)\n {\n // Log but continue with other compensations\n this.logger.error(\n `[Workflow:${workflow.name}] Compensate error for step ${stepExecution.stepName}:`,\n compensateError\n );\n }\n }\n\n await this.updateExecutionStatus(executionId, 'compensated');\n }\n\n /**\n * Complete the workflow execution\n */\n private async completeExecution(executionId: string): Promise<void>\n {\n const execution = await this.getExecution(executionId);\n if (!execution) return;\n\n await this.db\n .update(workflowExecutions)\n .set({\n status: 'completed' as WorkflowStatus,\n completedAt: new Date(),\n updatedAt: new Date(),\n })\n .where(eq(workflowExecutions.id, executionId));\n\n this.emitEvent({\n type: 'completed',\n workflowName: execution.workflowName,\n executionId,\n timestamp: new Date(),\n });\n }\n\n /**\n * Get execution with steps\n */\n private async getExecution(executionId: string): Promise<ExecutionStatus | null>\n {\n const [execution] = await this.db\n .select()\n .from(workflowExecutions)\n .where(eq(workflowExecutions.id, executionId)) as WorkflowExecution[];\n\n if (!execution) return null;\n\n const steps = await this.db\n .select()\n .from(workflowStepExecutions)\n .where(eq(workflowStepExecutions.executionId, executionId))\n .orderBy(workflowStepExecutions.stepIndex) as WorkflowStepExecution[];\n\n return { ...execution, steps };\n }\n\n /**\n * Get step execution\n */\n private async getStepExecution(\n executionId: string,\n stepName: string\n ): Promise<WorkflowStepExecution | null>\n {\n const [step] = await this.db\n .select()\n .from(workflowStepExecutions)\n .where(\n and(\n eq(workflowStepExecutions.executionId, executionId),\n eq(workflowStepExecutions.stepName, stepName)\n )\n ) as WorkflowStepExecution[];\n\n return step || null;\n }\n\n /**\n * Get completed step results\n */\n private async getCompletedResults(executionId: string): Promise<Record<string, unknown>>\n {\n const steps = await this.db\n .select()\n .from(workflowStepExecutions)\n .where(\n and(\n eq(workflowStepExecutions.executionId, executionId),\n eq(workflowStepExecutions.status, 'completed')\n )\n ) as WorkflowStepExecution[];\n\n const results: Record<string, unknown> = {};\n for (const step of steps)\n {\n results[step.stepName] = await this.resolveOutput(step.output);\n }\n return results;\n }\n\n /**\n * Update execution status\n */\n private async updateExecutionStatus(\n executionId: string,\n status: WorkflowStatus\n ): Promise<void>\n {\n await this.db\n .update(workflowExecutions)\n .set({\n status,\n updatedAt: new Date(),\n })\n .where(eq(workflowExecutions.id, executionId));\n }\n\n /**\n * Update step status\n */\n private async updateStepStatus(\n stepId: string,\n status: WorkflowStepStatus,\n output?: unknown,\n error?: string\n ): Promise<void>\n {\n const updates: Record<string, unknown> = {\n status,\n updatedAt: new Date(),\n };\n\n if (status === 'running')\n {\n updates.startedAt = new Date();\n }\n if (status === 'completed' || status === 'failed')\n {\n updates.completedAt = new Date();\n }\n if (output !== undefined)\n {\n updates.output = output;\n }\n if (error !== undefined)\n {\n updates.error = error;\n }\n\n await this.db\n .update(workflowStepExecutions)\n .set(updates)\n .where(eq(workflowStepExecutions.id, stepId));\n }\n\n /**\n * Store output (handle large data)\n */\n private async storeOutput(output: unknown): Promise<unknown>\n {\n if (!output || !this.config.storage) return output;\n\n const json = JSON.stringify(output);\n const threshold = this.config.largeOutputThreshold ?? DEFAULT_LARGE_OUTPUT_THRESHOLD;\n\n if (Buffer.byteLength(json, 'utf8') > threshold)\n {\n const url = await this.config.storage.upload(output);\n return { $ref: url };\n }\n\n return output;\n }\n\n /**\n * Resolve output (fetch from storage if needed)\n */\n private async resolveOutput(output: unknown): Promise<unknown>\n {\n if (!output) return output;\n\n const ref = output as { $ref?: string };\n if (ref.$ref && this.config.storage)\n {\n return await this.config.storage.download(ref.$ref);\n }\n\n return output;\n }\n\n /**\n * Emit event to subscribers and notification providers\n */\n private emitEvent(event: WorkflowEvent): void\n {\n // Notify subscribers\n const subscribers = this.subscribers.get(event.executionId);\n if (subscribers)\n {\n for (const callback of subscribers)\n {\n try\n {\n callback(event);\n }\n catch (error)\n {\n this.logger.error('[WorkflowEngine] Subscriber error:', error);\n }\n }\n\n // Cleanup subscribers on terminal events to prevent memory leaks\n const terminalEvents: string[] = ['completed', 'failed', 'cancelled'];\n if (terminalEvents.includes(event.type))\n {\n this.subscribers.delete(event.executionId);\n }\n }\n\n // Send notifications (async, don't block)\n this.sendNotifications(event).catch((error) =>\n {\n this.logger.error('[WorkflowEngine] Notification error:', error);\n });\n }\n\n /**\n * Send notifications based on workflow config\n */\n private async sendNotifications(event: WorkflowEvent): Promise<void>\n {\n const workflow = this.workflows.get(event.workflowName);\n if (!workflow || workflow.notifyConfigs.length === 0)\n {\n return;\n }\n\n for (const { on, when, providers } of workflow.notifyConfigs)\n {\n // Check if this event type should trigger notification\n if (!on.includes(event.type))\n {\n continue;\n }\n\n // Check conditional\n if (when && !when(event))\n {\n continue;\n }\n\n // Send to all providers\n await Promise.all(\n providers.map(async (provider) =>\n {\n try\n {\n await provider.notify(event);\n }\n catch (error)\n {\n this.logger.error(\n `[WorkflowEngine] Notification provider '${provider.name}' error:`,\n error\n );\n }\n })\n );\n }\n }\n\n // Public API methods\n\n async get(executionId: string): Promise<ExecutionStatus | null>\n {\n return this.getExecution(executionId);\n }\n\n async getStepOutput(executionId: string, stepName: string): Promise<unknown>\n {\n const step = await this.getStepExecution(executionId, stepName);\n if (!step) return null;\n return this.resolveOutput(step.output);\n }\n\n async list(options?: ListOptions): Promise<ExecutionStatus[]>\n {\n // Build where conditions\n const conditions = [];\n if (options?.workflowName)\n {\n conditions.push(eq(workflowExecutions.workflowName, options.workflowName));\n }\n if (options?.status)\n {\n conditions.push(eq(workflowExecutions.status, options.status as WorkflowStatus));\n }\n\n // Build query with DB-level pagination\n let query = this.db\n .select()\n .from(workflowExecutions)\n .orderBy(desc(workflowExecutions.createdAt));\n\n if (conditions.length > 0)\n {\n query = query.where(conditions.length === 1 ? conditions[0] : and(...conditions));\n }\n\n if (options?.limit)\n {\n query = query.limit(options.limit);\n }\n if (options?.offset)\n {\n query = query.offset(options.offset);\n }\n\n const executions = await query as WorkflowExecution[];\n\n if (executions.length === 0)\n {\n return [];\n }\n\n // Fetch all steps in single query (avoid N+1)\n const executionIds = executions.map(e => e.id);\n const allSteps = await this.db\n .select()\n .from(workflowStepExecutions)\n .where(inArray(workflowStepExecutions.executionId, executionIds))\n .orderBy(workflowStepExecutions.stepIndex) as WorkflowStepExecution[];\n\n // Group steps by executionId\n const stepsByExecutionId = new Map<string, WorkflowStepExecution[]>();\n for (const step of allSteps)\n {\n const steps = stepsByExecutionId.get(step.executionId) ?? [];\n steps.push(step);\n stepsByExecutionId.set(step.executionId, steps);\n }\n\n // Combine executions with their steps\n return executions.map(execution => ({\n ...execution,\n steps: stepsByExecutionId.get(execution.id) ?? [],\n }));\n }\n\n async retry(executionId: string): Promise<ExecutionResult>\n {\n // Prevent concurrent retry calls for the same execution\n if (this.processingExecutions.has(executionId))\n {\n throw new Error(`Execution '${executionId}' is already being processed`);\n }\n\n const execution = await this.getExecution(executionId);\n if (!execution)\n {\n throw new Error(`Execution '${executionId}' not found`);\n }\n\n // Validate execution status - only failed or compensated can be retried\n const retryableStatuses: WorkflowStatus[] = ['failed', 'compensated'];\n if (!retryableStatuses.includes(execution.status))\n {\n throw new Error(\n `Cannot retry execution '${executionId}' with status '${execution.status}'. ` +\n `Only 'failed' or 'compensated' executions can be retried.`\n );\n }\n\n const workflow = this.workflows.get(execution.workflowName);\n if (!workflow)\n {\n throw new Error(`Workflow '${execution.workflowName}' not found`);\n }\n\n // Mark as processing to prevent race conditions\n this.processingExecutions.add(executionId);\n\n try\n {\n if (workflow.resumable)\n {\n // Resume from failed step - only reset failed steps\n await this.updateExecutionStatus(executionId, 'running');\n\n const failedSteps = execution.steps.filter(s => s.status === 'failed');\n for (const step of failedSteps)\n {\n await this.updateStepStatus(step.id, 'pending');\n }\n }\n else\n {\n // Restart from beginning - reset all steps\n await this.resetAllSteps(execution.steps);\n\n await this.db\n .update(workflowExecutions)\n .set({\n status: 'pending' as WorkflowStatus,\n currentStep: 0,\n error: null,\n completedAt: null,\n updatedAt: new Date(),\n })\n .where(eq(workflowExecutions.id, executionId));\n }\n\n // Start execution (async)\n this.executeNextStep(\n executionId,\n workflow,\n execution.input as Record<string, unknown>\n )\n .catch((error) =>\n {\n this.logger.error(`[Workflow:${workflow.name}] Retry error:`, error);\n })\n .finally(() =>\n {\n this.processingExecutions.delete(executionId);\n });\n\n return {\n id: executionId,\n workflowName: execution.workflowName,\n status: 'pending',\n };\n }\n catch (error)\n {\n this.processingExecutions.delete(executionId);\n throw error;\n }\n }\n\n /**\n * Reset all steps to pending state\n */\n private async resetAllSteps(steps: WorkflowStepExecution[]): Promise<void>\n {\n if (steps.length === 0) return;\n\n await this.db\n .update(workflowStepExecutions)\n .set({\n status: 'pending' as WorkflowStepStatus,\n output: null,\n error: null,\n startedAt: null,\n completedAt: null,\n updatedAt: new Date(),\n })\n .where(inArray(workflowStepExecutions.id, steps.map(s => s.id)));\n }\n\n async cancel(executionId: string, options?: CancelOptions): Promise<void>\n {\n const execution = await this.getExecution(executionId);\n if (!execution)\n {\n throw new Error(`Execution '${executionId}' not found`);\n }\n\n // Validate execution status - only pending or running can be cancelled\n const cancellableStatuses: WorkflowStatus[] = ['pending', 'running'];\n if (!cancellableStatuses.includes(execution.status))\n {\n throw new Error(\n `Cannot cancel execution '${executionId}' with status '${execution.status}'. ` +\n `Only 'pending' or 'running' executions can be cancelled.`\n );\n }\n\n const workflow = this.workflows.get(execution.workflowName);\n\n await this.updateExecutionStatus(executionId, 'cancelled');\n\n this.emitEvent({\n type: 'cancelled',\n workflowName: execution.workflowName,\n executionId,\n timestamp: new Date(),\n });\n\n if (options?.rollback && workflow)\n {\n await this.executeRollback(executionId, workflow);\n }\n }\n\n subscribe(\n executionId: string,\n callback: (event: WorkflowEvent) => void\n ): () => void\n {\n if (!this.subscribers.has(executionId))\n {\n this.subscribers.set(executionId, new Set());\n }\n\n this.subscribers.get(executionId)!.add(callback);\n\n return () =>\n {\n this.subscribers.get(executionId)?.delete(callback);\n };\n }\n}\n\n/**\n * Create a workflow engine\n *\n * @example\n * ```typescript\n * const engine = createWorkflowEngine({\n * workflows: [provisionTenant, deprovisionTenant],\n * db: database,\n * });\n *\n * const execution = await engine.start('provision-tenant', {\n * tenantId: 'abc',\n * plan: 'pro',\n * });\n * ```\n */\nexport function createWorkflowEngine<TWorkflows extends WorkflowDef<string, unknown>[]>(\n options: {\n workflows: TWorkflows;\n } & WorkflowEngineConfig\n): WorkflowEngine<TWorkflows>\n{\n const { workflows, ...config } = options;\n return new WorkflowEngineImpl(workflows, config);\n}\n","/**\n * Built-in Notification Providers\n *\n * Only consoleProvider is provided by default.\n * For email, SMS, Slack, etc., implement your own provider using @spfn/notification.\n *\n * @example\n * ```typescript\n * import { sendEmail } from '@spfn/notification/server';\n * import type { NotificationProvider } from '@spfn/workflow';\n *\n * const emailProvider: NotificationProvider = {\n * name: 'email',\n * async notify(event) {\n * await sendEmail({\n * to: 'admin@example.com',\n * subject: `[Workflow] ${event.workflowName}: ${event.type}`,\n * text: formatEventAsText(event),\n * });\n * },\n * };\n * ```\n */\n\nimport type { WorkflowEvent } from '../builder';\nimport type { NotificationProvider } from './types';\n\n/**\n * Console notification provider\n *\n * Logs workflow events to console. This is the only built-in provider.\n *\n * @example\n * ```typescript\n * workflow('provision')\n * .notify({\n * on: ['failed'],\n * providers: [consoleProvider],\n * });\n * ```\n */\nexport const consoleProvider: NotificationProvider = {\n name: 'console',\n async notify(event: WorkflowEvent): Promise<void>\n {\n const timestamp = event.timestamp.toISOString();\n const prefix = `[Workflow:${event.workflowName}]`;\n\n switch (event.type)\n {\n case 'started':\n console.log(`${timestamp} ${prefix} Started (id: ${event.executionId})`);\n break;\n case 'completed':\n console.log(`${timestamp} ${prefix} Completed (id: ${event.executionId})`);\n break;\n case 'failed':\n console.error(`${timestamp} ${prefix} Failed: ${event.error} (id: ${event.executionId})`);\n break;\n case 'cancelled':\n console.log(`${timestamp} ${prefix} Cancelled (id: ${event.executionId})`);\n break;\n case 'step.started':\n console.log(`${timestamp} ${prefix} Step '${event.stepName}' started`);\n break;\n case 'step.completed':\n console.log(`${timestamp} ${prefix} Step '${event.stepName}' completed`);\n break;\n case 'step.failed':\n console.error(`${timestamp} ${prefix} Step '${event.stepName}' failed: ${event.error}`);\n break;\n }\n },\n};\n\n/**\n * Helper: Format workflow event as plain text\n *\n * Use this when implementing custom notification providers.\n *\n * @example\n * ```typescript\n * import { formatEventAsText } from '@spfn/workflow';\n * import { sendEmail } from '@spfn/notification/server';\n *\n * const emailProvider: NotificationProvider = {\n * name: 'email',\n * async notify(event) {\n * await sendEmail({\n * to: 'admin@example.com',\n * subject: `[Workflow] ${event.workflowName}: ${event.type}`,\n * text: formatEventAsText(event),\n * });\n * },\n * };\n * ```\n */\nexport function formatEventAsText(event: WorkflowEvent): string\n{\n const lines = [\n `Workflow: ${event.workflowName}`,\n `Event: ${event.type}`,\n `Execution ID: ${event.executionId}`,\n `Timestamp: ${event.timestamp.toISOString()}`,\n ];\n\n if (event.stepName)\n {\n lines.push(`Step: ${event.stepName}`);\n }\n if (event.error)\n {\n lines.push(`Error: ${event.error}`);\n }\n\n return lines.join('\\n');\n}\n","/**\n * Workflow Router\n *\n * Defines a collection of workflows for server registration\n */\n\nimport type { WorkflowDef } from '../builder';\nimport type { WorkflowEngine, WorkflowEngineConfig, OutputStorage, WorkflowLogger } from '../engine';\nimport { createWorkflowEngine } from '../engine';\n\n/**\n * Workflow router configuration options\n */\nexport interface WorkflowRouterConfig\n{\n /**\n * Large output threshold in bytes\n * Outputs larger than this will be stored in external storage\n * @default 1024 * 1024 (1MB)\n */\n largeOutputThreshold?: number;\n\n /**\n * Storage for large outputs (optional)\n */\n storage?: OutputStorage;\n\n /**\n * Custom logger (optional, defaults to console)\n */\n logger?: WorkflowLogger;\n\n /**\n * Enable input schema validation (default: true)\n */\n validateInput?: boolean;\n}\n\n/**\n * Workflow router instance\n *\n * Contains workflow definitions and provides access to the engine\n */\nexport interface WorkflowRouter<TWorkflows extends WorkflowDef[]>\n{\n /**\n * Registered workflows\n */\n readonly workflows: TWorkflows;\n\n /**\n * Internal workflows reference\n */\n readonly _workflows: TWorkflows;\n\n /**\n * Workflow engine instance (available after initialization)\n */\n readonly engine: WorkflowEngine<TWorkflows>;\n\n /**\n * Check if engine is initialized\n */\n readonly isInitialized: boolean;\n\n /**\n * Initialize the workflow engine\n * Called internally by @spfn/core server\n *\n * @internal\n */\n _init: (db: WorkflowEngineConfig['db'], options?: WorkflowRouterConfig) => void;\n}\n\n/**\n * Internal state for workflow router\n */\ninterface WorkflowRouterState<TWorkflows extends WorkflowDef[]>\n{\n engine: WorkflowEngine<TWorkflows> | null;\n}\n\n/**\n * Define a workflow router for server registration\n *\n * @example\n * ```typescript\n * import { workflow, defineWorkflowRouter } from '@spfn/workflow';\n *\n * const provisionTenant = workflow('provision-tenant')\n * .input(Type.Object({ tenantId: Type.String() }))\n * .pipe(createResources, ctx => ({ tenantId: ctx.input.tenantId }))\n * .build();\n *\n * export const workflowRouter = defineWorkflowRouter([\n * provisionTenant,\n * deprovisionTenant,\n * ]);\n *\n * // In server.config.ts\n * export default defineServerConfig()\n * .workflows(workflowRouter)\n * .build();\n *\n * // Usage\n * await workflowRouter.engine.start('provision-tenant', { tenantId: 'abc' });\n * ```\n */\nexport function defineWorkflowRouter<TWorkflows extends WorkflowDef[]>(\n workflows: TWorkflows\n): WorkflowRouter<TWorkflows>\n{\n const state: WorkflowRouterState<TWorkflows> = {\n engine: null,\n };\n\n return {\n workflows,\n _workflows: workflows,\n\n get engine(): WorkflowEngine<TWorkflows>\n {\n if (!state.engine)\n {\n throw new Error(\n 'Workflow engine not initialized. ' +\n 'Make sure the server is started with .workflows(router) configuration.'\n );\n }\n return state.engine;\n },\n\n get isInitialized(): boolean\n {\n return state.engine !== null;\n },\n\n _init(db: WorkflowEngineConfig['db'], options?: WorkflowRouterConfig): void\n {\n if (state.engine)\n {\n // Already initialized, skip\n return;\n }\n\n state.engine = createWorkflowEngine({\n db,\n workflows,\n largeOutputThreshold: options?.largeOutputThreshold,\n storage: options?.storage,\n logger: options?.logger,\n validateInput: options?.validateInput,\n });\n },\n };\n}\n\n/**\n * Type guard to check if value is a WorkflowRouter\n */\nexport function isWorkflowRouter(value: unknown): value is WorkflowRouter<WorkflowDef[]>\n{\n return (\n typeof value === 'object' &&\n value !== null &&\n '_workflows' in value &&\n '_init' in value &&\n typeof (value as WorkflowRouter<WorkflowDef[]>)._init === 'function'\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/builder/workflow-builder.ts","../src/entities/schema.ts","../src/entities/workflow-execution.entity.ts","../src/entities/workflow-step-execution.entity.ts","../src/engine/types.ts","../src/engine/workflow-engine.ts","../src/notification/providers.ts","../src/config/workflow-router.ts"],"names":["text","integer","jsonb","timestamp","timestamps","index","workflow"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Workflow Builder\n *\n * Fluent API for defining workflows\n */\n\nimport type { TSchema, Static } from '@sinclair/typebox';\nimport type { JobDef, InferJobInput, InferJobOutput } from '@spfn/core/job';\nimport type {\n WorkflowDef,\n WorkflowStepDef,\n StepMapper,\n NotifyConfig,\n} from './types';\n\n/**\n * Workflow builder with fluent API and type inference\n */\nexport class WorkflowBuilder<\n TName extends string,\n TInput = void,\n TResults extends Record<string, unknown> = {}\n>\n{\n private readonly _name: TName;\n private _inputSchema?: TSchema;\n private _steps: WorkflowStepDef[] = [];\n private _resumable: boolean = false;\n private _rollbackEnabled: boolean = true;\n private _notifyConfigs: NotifyConfig[] = [];\n\n constructor(name: TName)\n {\n this._name = name;\n }\n\n /**\n * Define input schema\n */\n input<TSchema extends import('@sinclair/typebox').TSchema>(\n schema: TSchema\n ): WorkflowBuilder<TName, Static<TSchema>, TResults>\n {\n const builder = new WorkflowBuilder<TName, Static<TSchema>, TResults>(this._name);\n builder._inputSchema = schema;\n builder._steps = this._steps;\n builder._resumable = this._resumable;\n builder._rollbackEnabled = this._rollbackEnabled;\n builder._notifyConfigs = [...this._notifyConfigs];\n return builder;\n }\n\n /**\n * Add a sequential step\n */\n pipe<\n TJob extends JobDef<any, any>,\n TStepName extends string = TJob['name']\n >(\n job: TJob,\n mapper: StepMapper<TInput, TResults, InferJobInput<TJob>>\n ): WorkflowBuilder<\n TName,\n TInput,\n TResults & { [K in TStepName]: InferJobOutput<TJob> }\n >\n {\n const stepName = job.name as TStepName;\n\n const step: WorkflowStepDef = {\n name: stepName,\n job: job as JobDef<unknown, unknown>,\n mapper: mapper as StepMapper<unknown, Record<string, unknown>, unknown>,\n type: 'sequential',\n };\n\n const builder = new WorkflowBuilder<\n TName,\n TInput,\n TResults & { [K in TStepName]: InferJobOutput<TJob> }\n >(this._name);\n builder._inputSchema = this._inputSchema;\n builder._steps = [...this._steps, step];\n builder._resumable = this._resumable;\n builder._rollbackEnabled = this._rollbackEnabled;\n builder._notifyConfigs = [...this._notifyConfigs];\n\n return builder;\n }\n\n /**\n * Add parallel steps\n */\n parallel<\n TParallel extends Record<string, [JobDef<any, any>, StepMapper<TInput, TResults, any>]>\n >(\n steps: TParallel\n ): WorkflowBuilder<\n TName,\n TInput,\n TResults & { [K in keyof TParallel]: InferJobOutput<TParallel[K][0]> }\n >\n {\n const parallelGroup = `parallel_${this._steps.length}`;\n const parallelSteps: WorkflowStepDef[] = [];\n\n for (const [name, [job, mapper]] of Object.entries(steps))\n {\n parallelSteps.push({\n name,\n job: job as JobDef<unknown, unknown>,\n mapper: mapper as StepMapper<unknown, Record<string, unknown>, unknown>,\n type: 'parallel',\n parallelGroup,\n });\n }\n\n const builder = new WorkflowBuilder<\n TName,\n TInput,\n TResults & { [K in keyof TParallel]: InferJobOutput<TParallel[K][0]> }\n >(this._name);\n builder._inputSchema = this._inputSchema;\n builder._steps = [...this._steps, ...parallelSteps];\n builder._resumable = this._resumable;\n builder._rollbackEnabled = this._rollbackEnabled;\n builder._notifyConfigs = [...this._notifyConfigs];\n\n return builder;\n }\n\n /**\n * Enable/disable resumable (restart from failure point)\n */\n resumable(enabled: boolean = true): this\n {\n this._resumable = enabled;\n return this;\n }\n\n /**\n * Enable/disable rollback on failure\n */\n rollback(enabled: boolean = true): this\n {\n this._rollbackEnabled = enabled;\n return this;\n }\n\n /**\n * Configure notifications (chainable — each call adds a separate config)\n */\n notify(config: NotifyConfig): this\n {\n this._notifyConfigs.push(config);\n return this;\n }\n\n /**\n * Build the workflow definition\n */\n build(): WorkflowDef<TName, TInput>\n {\n return {\n name: this._name,\n inputSchema: this._inputSchema,\n steps: this._steps,\n resumable: this._resumable,\n rollbackEnabled: this._rollbackEnabled,\n notifyConfigs: this._notifyConfigs,\n _input: undefined as unknown as TInput,\n };\n }\n}\n\n/**\n * Create a new workflow definition\n *\n * @example\n * ```typescript\n * const provisionTenant = workflow('provision-tenant')\n * .input(Type.Object({\n * tenantId: Type.String(),\n * plan: Type.String(),\n * }))\n * .resumable(true)\n * .pipe(createPodIdentity, (ctx) => ({\n * tenantId: ctx.input.tenantId,\n * }))\n * .parallel({\n * appRepo: [createAppRepo, (ctx) => ({ tenantId: ctx.input.tenantId })],\n * gitopsRepo: [createGitopsRepo, (ctx) => ({ tenantId: ctx.input.tenantId })],\n * })\n * .pipe(notifyComplete, (ctx) => ({\n * appRepoUrl: ctx.results.appRepo.repoUrl,\n * gitopsRepoUrl: ctx.results.gitopsRepo.repoUrl,\n * }))\n * .build();\n * ```\n */\nexport function workflow<TName extends string>(name: TName): WorkflowBuilder<TName>\n{\n return new WorkflowBuilder(name);\n}\n","/**\n * @spfn/workflow - Database Schema Definition\n *\n * Defines the 'spfn_workflow' PostgreSQL schema for all workflow-related tables\n */\n\nimport { createSchema } from '@spfn/core/db';\n\n/**\n * Workflow schema for all workflow execution tables\n * Tables: executions, step_executions\n */\nexport const workflowSchema = createSchema('@spfn/workflow');\n","/**\n * Workflow Execution Entity\n *\n * Stores the state of workflow executions\n */\n\nimport { text, integer, timestamp, jsonb, index } from 'drizzle-orm/pg-core';\nimport { timestamps } from '@spfn/core/db';\nimport type { WorkflowStatus } from '../types';\nimport { workflowSchema } from './schema';\n\nexport const workflowExecutions = workflowSchema.table(\n 'executions',\n {\n id: text('id').primaryKey().$defaultFn(() => crypto.randomUUID()),\n\n /**\n * Workflow name (identifier)\n */\n workflowName: text('workflow_name').notNull(),\n\n /**\n * Execution status\n */\n status: text('status').$type<WorkflowStatus>().notNull().default('pending'),\n\n /**\n * Input data (JSON)\n */\n input: jsonb('input'),\n\n /**\n * Current step index\n */\n currentStep: integer('current_step').notNull().default(0),\n\n /**\n * Error message (if failed)\n */\n error: text('error'),\n\n /**\n * Completed timestamp\n */\n completedAt: timestamp('completed_at', { withTimezone: true }),\n\n ...timestamps(),\n },\n (table) => [\n index('wf_exec_workflow_name_idx').on(table.workflowName),\n index('wf_exec_status_idx').on(table.status),\n index('wf_exec_created_at_idx').on(table.createdAt),\n index('wf_exec_workflow_status_idx').on(table.workflowName, table.status),\n ]\n);\n\nexport type WorkflowExecution = typeof workflowExecutions.$inferSelect;\nexport type NewWorkflowExecution = typeof workflowExecutions.$inferInsert;\n","/**\n * Workflow Step Execution Entity\n *\n * Stores the state of individual step executions within a workflow\n */\n\nimport { text, integer, timestamp, jsonb, index } from 'drizzle-orm/pg-core';\nimport { timestamps } from '@spfn/core/db';\nimport type { WorkflowStepStatus } from '../types';\nimport { workflowExecutions } from './workflow-execution.entity';\nimport { workflowSchema } from './schema';\n\nexport const workflowStepExecutions = workflowSchema.table(\n 'step_executions',\n {\n id: text('id').primaryKey().$defaultFn(() => crypto.randomUUID()),\n\n /**\n * Parent workflow execution ID\n */\n executionId: text('execution_id')\n .notNull()\n .references(() => workflowExecutions.id, { onDelete: 'cascade' }),\n\n /**\n * Step name (job name)\n */\n stepName: text('step_name').notNull(),\n\n /**\n * Step index in the workflow\n */\n stepIndex: integer('step_index').notNull(),\n\n /**\n * Step execution status\n */\n status: text('status').$type<WorkflowStepStatus>().notNull().default('pending'),\n\n /**\n * Step output data (JSON or URL reference for large data)\n */\n output: jsonb('output'),\n\n /**\n * Error message (if failed)\n */\n error: text('error'),\n\n /**\n * Started timestamp\n */\n startedAt: timestamp('started_at', { withTimezone: true }),\n\n /**\n * Completed timestamp\n */\n completedAt: timestamp('completed_at', { withTimezone: true }),\n\n ...timestamps(),\n },\n (table) => [\n index('wf_step_exec_execution_id_idx').on(table.executionId),\n index('wf_step_exec_status_idx').on(table.status),\n index('wf_step_exec_exec_step_idx').on(table.executionId, table.stepIndex),\n ]\n);\n\nexport type WorkflowStepExecution = typeof workflowStepExecutions.$inferSelect;\nexport type NewWorkflowStepExecution = typeof workflowStepExecutions.$inferInsert;\n","/**\n * Workflow Engine Types\n */\n\nimport type { WorkflowDef, WorkflowEvent } from '../builder';\nimport type { WorkflowExecution, WorkflowStepExecution } from '../entities';\n\n/**\n * Logger interface for workflow engine\n */\nexport interface WorkflowLogger\n{\n info(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n debug(message: string, ...args: unknown[]): void;\n}\n\n/**\n * Default console logger\n */\nexport const defaultLogger: WorkflowLogger = {\n info: (message, ...args) => console.log(message, ...args),\n error: (message, ...args) => console.error(message, ...args),\n warn: (message, ...args) => console.warn(message, ...args),\n debug: (message, ...args) => console.debug(message, ...args),\n};\n\n/**\n * Workflow engine configuration\n */\nexport interface WorkflowEngineConfig\n{\n /**\n * Database instance (drizzle)\n */\n db: unknown;\n\n /**\n * Storage for large outputs (optional)\n */\n storage?: OutputStorage;\n\n /**\n * Large output threshold in bytes (default: 1MB)\n */\n largeOutputThreshold?: number;\n\n /**\n * Custom logger (optional, defaults to console)\n */\n logger?: WorkflowLogger;\n\n /**\n * Enable input schema validation (default: true)\n */\n validateInput?: boolean;\n}\n\n/**\n * Output storage interface for large data\n */\nexport interface OutputStorage\n{\n /**\n * Upload data and return URL reference\n */\n upload(data: unknown): Promise<string>;\n\n /**\n * Download data from URL reference\n */\n download(url: string): Promise<unknown>;\n}\n\n/**\n * Execution result from start()\n */\nexport interface ExecutionResult\n{\n /**\n * Execution ID\n */\n id: string;\n\n /**\n * Workflow name\n */\n workflowName: string;\n\n /**\n * Initial status\n */\n status: 'pending';\n}\n\n/**\n * Execution status with details\n */\nexport interface ExecutionStatus extends WorkflowExecution\n{\n /**\n * Step executions\n */\n steps: WorkflowStepExecution[];\n}\n\n/**\n * Cancel options\n */\nexport interface CancelOptions\n{\n /**\n * Execute rollback after cancel\n */\n rollback?: boolean;\n}\n\n/**\n * List filter options\n */\nexport interface ListOptions\n{\n /**\n * Filter by workflow name\n */\n workflowName?: string;\n\n /**\n * Filter by status\n */\n status?: string;\n\n /**\n * Limit results\n */\n limit?: number;\n\n /**\n * Offset for pagination\n */\n offset?: number;\n}\n\n/**\n * Workflow engine interface\n */\nexport interface WorkflowEngine<TWorkflows extends WorkflowDef<string, unknown>[]>\n{\n /**\n * Start a workflow execution\n */\n start<TName extends TWorkflows[number]['name']>(\n name: TName,\n input: ExtractWorkflowInput<TWorkflows, TName>\n ): Promise<ExecutionResult>;\n\n /**\n * Get execution status\n */\n get(executionId: string): Promise<ExecutionStatus | null>;\n\n /**\n * Get step output\n */\n getStepOutput(executionId: string, stepName: string): Promise<unknown>;\n\n /**\n * List executions\n */\n list(options?: ListOptions): Promise<ExecutionStatus[]>;\n\n /**\n * Retry failed execution\n */\n retry(executionId: string): Promise<ExecutionResult>;\n\n /**\n * Cancel execution\n */\n cancel(executionId: string, options?: CancelOptions): Promise<void>;\n\n /**\n * Subscribe to execution events\n */\n subscribe(\n executionId: string,\n callback: (event: WorkflowEvent) => void\n ): () => void;\n}\n\n/**\n * Extract input type from workflow by name\n */\nexport type ExtractWorkflowInput<\n TWorkflows extends WorkflowDef<string, unknown>[],\n TName extends string\n> = TWorkflows extends (infer W)[]\n ? W extends WorkflowDef<TName, infer TInput>\n ? TInput\n : never\n : never;\n","/**\n * Workflow Engine Implementation\n *\n * Orchestrates workflow execution using @spfn/core Job and Events\n */\n\nimport { eq, and, desc, inArray } from 'drizzle-orm';\nimport { Value } from '@sinclair/typebox/value';\nimport type { WorkflowDef, WorkflowEvent, WorkflowStepDef } from '../builder';\nimport type { WorkflowStatus, WorkflowStepStatus } from '../types';\nimport {\n workflowExecutions,\n workflowStepExecutions,\n type WorkflowExecution,\n type WorkflowStepExecution,\n} from '../entities';\nimport {\n defaultLogger,\n type WorkflowEngineConfig,\n type WorkflowEngine,\n type WorkflowLogger,\n type ExecutionResult,\n type ExecutionStatus,\n type CancelOptions,\n type ListOptions,\n type ExtractWorkflowInput,\n} from './types';\n\n/**\n * Default large output threshold (1MB)\n */\nconst DEFAULT_LARGE_OUTPUT_THRESHOLD = 1024 * 1024;\n\n/**\n * Internal workflow engine implementation\n */\nclass WorkflowEngineImpl<TWorkflows extends WorkflowDef[]>\n implements WorkflowEngine<TWorkflows>\n{\n private config: WorkflowEngineConfig;\n private workflows: Map<string, WorkflowDef>;\n private subscribers: Map<string, Set<(event: WorkflowEvent) => void>>;\n private logger: WorkflowLogger;\n /** Track executions currently being processed to prevent race conditions */\n private processingExecutions: Set<string>;\n\n constructor(\n workflows: TWorkflows,\n config: WorkflowEngineConfig\n )\n {\n this.config = config;\n this.workflows = new Map();\n this.subscribers = new Map();\n this.logger = config.logger ?? defaultLogger;\n this.processingExecutions = new Set();\n\n // Register workflows\n for (const wf of workflows)\n {\n this.workflows.set(wf.name, wf);\n }\n }\n\n /**\n * Get database instance\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private get db(): any\n {\n return this.config.db;\n }\n\n /**\n * Start a workflow execution\n */\n async start<TName extends TWorkflows[number]['name']>(\n name: TName,\n input: ExtractWorkflowInput<TWorkflows, TName>\n ): Promise<ExecutionResult>\n {\n const workflow = this.workflows.get(name);\n if (!workflow)\n {\n throw new Error(`Workflow '${name}' not found`);\n }\n\n // Validate input against schema if enabled (default: true)\n if (this.config.validateInput !== false && workflow.inputSchema)\n {\n if (!Value.Check(workflow.inputSchema, input))\n {\n const errors = [...Value.Errors(workflow.inputSchema, input)];\n const errorMessages = errors.map(e => `${e.path}: ${e.message}`).join(', ');\n throw new Error(`Invalid workflow input: ${errorMessages}`);\n }\n }\n\n // Create execution and steps in a transaction for atomicity\n const execution = await this.db.transaction(async (tx: typeof this.db) =>\n {\n // Create execution record\n const [exec] = await tx\n .insert(workflowExecutions)\n .values({\n workflowName: name,\n status: 'pending' as WorkflowStatus,\n input: input as Record<string, unknown>,\n currentStep: 0,\n })\n .returning() as WorkflowExecution[];\n\n // Create step execution records\n const stepRecords = workflow.steps.map((step, index) => ({\n executionId: exec.id,\n stepName: step.name,\n stepIndex: index,\n status: 'pending' as WorkflowStepStatus,\n }));\n\n if (stepRecords.length > 0)\n {\n await tx\n .insert(workflowStepExecutions)\n .values(stepRecords);\n }\n\n return exec;\n });\n\n // Emit started event\n this.emitEvent({\n type: 'started',\n workflowName: name,\n executionId: execution.id,\n input: input as unknown,\n timestamp: new Date(),\n });\n\n // Start first step (async, don't await)\n this.executeNextStep(execution.id, workflow, input as Record<string, unknown>)\n .catch((error) =>\n {\n this.logger.error(`[Workflow:${name}] Execution error:`, error);\n });\n\n return {\n id: execution.id,\n workflowName: name,\n status: 'pending',\n };\n }\n\n /**\n * Execute steps iteratively until completion or failure\n */\n private async executeNextStep(\n executionId: string,\n workflow: WorkflowDef,\n input: Record<string, unknown>\n ): Promise<void>\n {\n while (true)\n {\n // Get current execution state\n const execution = await this.getExecution(executionId);\n if (!execution || (execution.status !== 'pending' && execution.status !== 'running'))\n {\n return;\n }\n\n // Update status to running\n if (execution.status === 'pending')\n {\n await this.updateExecutionStatus(executionId, 'running');\n }\n\n // Get completed results\n const results = await this.getCompletedResults(executionId);\n\n // Find next pending steps\n const pendingSteps = execution.steps.filter(s => s.status === 'pending');\n if (pendingSteps.length === 0)\n {\n // All steps completed\n await this.completeExecution(executionId);\n return;\n }\n\n // Get the next step(s) to execute\n const currentStepIndex = Math.min(...pendingSteps.map(s => s.stepIndex));\n\n // Update currentStep in execution record\n await this.db\n .update(workflowExecutions)\n .set({ currentStep: currentStepIndex, updatedAt: new Date() })\n .where(eq(workflowExecutions.id, executionId));\n\n // Check if this is a parallel group\n const stepDef = workflow.steps[currentStepIndex];\n if (stepDef.type === 'parallel')\n {\n // Execute all parallel steps concurrently.\n // Wait for ALL steps to complete before handling failures\n // to prevent rollback from racing with still-running steps.\n const parallelSteps = workflow.steps.filter(\n s => s.parallelGroup === stepDef.parallelGroup\n );\n const errors = await Promise.all(\n parallelSteps.map(step =>\n this.executeStep(executionId, workflow, step, input, results)\n )\n );\n\n // Handle failure after all parallel steps have settled\n const firstError = errors.find(e => e !== null);\n if (firstError)\n {\n await this.handleStepFailure(executionId, workflow, firstError);\n return;\n }\n }\n else\n {\n // Execute sequential step\n const error = await this.executeStep(executionId, workflow, stepDef, input, results);\n if (error)\n {\n await this.handleStepFailure(executionId, workflow, error);\n return;\n }\n }\n }\n }\n\n /**\n * Execute a single step\n *\n * Returns the error message if the step failed, or null if successful.\n */\n private async executeStep(\n executionId: string,\n workflow: WorkflowDef,\n step: WorkflowStepDef,\n input: Record<string, unknown>,\n results: Record<string, unknown>\n ): Promise<string | null>\n {\n const stepExecution = await this.getStepExecution(executionId, step.name);\n if (!stepExecution || stepExecution.status !== 'pending')\n {\n return null;\n }\n\n // Update step status to running\n await this.updateStepStatus(stepExecution.id, 'running');\n\n this.emitEvent({\n type: 'step.started',\n workflowName: workflow.name,\n executionId,\n stepName: step.name,\n stepIndex: stepExecution.stepIndex,\n timestamp: new Date(),\n });\n\n try\n {\n // Map input using the mapper function\n const context = {\n input,\n results,\n execution: {\n id: executionId,\n workflowName: workflow.name,\n startedAt: new Date(),\n },\n };\n\n const stepInput = step.mapper(context);\n\n // Execute the job\n const output = await step.job.run(stepInput);\n\n // Store output (handle large data)\n const storedOutput = await this.storeOutput(output);\n\n // Update step as completed\n await this.updateStepStatus(stepExecution.id, 'completed', storedOutput);\n\n this.emitEvent({\n type: 'step.completed',\n workflowName: workflow.name,\n executionId,\n stepName: step.name,\n stepIndex: stepExecution.stepIndex,\n output: storedOutput,\n timestamp: new Date(),\n });\n\n return null;\n }\n catch (error)\n {\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n // Update step as failed\n await this.updateStepStatus(stepExecution.id, 'failed', undefined, errorMessage);\n\n this.emitEvent({\n type: 'step.failed',\n workflowName: workflow.name,\n executionId,\n stepName: step.name,\n stepIndex: stepExecution.stepIndex,\n error: errorMessage,\n timestamp: new Date(),\n });\n\n return errorMessage;\n }\n }\n\n /**\n * Handle step failure - rollback if enabled\n */\n private async handleStepFailure(\n executionId: string,\n workflow: WorkflowDef,\n error: string\n ): Promise<void>\n {\n // Update execution status\n await this.db\n .update(workflowExecutions)\n .set({\n status: 'failed' as WorkflowStatus,\n error,\n updatedAt: new Date(),\n })\n .where(eq(workflowExecutions.id, executionId));\n\n this.emitEvent({\n type: 'failed',\n workflowName: workflow.name,\n executionId,\n error,\n timestamp: new Date(),\n });\n\n // Execute rollback if enabled\n if (workflow.rollbackEnabled)\n {\n await this.executeRollback(executionId, workflow);\n }\n }\n\n /**\n * Execute rollback in reverse order\n */\n private async executeRollback(\n executionId: string,\n workflow: WorkflowDef\n ): Promise<void>\n {\n await this.updateExecutionStatus(executionId, 'compensating');\n\n const execution = await this.getExecution(executionId);\n if (!execution) return;\n\n // Get completed steps in reverse order\n const completedSteps = execution.steps\n .filter(s => s.status === 'completed')\n .sort((a, b) => b.stepIndex - a.stepIndex);\n\n for (const stepExecution of completedSteps)\n {\n const stepDef = workflow.steps.find(s => s.name === stepExecution.stepName);\n if (!stepDef || !stepDef.job.compensate)\n {\n continue;\n }\n\n try\n {\n const input = execution.input as Record<string, unknown>;\n const output = await this.resolveOutput(stepExecution.output);\n\n await stepDef.job.compensate(input, output);\n\n await this.updateStepStatus(stepExecution.id, 'compensated');\n }\n catch (compensateError)\n {\n // Log but continue with other compensations\n this.logger.error(\n `[Workflow:${workflow.name}] Compensate error for step ${stepExecution.stepName}:`,\n compensateError\n );\n }\n }\n\n await this.updateExecutionStatus(executionId, 'compensated');\n }\n\n /**\n * Complete the workflow execution\n */\n private async completeExecution(executionId: string): Promise<void>\n {\n const execution = await this.getExecution(executionId);\n if (!execution) return;\n\n await this.db\n .update(workflowExecutions)\n .set({\n status: 'completed' as WorkflowStatus,\n completedAt: new Date(),\n updatedAt: new Date(),\n })\n .where(eq(workflowExecutions.id, executionId));\n\n this.emitEvent({\n type: 'completed',\n workflowName: execution.workflowName,\n executionId,\n timestamp: new Date(),\n });\n }\n\n /**\n * Get execution with steps\n */\n private async getExecution(executionId: string): Promise<ExecutionStatus | null>\n {\n const [execution] = await this.db\n .select()\n .from(workflowExecutions)\n .where(eq(workflowExecutions.id, executionId)) as WorkflowExecution[];\n\n if (!execution) return null;\n\n const steps = await this.db\n .select()\n .from(workflowStepExecutions)\n .where(eq(workflowStepExecutions.executionId, executionId))\n .orderBy(workflowStepExecutions.stepIndex) as WorkflowStepExecution[];\n\n return { ...execution, steps };\n }\n\n /**\n * Get step execution\n */\n private async getStepExecution(\n executionId: string,\n stepName: string\n ): Promise<WorkflowStepExecution | null>\n {\n const [step] = await this.db\n .select()\n .from(workflowStepExecutions)\n .where(\n and(\n eq(workflowStepExecutions.executionId, executionId),\n eq(workflowStepExecutions.stepName, stepName)\n )\n ) as WorkflowStepExecution[];\n\n return step || null;\n }\n\n /**\n * Get completed step results\n */\n private async getCompletedResults(executionId: string): Promise<Record<string, unknown>>\n {\n const steps = await this.db\n .select()\n .from(workflowStepExecutions)\n .where(\n and(\n eq(workflowStepExecutions.executionId, executionId),\n eq(workflowStepExecutions.status, 'completed')\n )\n ) as WorkflowStepExecution[];\n\n const results: Record<string, unknown> = {};\n for (const step of steps)\n {\n results[step.stepName] = await this.resolveOutput(step.output);\n }\n return results;\n }\n\n /**\n * Update execution status\n */\n private async updateExecutionStatus(\n executionId: string,\n status: WorkflowStatus\n ): Promise<void>\n {\n await this.db\n .update(workflowExecutions)\n .set({\n status,\n updatedAt: new Date(),\n })\n .where(eq(workflowExecutions.id, executionId));\n }\n\n /**\n * Update step status\n */\n private async updateStepStatus(\n stepId: string,\n status: WorkflowStepStatus,\n output?: unknown,\n error?: string\n ): Promise<void>\n {\n const updates: Record<string, unknown> = {\n status,\n updatedAt: new Date(),\n };\n\n if (status === 'running')\n {\n updates.startedAt = new Date();\n }\n if (status === 'completed' || status === 'failed')\n {\n updates.completedAt = new Date();\n }\n if (output !== undefined)\n {\n updates.output = output;\n }\n if (error !== undefined)\n {\n updates.error = error;\n }\n\n await this.db\n .update(workflowStepExecutions)\n .set(updates)\n .where(eq(workflowStepExecutions.id, stepId));\n }\n\n /**\n * Store output (handle large data)\n */\n private async storeOutput(output: unknown): Promise<unknown>\n {\n if (!output || !this.config.storage) return output;\n\n const json = JSON.stringify(output);\n const threshold = this.config.largeOutputThreshold ?? DEFAULT_LARGE_OUTPUT_THRESHOLD;\n\n if (Buffer.byteLength(json, 'utf8') > threshold)\n {\n const url = await this.config.storage.upload(output);\n return { $ref: url };\n }\n\n return output;\n }\n\n /**\n * Resolve output (fetch from storage if needed)\n */\n private async resolveOutput(output: unknown): Promise<unknown>\n {\n if (!output) return output;\n\n const ref = output as { $ref?: string };\n if (ref.$ref && this.config.storage)\n {\n return await this.config.storage.download(ref.$ref);\n }\n\n return output;\n }\n\n /**\n * Emit event to subscribers and notification providers\n */\n private emitEvent(event: WorkflowEvent): void\n {\n // Notify subscribers\n const subscribers = this.subscribers.get(event.executionId);\n if (subscribers)\n {\n for (const callback of subscribers)\n {\n try\n {\n callback(event);\n }\n catch (error)\n {\n this.logger.error('[WorkflowEngine] Subscriber error:', error);\n }\n }\n\n // Cleanup subscribers on terminal events to prevent memory leaks\n const terminalEvents: string[] = ['completed', 'failed', 'cancelled'];\n if (terminalEvents.includes(event.type))\n {\n this.subscribers.delete(event.executionId);\n }\n }\n\n // Send notifications (async, don't block)\n this.sendNotifications(event).catch((error) =>\n {\n this.logger.error('[WorkflowEngine] Notification error:', error);\n });\n }\n\n /**\n * Send notifications based on workflow config\n */\n private async sendNotifications(event: WorkflowEvent): Promise<void>\n {\n const workflow = this.workflows.get(event.workflowName);\n if (!workflow || workflow.notifyConfigs.length === 0)\n {\n return;\n }\n\n for (const { on, when, providers } of workflow.notifyConfigs)\n {\n // Check if this event type should trigger notification\n if (!on.includes(event.type))\n {\n continue;\n }\n\n // Check conditional\n if (when && !when(event))\n {\n continue;\n }\n\n // Send to all providers\n await Promise.all(\n providers.map(async (provider) =>\n {\n try\n {\n await provider.notify(event);\n }\n catch (error)\n {\n this.logger.error(\n `[WorkflowEngine] Notification provider '${provider.name}' error:`,\n error\n );\n }\n })\n );\n }\n }\n\n // Public API methods\n\n async get(executionId: string): Promise<ExecutionStatus | null>\n {\n return this.getExecution(executionId);\n }\n\n async getStepOutput(executionId: string, stepName: string): Promise<unknown>\n {\n const step = await this.getStepExecution(executionId, stepName);\n if (!step) return null;\n return this.resolveOutput(step.output);\n }\n\n async list(options?: ListOptions): Promise<ExecutionStatus[]>\n {\n // Build where conditions\n const conditions = [];\n if (options?.workflowName)\n {\n conditions.push(eq(workflowExecutions.workflowName, options.workflowName));\n }\n if (options?.status)\n {\n conditions.push(eq(workflowExecutions.status, options.status as WorkflowStatus));\n }\n\n // Build query with DB-level pagination\n let query = this.db\n .select()\n .from(workflowExecutions)\n .orderBy(desc(workflowExecutions.createdAt));\n\n if (conditions.length > 0)\n {\n query = query.where(conditions.length === 1 ? conditions[0] : and(...conditions));\n }\n\n if (options?.limit)\n {\n query = query.limit(options.limit);\n }\n if (options?.offset)\n {\n query = query.offset(options.offset);\n }\n\n const executions = await query as WorkflowExecution[];\n\n if (executions.length === 0)\n {\n return [];\n }\n\n // Fetch all steps in single query (avoid N+1)\n const executionIds = executions.map(e => e.id);\n const allSteps = await this.db\n .select()\n .from(workflowStepExecutions)\n .where(inArray(workflowStepExecutions.executionId, executionIds))\n .orderBy(workflowStepExecutions.stepIndex) as WorkflowStepExecution[];\n\n // Group steps by executionId\n const stepsByExecutionId = new Map<string, WorkflowStepExecution[]>();\n for (const step of allSteps)\n {\n const steps = stepsByExecutionId.get(step.executionId) ?? [];\n steps.push(step);\n stepsByExecutionId.set(step.executionId, steps);\n }\n\n // Combine executions with their steps\n return executions.map(execution => ({\n ...execution,\n steps: stepsByExecutionId.get(execution.id) ?? [],\n }));\n }\n\n async retry(executionId: string): Promise<ExecutionResult>\n {\n // Prevent concurrent retry calls for the same execution\n if (this.processingExecutions.has(executionId))\n {\n throw new Error(`Execution '${executionId}' is already being processed`);\n }\n\n const execution = await this.getExecution(executionId);\n if (!execution)\n {\n throw new Error(`Execution '${executionId}' not found`);\n }\n\n // Validate execution status - only failed or compensated can be retried\n const retryableStatuses: WorkflowStatus[] = ['failed', 'compensated'];\n if (!retryableStatuses.includes(execution.status))\n {\n throw new Error(\n `Cannot retry execution '${executionId}' with status '${execution.status}'. ` +\n `Only 'failed' or 'compensated' executions can be retried.`\n );\n }\n\n const workflow = this.workflows.get(execution.workflowName);\n if (!workflow)\n {\n throw new Error(`Workflow '${execution.workflowName}' not found`);\n }\n\n // Mark as processing to prevent race conditions\n this.processingExecutions.add(executionId);\n\n try\n {\n if (workflow.resumable)\n {\n // Resume from failed step - only reset failed steps\n await this.updateExecutionStatus(executionId, 'running');\n\n const failedSteps = execution.steps.filter(s => s.status === 'failed');\n for (const step of failedSteps)\n {\n await this.updateStepStatus(step.id, 'pending');\n }\n }\n else\n {\n // Restart from beginning - reset all steps\n await this.resetAllSteps(execution.steps);\n\n await this.db\n .update(workflowExecutions)\n .set({\n status: 'pending' as WorkflowStatus,\n currentStep: 0,\n error: null,\n completedAt: null,\n updatedAt: new Date(),\n })\n .where(eq(workflowExecutions.id, executionId));\n }\n\n // Start execution (async)\n this.executeNextStep(\n executionId,\n workflow,\n execution.input as Record<string, unknown>\n )\n .catch((error) =>\n {\n this.logger.error(`[Workflow:${workflow.name}] Retry error:`, error);\n })\n .finally(() =>\n {\n this.processingExecutions.delete(executionId);\n });\n\n return {\n id: executionId,\n workflowName: execution.workflowName,\n status: 'pending',\n };\n }\n catch (error)\n {\n this.processingExecutions.delete(executionId);\n throw error;\n }\n }\n\n /**\n * Reset all steps to pending state\n */\n private async resetAllSteps(steps: WorkflowStepExecution[]): Promise<void>\n {\n if (steps.length === 0) return;\n\n await this.db\n .update(workflowStepExecutions)\n .set({\n status: 'pending' as WorkflowStepStatus,\n output: null,\n error: null,\n startedAt: null,\n completedAt: null,\n updatedAt: new Date(),\n })\n .where(inArray(workflowStepExecutions.id, steps.map(s => s.id)));\n }\n\n async cancel(executionId: string, options?: CancelOptions): Promise<void>\n {\n const execution = await this.getExecution(executionId);\n if (!execution)\n {\n throw new Error(`Execution '${executionId}' not found`);\n }\n\n // Validate execution status - only pending or running can be cancelled\n const cancellableStatuses: WorkflowStatus[] = ['pending', 'running'];\n if (!cancellableStatuses.includes(execution.status))\n {\n throw new Error(\n `Cannot cancel execution '${executionId}' with status '${execution.status}'. ` +\n `Only 'pending' or 'running' executions can be cancelled.`\n );\n }\n\n const workflow = this.workflows.get(execution.workflowName);\n\n await this.updateExecutionStatus(executionId, 'cancelled');\n\n this.emitEvent({\n type: 'cancelled',\n workflowName: execution.workflowName,\n executionId,\n timestamp: new Date(),\n });\n\n if (options?.rollback && workflow)\n {\n await this.executeRollback(executionId, workflow);\n }\n }\n\n subscribe(\n executionId: string,\n callback: (event: WorkflowEvent) => void\n ): () => void\n {\n if (!this.subscribers.has(executionId))\n {\n this.subscribers.set(executionId, new Set());\n }\n\n this.subscribers.get(executionId)!.add(callback);\n\n return () =>\n {\n this.subscribers.get(executionId)?.delete(callback);\n };\n }\n}\n\n/**\n * Create a workflow engine\n *\n * @example\n * ```typescript\n * const engine = createWorkflowEngine({\n * workflows: [provisionTenant, deprovisionTenant],\n * db: database,\n * });\n *\n * const execution = await engine.start('provision-tenant', {\n * tenantId: 'abc',\n * plan: 'pro',\n * });\n * ```\n */\nexport function createWorkflowEngine<TWorkflows extends WorkflowDef<string, unknown>[]>(\n options: {\n workflows: TWorkflows;\n } & WorkflowEngineConfig\n): WorkflowEngine<TWorkflows>\n{\n const { workflows, ...config } = options;\n return new WorkflowEngineImpl(workflows, config);\n}\n","/**\n * Built-in Notification Providers\n *\n * Only consoleProvider is provided by default.\n * For email, SMS, Slack, etc., implement your own provider using @spfn/notification.\n *\n * @example\n * ```typescript\n * import { sendEmail } from '@spfn/notification/server';\n * import type { NotificationProvider } from '@spfn/workflow';\n *\n * const emailProvider: NotificationProvider = {\n * name: 'email',\n * async notify(event) {\n * await sendEmail({\n * to: 'admin@example.com',\n * subject: `[Workflow] ${event.workflowName}: ${event.type}`,\n * text: formatEventAsText(event),\n * });\n * },\n * };\n * ```\n */\n\nimport type { WorkflowEvent } from '../builder';\nimport type { NotificationProvider } from './types';\n\n/**\n * Console notification provider\n *\n * Logs workflow events to console. This is the only built-in provider.\n *\n * @example\n * ```typescript\n * workflow('provision')\n * .notify({\n * on: ['failed'],\n * providers: [consoleProvider],\n * });\n * ```\n */\nexport const consoleProvider: NotificationProvider = {\n name: 'console',\n async notify(event: WorkflowEvent): Promise<void>\n {\n const timestamp = event.timestamp.toISOString();\n const prefix = `[Workflow:${event.workflowName}]`;\n\n switch (event.type)\n {\n case 'started':\n console.log(`${timestamp} ${prefix} Started (id: ${event.executionId})`);\n break;\n case 'completed':\n console.log(`${timestamp} ${prefix} Completed (id: ${event.executionId})`);\n break;\n case 'failed':\n console.error(`${timestamp} ${prefix} Failed: ${event.error} (id: ${event.executionId})`);\n break;\n case 'cancelled':\n console.log(`${timestamp} ${prefix} Cancelled (id: ${event.executionId})`);\n break;\n case 'step.started':\n console.log(`${timestamp} ${prefix} Step '${event.stepName}' started`);\n break;\n case 'step.completed':\n console.log(`${timestamp} ${prefix} Step '${event.stepName}' completed`);\n break;\n case 'step.failed':\n console.error(`${timestamp} ${prefix} Step '${event.stepName}' failed: ${event.error}`);\n break;\n }\n },\n};\n\n/**\n * Helper: Format workflow event as plain text\n *\n * Use this when implementing custom notification providers.\n *\n * @example\n * ```typescript\n * import { formatEventAsText } from '@spfn/workflow';\n * import { sendEmail } from '@spfn/notification/server';\n *\n * const emailProvider: NotificationProvider = {\n * name: 'email',\n * async notify(event) {\n * await sendEmail({\n * to: 'admin@example.com',\n * subject: `[Workflow] ${event.workflowName}: ${event.type}`,\n * text: formatEventAsText(event),\n * });\n * },\n * };\n * ```\n */\nexport function formatEventAsText(event: WorkflowEvent): string\n{\n const lines = [\n `Workflow: ${event.workflowName}`,\n `Event: ${event.type}`,\n `Execution ID: ${event.executionId}`,\n `Timestamp: ${event.timestamp.toISOString()}`,\n ];\n\n if (event.stepName)\n {\n lines.push(`Step: ${event.stepName}`);\n }\n if (event.error)\n {\n lines.push(`Error: ${event.error}`);\n }\n\n return lines.join('\\n');\n}\n","/**\n * Workflow Router\n *\n * Defines a collection of workflows for server registration\n */\n\nimport type { WorkflowDef } from '../builder';\nimport type { WorkflowEngine, WorkflowEngineConfig, OutputStorage, WorkflowLogger } from '../engine';\nimport { createWorkflowEngine } from '../engine';\n\n/**\n * Workflow router configuration options\n */\nexport interface WorkflowRouterConfig\n{\n /**\n * Large output threshold in bytes\n * Outputs larger than this will be stored in external storage\n * @default 1024 * 1024 (1MB)\n */\n largeOutputThreshold?: number;\n\n /**\n * Storage for large outputs (optional)\n */\n storage?: OutputStorage;\n\n /**\n * Custom logger (optional, defaults to console)\n */\n logger?: WorkflowLogger;\n\n /**\n * Enable input schema validation (default: true)\n */\n validateInput?: boolean;\n}\n\n/**\n * Workflow router instance\n *\n * Contains workflow definitions and provides access to the engine\n */\nexport interface WorkflowRouter<TWorkflows extends WorkflowDef[]>\n{\n /**\n * Registered workflows\n */\n readonly workflows: TWorkflows;\n\n /**\n * Internal workflows reference\n */\n readonly _workflows: TWorkflows;\n\n /**\n * Workflow engine instance (available after initialization)\n */\n readonly engine: WorkflowEngine<TWorkflows>;\n\n /**\n * Check if engine is initialized\n */\n readonly isInitialized: boolean;\n\n /**\n * Initialize the workflow engine\n * Called internally by @spfn/core server\n *\n * @internal\n */\n _init: (db: WorkflowEngineConfig['db'], options?: WorkflowRouterConfig) => void;\n}\n\n/**\n * Internal state for workflow router\n */\ninterface WorkflowRouterState<TWorkflows extends WorkflowDef[]>\n{\n engine: WorkflowEngine<TWorkflows> | null;\n}\n\n/**\n * Define a workflow router for server registration\n *\n * @example\n * ```typescript\n * import { workflow, defineWorkflowRouter } from '@spfn/workflow';\n *\n * const provisionTenant = workflow('provision-tenant')\n * .input(Type.Object({ tenantId: Type.String() }))\n * .pipe(createResources, ctx => ({ tenantId: ctx.input.tenantId }))\n * .build();\n *\n * export const workflowRouter = defineWorkflowRouter([\n * provisionTenant,\n * deprovisionTenant,\n * ]);\n *\n * // In server.config.ts\n * export default defineServerConfig()\n * .workflows(workflowRouter)\n * .build();\n *\n * // Usage\n * await workflowRouter.engine.start('provision-tenant', { tenantId: 'abc' });\n * ```\n */\nexport function defineWorkflowRouter<TWorkflows extends WorkflowDef[]>(\n workflows: TWorkflows\n): WorkflowRouter<TWorkflows>\n{\n const state: WorkflowRouterState<TWorkflows> = {\n engine: null,\n };\n\n return {\n workflows,\n _workflows: workflows,\n\n get engine(): WorkflowEngine<TWorkflows>\n {\n if (!state.engine)\n {\n throw new Error(\n 'Workflow engine not initialized. ' +\n 'Make sure the server is started with .workflows(router) configuration.'\n );\n }\n return state.engine;\n },\n\n get isInitialized(): boolean\n {\n return state.engine !== null;\n },\n\n _init(db: WorkflowEngineConfig['db'], options?: WorkflowRouterConfig): void\n {\n if (state.engine)\n {\n // Already initialized, skip\n return;\n }\n\n state.engine = createWorkflowEngine({\n db,\n workflows,\n largeOutputThreshold: options?.largeOutputThreshold,\n storage: options?.storage,\n logger: options?.logger,\n validateInput: options?.validateInput,\n });\n },\n };\n}\n\n/**\n * Type guard to check if value is a WorkflowRouter\n */\nexport function isWorkflowRouter(value: unknown): value is WorkflowRouter<WorkflowDef[]>\n{\n return (\n typeof value === 'object' &&\n value !== null &&\n '_workflows' in value &&\n '_init' in value &&\n typeof (value as WorkflowRouter<WorkflowDef[]>)._init === 'function'\n );\n}\n"]}
|