/** Lifecycle state for flows and steps */ type FlowState = 'running' | 'completed'; /** Final status of a completed flow */ type FlowStatus = 'success' | 'error'; /** Final status of a completed step */ type StepStatus = 'pending' | 'success' | 'error'; /** Normalized error shape — all errors converge to this */ interface NormalizedError { name: string; message: string; stack?: string; } /** Complete execution flow trace */ interface FlowTrace { id: string; name: string; parentId?: string; state: FlowState; status?: FlowStatus; tags: string[]; start: number; end?: number; error?: NormalizedError; context: Record; steps: StepTrace[]; meta?: { maxStepsExceeded: boolean; }; } /** Individual step within a flow */ interface StepTrace { id: string; name: string; sequence: number; state: FlowState; status: StepStatus; start: number; end?: number; data?: unknown; error?: NormalizedError; children: StepTrace[]; } /** Options for creating a flow */ interface FlowOptions { /** Enable/disable this flow. Default: true. If false, all operations are no-ops */ enabled?: boolean; /** Indexing labels for grouping/filtering */ tags?: string[]; /** Safety limit for step count (default: unlimited) */ maxSteps?: number; /** Sampling rate (0.0 to 1.0). Default: 1.0 (all flows logged). V2 */ sample?: number; /** Initial context to seed the flow with. V2 */ initialContext?: Record; } /** Contract for clock implementations */ interface Clock { now(): number; } /** Contract for ID generation strategies */ interface IdGenerator { generate(): string; } /** Public StepHandle interface */ interface StepHandle { success(): void; fail(error?: unknown): void; } /** Public FlowHandle interface */ interface FlowHandle { step(name: string, data?: Data): StepHandle; child(name: string): FlowHandle; tag(tag: string): void; tags(): string[]; setContext(context: Record): void; getContext(): Record; success(): void; fail(error?: unknown): void; /** V2: Async boundary helper — creates a step, executes fn, auto-completes */ run(name: string, fn: () => Promise | T): Promise; } /** Listener type for subscribe */ type FlowListener = (flow: Readonly) => void; /** * Register a listener that receives frozen snapshots on flow completion. * Zero overhead when no listeners registered. */ declare function subscribe(listener: FlowListener): () => void; /** * Normalizes any error input into a consistent NormalizedError shape. * * Rules: * - Error instance → { name, message, stack } * - String → { name: 'Error', message } * - Other → { name: 'Error', message: String(input) } * - undefined/no arg → { name: 'Error', message: 'Unknown error' } */ declare function normalizeError(input: unknown): NormalizedError; interface SerializeOptions { maxDepth?: number; maxLength?: number; } /** Safely serialize arbitrary data to JSON string. Never throws. */ declare function safeSerialize(data: unknown, options?: SerializeOptions): string; /** * NoOp StepHandle — reused across all disabled/guarded paths. * Type matches FlowHandle's StepHandle exactly. */ interface NoOpStepHandle { success(): void; fail(error?: unknown): void; } /** * NoOp FlowHandle — reused across all disabled/guarded paths. * Type signature matches FlowHandle interface exactly. */ interface NoOpFlowHandle { step(name: string, data?: unknown): NoOpStepHandle; child(name: string): NoOpFlowHandle; tag(name: string): void; tags(): string[]; setContext(context: Record): void; getContext(): Record; success(): void; fail(error?: unknown): void; run(name: string, fn: () => Promise): Promise; } declare const NOOP_STEP: NoOpStepHandle; declare const NOOP_FLOW: NoOpFlowHandle; /** * Set the global enabled state for all new flows. V2 feature. * Affects only flows created after this call — in-flight flows retain their state. * * @param enabled - true to enable, false to disable all new flows */ declare function setEnabled(enabled: boolean): void; /** * Get the current global enabled state. V2 feature. */ declare function isEnabled(): boolean; /** * Override the default ID generator. V2 feature. * Affects only flows created after this call. * * @param idGen - The ID generator to use */ declare function setIdGenerator(idGen: IdGenerator): void; /** * Override the default clock. V2 feature. * Affects only flows created after this call. * * @param clock - The clock to use */ declare function setClock(clock: Clock): void; /** * Create a new execution flow with a human-readable name and optional configuration. * * @param name - Human-readable flow name * @param options - Optional configuration (enabled, tags, maxSteps, sample, initialContext) * @returns FlowHandle for interacting with the flow */ declare function createFlow(name: string, options?: FlowOptions): FlowHandle; /** * V3+: Zero-Friction better.log API — Unified Entry Point * * Core API (≤ 5 functions): * better.log() — Drop-in for console.log * better.flow() — Explicit flows * better.setEnabled() — Global toggle * better.subscribe() — Flow completion events * better.toJSON() — Export flow as JSON * * Transports (Phase 3): * better.log.toFile() — File transport (zero-dep) * better.log.toStream() — Stream transport * better.log.toHttp() — HTTP transport * * Production Features (Phase 3): * better.log.redact() — PII redaction * better.log.async() — Non-blocking async mode */ /** Options for individual log calls */ interface LogCallOptions { flow?: string; tags?: string[]; } /** Options for creating an explicit flow */ interface BetterFlowOptions { tags?: string[]; maxSteps?: number; sample?: number; initialContext?: Record; } declare function logFn(message: string, dataOrOptions?: unknown, options?: LogCallOptions): void; declare namespace logFn { var info: (message: string, dataOrOptions?: unknown, options?: LogCallOptions) => void; var warn: (message: string, dataOrOptions?: unknown, options?: LogCallOptions) => void; var error: (message: string, dataOrOptions?: unknown, options?: LogCallOptions) => void; var toFile: (path: string, options?: { append?: boolean; }) => void; var toStream: (stream: NodeJS.WriteStream) => void; var toHttp: (url: string, options?: { method?: string; headers?: Record; }) => void; var redact: (fields: string[]) => void; var async: (enabled?: boolean) => void; var setIdleTimeout: (ms: number) => void; var setFlowName: (name: string) => void; var setDefaultTags: (tags: string[]) => void; var activeFlow: () => FlowHandle | null; var flush: () => void; } declare function betterBase(message: string, dataOrOptions?: unknown, options?: LogCallOptions): void; declare namespace betterBase { var log: typeof logFn; var flow: (name: string, options?: BetterFlowOptions) => FlowHandle; var setIdleTimeout: (ms: number) => void; var setFlowName: (name: string) => void; var setDefaultTags: (tags: string[]) => void; var activeFlow: () => FlowHandle | null; var flush: () => void; var setEnabled: typeof setEnabled; var isEnabled: typeof isEnabled; var subscribe: typeof subscribe; var toJSON: (flow: FlowHandle | FlowTrace) => string; } /** Contract for all renderer implementations */ interface FlowRenderer { /** Render a frozen snapshot of a completed flow */ render(snapshot: Readonly): void; /** Optional name for debugging/identification — V2 */ name?: string; } /** * Set the global renderer. V2 feature. * @param renderer - The renderer to use for all new flows */ declare function setRenderer(renderer: FlowRenderer): void; /** * Get the current global renderer, or null if none set. V2 feature. */ declare function getRenderer(): FlowRenderer | null; /** * Serialize a FlowTrace to versioned JSON string. * Accepts either a FlowTrace directly or a FlowHandle (extracts .trace). * Omits undefined values for clean output. */ declare function toJSON(input: Readonly | { trace: Readonly; }): string; export { type BetterFlowOptions, type Clock, type FlowListener, type FlowOptions, type FlowRenderer, type FlowState, type FlowStatus, type FlowTrace, type IdGenerator, type LogCallOptions, NOOP_FLOW, NOOP_STEP, type NoOpFlowHandle, type NoOpStepHandle, type NormalizedError, type SerializeOptions, type StepStatus, type StepTrace, betterBase as better, createFlow, getRenderer, isEnabled, normalizeError, safeSerialize, setClock, setEnabled, setIdGenerator, setRenderer, subscribe, toJSON };