import { JobConsole } from './job_console.ts';
import { Channel, type OwnedStream } from './types.ts';
/**
 * A shell's screen: what its lines and its background jobs wrote, in the
 * order it arrived, until a line takes it.
 *
 * A line writes here through the sink it runs with, a background job
 * through `jobs`, the line's own `JobOutput`. A job that writes while no
 * line runs waits here for the next one, as bash's job prints to the
 * terminal whenever it likes. With a reader attached (a caller streaming
 * the line), every chunk goes straight on to it; what it keeps must fit in
 * what the workspace's `max_memory` has left. A session has one (`tty`),
 * shared by every fork of it.
 */
export declare class Terminal extends JobConsole {
    chunks: [Channel, Uint8Array, boolean][];
    held: number;
    reader: JobConsole | null;
    readonly jobs: JobOutput;
    ended: number;
    attaching: Promise<void> | null;
    private attached;
    private prefix;
    private prefixSize;
    private errPrefix;
    private errPrefixSize;
    private taken;
    private marked;
    /** A bounded prefix of stdout handed to the current line's reader. */
    get stdoutPrefix(): Uint8Array;
    /** A bounded prefix of stderr handed to the current line's reader. */
    get stderrPrefix(): Uint8Array;
    private remember;
    /** Take what the line wrote. */
    emit(channel: Channel, data: Uint8Array): Promise<void>;
    /**
     * Pass a chunk to the reader, or keep it for the line; while a reader
     * takes what waited (`attach`), keep it and wait. What was handed back to
     * an attached reader (`handOver`) goes to it first. `job` says a job wrote it.
     */
    put(channel: Channel, data: Uint8Array, job: boolean): Promise<void>;
    /**
     * Start a line, handing a streaming caller (`reader`) what waited for it.
     *
     * The reader takes the chunks one at a time and becomes the line's only
     * once none is left. A job that writes meanwhile lands behind what waited
     * and waits until the reader is attached, so each writer adds at most one
     * chunk and a noisy job cannot hold the line back; a line ended before
     * that never attaches the reader.
     */
    attach(reader: JobConsole | null): Promise<void>;
    /** Hand `reader` what waits, one chunk at a time, and make it the line's once none is left. */
    private pass;
    /**
     * Once its last line has ended, give `to` what is left here, ahead of what
     * reached it meanwhile, and send there what jobs write from now on. A
     * reader attached to `to` takes it before anything written after.
     */
    handOver(to: Terminal): void;
    /** What reached the terminal so far, taken out to be bounded and put back. */
    drain(): [Uint8Array, Uint8Array];
    /**
     * What reached the terminal for one history entry of the line, since the
     * entry before it: a line bash's reader reads as several commands
     * records each with what it wrote. With a reader attached, what it was
     * handed, its prefix starting again for the next.
     */
    entry(): [Uint8Array, Uint8Array];
    /**
     * Return drained output ahead of whatever arrived meanwhile, what the
     * line's history entries took of it first.
     */
    putBack(out: Uint8Array, err: Uint8Array): void;
    /** End a line: its stdout and stderr, jobs' output among them. */
    take(): [Uint8Array, Uint8Array];
    /** End an abandoned line: what it wrote goes, its jobs' stays. */
    dropLine(): void;
    /** Detach the line's reader and let go the writers waiting on its attach. */
    private end;
}
/** Where the background jobs write on a terminal. */
export declare class JobSide extends JobConsole {
    readonly terminal: Terminal;
    constructor(terminal: Terminal);
    /** Take what a job wrote. */
    emit(channel: Channel, data: Uint8Array): Promise<void>;
}
/**
 * Where the background jobs one shell (a line, a subshell, a job, a
 * substitution, a pipe stage) starts write.
 *
 * Into the statement that shell is running, among what the statement
 * writes, so the two keep the order they were written in; when it runs
 * none (between statements, or once it has ended), on to where the shell
 * itself writes (`target`). A session's `jobOutput` is null in a typed
 * line, whose jobs write through its terminal's `jobs`.
 */
export declare class JobOutput extends JobConsole {
    target: JobConsole;
    recorder: JobConsole | null;
    private readonly taken;
    private tail;
    private turns;
    constructor(target: JobConsole);
    /**
     * Keep what jobs write from now behind `after`, in the order they write:
     * a statement that stops recording them still lands what it recorded
     * first. Mirrors Python's hold_until.
     */
    holdUntil(after: Promise<void>): void;
    /** Run `write` once every write queued before it has run. */
    private turn;
    private turned;
    /**
     * Send what jobs write into `recorder` until the returned call puts back
     * what was there before. That call also ends every recording begun
     * inside this one: a run its caller abandoned (timeout's) can end after
     * the caller has, and then has nothing left to put back.
     */
    record(recorder: JobConsole): () => void;
    /** Write what a job wrote where it belongs now, behind what is held. */
    emit(channel: Channel, data: Uint8Array): Promise<void>;
    /** Write what a job wrote to a stream a level owns, keeping the stream. */
    emitTo(stream: OwnedStream, data: Uint8Array): Promise<void>;
    /**
     * Which of the writes of the shell this leads to (`target`), or the
     * streams above it, a job's streams reach: a shell passes them on as
     * they are, a redirect (`JobRoute`) through its descriptors.
     */
    passes(streams: ReadonlySet<Channel | OwnedStream>): Set<Channel | OwnedStream>;
}
/**
 * A job's output, kept in its own console and copied to where the shell
 * that started it writes.
 */
export declare class Tee extends JobConsole {
    readonly console: JobConsole;
    readonly copy: JobConsole;
    constructor(console: JobConsole, copy: JobConsole);
    /** Write to both. */
    emit(channel: Channel, data: Uint8Array): Promise<void>;
    /** Write to both, the copy keeping the stream. */
    emitTo(stream: OwnedStream, data: Uint8Array): Promise<void>;
}
//# sourceMappingURL=terminal.d.ts.map