import type { DispatchFn } from '../../../runtime/types.ts';
import { FileStat, PathSpec } from '../../../types.ts';
import type { MountView } from '../../../view/types.ts';
export type ReadTree = (path: PathSpec, limit?: number, level?: boolean) => Promise<Map<string, FileStat> | null>;
export type WalkCall<R> = (path: PathSpec, nofollow?: boolean, limit?: number) => Promise<R>;
/**
 * Let the mount that owns `path` refuse a command about to read every file
 * under it. The mount is asked at the resolved path: the command already
 * judged the spelling it was typed in, and reports a path that reaches no
 * directory (missing, not one, a link loop) itself. The mount refuses by
 * rejecting, which becomes the command's own error, `command: message` and
 * exit 1, on one mount or across several; any other filesystem error stays
 * one. Mirrors Python's `before_full_walk`.
 */
export declare function beforeFullWalk(dispatch: DispatchFn | undefined, path: PathSpec, command: string): Promise<void>;
/**
 * The entries one walk of an operand may still list.
 *
 * A walk lists at most `walkLimit` entries of each mount it crosses: an
 * entry is charged to the mount serving the directory that lists it, counted
 * under the operand, or under the mount's root where that mount starts below
 * the operand. Once a count runs out the walk lists nothing more there, and
 * `stopped` holds what the command says about it, one line per folder,
 * without the command's name, in the order the walk met them. Mirrors
 * Python's `WalkBudget`.
 */
export declare class WalkBudget {
    readonly operand: PathSpec;
    readonly mounts: MountView | null;
    readonly spent: Map<string, number>;
    readonly stopped: string[];
    constructor(operand: PathSpec, mounts: MountView | null);
    private limitAt;
    private folderOf;
    private stop;
    /**
     * Charge one entry `directory` lists, or the one file a search reads when
     * `directory` is that file: true if the walk may keep it, false once its
     * folder's count is out, which records the stop.
     */
    spend(directory: string): boolean;
    /**
     * Whether the walk may still list `directory`; a folder whose count is out
     * records the stop and is not listed at all.
     */
    opens(directory: string): boolean;
    /**
     * The `limit` a listing of `directory` hands its backend: one entry past
     * what the walk may still keep there, so a backend that stops at it still
     * leaves the walk the entry that records its stop; null when nothing caps
     * the walk.
     */
    listingLimit(directory: string): number | null;
    /**
     * `readdir` of `directory`, cut to what the walk may still list; the
     * backend is handed the `limit` past which it may stop.
     */
    listing(readdir: WalkCall<string[]>, directory: PathSpec): Promise<string[]>;
}
/**
 * A walk's `readdir` and `stat`, answered from the mount's `readTree`.
 *
 * The first `readdir` of a directory no answer covers asks `readTree` for
 * everything under it, and every later `readdir` and `stat` below it answers
 * from that, so a walk costs one call. An answer of null, a mount without
 * `readTree`, or a dispatcher that declines it (a path rule below the
 * directory) leaves the walk to `readdir` and `stat`, each judged on its own,
 * as does a path the answer does not hold; under a hide the dispatcher
 * answers without the hidden entries. A subtree read stops at a link
 * (ENOTDIR), so a directory a walk reached through one is opened by
 * `readdir`, which follows it as opendir(3) does and meets whatever refuses
 * the directory it leads to. Both take the path first and pass the rest
 * through; a listing's `limit` reaches `readTree` too, which may then answer
 * null for a subtree past it.
 *
 * A directory no whole answer covers is read one level at a time
 * (`readTree(path, limit, true)`): its listing and each child's stat in one
 * call, so a walk the mount reads no subtree for, or one a depth bounds,
 * stats no child on its own either. A listing a limit cuts is read again
 * under the next one, as `readdir` would be. `whole` false reads levels only,
 * for a walk a depth bounds or a single listing. Mirrors Python's
 * `tree_walk`.
 *
 * An answer from the tree resolves in a microtask, so the walk spends a
 * yield budget under `signal` (the line's abort and deadline) and stops once
 * it fires.
 */
export declare function treeWalk<D, S>(readTree: ReadTree | undefined, readdir: WalkCall<D>, stat: WalkCall<S>, whole?: boolean, signal?: AbortSignal): [WalkCall<D>, WalkCall<S>];
//# sourceMappingURL=tree.d.ts.map