swfme
v0.1.2
Published
Process-Oriented Programming Framework for TypeScript - Workflow Management Engine
Maintainers
Readme
sWFME - TypeScript
Process-Oriented Programming Framework for TypeScript
A modern workflow management engine inspired by the original sWFME C# implementation (2010). Build complex workflows by composing atomic processes with sequential and parallel execution.
Features
- Process Abstraction - Define atomic and orchestrated processes
- Type-Safe Parameters - Strongly typed input/output parameters
- Sequential & Parallel Execution - Compose workflows with execution flags
- Event-Driven Monitoring - Real-time process events via EventBus
- Metrics Collection - Automatic performance tracking
- Process Registry - Dynamic workflow discovery and creation
Installation
npm install swfmeQuick Start
1. Define Atomic Processes
import {
AtomarProcess,
InputParameter,
OutputParameter,
} from 'swfme';
class ProcessAdd extends AtomarProcess {
defineParameters(): void {
this.input.add(new InputParameter({ name: 'a', type: 'number' }));
this.input.add(new InputParameter({ name: 'b', type: 'number' }));
this.output.add(new OutputParameter({ name: 'sum', type: 'number' }));
}
async executeImpl(): Promise<void> {
const a = this.input.get<'number'>('a')!.value!;
const b = this.input.get<'number'>('b')!.value!;
this.output.get<'number'>('sum')!.value = a + b;
}
}2. Create Orchestrated Workflows
import {
OrchestratedProcess,
SEQUENTIAL,
PARALLEL,
} from 'swfme';
class MathPipeline extends OrchestratedProcess {
defineParameters(): void {
this.input.add(new InputParameter({ name: 'a', type: 'number' }));
this.input.add(new InputParameter({ name: 'b', type: 'number' }));
this.output.add(new OutputParameter({ name: 'result', type: 'number' }));
}
orchestrate(): void {
// Step 1: Add
const add = new ProcessAdd('Add');
this.connectParam(this.input.get('a')!, add.input.get('a')!);
this.connectParam(this.input.get('b')!, add.input.get('b')!);
this.addChild(add, SEQUENTIAL);
// Step 2: Multiply by 2
const multiply = new ProcessMultiply('Multiply');
this.connectParam(add.output.get('sum')!, multiply.input.get('value')!);
multiply.input.get('factor')!.value = 2;
this.addChild(multiply, SEQUENTIAL);
// Output derivation
this.connectParam(multiply.output.get('result')!, this.output.get('result')!);
}
}3. Execute Workflows
const pipeline = new MathPipeline();
pipeline.input.get('a')!.value = 5;
pipeline.input.get('b')!.value = 3;
const success = await pipeline.execute();
if (success) {
console.log('Result:', pipeline.output.get('result')!.value); // 16
}Execution Flags
SEQUENTIAL- Execute one after anotherPARALLEL- Execute concurrently
// Sequential execution
this.addChild(process1, SEQUENTIAL);
this.addChild(process2, SEQUENTIAL); // Waits for process1
// Parallel execution
this.addChild(processA, PARALLEL);
this.addChild(processB, PARALLEL); // Runs simultaneously
this.addChild(processC, SEQUENTIAL); // Waits for A and BEvent Monitoring
import { eventBus } from 'swfme';
eventBus.subscribe('process.started', (event) => {
console.log(`Started: ${event.processName}`);
});
eventBus.subscribe('process.completed', (event) => {
console.log(`Completed: ${event.processName} in ${event.executionTimeMs}ms`);
});
eventBus.subscribe('process.failed', (event) => {
console.log(`Failed: ${event.processName} - ${event.error}`);
});Metrics
import { metricsCollector } from 'swfme';
// Get summary
const summary = metricsCollector.getSummary();
console.log(`Total: ${summary.totalProcesses}`);
console.log(`Success Rate: ${(summary.successRate * 100).toFixed(1)}%`);
// Get per-process metrics
const metrics = metricsCollector.getMetrics(process.id);
console.log(`Execution Time: ${metrics?.executionTimeMs}ms`);Process Registry
import { processRegistry } from 'swfme';
// Register processes
processRegistry.register(MathPipeline);
processRegistry.register(DataPipeline, 'CustomName');
// List registered processes
const processes = processRegistry.listProcesses();
// Create by name
const workflow = processRegistry.create('MathPipeline');Parameter Types
Supported parameter types:
'string''number''boolean''object''array''any'
this.input.add(new InputParameter({
name: 'data',
type: 'array',
required: true,
description: 'Input data array'
}));Examples
Run the included examples:
npm run example # Simple workflow
npm run example:math # Math pipelineDevelopment
# Install dependencies
npm install
# Build
npm run build
# Run tests
npm test
# Watch mode
npm run devArchitecture
swfme/
├── core/
│ ├── process.ts # Process, AtomarProcess, OrchestratedProcess
│ └── parameters.ts # Parameter, ParameterSet
├── monitoring/
│ ├── event-bus.ts # EventBus for process events
│ └── metrics.ts # MetricsCollector
└── registry/
└── process-registry.ts # ProcessRegistryLicense
MIT
Author
Alex Popovic (Arkturian) - 2025
Modernized from the original sWFME C# implementation (2010).
