Skip to content
Prose v0.3.2

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.