@struktoai/mirage-core
Version:
A Unified Virtual Filesystem For AI Agents
160 lines • 7.47 kB
TypeScript
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