Skip to content
Prose v0.3.3

Observers

All hooks are optional. Implement only the ones you need.

interface FlowObserver {
onFlowStart?(flowName: string, input: unknown): void;
onFlowComplete?(flowName: string, output: unknown, duration: number): void;
onFlowError?(flowName: string, error: Error, duration: number): void;
onFlowBreak?(
flowName: string,
breakStepName: string,
returnValue: unknown,
duration: number
): void;
onStepStart?(stepName: string, context: FlowContext): void;
onStepComplete?(
stepName: string,
result: unknown,
duration: number,
context: FlowContext
): void;
onStepError?(
stepName: string,
error: Error,
duration: number,
context: FlowContext
): void;
onStepRetry?(
stepName: string,
attempt: number,
maxAttempts: number,
error: Error
): void;
onStepSkipped?(stepName: string, context: FlowContext): void;
}

Console-based logging. Accepts an optional logger interface.

import { DefaultObserver } from '@celom/prose';
// Uses console by default
const observer = new DefaultObserver();
// Custom logger
const observer = new DefaultObserver({
debug: (msg) => myLogger.debug(msg),
error: (msg, err) => myLogger.error(msg, err),
warn: (msg) => myLogger.warn(msg),
});

Silent observer — all hooks are no-ops. Useful as a default value to avoid null checks.

import { NoOpObserver } from '@celom/prose';
const observer = new NoOpObserver();

Structured JSON logging with any Pino-compatible logger.

import { PinoFlowObserver } from '@celom/prose';
import pino from 'pino';
const observer = new PinoFlowObserver(pino());

Works with Fastify’s built-in logger:

fastify.post('/orders', async (request) => {
const observer = new PinoFlowObserver(request.log);
await flow.execute(input, deps, { observer });
});

Each hook produces a structured log entry with flow name, step name, duration, and contextual data — ready for log aggregation and analysis.