import type { ByteSource } from '../io/types.ts';
import { SharedInput } from '../io/async_line_iterator.ts';
import { type Channel, JobConsole, type OwnedStream } from './console/index.ts';
import type { PathSpec } from '../types.ts';
import { type Redirect } from './types.ts';
/**
 * The first descriptor outside the signed 32-bit range, or null. Both slots count: the
 * descriptor a redirect claims (`3>f`, `3<f`, `3>&1`, `3>&-`) and the one
 * it duplicates from (`>&3`, `<&3`, `2>&3`). `&>`'s FD_BOTH and `>&-`'s
 * FD_CLOSE are the two sentinels the parser spells with -1, and neither is
 * a descriptor.
 */
export declare function unsupportedDescriptor(redirects: readonly Redirect[]): number | null;
/** Bash's error for a closed descriptor, without the line-number prefix. */
export declare function badDescriptorLine(fd: number): Uint8Array;
/**
 * Standard input that fails on its first read with EBADF. bash opens a
 * command whose stdin is closed (`<&-`) or duplicated from a write-only
 * descriptor (`0<&1`) all the same; the descriptor exists, and only a
 * read of it fails. A command that never reads (`true 0<&1`) succeeds,
 * and one that does reports `<cmd>: -: Bad file descriptor` and exits 1,
 * which is what the chokepoint renders from the error this throws.
 */
export declare function unreadableStdin(): AsyncIterable<Uint8Array>;
export declare class FileDescription {
    readonly scope: PathSpec;
    readonly append: boolean;
    readonly pipe: boolean;
    opened: boolean;
    offset: number;
    source: FileInput | null;
    emit: ((data: Uint8Array) => Promise<void>) | null;
    /** Settles when the last write through this description has. */
    writing: Promise<void>;
    constructor(scope: PathSpec, append?: boolean, pipe?: boolean);
}
export declare class FileInput extends SharedInput {
    readonly description: FileDescription;
    constructor(description: FileDescription, data: ByteSource);
    dup(): this;
}
/**
 * Who a stream a level was given belongs to: a redirect level's recorder,
 * or a session, whose own line its terminal streams are. Mirrors Python's
 * StreamOwner.
 */
export type StreamOwner = symbol;
/**
 * The stdout or stderr a level was given rather than opened. A descriptor
 * copied from it (`3>&1`, `exec 3>&1`) keeps naming it after the level
 * rebinds its own (`3>&1 >f`), as bash's copy keeps the open file
 * description. Mirrors Python's Inherited.
 */
export declare class Inherited {
    readonly owner: StreamOwner;
    readonly channel: Channel;
    constructor(owner: StreamOwner, channel: Channel);
}
/**
 * What one level's command wrote, in order, for the level to route. A chunk
 * on a channel goes through the level's descriptor table; one written to a
 * stream another level owns stays in place on its way up to that level, so it
 * lands among the bytes written around it. Mirrors Python's Recorder.
 */
export declare class Recorder extends JobConsole {
    readonly chunks: [Channel | Inherited, number, number][];
    readonly owner: StreamOwner;
    private storage;
    private writing;
    private pending;
    /** Whether a write is under way or recorded bytes wait to be taken. Mirrors Python's busy. */
    get busy(): boolean;
    private record;
    emit(channel: Channel, data: Uint8Array): Promise<void>;
    emitTo(stream: OwnedStream, data: Uint8Array): Promise<void>;
    /**
     * Drop what was recorded and never taken, for a level that failed before
     * it routed its output; a late job write starts afresh. Mirrors Python.
     */
    close(): Promise<void>;
    take(): Promise<[Channel | Inherited, ByteSource][]>;
}
/**
 * Send bytes written to a stream another level owns toward it: up through
 * the sink, or the enclosing level's recorder when the level returns its
 * output as a value or writes to a terminal of its own (a line's, a
 * substitution's), which owns no stream above it. A console that keeps no
 * streams takes them on their channel. False when there is nowhere above.
 * `enclosing` is the enclosing level's recorder, its caller's. Mirrors
 * Python's deliver.
 */
export declare function deliver(sink: JobConsole | null, stream: Inherited, data: ByteSource, enclosing: JobConsole | null): Promise<boolean>;
export interface Descriptor {
    readonly identity: string;
    readonly append: boolean;
    readonly source: SharedInput | null;
    readonly file: FileDescription | null;
    readonly stream?: Inherited | null;
}
//# sourceMappingURL=descriptors.d.ts.map