/**
 * `RepackedSyncClient` — the backend side of the synchronous broker.
 *
 * Every method blocks the calling thread in `Atomics.wait` until the coordinator answers, which is the
 * whole point: a thread running wasm parks in futexes and can never observe a promise, so the file
 * layer under it has to be synchronous. Nothing here is async, and nothing here knows about wasm.
 *
 * ## What throws and what does not
 *
 * A FILE rejection is data: every method returns `{ errno }` (0 on success) with whatever else the
 * operation produced. Callers map the errno straight into their own ABI — the values are WASI preview1
 * errno numbers already.
 *
 * A TRANSPORT failure throws, because there is no answer to return: the server detached this client,
 * the client sent something the server refused, the server never replied inside the timeout, or the
 * store itself failed. Those are `RepackedBrokerTransportError` and `RepackedBrokerStoreError`.
 *
 * ## Mapping onto WASI preview1
 *
 * The method set is shaped so a preview1 adapter is a straight translation, with no state of its own
 * beyond the preopen table:
 *
 *     path_open              → open(path, flags, mode)          (flags are the POSIX bits, see protocol)
 *     fd_close               → close(fd)
 *     fd_read                → read(fd, length)                 (no position: the store's own cursor)
 *     fd_pread               → read(fd, length, position)
 *     fd_write               → write(fd, bytes)
 *     fd_pwrite              → write(fd, bytes, position)
 *     fd_seek                → resolved by the caller; the store's cursor moves on cursor reads/writes
 *     fd_sync / fd_datasync  → fsync(fd)                        (store-wide; see the server's note)
 *     fd_filestat_get        → fstat(fd)
 *     path_filestat_get      → stat(path) / lstat(path)
 *     fd_readdir             → readdir(path) or readdirPage(path, cursor) for the cookie form
 *     path_create_directory  → mkdir(path)
 *     path_remove_directory  → rmdir(path)
 *     path_unlink_file       → unlink(path)
 *     path_rename            → rename(oldPath, newPath)
 *     path_symlink           → symlink(target, path)      (targets are ABSOLUTE; see the core)
 *     path_readlink          → readlink(path)
 *     fd_filestat_set_size   → truncate(path, size) — the core resizes by PATH only, so the adapter
 *                              keeps the path it opened each fd with and resolves it here
 *
 * Reads and writes larger than the channel's payload region are split transparently; a caller never
 * has to know the channel size.
 */
