import { type ByteSource, type PipeEnd } from './types.ts';
import type { PathSpec } from '../types.ts';
/**
 * The read end an `exec` keeps on a live pipe (`exec 3<"$1"`). It holds the
 * pipe, not the name it was opened by. Each read takes a stream of its own
 * under the reading command's signal and closes it after one chunk, so a read
 * that gives up (`timeout`) leaves the rest to the next read. Mirrors
 * Python's PipeInput.
 */
export declare class PipeInput implements AsyncIterableIterator<Uint8Array> {
    readonly path: PathSpec;
    private readonly end;
    private readonly signal;
    /** `path` is the pipe's own (`/dev/fd/N`); `signal` gives each read its reader's. */
    constructor(path: PathSpec, end: PipeEnd, signal: () => AbortSignal | undefined);
    [Symbol.asyncIterator](): AsyncIterableIterator<Uint8Array>;
    next(): Promise<IteratorResult<Uint8Array>>;
}
export declare class AsyncLineIterator implements AsyncIterableIterator<Uint8Array> {
    private readonly input;
    private readonly source;
    private buf;
    private pulled;
    private exhausted;
    private readonly budget;
    private linesSinceCheck;
    private pulling;
    private started;
    holders: number;
    private released;
    constructor(input: ByteSource | AsyncIterator<Uint8Array>);
    [Symbol.asyncIterator](): AsyncIterableIterator<Uint8Array>;
    get position(): number;
    unread(data: Uint8Array): void;
    get loaded(): number;
    next(): Promise<IteratorResult<Uint8Array>>;
    readline(signal?: AbortSignal, eol?: number): Promise<Uint8Array | null>;
    /** Close the source and drop what it buffered, for input a failed line abandoned. */
    discard(): Promise<void>;
    /** Close once no descriptor names this reader, or when the last job still holding it ends. */
    release(): Promise<void>;
    /** End a job's hold, closing a reader its shell already closed. */
    unhold(): Promise<void>;
    /**
     * Discard this reader for one over `source` that keeps its holds and its
     * release, for a descriptor a write moved. Mirrors Python's reopen.
     */
    reopen(source: ByteSource): Promise<AsyncLineIterator>;
    /**
     * Read what the source has left into the buffer, for a descriptor that
     * outlives its pipe: reads go on from memory. Mirrors Python's load_rest.
     */
    loadRest(): Promise<void>;
    /**
     * Close the source after a failed read, unless it was a reader's own abort
     * on a pipe an `exec` keeps, which stays open with `taken`, what the read
     * had taken, put back. Mirrors Python's _failed.
     */
    private failed;
    private check;
    private close;
    private pull;
    private readDelimited;
    /**
     * Read up to (not including) `delim`, or to EOF. Returns the bytes and
     * whether the delimiter was found (false means EOF, which `read`/
     * `mapfile` report as status 1).
     */
    readUntil(delim: number | Uint8Array, signal?: AbortSignal): Promise<[Uint8Array<ArrayBuffer>, boolean]>;
    /**
     * Whether another byte follows, consuming nothing. Pulls the source's next
     * chunk only when nothing is buffered, so a line still arriving never holds
     * the answer up. Mirrors Python's peek.
     */
    peek(signal?: AbortSignal): Promise<boolean>;
    /** Hand over what is buffered, else the source's next chunk; null at end of input. */
    readChunk(): Promise<Uint8Array | null>;
    /**
     * At most `size` bytes with at most one pull of the source, as a
     * read(2) of a pipe answers (Python's `read1`): what has arrived, the
     * rest kept for the next read; empty at the end of input.
     */
    read1(size: number): Promise<Uint8Array>;
    /**
     * Read at most `count` characters, stopping early at `delim` (null
     * reads through delimiters). `read -n` is the delimited form, `read
     * -N` the null one. The delimiter is consumed and not returned.
     * Returns the bytes and whether the read ended on its own terms
     * rather than EOF.
     *
     * Characters, not bytes: bash counts them in the shell's locale, so
     * `read -n 1` on `éx` assigns `é` and leaves `x`. Counting bytes
     * would hand back half a character and leave the other half to
     * corrupt the next read.
     */
    readChars(count: number, delim: number | null, signal?: AbortSignal): Promise<[Uint8Array<ArrayBuffer>, boolean]>;
}
/**
 * Standard input that the commands of one group, loop or shell read in
 * turn, as bash's all read one open descriptor.
 *
 * What one command reads the next does not see again: `read` takes its
 * line off `lines` and leaves the rest buffered there, and any other
 * command iterates this object for that rest, then for what the source
 * still holds. It has no `return`, so a command that stops early never
 * closes the source a later command may still read; whoever opened the
 * source closes it, and a failed line discards it.
 */
export declare class SharedInput implements AsyncIterableIterator<Uint8Array> {
    readonly seekable: boolean;
    lines: AsyncLineIterator;
    /**
     * The live pipe this reads while the substitution's command runs; when that
     * ends, its scope loads the rest for a descriptor the shell still holds
     * (`f() { exec 3<"$1"; }; f <(cmd)`) and clears the name.
     */
    pipe: PathSpec | null;
    /** `source` is what the descriptor reads, or the line buffer of the
     * descriptor it duplicates, whose live pipe `pipe` names; one built over
     * a `PipeStream` takes that stream's. */
    constructor(source: ByteSource | AsyncLineIterator, pipe?: PathSpec | null, seekable?: boolean);
    [Symbol.asyncIterator](): AsyncIterableIterator<Uint8Array>;
    /** Another descriptor on the same open file, as `dup` makes: a read
     * through either moves the one offset. */
    dup(): SharedInput;
    next(): Promise<IteratorResult<Uint8Array>>;
    /** Close the source for good, for a line that failed reading it. */
    discard(): Promise<void>;
}
/**
 * The one descriptor a construct hands every command it runs. `<
 * /dev/null` stays as it is: it reads nothing, so there is no position
 * to share, and its type tells a command no file is attached.
 */
export declare function share(stdin: ByteSource | null): ByteSource | null;
/**
 * The line reader `read`, `mapfile` and `select` take input from: a
 * shared descriptor's own, so what they leave the next command reads,
 * else one over `stdin` alone.
 */
export declare function lineBuffer(stdin: ByteSource): AsyncLineIterator;
/**
 * How many bytes `data`'s first character spans, decoded as UTF-8.
 *
 * Always at least one and never more than what is there, so a caller
 * stepping by this never splits a character and never stalls. Bytes that
 * decode to one replacement character answer 1, which is what a
 * fatal:false TextDecoder makes of them: a stray continuation byte, a
 * lead the encoding never uses, and a sequence cut short by a byte that
 * cannot continue it.
 */
export declare function charWidth(data: Uint8Array): number;
/** Close unreferenced cursors once, preserving duplicate descriptors. */
export declare function releaseInputs(inputs: SharedInput[], keep?: SharedInput[]): Promise<void>;
/**
 * Keep each reader a job inherits open until the job ends, as the
 * descriptor's: a write that replaces it hands the hold on.
 */
export declare function holdInputs(inputs: SharedInput[]): SharedInput[];
//# sourceMappingURL=async_line_iterator.d.ts.map