import type { Entry } from '../entry/entry.js';
/**
 * A single node in a trace/batch waterfall. Offsets are relative to the trace's
 * earliest start so the UI can lay each bar out as
 * `left = offsetMs / totalDurationMs`, `width = durationMs / totalDurationMs`.
 */
export interface WaterfallSpan {
    id: string;
    type: string;
    /** A human label derived from the entry's content (route, sql, queue:job, …). */
    label: string;
    /** Start offset (ms) from the trace start. */
    offsetMs: number;
    /** Span duration (ms); a null `durationMs` becomes a zero-width instant span. */
    durationMs: number;
    /** Nesting depth (0 for roots). */
    depth: number;
    /** Stable record order within the batch (the entry's `sequence`). */
    sequence: number;
    children: WaterfallSpan[];
}
export interface Waterfall {
    /** Absolute trace start (epoch ms) — the earliest entry start. */
    traceStartMs: number;
    /** Wall-clock span of the whole trace (latest end − earliest start), >= 0. */
    totalDurationMs: number;
    /** Root spans (those not contained by any other), ordered by start then sequence. */
    spans: WaterfallSpan[];
}
/**
 * Reconstruct a nested span waterfall from a batch/trace's entries.
 *
 * DESIGN: the entry model carries `traceId`/`spanId` but NOT a parent-span
 * pointer, so we cannot rebuild the exact OTel span tree from explicit links.
 * Instead — exactly as Sentry/Tempo do when parent links are missing — we infer
 * nesting from **time-interval containment**: a span is a child of the tightest
 * enclosing span whose `[start, end]` strictly contains it. `sequence` provides a
 * stable tie-break for spans that start at the same instant. This yields the
 * familiar request → query/http_client → nested-op nesting from data we already
 * capture, with zero new watcher overhead.
 *
 * Returns `null` for an empty input. Pure.
 */
export declare function buildWaterfall(entries: Entry[]): Waterfall | null;
//# sourceMappingURL=waterfall.d.ts.map