import type { BrokerStat, RepackedChannel } from "./protocol";
/** The transport failed: there is no answer, and this client can no longer make progress. */
export declare class RepackedBrokerTransportError extends Error {
    readonly brokerCode: "detached" | "protocol" | "timeout";
    constructor(brokerCode: "detached" | "protocol" | "timeout", message: string);
}
/** The store behind the broker failed. Not a file rejection, and not this client's mistake. */
export declare class RepackedBrokerStoreError extends Error {
    readonly brokerCode = "store";
    constructor(message: string);
}
/** Every result carries an errno; 0 means the operation succeeded. */
export interface BrokerResult {
    readonly errno: number;
}
export interface BrokerOpenResult extends BrokerResult {
    readonly fd: number;
}
export interface BrokerCountResult extends BrokerResult {
    /** Bytes actually transferred. Short of the request means end-of-file (read) or a store limit (write). */
    readonly count: number;
}
export interface BrokerReadResult extends BrokerCountResult {
    readonly bytes: Uint8Array;
}
export interface BrokerStatResult extends BrokerResult {
    readonly stat: BrokerStat | undefined;
}
export interface BrokerSizeResult extends BrokerResult {
    readonly size: bigint;
}
export interface BrokerReaddirResult extends BrokerResult {
    readonly entries: readonly string[];
}
export interface BrokerReadlinkResult extends BrokerResult {
    /** The link's target, or `undefined` when the call was rejected. */
    readonly target: string | undefined;
}
export interface BrokerReaddirPageResult extends BrokerReaddirResult {
    /** The cursor to resume from, or `undefined` when the listing is complete. */
    readonly nextCursor: number | undefined;
}
export interface RepackedSyncClientOptions {
    /**
     * How long one request may go unanswered before the client gives up and throws. A dead coordinator
     * would otherwise park this thread forever, which is worse than a loud failure. Pass `Infinity` for
     * a host that genuinely prefers to wait.
     */
    readonly requestTimeoutMs?: number;
}
export declare class RepackedSyncClient {
    #private;
    readonly channel: RepackedChannel;
    constructor(channel: RepackedChannel, options?: RepackedSyncClientOptions);
    /** The largest single read or write that fits one request. Reads/writes above it are chunked. */
    get maxTransferBytes(): number;
    open(path: string, flags: number, mode?: number): BrokerOpenResult;
    close(fd: number): BrokerResult;
    /**
     * Read up to `length` bytes. With no `position` the store's own descriptor cursor is used and
     * advances; with a `position` the cursor is untouched (`fd_pread`). A result shorter than `length`
     * means end-of-file, never a partial transport.
     */
    read(fd: number, length: number, position?: bigint): BrokerReadResult;
    /**
     * Write `bytes`. With no `position` the store's own descriptor cursor is used and advances; with a
     * `position` the cursor is untouched (`fd_pwrite`). A descriptor opened with `O_APPEND` always
     * writes at end-of-file and ignores `position`, exactly as POSIX requires.
     */
    write(fd: number, bytes: Uint8Array, position?: bigint): BrokerCountResult;
    /**
     * Flush the store. Durability is STORE-WIDE, not per-descriptor: on success every byte written
     * through this broker by any client before the call returned is recoverable. `fd` is validated so
     * the call still rejects a descriptor this client does not own.
     */
    fsync(fd?: number): BrokerResult;
    fstat(fd: number): BrokerStatResult;
    stat(path: string): BrokerStatResult;
    /** Reports the LINK itself when the final component is one; `stat` follows it instead. */
    lstat(path: string): BrokerStatResult;
    /**
     * Create a symbolic link at `path` pointing at `target`. Targets are ABSOLUTE — the store refuses
     * a relative one with `EINVAL` rather than reinterpreting it against the link's directory.
     */
    symlink(target: string, path: string): BrokerResult;
    /** The target of the symbolic link at `path`. `EINVAL` when the path is not a link. */
    readlink(path: string): BrokerReadlinkResult;
    /** The complete listing, paged transparently over as many requests as the channel needs. */
    readdir(path: string): BrokerReaddirResult;
    /**
     * One page of a listing, for a caller that owns its own cookie (WASI `fd_readdir`). The cursor is an
     * index into the store's sorted listing, recomputed per call — a paged listing is therefore not an
     * atomic snapshot, which is exactly what POSIX `readdir` allows.
     */
    readdirPage(path: string, cursor?: number): BrokerReaddirPageResult;
    mkdir(path: string, options?: {
        recursive?: boolean;
        mode?: number;
    }): BrokerResult;
    rmdir(path: string): BrokerResult;
    unlink(path: string): BrokerResult;
    rename(oldPath: string, newPath: string): BrokerResult;
    /**
     * Resize by PATH. The core store has no resize-by-descriptor, so a WASI `fd_filestat_set_size`
     * adapter keeps the path each fd was opened with and calls this. Nothing is lost by that: the store
     * has no hard links, and a descriptor whose path was unlinked meanwhile is an orphan the core keeps
     * readable but no longer resizes.
     */
    truncate(path: string, size: bigint): BrokerResult;
    /** The size of one file, without the rest of a stat. `EISDIR` for a directory. */
    size(path: string): BrokerSizeResult;
}
/**
 * Turn a broker result into the throw the core store would have produced, for a caller that prefers
 * exceptions to errnos. The rebuilt `FsError` carries the same numeric `code` the broker reported.
 */
export declare function throwOnErrno(result: BrokerResult, operation: string, path?: string): void;
//# sourceMappingURL=client.d.ts.map