import type { ByteSource } from '../../io/types.ts';
import type { OutputFn } from '../types.ts';
import type { WasmView } from './view.ts';
/** One run the host hands a worker: the module and what the guest starts with. */
export interface GuestRun {
    module: WebAssembly.Module;
    argv: string[];
    /** `NAME=value` entries. */
    env: string[];
    /** The run has input, which the guest reads as from a pipe. */
    piped: boolean;
    /** Seconds the guest's wall clock runs ahead of the host's: the workspace's system_time. */
    offset: number;
    /** The page URL the service worker bridges calls at, where no memory is shared. */
    bridge?: string;
}
/** One blocking call the guest makes of the host. */
export interface GuestCall {
    op: 'view' | 'file' | 'stdin' | 'output' | 'sleep';
    method?: string;
    /** The open file a `file` call is on: its core handle. */
    file?: number;
    args?: unknown[];
}
export type GuestReply = {
    kind: 'ready';
} | {
    kind: 'result';
    exitCode: number;
    trap: string | null;
    lost: string[];
} | {
    kind: 'error';
    message: string;
};
/** Why no guest worker can start here, or null when one can. */
export declare function workerUnavailable(): Promise<string | null>;
/**
 * Compile-once, run-many WASI module, each run on a worker. Mirrors
 * Python's `WasmExecution`: the module compiles once, each request runs
 * on a worker of its own (an idle one when there is), and a stopped run
 * ends its worker, the only way to stop a guest that never calls out.
 *
 * Filesystem imports are answered here: every fd and path call the guest
 * makes lands in its `WasiFs`, whose view and open files are this run's
 * `WasmView` and its descriptors, so the run sees exactly what the view
 * serves, only the passed environment, and no network.
 *
 * @param source - the module's bytes.
 * @param trapPrefix - the command name a wasm trap's stderr line starts with.
 */
export declare class WasmExecution {
    private readonly source;
    private readonly trapPrefix;
    private compiled;
    private idle;
    private closed;
    constructor(source: () => Promise<Uint8Array>, trapPrefix: string);
    /** The compiled module; a load that failed is tried again on the next run. */
    private module;
    /**
     * Run the module once and return `[stdout, stderr, exitCode]`. A guest
     * write to a stream with a sink waits until the sink takes it, so a
     * reader that falls behind holds the guest back, as a full pipe would;
     * that stream then comes back empty. A stop ends the guest where it is:
     * the files it left open land, and the run rejects with the stop.
     *
     * @param argv - full argv, the program name included.
     * @param stdin - the run's input, which the guest takes as it reads it.
     * @param env - the environment as `[name, value]` pairs.
     * @param view - the files the guest sees.
     * @param output - receives stdout as the guest writes it; absent returns it.
     * @param errors - the same for stderr.
     * @param stop - ends the run.
     */
    run(argv: string[], stdin: ByteSource | null, env: [string, string][], view: WasmView, output?: OutputFn, errors?: OutputFn, stop?: AbortSignal): Promise<[Uint8Array, Uint8Array | null, number]>;
    private checkOpen;
    /** A started worker, or the stop; one that starts after the stop goes. */
    private started;
    /** A started worker, listening; one that fails to start is let go,
     * its blob URL with it. */
    private ready;
    private viewCall;
    private fileCall;
    /** Let the idle workers go. */
    close(): Promise<void>;
}
//# sourceMappingURL=execution.d.ts.map