flowtify
Version:
A flexible workflow orchestration library with TypeScript support
1,573 lines (1,549 loc) • 52.7 kB
text/typescript
import { AwilixContainer } from 'awilix';
import { Container } from 'typedi';
interface WorkflowContainer {
resolve<T = any>(key: string | symbol): T;
register<T = any>(key: string | symbol, value: T | (() => T), options?: RegistrationOptions): void;
has(key: string | symbol): boolean;
createScope?(): WorkflowContainer;
dispose?(): Promise<void>;
}
interface RegistrationOptions {
lifetime?: 'singleton' | 'scoped' | 'transient';
dispose?: (service: any) => void | Promise<void>;
}
interface ContainerAdapter<TContainer = any> {
from(container: TContainer): WorkflowContainer;
create(options?: any): WorkflowContainer;
}
declare class AwilixWorkflowContainer implements WorkflowContainer {
private container;
constructor(container: AwilixContainer);
resolve<T = any>(key: string | symbol): T;
register<T = any>(key: string | symbol, value: T | (() => T), options?: RegistrationOptions): void;
has(key: string | symbol): boolean;
createScope(): WorkflowContainer;
dispose(): Promise<void>;
private mapLifetime;
}
declare class AwilixAdapter implements ContainerAdapter<AwilixContainer> {
from(container: AwilixContainer): WorkflowContainer;
create(options?: any): WorkflowContainer;
}
declare const awilixAdapter: AwilixAdapter;
declare class TypeDIWorkflowContainer implements WorkflowContainer {
private container;
constructor(container: typeof Container);
resolve<T = any>(key: string | symbol): T;
register<T = any>(key: string | symbol, value: T | (() => T), options?: RegistrationOptions): void;
has(key: string | symbol): boolean;
createScope(): WorkflowContainer;
dispose(): Promise<void>;
}
declare class TypeDIAdapter implements ContainerAdapter<typeof Container> {
from(container: typeof Container): WorkflowContainer;
create(options?: any): WorkflowContainer;
}
declare const typeDIAdapter: TypeDIAdapter;
declare class StepResponse<TOutput = any, TCompensateInput = TOutput> {
output?: TOutput;
compensateInput?: TCompensateInput;
private _permanentFailure;
private _skip;
constructor(output?: TOutput, compensateInput?: TCompensateInput);
permanentFailure(): StepResponse<TOutput, TCompensateInput>;
skip(): StepResponse<TOutput, TCompensateInput>;
get isPermanentFailure(): boolean;
get isSkipped(): boolean;
}
declare class WorkflowResponse<TResult = any, THooks = any> {
result: TResult;
hooks?: THooks;
constructor(result: TResult, options?: {
hooks?: THooks;
});
}
interface StepExecutionContext {
container: WorkflowContainer;
metadata?: Record<string, any>;
}
type InvokeFn<TInput = any, TOutput = any, TCompensateInput = any> = (input: TInput, context: StepExecutionContext) => Promise<StepResponse<TOutput, TCompensateInput>>;
type CompensateFn<TCompensateInput = any> = (compensateInput: TCompensateInput, context: StepExecutionContext) => Promise<void>;
interface StepFunction<TInput = any, TOutput = any> {
(input: TInput): TOutput;
__stepId: string;
__stepDefinition: WorkflowStepDefinition;
}
interface WorkflowStepDefinition<TInput = any, TOutput = any, TCompensateInput = any> {
id: string;
invoke: InvokeFn<TInput, TOutput, TCompensateInput>;
compensate?: CompensateFn<TCompensateInput>;
}
type WorkflowData<T> = T;
type WorkflowComposer<TInput = any, TResult = any, THooks = any> = (input: WorkflowData<TInput>) => void | WorkflowResponse<TResult, THooks>;
interface WorkflowDefinition<TInput = any, TResult = any, THooks = any> {
id: string;
composer: WorkflowComposer<TInput, TResult, THooks>;
}
interface WorkflowExecutionContext {
container?: WorkflowContainer;
scope?: WorkflowContainer;
metadata?: Record<string, any>;
}
interface WorkflowRunner<TInput = any, TResult = any> {
run(input: {
input: TInput;
} & WorkflowExecutionContext): Promise<{
result: TResult;
}>;
}
interface ReturnWorkflow<TInput = any, TResult = any, THooks = any> {
(scope?: WorkflowContainer): WorkflowRunner<TInput, TResult>;
}
declare class WorkflowRegistry {
private workflows;
register<TInput = any, TOutput = any>(workflow: WorkflowDefinition<TInput, TOutput>): void;
get<TInput = any, TOutput = any>(id: string): WorkflowDefinition<TInput, TOutput> | undefined;
has(id: string): boolean;
getAll(): WorkflowDefinition[];
clear(): void;
remove(id: string): boolean;
}
declare const workflowRegistry: WorkflowRegistry;
/**
* Hooks system for workflow events and middleware
* Workflow hook system
*/
/**
* Hook function signature
*/
type HookFunction<TData = any, TResult = any> = (data: TData, context: HookExecutionContext) => Promise<TResult> | TResult;
/**
* Hook execution context
*/
interface HookExecutionContext {
container?: WorkflowContainer;
metadata?: Record<string, any>;
workflowId?: string;
stepId?: string;
}
/**
* Hook definition interface
*/
interface HookDefinition<TData = any, TResult = any> {
id: string;
hookFn: HookFunction<TData, TResult>;
cached?: boolean;
priority?: number;
}
/**
* Hook registry for managing hooks
*/
declare class HookRegistry {
private hooks;
private cache;
/**
* Register a hook
* @param hookName - Name of the hook
* @param hookDef - Hook definition
*/
register<TData = any, TResult = any>(hookName: string, hookDef: HookDefinition<TData, TResult>): void;
/**
* Execute all hooks for a given name
* @param hookName - Name of the hook
* @param data - Data to pass to hooks
* @param context - Execution context
* @returns Array of hook results
*/
execute<TData = any, TResult = any>(hookName: string, data: TData, context?: HookExecutionContext): Promise<TResult[]>;
/**
* Get all hooks for a name
* @param hookName - Name of the hook
* @returns Array of hook definitions
*/
getHooks(hookName: string): HookDefinition[];
/**
* Remove a specific hook
* @param hookName - Name of the hook
* @param hookId - ID of the specific hook to remove
* @returns True if hook was removed
*/
remove(hookName: string, hookId: string): boolean;
/**
* Clear all hooks for a name
* @param hookName - Name of the hook
*/
clear(hookName: string): void;
/**
* Clear all hooks and cache
*/
clearAll(): void;
/**
* Get all registered hook names
* @returns Array of hook names
*/
getAllHookNames(): string[];
}
/**
* Global hook registry instance
*/
declare const hookRegistry: HookRegistry;
/**
* Create a hook function (similar to Medusa's createHook)
* @param hookName - Name of the hook
* @param data - Initial data for the hook
* @returns Hook creator function
*/
declare function createHook<TData = any>(hookName: string, data?: TData): HookCreator<TData>;
/**
* Hook creator interface
*/
interface HookCreator<TData = any> {
hookName: string;
initialData?: TData;
register<TResult = any>(hookId: string, hookFn: HookFunction<TData, TResult>, options?: {
cached?: boolean;
priority?: number;
}): void;
run<TResult = any>(data?: TData, context?: HookExecutionContext): Promise<TResult[]>;
getRegistered(): HookDefinition<TData>[];
remove(hookId: string): boolean;
clear(): void;
}
/**
* Built-in workflow hooks
*/
declare const WorkflowHooks: {
/**
* Called before workflow execution starts
*/
readonly beforeWorkflow: HookCreator<{
workflowId: string;
input: any;
}>;
/**
* Called after workflow execution completes
*/
readonly afterWorkflow: HookCreator<{
workflowId: string;
result: any;
duration: number;
}>;
/**
* Called when workflow execution fails
*/
readonly onWorkflowError: HookCreator<{
workflowId: string;
error: Error;
input: any;
}>;
/**
* Called before step execution
*/
readonly beforeStep: HookCreator<{
stepId: string;
input: any;
workflowId: string;
}>;
/**
* Called after step execution
*/
readonly afterStep: HookCreator<{
stepId: string;
output: any;
duration: number;
workflowId: string;
}>;
/**
* Called when step execution fails
*/
readonly onStepError: HookCreator<{
stepId: string;
error: Error;
input: any;
workflowId: string;
}>;
/**
* Called during compensation
*/
readonly onCompensation: HookCreator<{
stepId: string;
compensateInput: any;
workflowId: string;
}>;
};
/**
* Utility to execute workflow hooks at specific points
*/
declare class WorkflowHookExecutor {
static executeBeforeWorkflow(workflowId: string, input: any, context?: HookExecutionContext): Promise<void>;
static executeAfterWorkflow(workflowId: string, result: any, duration: number, context?: HookExecutionContext): Promise<void>;
static executeOnWorkflowError(workflowId: string, error: Error, input: any, context?: HookExecutionContext): Promise<void>;
static executeBeforeStep(stepId: string, input: any, workflowId: string, context?: HookExecutionContext): Promise<void>;
static executeAfterStep(stepId: string, output: any, duration: number, workflowId: string, context?: HookExecutionContext): Promise<void>;
static executeOnStepError(stepId: string, error: Error, input: any, workflowId: string, context?: HookExecutionContext): Promise<void>;
static executeOnCompensation(stepId: string, compensateInput: any, workflowId: string, context?: HookExecutionContext): Promise<void>;
}
/**
* Transaction ID generation and tracking system
* Provides unique transaction identifiers and event group tracking
*/
/**
* Transaction information interface
*/
interface TransactionInfo {
transactionId: string;
workflowId: string;
eventGroupId?: string;
createdAt: Date;
status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
steps: StepTransactionInfo[];
metadata?: Record<string, any>;
}
/**
* Step transaction information
*/
interface StepTransactionInfo {
stepId: string;
transactionId: string;
startedAt: Date;
completedAt?: Date;
status: 'pending' | 'running' | 'completed' | 'failed' | 'skipped' | 'compensating' | 'compensated';
input?: any;
output?: any;
error?: string;
duration?: number;
}
/**
* Event group for tracking related workflows
*/
interface EventGroup {
eventGroupId: string;
createdAt: Date;
transactions: string[];
metadata?: Record<string, any>;
}
/**
* Transaction tracking registry
*/
declare class TransactionTracker {
private transactions;
private eventGroups;
private stepTransactions;
/**
* Generate a new transaction ID
* @returns Unique transaction identifier
*/
generateTransactionId(): string;
/**
* Generate a new event group ID
* @returns Unique event group identifier
*/
generateEventGroupId(): string;
/**
* Start a new transaction
* @param workflowId - The workflow identifier
* @param eventGroupId - Optional event group ID
* @param metadata - Optional metadata
* @returns Transaction information
*/
startTransaction(workflowId: string, eventGroupId?: string, metadata?: Record<string, any>): TransactionInfo;
/**
* Update transaction status
* @param transactionId - Transaction identifier
* @param status - New status
*/
updateTransactionStatus(transactionId: string, status: TransactionInfo['status']): void;
/**
* Start tracking a step
* @param transactionId - Transaction identifier
* @param stepId - Step identifier
* @param input - Step input
* @returns Step transaction info
*/
startStep(transactionId: string, stepId: string, input?: any): StepTransactionInfo;
/**
* Complete a step
* @param transactionId - Transaction identifier
* @param stepId - Step identifier
* @param output - Step output
* @param status - Final status
*/
completeStep(transactionId: string, stepId: string, output?: any, status?: StepTransactionInfo['status']): void;
/**
* Mark a step as failed
* @param transactionId - Transaction identifier
* @param stepId - Step identifier
* @param error - Error message
*/
failStep(transactionId: string, stepId: string, error: string): void;
/**
* Get transaction information
* @param transactionId - Transaction identifier
* @returns Transaction info or undefined
*/
getTransaction(transactionId: string): TransactionInfo | undefined;
/**
* Get all transactions for a workflow
* @param workflowId - Workflow identifier
* @returns Array of transactions
*/
getTransactionsByWorkflow(workflowId: string): TransactionInfo[];
/**
* Create or get an event group
* @param eventGroupId - Optional event group ID (generates new if not provided)
* @param metadata - Optional metadata
* @returns Event group
*/
createEventGroup(eventGroupId?: string, metadata?: Record<string, any>): EventGroup;
/**
* Add a transaction to an event group
* @param eventGroupId - Event group identifier
* @param transactionId - Transaction identifier
*/
addTransactionToEventGroup(eventGroupId: string, transactionId: string): void;
/**
* Get event group information
* @param eventGroupId - Event group identifier
* @returns Event group or undefined
*/
getEventGroup(eventGroupId: string): EventGroup | undefined;
/**
* Get all transactions in an event group
* @param eventGroupId - Event group identifier
* @returns Array of transactions
*/
getEventGroupTransactions(eventGroupId: string): TransactionInfo[];
/**
* Clean up old transactions and event groups
* @param olderThanHours - Remove items older than this many hours
*/
cleanup(olderThanHours?: number): void;
/**
* Get transaction statistics
* @returns Transaction statistics
*/
getStatistics(): {
totalTransactions: number;
totalEventGroups: number;
totalSteps: number;
statusCounts: Record<string, number>;
};
}
/**
* Global transaction tracker instance
*/
declare const transactionTracker: TransactionTracker;
/**
* Transaction context for workflow execution
*/
declare class TransactionContext {
readonly transactionId: string;
readonly workflowId: string;
readonly eventGroupId?: string | undefined;
constructor(transactionId: string, workflowId: string, eventGroupId?: string | undefined);
/**
* Start tracking a step
* @param stepId - Step identifier
* @param input - Step input
* @returns Step transaction info
*/
startStep(stepId: string, input?: any): StepTransactionInfo;
/**
* Complete a step
* @param stepId - Step identifier
* @param output - Step output
* @param status - Final status
*/
completeStep(stepId: string, output?: any, status?: StepTransactionInfo['status']): void;
/**
* Mark a step as failed
* @param stepId - Step identifier
* @param error - Error message
*/
failStep(stepId: string, error: string): void;
/**
* Get transaction information
* @returns Transaction info
*/
getTransaction(): TransactionInfo | undefined;
/**
* Update transaction status
* @param status - New status
*/
updateStatus(status: TransactionInfo['status']): void;
}
/**
* Create a new transaction context
* @param workflowId - Workflow identifier
* @param eventGroupId - Optional event group ID
* @param metadata - Optional metadata
* @returns Transaction context
*/
declare function createTransactionContext(workflowId: string, eventGroupId?: string, metadata?: Record<string, any>): TransactionContext;
/**
* Enhanced type system with flow options and result types
* Provides comprehensive typing for advanced workflow features
*/
/**
* Flow run options for workflow execution
*/
interface FlowRunOptions<TData = any> {
input: TData;
container?: WorkflowContainer;
scope?: any;
transactionId?: string;
eventGroupId?: string;
metadata?: Record<string, any>;
timeout?: number;
retries?: number;
hooks?: {
beforeWorkflow?: (data: {
workflowId: string;
input: TData;
}) => Promise<void> | void;
afterWorkflow?: (data: {
workflowId: string;
result: any;
duration: number;
}) => Promise<void> | void;
onError?: (data: {
workflowId: string;
error: Error;
input: TData;
}) => Promise<void> | void;
};
}
/**
* Options for registering step success
*/
interface FlowRegisterStepSuccessOptions {
stepId: string;
output: any;
transactionId?: string;
metadata?: Record<string, any>;
timestamp?: Date;
}
/**
* Options for registering step failure
*/
interface FlowRegisterStepFailureOptions {
stepId: string;
error: Error | string;
transactionId?: string;
metadata?: Record<string, any>;
timestamp?: Date;
isPermanentFailure?: boolean;
}
/**
* Options for workflow cancellation
*/
interface FlowCancelOptions {
reason?: string;
transactionId?: string;
metadata?: Record<string, any>;
compensate?: boolean;
timeout?: number;
}
/**
* Comprehensive workflow result type
*/
interface WorkflowResult<TResult = any> {
result: TResult;
transactionId?: string;
eventGroupId?: string;
duration: number;
stepCount: number;
successfulSteps: number;
failedSteps: number;
skippedSteps: number;
metadata?: Record<string, any>;
errors?: Array<{
stepId: string;
error: string;
timestamp: Date;
}>;
timeline?: Array<{
stepId: string;
event: 'started' | 'completed' | 'failed' | 'skipped' | 'compensated';
timestamp: Date;
data?: any;
}>;
}
/**
* Enhanced step execution context with advanced features
*/
interface EnhancedStepExecutionContext {
container: WorkflowContainer;
metadata?: Record<string, any>;
workflowId: string;
stepId: string;
transactionContext?: TransactionContext;
retry?: {
attempt: number;
maxAttempts: number;
lastError?: Error;
};
timeout?: number;
hooks?: HookExecutionContext;
input?: any;
previousStepResults?: Map<string, any>;
}
/**
* Enhanced workflow execution context
*/
interface EnhancedWorkflowExecutionContext {
container?: WorkflowContainer;
scope?: any;
metadata?: Record<string, any>;
transactionContext?: TransactionContext;
timeout?: number;
retries?: number;
parallelism?: {
maxConcurrency?: number;
batchSize?: number;
};
hooks?: {
beforeWorkflow?: Function;
afterWorkflow?: Function;
onError?: Function;
beforeStep?: Function;
afterStep?: Function;
onStepError?: Function;
};
}
/**
* Step configuration options
*/
interface StepConfiguration {
timeout?: number;
retries?: number;
retryDelay?: number;
retryBackoff?: 'linear' | 'exponential';
idempotent?: boolean;
critical?: boolean;
async?: boolean;
priority?: number;
tags?: string[];
description?: string;
}
/**
* Workflow configuration options
*/
interface WorkflowConfiguration {
timeout?: number;
retries?: number;
maxParallelSteps?: number;
persistState?: boolean;
enableHooks?: boolean;
enableTransaction?: boolean;
description?: string;
version?: string;
tags?: string[];
deprecated?: boolean;
}
/**
* Enhanced step definition with configuration
*/
interface EnhancedStepDefinition<TInvokeInput = any, TInvokeResultOutput = any, TCompensateInput = any> {
id: string;
invoke: (input: TInvokeInput, context: EnhancedStepExecutionContext) => Promise<TInvokeResultOutput> | TInvokeResultOutput;
compensate?: (input: TCompensateInput, context: EnhancedStepExecutionContext) => Promise<void> | void;
config?: StepConfiguration;
}
/**
* Enhanced workflow definition with configuration
*/
interface EnhancedWorkflowDefinition<TData = any, TResult = any, THooks = any> {
id: string;
composer: (input: TData) => TResult;
config?: WorkflowConfiguration;
dependencies?: string[];
version?: string;
}
/**
* Workflow execution plan
*/
interface WorkflowExecutionPlan {
workflowId: string;
steps: Array<{
stepId: string;
dependencies: string[];
parallel: boolean;
conditionalOn?: string;
transformInput?: boolean;
}>;
parallelGroups: Array<{
groupId: string;
stepIds: string[];
}>;
criticalPath: string[];
estimatedDuration?: number;
}
/**
* Step execution statistics
*/
interface StepExecutionStats {
stepId: string;
totalExecutions: number;
successfulExecutions: number;
failedExecutions: number;
skippedExecutions: number;
averageDuration: number;
minDuration: number;
maxDuration: number;
lastExecuted?: Date;
errorRate: number;
}
/**
* Workflow execution statistics
*/
interface WorkflowExecutionStats {
workflowId: string;
totalExecutions: number;
successfulExecutions: number;
failedExecutions: number;
averageDuration: number;
minDuration: number;
maxDuration: number;
lastExecuted?: Date;
successRate: number;
stepStats: StepExecutionStats[];
}
/**
* Workflow health status
*/
interface WorkflowHealthStatus {
workflowId: string;
status: 'healthy' | 'warning' | 'critical' | 'unknown';
issues: Array<{
type: 'performance' | 'reliability' | 'configuration' | 'dependency';
severity: 'low' | 'medium' | 'high' | 'critical';
message: string;
stepId?: string;
}>;
metrics: {
successRate: number;
averageExecutionTime: number;
errorRate: number;
lastExecutionTime?: Date;
};
recommendations?: string[];
}
/**
* Workflow dependency graph
*/
interface WorkflowDependencyGraph {
workflowId: string;
nodes: Array<{
id: string;
type: 'step' | 'parallel' | 'conditional' | 'transform';
config?: any;
}>;
edges: Array<{
from: string;
to: string;
type: 'data' | 'control' | 'compensation';
condition?: string;
}>;
}
/**
* Enhanced exported workflow interface
*/
interface EnhancedExportedWorkflow<TData = any, TResult = any> {
workflowId: string;
version?: string;
config?: WorkflowConfiguration;
run(options: FlowRunOptions<TData>): Promise<WorkflowResult<TResult>>;
runWithScope(scope: any, options: FlowRunOptions<TData>): Promise<WorkflowResult<TResult>>;
registerStepSuccess(options: FlowRegisterStepSuccessOptions): Promise<{
success: boolean;
}>;
registerStepFailure(options: FlowRegisterStepFailureOptions): Promise<{
success: boolean;
}>;
cancel(options?: FlowCancelOptions): Promise<{
cancelled: boolean;
}>;
pause(transactionId: string): Promise<{
paused: boolean;
}>;
resume(transactionId: string): Promise<{
resumed: boolean;
}>;
getExecutionPlan(): WorkflowExecutionPlan;
getDependencyGraph(): WorkflowDependencyGraph;
getStats(): WorkflowExecutionStats;
getHealth(): WorkflowHealthStatus;
updateConfig(config: Partial<WorkflowConfiguration>): void;
getConfig(): WorkflowConfiguration;
}
/**
* Workflow registry interface with enhanced features
*/
interface EnhancedWorkflowRegistry {
register<TData = any, TResult = any>(workflow: EnhancedWorkflowDefinition<TData, TResult>): void;
get<TData = any, TResult = any>(workflowId: string): EnhancedWorkflowDefinition<TData, TResult> | undefined;
has(workflowId: string): boolean;
remove(workflowId: string): boolean;
getAll(): EnhancedWorkflowDefinition[];
clear(): void;
getByTag(tag: string): EnhancedWorkflowDefinition[];
getByVersion(workflowId: string, version: string): EnhancedWorkflowDefinition | undefined;
getVersions(workflowId: string): string[];
deprecate(workflowId: string, version?: string): void;
getStats(): Array<{
workflowId: string;
executions: number;
lastUsed: Date;
}>;
}
/**
* Step registry interface with enhanced features
*/
interface EnhancedStepRegistry {
register<TInput = any, TOutput = any, TCompensate = any>(step: EnhancedStepDefinition<TInput, TOutput, TCompensate>): void;
get<TInput = any, TOutput = any, TCompensate = any>(stepId: string): EnhancedStepDefinition<TInput, TOutput, TCompensate> | undefined;
has(stepId: string): boolean;
remove(stepId: string): boolean;
getAll(): EnhancedStepDefinition[];
clear(): void;
getByTag(tag: string): EnhancedStepDefinition[];
getCritical(): EnhancedStepDefinition[];
getStats(): Array<{
stepId: string;
usageCount: number;
lastUsed: Date;
}>;
}
/**
* Event types for workflow execution
*/
declare enum WorkflowEventType {
WORKFLOW_STARTED = "workflow.started",
WORKFLOW_COMPLETED = "workflow.completed",
WORKFLOW_FAILED = "workflow.failed",
WORKFLOW_CANCELLED = "workflow.cancelled",
WORKFLOW_PAUSED = "workflow.paused",
WORKFLOW_RESUMED = "workflow.resumed",
STEP_STARTED = "step.started",
STEP_COMPLETED = "step.completed",
STEP_FAILED = "step.failed",
STEP_SKIPPED = "step.skipped",
STEP_RETRYING = "step.retrying",
STEP_COMPENSATING = "step.compensating",
STEP_COMPENSATED = "step.compensated"
}
/**
* Workflow event data
*/
interface WorkflowEvent {
type: WorkflowEventType;
workflowId: string;
stepId?: string;
transactionId?: string;
timestamp: Date;
data?: any;
metadata?: Record<string, any>;
}
declare function createStep<TInvokeInput = any, TInvokeResultOutput = any, TInvokeResultCompensateInput = TInvokeResultOutput>(nameOrConfig: string | object, invokeFn: InvokeFn<TInvokeInput, TInvokeResultOutput, TInvokeResultCompensateInput>, compensateFn?: CompensateFn<TInvokeResultCompensateInput>): StepFunction<TInvokeInput, TInvokeResultOutput>;
declare function createWorkflow<TData = any, TResult = any, THooks = any>(nameOrConfig: string | object, composer: WorkflowComposer<TData, TResult, THooks>): ReturnWorkflow<TData, TResult, THooks>;
/**
* Composer utilities for advanced workflow composition
* Provides parallelize, when, and transform functions for workflow composition
*/
/**
* Symbol used to identify parallel execution groups
*/
declare const PARALLEL_SYMBOL: unique symbol;
/**
* Symbol used to identify conditional execution
*/
declare const CONDITIONAL_SYMBOL: unique symbol;
/**
* Symbol used to identify data transformations
*/
declare const TRANSFORM_SYMBOL: unique symbol;
/**
* Parallel execution wrapper for steps
*/
interface ParallelWrapper<T extends any[]> {
readonly __isParallel: true;
readonly __parallelSymbol: typeof PARALLEL_SYMBOL;
readonly steps: T;
}
/**
* Conditional execution wrapper
*/
interface ConditionalWrapper<T> {
readonly __isConditional: true;
readonly __conditionalSymbol: typeof CONDITIONAL_SYMBOL;
readonly condition: T;
readonly checkFn: (input: T) => boolean | Promise<boolean>;
then<R extends any[]>(...steps: R): ConditionalResult<T, R>;
}
/**
* Conditional result with steps to execute
*/
interface ConditionalResult<T, R extends any[]> {
readonly __isConditionalResult: true;
readonly __conditionalSymbol: typeof CONDITIONAL_SYMBOL;
readonly condition: T;
readonly checkFn: (input: T) => boolean | Promise<boolean>;
readonly steps: R;
readonly elseSteps?: any[];
readonly elseConditions?: Array<{
condition: any;
checkFn: (input: any) => boolean | Promise<boolean>;
steps: any[];
}>;
else<E extends any[]>(...steps: E): ConditionalResultWithElse<T, R, E>;
elseIf<C, E extends any[]>(condition: C, checkFn?: (input: C) => boolean | Promise<boolean>): ConditionalElseIf<T, R, C, E>;
}
/**
* Conditional result with else clause
*/
interface ConditionalResultWithElse<T, R extends any[], E extends any[]> {
readonly __isConditionalResult: true;
readonly __conditionalSymbol: typeof CONDITIONAL_SYMBOL;
readonly condition: T;
readonly checkFn: (input: T) => boolean | Promise<boolean>;
readonly steps: R;
readonly elseSteps: E;
readonly elseConditions?: Array<{
condition: any;
checkFn: (input: any) => boolean | Promise<boolean>;
steps: any[];
}>;
}
/**
* Conditional elseIf builder
*/
interface ConditionalElseIf<T, R extends any[], C, E extends any[]> {
then<S extends any[]>(...steps: S): ConditionalResultWithElseIf<T, R, C, S>;
}
/**
* Conditional result with elseIf clause
*/
interface ConditionalResultWithElseIf<T, R extends any[], C, S extends any[]> {
readonly __isConditionalResult: true;
readonly __conditionalSymbol: typeof CONDITIONAL_SYMBOL;
readonly condition: T;
readonly checkFn: (input: T) => boolean | Promise<boolean>;
readonly steps: R;
readonly elseSteps?: any[];
readonly elseConditions: Array<{
condition: any;
checkFn: (input: any) => boolean | Promise<boolean>;
steps: any[];
}>;
else<E extends any[]>(...steps: E): ConditionalResultWithElse<T, R, E>;
elseIf<NC, NS extends any[]>(condition: NC, checkFn?: (input: NC) => boolean | Promise<boolean>): ConditionalElseIf<T, R, NC, NS>;
}
/**
* Transform wrapper for data transformation
*/
interface TransformWrapper<TInput, TOutput> {
readonly __isTransform: true;
readonly __transformSymbol: typeof TRANSFORM_SYMBOL;
readonly input: TInput;
readonly transformFn: (input: TInput) => TOutput;
}
/**
* Execute multiple steps in parallel
* @param steps - Array of steps to execute in parallel
* @returns Parallel wrapper containing all steps
*/
declare function parallelize<T extends any[]>(...steps: T): ParallelWrapper<T>;
/**
* Conditional execution of steps based on input
* @param condition - The input to evaluate
* @param checkFn - Function to determine if condition is met (can be async)
* @returns Conditional wrapper
*/
declare function when<T>(condition: T, checkFn?: (input: T) => boolean | Promise<boolean>): ConditionalWrapper<T>;
/**
* Transform data using a transformation function
* @param input - Input data to transform
* @param transformFn - Function to transform the data
* @returns Transform wrapper
*/
declare function transform<TInput, TOutput>(input: TInput, transformFn: (input: TInput) => TOutput): TransformWrapper<TInput, TOutput>;
/**
* Switch-case style conditional execution
* @param switchValue - The value to switch on
* @param cases - Array of case objects with value and steps
* @param defaultSteps - Optional default steps if no cases match
* @returns Conditional result for switch-case execution
*/
declare function switchCase<T>(switchValue: T, cases: Array<{
value: T | ((input: T) => boolean | Promise<boolean>);
steps: any[];
}>, defaultSteps?: any[]): any;
/**
* Type guards for composer utilities
*/
declare function isParallelWrapper(value: any): value is ParallelWrapper<any[]>;
declare function isConditionalWrapper(value: any): value is ConditionalWrapper<any>;
declare function isConditionalResult(value: any): value is ConditionalResult<any, any[]>;
declare function isTransformWrapper(value: any): value is TransformWrapper<any, any>;
/**
* Utility to check if a value is any kind of composer wrapper
*/
declare function isComposerWrapper(value: any): boolean;
/**
* Global Workflow Registry for static workflow management
* Global workflow management system
*/
/**
* Global workflow registry providing static methods for workflow management
*/
declare class FlowtifyWorkflow {
private static registry;
private static maxWorkflows;
/**
* Register a workflow globally
* @param workflowId - Unique identifier for the workflow
* @param exportedWorkflow - The exported workflow function
*/
static registerWorkflow<TData = any, TResult = any, THooks = any>(workflowId: string, exportedWorkflow: ReturnWorkflow<TData, TResult, THooks>): void;
/**
* Get a registered workflow by ID
* @param workflowId - The workflow identifier
* @returns The workflow function or undefined if not found
*/
static getWorkflow<TData = any, TResult = any, THooks = any>(workflowId: string): ReturnWorkflow<TData, TResult, THooks> | undefined;
/**
* Check if a workflow is registered
* @param workflowId - The workflow identifier
* @returns True if workflow exists
*/
static hasWorkflow(workflowId: string): boolean;
/**
* Get all registered workflow IDs
* @returns Array of workflow identifiers
*/
static getAllWorkflowIds(): string[];
/**
* Remove a workflow from the registry
* @param workflowId - The workflow identifier
* @returns True if workflow was removed, false if it didn't exist
*/
static removeWorkflow(workflowId: string): boolean;
/**
* Clear all registered workflows
*/
static clearAll(): void;
/**
* Get the number of registered workflows
* @returns Count of registered workflows
*/
static count(): number;
/**
* Configure the maximum registry size
* @param maxSize - Maximum number of workflows to keep (default: 10,000)
* @param recreateRegistry - Whether to recreate the registry with new size
*/
static setMaxWorkflows(maxSize?: number, recreateRegistry?: boolean): void;
/**
* Get the current maximum workflow limit
* @returns Maximum number of workflows
*/
static getMaxWorkflows(): number;
/**
* Get registry statistics
* @returns Registry stats including size and fill ratio
*/
static getStats(): any;
}
/**
* Create and automatically register a workflow globally
* @param workflowId - Unique identifier for the workflow
* @param composer - The workflow composer function
* @returns The workflow function
*/
declare function createAndRegisterWorkflow<TData = any, TResult = any, THooks = any>(workflowId: string, composer: WorkflowComposer<TData, TResult, THooks>): ReturnWorkflow<TData, TResult, THooks>;
/**
* Export a workflow for external use (similar to Medusa's exportWorkflow)
* @param workflowId - The workflow identifier
* @param composer - The workflow composer function
* @returns Enhanced workflow with export capabilities
*/
declare function exportWorkflow<TData = any, TResult = any, THooks = any>(workflowId: string, composer?: WorkflowComposer<TData, TResult, THooks>): ExportedWorkflow<TData, TResult>;
/**
* Create a contextual workflow runner that automatically uses a default container
* @param workflowId - The workflow identifier
* @param defaultContainer - Default container to use if none provided
* @returns Contextual workflow runner
*/
declare function createContextualWorkflowRunner<TData = any, TResult = any>(workflowId: string, defaultContainer?: any): {
run: (input: {
input: TData;
[key: string]: any;
}) => Promise<{
result: TResult;
}>;
runWithScope: (scope: any, input: {
input: TData;
[key: string]: any;
}) => Promise<{
result: TResult;
}>;
};
/**
* Enhanced workflow interface with export capabilities
*/
interface ExportedWorkflow<TData = any, TResult = any> {
workflowId: string;
run(input: {
input: TData;
[key: string]: any;
}): Promise<{
result: TResult;
}>;
runWithScope(scope: any, input: {
input: TData;
[key: string]: any;
}): Promise<{
result: TResult;
}>;
registerStepSuccess(stepId: string, output: any, options?: any): Promise<{
success: boolean;
}>;
registerStepFailure(stepId: string, error: any, options?: any): Promise<{
success: boolean;
}>;
cancel(options?: any): Promise<{
cancelled: boolean;
}>;
}
/**
* Value resolution utilities for complex workflow data handling
* Provides utilities for resolving nested data structures and workflow-specific values
*/
/**
* Workflow-specific symbols for special value types
*/
declare const WorkflowSymbols: {
readonly STEP_RESULT: symbol;
readonly WORKFLOW_INPUT: symbol;
readonly CONTAINER_VALUE: symbol;
readonly DEFERRED_VALUE: symbol;
};
/**
* Step result reference for lazy evaluation
*/
interface StepResultReference {
readonly __symbol: typeof WorkflowSymbols.STEP_RESULT;
readonly stepId: string;
readonly propertyPath?: string[];
}
/**
* Workflow input reference
*/
interface WorkflowInputReference {
readonly __symbol: typeof WorkflowSymbols.WORKFLOW_INPUT;
readonly propertyPath?: string[];
}
/**
* Container value reference
*/
interface ContainerValueReference {
readonly __symbol: typeof WorkflowSymbols.CONTAINER_VALUE;
readonly serviceKey: string | symbol;
readonly propertyPath?: string[];
}
/**
* Deferred value reference for complex computations
*/
interface DeferredValueReference<T = any> {
readonly __symbol: typeof WorkflowSymbols.DEFERRED_VALUE;
readonly resolver: () => Promise<T> | T;
readonly dependencies?: string[];
}
/**
* Union type for all resolvable values
*/
type ResolvableValue = StepResultReference | WorkflowInputReference | ContainerValueReference | DeferredValueReference;
/**
* Value resolution context
*/
interface ValueResolutionContext {
workflowInput?: any;
stepResults?: Map<string, any>;
container?: any;
metadata?: Record<string, any>;
}
/**
* Create a reference to a step result
* @param stepId - The step identifier
* @param propertyPath - Optional property path within the result
* @returns Step result reference
*/
declare function stepResult(stepId: string, propertyPath?: string[]): StepResultReference;
/**
* Create a reference to workflow input
* @param propertyPath - Optional property path within the input
* @returns Workflow input reference
*/
declare function workflowInput(propertyPath?: string[]): WorkflowInputReference;
/**
* Create a reference to a container value
* @param serviceKey - The service key to resolve from container
* @param propertyPath - Optional property path within the service
* @returns Container value reference
*/
declare function containerValue(serviceKey: string | symbol, propertyPath?: string[]): ContainerValueReference;
/**
* Create a deferred value reference
* @param resolver - Function to resolve the value
* @param dependencies - Optional list of step dependencies
* @returns Deferred value reference
*/
declare function deferredValue<T>(resolver: () => Promise<T> | T, dependencies?: string[]): DeferredValueReference<T>;
/**
* Type guards for resolvable values
*/
declare function isStepResultReference(value: any): value is StepResultReference;
declare function isWorkflowInputReference(value: any): value is WorkflowInputReference;
declare function isContainerValueReference(value: any): value is ContainerValueReference;
declare function isDeferredValueReference(value: any): value is DeferredValueReference;
declare function isResolvableValue(value: any): value is ResolvableValue;
/**
* Resolve a value using the provided context
* @param value - The value to resolve
* @param context - Resolution context
* @returns Resolved value
*/
declare function resolveValue(value: any, context: ValueResolutionContext): Promise<any>;
/**
* Resolve multiple values in parallel
* @param values - Array of values to resolve
* @param context - Resolution context
* @returns Array of resolved values
*/
declare function resolveValues(values: any[], context: ValueResolutionContext): Promise<any[]>;
/**
* Create a value resolver function bound to a specific context
* @param context - Resolution context
* @returns Resolver function
*/
declare function createValueResolver(context: ValueResolutionContext): (value: any) => Promise<any>;
/**
* Utility to create property path arrays from dot notation
* @param path - Dot-separated property path (e.g., "user.profile.name")
* @returns Array of property names
*/
declare function createPropertyPath(path: string): string[];
/**
* Deep clone an object while preserving resolvable value references
* @param obj - Object to clone
* @returns Cloned object
*/
declare function deepCloneWithReferences(obj: any): any;
/**
* Check if an object contains any resolvable values
* @param obj - Object to check
* @returns True if contains resolvable values
*/
declare function containsResolvableValues(obj: any): boolean;
/**
* Memory management utilities for preventing memory leaks
*/
interface CleanupConfig {
transactionTTLHours?: number;
maxWorkflowRegistrySize?: number;
maxTransactionRegistrySize?: number;
cleanupIntervalMinutes?: number;
enableAutoCleanup?: boolean;
}
declare class MemoryManager {
private static instance;
private cleanupInterval?;
private config;
private constructor();
static getInstance(): MemoryManager;
configure(config: CleanupConfig): void;
startAutoCleanup(): void;
stopAutoCleanup(): void;
private restartAutoCleanup;
performCleanup(): Promise<void>;
private checkAndEvictFromRegistries;
getMemoryStats(): {
workflowRegistrySize: number;
globalWorkflowRegistrySize: number;
transactionStats: any;
memoryUsage: NodeJS.MemoryUsage;
};
dispose(): void;
}
declare const memoryManager: MemoryManager;
/**
* LRU (Least Recently Used) registry implementation
* Automatically evicts least recently used items when size limit is reached
*/
declare class LRURegistry<K, V> {
private maxSize;
private cache;
private accessOrder;
constructor(maxSize?: number);
set(key: K, value: V): void;
get(key: K): V | undefined;
has(key: K): boolean;
delete(key: K): boolean;
clear(): void;
size(): number;
keys(): K[];
values(): V[];
entries(): Array<[K, V]>;
private evictOldest;
setMaxSize(maxSize: number): void;
getStats(): {
size: number;
maxSize: number;
fillRatio: number;
};
}
/**
* Initialize Flowtify with memory management
*/
/**
* Initialize Flowtify with automatic memory management
* This should be called once at application startup
*
* @param config - Optional configuration for memory management
*/
declare function initializeFlowtify(config?: {
enableAutoCleanup?: boolean;
transactionTTLHours?: number;
maxWorkflowRegistrySize?: number;
cleanupIntervalMinutes?: number;
}): void;
/**
* Shutdown Flowtify and clean up resources
*/
declare function shutdownFlowtify(): void;
/**
* Workflow configuration utilities
*/
interface WorkflowConfig {
/**
* Maximum number of workflows to keep in memory (default: 10,000)
*/
maxWorkflows?: number;
/**
* Enable memory optimization features (default: true)
*/
enableMemoryOptimization?: boolean;
/**
* Enable workflow performance metrics (default: false)
*/
enableMetrics?: boolean;
}
/**
* Configure Flowtify workflow engine
* @param config - Configuration options
*/
declare function configureWorkflows(config?: WorkflowConfig): void;
/**
* Get current workflow configuration
*/
declare function getWorkflowConfig(): {
maxWorkflows: number;
currentWorkflows: number;
memoryUsage: string;
};
/**
* Comprehensive input validation utilities for Flowtify workflows
*/
/**
* Validation result interface
*/
interface ValidationResult {
isValid: boolean;
errors: string[];
}
/**
* Validate workflow ID
*/
declare function validateWorkflowId(workflowId: any): ValidationResult;
/**
* Validate step ID
*/
declare function validateStepId(stepId: any): ValidationResult;
/**
* Validate step configuration
*/
declare function validateStepConfig(nameOrConfig: any, invokeFn?: any, compensateFn?: any): ValidationResult;
/**
* Validate workflow configuration
*/
declare function validateWorkflowConfig(nameOrConfig: any, composer?: WorkflowComposer): ValidationResult;
/**
* Validate workflow input data
*/
declare function validateWorkflowInput(input: any): ValidationResult;
/**
* Validate execution context
*/
declare function validateExecutionContext(context: any): ValidationResult;
/**
* Validate workflow configuration settings
*/
declare function validateWorkflowSettings(config: any): ValidationResult;
/**
* Assert validation result and throw appropriate error
*/
declare function assertValidation(result: ValidationResult, context: string): void;
/**
* Validate and sanitize string input
*/
declare function sanitizeStringInput(input: any, maxLength?: number): string;
/**
* Deep validation of nested objects
*/
declare function validateNestedObject(obj: any, path?: string, maxDepth?: number, currentDepth?: number): ValidationResult;
/**
* Comprehensive error types for Flowtify workflows
* Provides clear, actionable error messages for developers
*/
/**
* Base error class for all Flowtify errors
*/
declare class FlowtifyError extends Error {
readonly code: string;
readonly timestamp: Date;
readonly context?: Record<string, any>;
constructor(message: string, code?: string, context?: Record<string, any>);
/**
* Convert error to JSON format
*/
toJSON(): Record<string, any>;
/**
* Get a developer-friendly error description
*/
getDescription(): string;
}
/**
* Workflow-specific validation errors
*/
declare class WorkflowValidationError extends FlowtifyError {
constructor(message: string, context?: Record<string, any>);
}
/**
* Step-specific validation errors
*/
declare class StepValidationError extends FlowtifyError {
constructor(message: string, context?: Record<string, any>);
}
/**
* Workflow execution errors
*/
declare class WorkflowExecutionError extends FlowtifyError {
readonly workflowId: string;
readonly stepId?: string;
readonly originalError?: Error;
constructor(message: string, workflowId: string, stepId?: string, originalError?: Error);
}
/**
* Step execution errors
*/
declare class StepExecutionError extends FlowtifyError {
readonly stepId: string;
readonly workflowId?: string;
readonly originalError?: Error;
readonly isPermanentFailure: boolean;
constructor(message: string, stepId: string, workflowId?: string, originalError?: Error, isPermanentFailure?: boolean);
}
/**
* Workflow timeout errors
*/
declare class WorkflowTimeoutError extends FlowtifyError {
readonly workflowId: string;
readonly timeoutMs: number;
constructor(workflowId: string, timeoutMs: number);
}
/**
* Step timeout errors
*/
declare class StepTimeoutError extends FlowtifyError {
readonly stepId: string;
readonly workflowId?: string;
readonly timeoutMs: number;
constructor(stepId: string, timeoutMs: number, workflowId?: string);
}
/**
* Container resolution errors
*/
declare class ContainerResolutionError extends FlowtifyError {
readonly serviceName: string;
readonly containerType?: string;
constructor(serviceName: string, containerType?: string);
}
/**
* Workflow registry errors
*/
declare class WorkflowRegistryError extends FlowtifyError {
readonly operation: string;
readonly workflowId?: string;
constructor(message: string, operation: string, workflowId?: string);
}
/**
* Configuration errors
*/
declare class ConfigurationError extends FlowtifyError {
readonly configKey?: string;
readonly configValue?: any;
constructor(message: string, configKey?: string, configValue?: any);
}
/**
* Memory management errors
*/
declare class MemoryError extends FlowtifyError {
readonly memoryUsage?: number;
readonly limit?: number;
constructor(message: string, memoryUsage?: number, limit?: number);
}
/**
* Compensation errors
*/
declare class CompensationError extends FlowtifyError {
readonly stepId: string;
readonly workflowId?: string;
readonly originalError?: Error;
constructor(stepId: string, originalError?: Error, workflowId?: string);
}
/**
* Utility functions for error handling
*/
declare class ErrorUtils {
/**
* Check if an error is a Flowtify error
*/
static isFlowtifyError(error: any): error is FlowtifyError;
/**
* Check if an error is retryable
*/
static isRetryableError(error: any): boolean;
/**
* Extract meaningful error message from any error
*/
static extractErrorMessage(error: any): string;
/**
* Create a sanitized error object for logging
*/
static sanitizeError(error: any): Record<string, any>;
/**
* Wrap an unknown error into a FlowtifyError
*/
static wrapError(error: any, context?: string): FlowtifyError;
}
/**
* Error factory for creating common errors
*/
declare class ErrorFactory {
static workflowNotFound(workflowId: string): WorkflowRegistryError;
static stepNotFound(stepId: string, workflowId?: string): StepExecutionError;
static invalidWorkflowId(workflowId: any): WorkflowValidationError;
static invalidStepId(stepId: any): StepValidationError;
static containerServiceNotFound(serviceName: string, containerType?: string): ContainerResolutionError;
static workflow