import { PathSpec } from '../types.ts'; export type Allowed = (virtual: string) => boolean; /** * A remnant cascade met an entry the session can see. * * Thrown by `removeRemnants` before the visible entry is touched: the * caller's not-empty refusal is then simply true in the session's own * view, so every arm answers this by re-raising that original refusal * rather than deleting visible data. */ export declare class VisibleRemnant extends Error { readonly code = "ENOTEMPTY"; readonly virtual: string; constructor(virtual: string); } /** * The four ops a remnant cascade speaks, on one plane's own protected * channel. * * The channel carries every protection axis except visibility: a * deletion must still answer for its path's mode and rules exactly as * a first-class op would (the command plane binds its mode- and * rule-guarded slots, the dispatcher routes through its own fenced op * door), while the visibility filter stays off because the cascade * exists to see and destroy what the session cannot. The cascade never * sprinkles those checks itself; wiring a raw, unguarded channel here * is the bug this contract exists to prevent. */ export interface RemnantChannel { readdir(spec: PathSpec): Promise; stat(spec: PathSpec): Promise; unlink(spec: PathSpec): Promise; rmdir(spec: PathSpec): Promise; } /** * One listing entry's bare child name. Cold object-store listings mark * a directory with a trailing slash, and some backends report whole * paths rather than names; both normalize to the last component. */ export declare function entryName(entry: string): string; /** * Whether any listed name is visible as a child of `base`. * * The one emptiness predicate every remnant arm judges with, fed every * name source its plane can enumerate (the backend listing, and on the * ops plane the namespace's merged children too), so "visibly empty" * cannot mean different things at different doors. */ export declare function visibleBelow(base: string, names: Iterable, allowed: Allowed): boolean; /** The child PathSpec one cascade step descends to. */ export declare function childSpec(spec: PathSpec, name: string): PathSpec; /** * Remove one directory and everything under it, children first, * revalidating visibility at every step. * * The walk lists raw, but the moment any entry is visible the whole * cascade aborts with `VisibleRemnant` before that entry is touched: * between the caller's classification and each deletion another writer * may have created something visible, and destroying it would turn an * ostensibly empty rmdir into data loss. An entry that vanishes * mid-walk is a completed removal (a prefix-store directory disappears * with its last child), not an error. Every op goes through the * channel, so the plane's other protections refuse exactly as they * would a first-class op; the caller answers any cascade failure with * its original refusal. */ export declare function removeRemnants(channel: RemnantChannel, allowed: Allowed, spec: PathSpec): Promise; //# sourceMappingURL=remnants.d.ts.map