/** * The deep request-observation lifecycle. This module alone owns trace parent selection, identity, * timing, error recording, final status classification, and exactly-once completion. Integrations * should adapt completed spans; they should not reimplement this state machine. */ import type { AttributeValue, NifraSpan, ObservationAdapter, ObservationLink, SpanStatus } from "./span.js"; export interface ObservationContext { readonly traceId: string; readonly spanId: string; readonly parentSpanId?: string; readonly sampled: boolean; /** This span's outbound W3C trace context. */ readonly traceparent: string; } export interface ObservationParent { readonly traceId: string; readonly spanId: string; readonly sampled: boolean; } export interface StartObservation { readonly name: string; /** Explicit parent. `null` forces a root span; `undefined` falls back to `traceparent`. */ readonly parent?: ObservationParent | null; /** Inbound W3C header used when `parent` is undefined. */ readonly traceparent?: string | null; readonly attributes?: Readonly>; /** Non-parent causal relationships, for example an outbox event that resumed this workflow. */ readonly links?: readonly ObservationLink[]; } export interface EndObservation { readonly statusCode?: number; /** Explicit status wins over status-code and recorded-error classification. */ readonly status?: Exclude; readonly attributes?: Readonly>; } export interface ActiveObservation { readonly span: NifraSpan; readonly context: ObservationContext; /** Adds a sink to this in-flight span. Re-adding the same adapter is idempotent. */ addAdapter(adapter: ObservationAdapter): void; /** Starts a child that inherits this span's trace identity and sampling decision. */ startChild(input: Omit, additionalAdapters?: readonly ObservationAdapter[]): ActiveObservation; /** * Merge attributes onto the in-flight span - the seam for plugins that learn something mid-request * (an authenticated principal, a feature-flag bucket, a cache verdict) after the span opened. * Silently ignored once the observation has ended (the exported span is immutable). */ setAttributes(attributes: Readonly>): void; /** Records failure evidence without deciding the final status until the response is known. */ recordError(error: unknown): void; /** Ends and exports once. Repeated calls return the same completed span without notifying again. */ end(input?: EndObservation): NifraSpan; } export interface ObservationLifecycle { start(input: StartObservation, additionalAdapters?: readonly ObservationAdapter[]): ActiveObservation; } export interface ObservationClock { /** Epoch milliseconds for interoperable start/end timestamps. */ wallTime(): number; /** Monotonic milliseconds for durations. */ monotonicTime(): number; } export interface ObservationLifecycleOptions { readonly adapters?: readonly ObservationAdapter[]; /** Injectable seams are primarily useful for deterministic tests and constrained runtimes. */ readonly clock?: ObservationClock; readonly generateTraceId?: () => string; readonly generateSpanId?: () => string; } /** Creates an independent lifecycle factory. Adapters are always called fail-open. */ export declare function createObservationLifecycle(options?: ObservationLifecycleOptions): ObservationLifecycle; //# sourceMappingURL=lifecycle.d.ts.map