/**
 * The {@link Sink} contract: a consumer that drains a {@link SignalChannel}.
 *
 * A sink is the *terminal* end of the trace transport. Where a producer pushes
 * {@link TraceSignal}s into a {@link SignalChannel} (via `emit`), a sink pulls
 * them back out with `for await … of channel` and does something with them —
 * print a line, append NDJSON, forward to an injected stream. There is no
 * subscriber registration and no push: the sink owns its own pull loop and runs
 * until the channel is closed and drained.
 *
 * This mirrors the layer's deliberate divergence from the OTel exporter shape:
 * a sink is not an `Exporter` with `export(batch)` / `shutdown()`; it is a plain
 * object with a single mandatory {@link Sink.drain} coroutine plus optional
 * {@link Sink.flush}/{@link Sink.close} lifecycle hooks. Concrete sinks
 * (`ConsoleSink`, `FileSink`, `StreamSink`) implement this interface.
 */
import type { SignalChannel } from "../channel/signal";
/**
 * A terminal consumer of a {@link SignalChannel}.
 *
 * Implementations iterate the channel to completion inside {@link drain},
 * handling each {@link TraceSignal} as it arrives. {@link flush} and
 * {@link close} are optional: a buffered sink overrides `flush` to force pending
 * writes to their destination, and a sink that owns a resource (a file handle,
 * a socket) overrides `close` to release it. A sink with no buffering and no
 * owned resource needs neither.
 */
export interface Sink {
    /**
     * Pull every signal from `channel` and handle it, returning once the channel
     * is closed and fully drained.
     *
     * Implemented as a `for await … of channel` loop. A sink is expected to call
     * this once per channel; concurrent drains of the same channel are undefined
     * because the channel is single-consumer.
     */
    drain(channel: SignalChannel): Promise<void>;
    /**
     * Force any buffered output to its destination without ending the sink.
     *
     * Optional — only buffered sinks need it. Safe to call repeatedly.
     */
    flush?(): Promise<void>;
    /**
     * Release any resource the sink owns (file handle, socket, …).
     *
     * Optional — only resource-owning sinks need it. Should be idempotent and is
     * typically preceded by an implicit or explicit {@link flush}.
     */
    close?(): Promise<void>;
}
