O Motor
O WorkflowEngine é o coração da biblioteca. É uma classe stateless (sem estado) responsável por orquestrar a execução de um workflow com base em uma WorkflowDefinition (definição de workflow). Seu objetivo primário é transicionar entre estados, gerando um novo Snapshot imutável a cada passo.
Modelo de Execução: Passo a Passo
Para garantir a compatibilidade com ambientes serverless e outros ambientes efêmeros, o motor não executa um workflow inteiro em um único processo de longa duração. Em vez disso, ele opera com base em um modelo de passo a passo.
O método principal, execute, recebe o estado atual (seja um objeto Snapshot ou um initialNodeId) e executa o workflow passo a passo até que uma pausa, erro ou a finalização seja encontrada.
import { WorkflowEngine } from "@refluxo/core";
const engine = new WorkflowEngine({ workflow, nodeDefinitions });
// Iniciando uma nova execução
let snapshot = await engine.execute({
initialNodeId: "start-node",
workflowId: "my-first-workflow"
});
// Retomando uma execução pausada
let resumedSnapshot = await engine.execute({
snapshot: pausedSnapshot,
externalPayload: { approved: true } // Dados para o nó que está aguardando
});Como Funciona
- Inicialização: O método
executerecebe o estado inicial. Se for uma nova execução, ele cria umSnapshotnovo. Se estiver retomando, ele carrega o snapshot fornecido e define seu status paraactive. - Loop de Execução: Ele executa um loop
whileque continua enquanto oSnapshot.statusfor"active". executeStep: Dentro do loop, ele chamaexecuteStep, que é responsável por executar um único nó.- Executa os Middlewares configurados.
- Middlewares podem interceptar a execução antes e depois do
executordo nó. - Valida a entrada (input) com base no schema do nó.
- Chama a função
executordo nó. - Valida a saída (output).
- Determina o próximo nó a ser executado.
- Retorna um novo
Snapshotcom o estado atualizado.
O Objeto globals
O método execute também aceita um objeto opcional globals. Esses dados são passados diretamente para o context de todos os middlewares, mas não são armazenados no Snapshot. Este é o mecanismo para injetar dados sensíveis (segredos) ou configurações específicas do ambiente na execução do workflow sem persisti-los.
await engine.execute({
snapshot,
globals: {
API_KEY: process.env.API_KEY,
DB_CONNECTION: dbConnection
}
});- Finalização: O loop termina quando o
statusmuda parapaused,completed,failedouerror. OSnapshotfinal é então retornado.
Este modelo garante que cada passo seja uma transação atômica, tornando todo o processo altamente resiliente e observável.
Transform Engines
O motor utiliza um pipeline de Transform Engines para processar dados antes e depois da execução de um nó. Isso permite comportamentos dinâmicos, como resolução de expressões, injeção de segredos, criptografia/descriptografia ou manipulação de dados personalizada.
O WorkflowEngine aceita um array de transformEngines em seu construtor:
import { createJexlTransformEngine } from "@refluxo/jexl-transformer";
const engine = new WorkflowEngine({
workflow,
nodeDefinitions,
transformEngines: [createJexlTransformEngine(), seuTransformEngineCustomizado]
});O Padrão Transform Engine
O Refluxo usa um padrão de middleware estilo Koa. Um transformEngine é uma função que recebe um context e uma função next.
- Antes de
await next(): Executa antes que oexecutorde um nó seja chamado. Usado para resolver expressões (como Jexl) ou descriptografar dados recebidos. - Depois de
await next(): Executa depois que oexecutorde um nó termina. Usado para filtrar resultados, criptografar dados ou otimizar o armazenamento.
Por padrão, o motor não inclui nenhum transformEngine. Você geralmente vai querer adicionar createJexlTransformEngine para lidar com a resolução de expressões.