import type { Context } from '../../../commands/config.ts';
import { PythonRuntime } from '../base.ts';
import type { OutputFn, Program, RunResult, RuntimeReach } from '../../types.ts';
import { type RuntimeOptions } from '../../config.ts';
import type { SyncVFS } from './fs/types.ts';
import { type PyodideConfig } from './config.ts';
/**
 * Rewrite top-level imports of denied packages so Pyodide's
 * `loadPackagesFromImports` skips fetching them. The rewritten code is only
 * fed to the auto-loader's import scanner — user code still runs unchanged,
 * so the actual `import X` will hit any meta_path blocker installed in the
 * Python bootstrap.
 *
 * Recognises:
 *   - `import X`, `import X.Y`, `import X as alias`
 *   - `from X import …`, `from X.Y import …`
 * The match is line-scoped (`/m`) so multi-import lines like
 * `import X, Y` are blanked out as a single statement.
 */
export declare function stripDeniedImports(code: string, denyPackages: ReadonlySet<string>): string;
export declare class PyodideRuntime extends PythonRuntime<undefined> {
    private readonly sync?;
    private readonly interruptBuffer?;
    readonly name = "pyodide";
    protected readonly versionSuffix = " (pyodide)";
    readonly reach: RuntimeReach;
    readonly filesystem: readonly ["read", "write", "list", "stat", "glob"];
    private pyodide;
    private guest;
    private initPromise;
    private bootstrapPromise;
    private disposeModule;
    private queue;
    private pending;
    private readonly limiter;
    private readonly autoLoadFromImports;
    private readonly bootstrapCode;
    private readonly denyPackages;
    private readonly home;
    private readonly sysPath;
    private readonly packages;
    private readonly packageBaseUrl;
    private readonly lockFileUrl;
    private files;
    private readonly journal;
    private readonly deferred;
    private readonly streams;
    private readonly mounted;
    private readonly madeDirs;
    private readonly mountedFilesystems;
    private readonly refused;
    private readonly seedMissesReported;
    private seedNotices;
    private interrupter;
    private interrupterTried;
    private worker;
    private readonly maxMemory;
    private readonly syncFailures;
    private syncSkipped;
    private realmSeal;
    constructor(options?: RuntimeOptions<PyodideConfig>, sync?: SyncVFS | undefined, interruptBuffer?: SharedArrayBuffer | undefined);
    /**
     * Run one program on a fresh interpreter: in the worker for a run with
     * files, in process for one without. In the worker the guest reads its
     * input as it comes and its writes go to `output` and `errors` as it
     * makes them; in process it reads its input whole and its output comes
     * back in the result.
     *
     * @param _engine none; each run builds its own interpreter.
     * @param program the source and argv to run.
     * @param ctx the run's context.
     * @param output receives stdout as the guest writes it.
     * @param errors the same for stderr.
     */
    interpret(_engine: undefined, program: Program, ctx: Context, output?: OutputFn, errors?: OutputFn): Promise<RunResult>;
    private schedule;
    private enqueue;
    private withPermit;
    /**
     * The MemoryError for an interpreter whose heap is past `maxMemory`, null
     * while it is within it. The heap never shrinks, so its size when a run
     * ends is the most the run used, however fast it was. A run in the worker
     * is checked there, and on Node the worker is also watched while it runs
     * (`watchMemory`).
     */
    private passedCap;
    /** A run's result, or a MemoryError when the run passed `maxMemory`. */
    private capped;
    private createRuntime;
    private withFreshRuntime;
    close(): Promise<void>;
    private closeOne;
    private closeInterpreter;
    private wireInterruptIfNeeded;
    private guardRequestedPaths;
    private ensureLoaded;
    /**
     * Seal the Node worker the guest runs in, once the interpreter and any
     * trusted init have loaded. Only inside the worker (`sync` set): the main
     * thread runs no workspace-backed guest, and a browser worker shares the
     * page, whose CSP is its only limit. An `init_module` has host reach by
     * design (`'process'`), so its worker is left open; so is a Node too old
     * for `module.registerHooks`, documented as trusted-only there.
     *
     * @param pyodide The loaded interpreter.
     */
    private sealRealmIfWorker;
    /**
     * One request on the worker. A run that passes `maxMemory` takes the
     * worker with it (`watchMemory`), so the next run starts a fresh one.
     */
    private onWorker;
    private ensureWorker;
    /**
     * Rebuild mount nodes before each run so cached bytes never survive a
     * session change. The worker populates nodes on lookup and open, so
     * only a worker mounts anything; a bound run with no worker is refused
     * before it gets here (`noWorker`). Removed mounts disappear, and nested
     * mounts share their parent's Emscripten mountpoint while retaining
     * workspace routing boundaries.
     */
    private syncMounts;
    /**
     * Put the configured paths on sys.path, after every mount is in place.
     *
     * Runs on EVERY syncMounts pass rather than once at load: each pass
     * unmounts and remounts the prefixes, and zipimport caches an
     * archive's table of contents by path, so a `.whl` served from a
     * remounted tree would keep answering from the previous run. Both
     * guards inside are idempotent, so repeating is cheap.
     *
     * Args:
     *   pyodide: the loaded interpreter.
     */
    private seedSysPath;
    private guestProcess;
    private guestModule;
    /**
     * The guest's extended-attribute calls (its os.getxattr family, which
     * the harness installs over this module), answered by the workspace
     * dispatcher and handed back as JSON: `{value}`, or `{code}` naming the
     * condition the dispatcher reported. Only the worker can wait on the dispatcher
     * from inside a WASM frame, so without one, and for a path no mount
     * serves, the answer is ENOTSUP: what a filesystem without extended
     * attributes says.
     */
    private guestXattr;
    private takeSeedNotices;
    /**
     * Land what the run left open and replay every mutation the shim
     * recorded during it, in the order the guest performed them. The guest
     * cannot await the bridge from its sync WASM frames without JSPI, so it
     * only records; ordering is what makes a create-then-rename or
     * mkdir-then-write sequence land the same way it ran. Returns one
     * message per failure for the caller's stderr.
     */
    private drainMutations;
    private loadImports;
    private runOne;
    private guestCwd;
}
//# sourceMappingURL=runtime.d.ts.map