Event-driven NestJS State Machine

Business state management with zero dependencies, no vendor lock-in, no infrastructure constraints — just your entities and their transitions.

npm versionnpm downloadslicense

Define, Transit, Done

Define workflows with decorators, transit states with a clean type-safe API

import { Workflow, OnEvent, Entity, Payload } from 'nestflow-js/core';@Workflow({  name: 'OrderWorkflow',  states: {    finals: ['delivered', 'cancelled'],    idles: ['pending_payment'],    failed: 'cancelled',  },  transitions: [    { event: 'PAYMENT_RECEIVED', from: ['pending_payment'], to: 'processing' },    { event: 'SHIP_ORDER', from: ['processing'], to: 'shipped' },    { event: 'CONFIRM_DELIVERY', from: ['shipped'], to: 'delivered' },    { event: 'CANCEL', from: ['pending_payment', 'processing'], to: 'cancelled' },  ],  entityService: 'entity.order',})export class OrderWorkflow {  @OnEvent('PAYMENT_RECEIVED')  async onPayment(@Entity() order, @Payload() payload) {    order.paidAt = new Date();    return order;  }}
import { OrchestratorService } from 'nestflow-js/core';@Injectable()export class OrderService {  constructor(private orchestrator: OrchestratorService) {}  async processPayment(orderId: string, payload: PaymentDto) {    const result = await this.orchestrator.transit({      event: 'PAYMENT_RECEIVED',      urn: orderId,      payload,      attempt: 0,    });    // result.status: 'final' | 'idle' | 'continued' | 'no_transition'    return result;  }}