import type { Accessor } from '../../accessor/base.ts';
import { DirListing, FileStat } from '../../types.ts';
import type { ReaddirFn } from './probe.ts';
import { type DetectFn, type ScopeMatch } from './scope.ts';
export type Listed = FileStat[] | DirListing;
export type Lister<A extends Accessor> = (accessor: A, match: ScopeMatch) => Promise<Listed | null>;
export type EntryLister<A extends Accessor> = (accessor: A, match: ScopeMatch, entry: FileStat) => Promise<Listed>;
export type Guard<A extends Accessor> = (accessor: A, match: ScopeMatch, virtual: string) => Promise<void>;
export type PatternTest = (pattern: string) => boolean;
export type ExtraFn = (match: ScopeMatch) => Record<string, string>;
/**
 * What a paged listing's pages hold, and no page past the one that brings
 * `limit` rows; the pages are closed there. Mirrors Python's `held_pages`.
 */
export declare function heldPages<T>(pages: AsyncIterable<T[]>, limit: number | undefined): Promise<T[]>;
/**
 * A paged listing's rows, partial once they reach a walk's `limit`: its
 * lister stopped paging there, so a row past them may exist. Mirrors
 * Python's `cut_listing`.
 */
export declare function cutListing(rows: FileStat[], limit: number | undefined): Listed;
/**
 * Build a hierarchy readdir: dispatch, guards, rows as stat answers.
 *
 * A lister fetches one directory kind and answers its children's stats;
 * classification, existence guards and the shape a kind shares happen here,
 * identically for every backend. Each listed row is finished from its own
 * kind: `extras` add the slots it was addressed by, and a leaf the lister
 * left untyped renders as its scope's filetype (JSON by default), so a listed
 * row is what `stat` answers. A dot-prefixed name is dropped from the
 * listing: the classifier refuses every dot-leading segment, so listing one
 * would advertise a path that stat, read and child readdir all report
 * absent. A lister may answer null instead of a listing: the directory's
 * container does not exist, reported as ENOENT on the virtual path. A lister
 * may answer a `DirListing` to seed descendant listings its fetch already
 * proved, or to mark a view or a window. A walk's `limit` reaches every
 * lister in `ScopeMatch.limit`.
 *
 * An entry lister is for a directory whose existence and contents are
 * already proven by its parent's listing: it is handed the row that listing
 * named (`entry`), so entering a directory a traversal just listed costs no
 * call beyond its own listing. The facts a child listing needs beyond the
 * API's own answers ride that row's `extra` (trello stashes each `card.json`
 * size on the card's row).
 *
 * A parent-entry lister is for a directory whose existence is decided by its
 * PARENT's row rather than its own, so the proof is the parent's row
 * (`parent`) and the fetch takes the rest from the match. A kind appears in
 * at most one of the three tables.
 *
 * `staticRoot` names fixed top-level directories, for backends whose root
 * never changes. `guards` are existence checks that run before the listing,
 * so a vanished container is ENOENT. `patternKinds` holds one entry per kind
 * whose listing is a bounded window, the test for whether a glob is one its
 * lister can move the window to (`hasGlobSpan` for a date-keyed listing): a
 * glob that passes reaches the lister in `ScopeMatch.pattern`, and the mount
 * serves no stored window for a glob. `leafError` is what listing a leaf
 * raises; fixed hierarchies historically answer ENOENT. `extras` are
 * per-kind `FileStat.extra` payloads derived from a listed row's own slots.
 * Mirrors `make_readdir` in `mirage/core/hierarchy/readdir.py`.
 */
export declare function makeReaddir<A extends Accessor>(detect: DetectFn, options: {
    listers: Readonly<Record<string, Lister<A>>>;
    entryListers?: Readonly<Record<string, EntryLister<A>>>;
    parentEntryListers?: Readonly<Record<string, EntryLister<A>>>;
    staticRoot?: readonly string[];
    guards?: Readonly<Record<string, Guard<A>>>;
    patternKinds?: Readonly<Record<string, PatternTest>>;
    leafError?: 'enoent' | 'enotdir';
    extras?: Readonly<Record<string, ExtraFn>>;
}): ReaddirFn<A>;
//# sourceMappingURL=readdir.d.ts.map