import type { EventEnvelope } from "../statelog/wireTypes.js"; import type { ThreadEntry } from "./types.js"; /** Same envelope, with derived fields hoisted onto it so downstream * helpers never re-read raw wire fields. `raw` is preserved verbatim * for the rare helper that needs an obscure field this layer didn't * bother to hoist. */ export type NormalizedEnvelope = { raw: EventEnvelope; /** ms relative to the first event's timestamp. */ tMs: number; /** Resolved thread id (from `data.threadId` if present, else null). */ threadId: string | null; /** `ev.data.type` hoisted for terser switch/filter. */ type: string; /** `ev.span_id` hoisted. */ spanId: string | null; /** `ev.parent_span_id` hoisted. */ parentSpanId: string | null; }; export type Normalized = { events: NormalizedEnvelope[]; /** span_id → normalized envelope, for parent_span_id lookups. */ spanIndex: Record; /** Events grouped by `type` (one pass; reused by every helper). */ byType: Record; /** Warnings produced during normalization. */ warnings: string[]; }; /** One pass over the raw envelopes that hoists relative timestamps, * resolves thread ids, and builds the span/byType indices. Every * later helper consumes the result; no helper re-reads `data.foo` * for these fields. */ export declare function normalize(events: EventEnvelope[]): Normalized; /** One entry per `threadCreated` event. `threadResumed` events do * NOT create entries — they map back to the existing thread by id. * * This is the one helper that reaches into `ev.raw.data.*` for * thread-specific fields. If a second consumer ever needs them, * promote them into the wire accessor layer. */ export declare function extractThreads(n: Normalized): ThreadEntry[];