import type { HitFrame, ListFrame, PathFrame } from "../types"; /** A framed adapter surface exercised by the shared protocol battery. */ export type FramedSource = (signal?: AbortSignal, onStart?: () => void) => AsyncIterable; /** * The adapter surfaces the shared conformance battery exercises. * * @remarks * A DUCK-TYPE GUARD CANNOT CHECK BEHAVIOUR, which is why this suite exists. `implementsX()` proves a * backend has the right method names; it cannot prove the iterable is lazy, that it emits the mandatory * terminal frame, or that `signal` actually aborts mid-stream. Without those checks a conformant-LOOKING * OPFS adapter could silently impose limits the Node one does not, and the boundary would differ by * environment. * * Every framed surface must be lazy, emit each `item` frame (there is no count cap to stop at), then * EXACTLY ONE terminal `done` frame matching one union arm exactly. **A stream that ends without `done` * is a protocol violation** the tools classify as `io-failure` — never as "no overflow", because * silence is precisely what an unannounced truncation looks like. */ export interface ConformanceSources { /** Directory traversal: `item` frames carrying a path and entry kind, then one terminal frame. */ list: FramedSource; /** Name search: `item` frames carrying a path, then one terminal frame. */ findPaths: FramedSource; /** Content search: `item` frames carrying path, line, and the WHOLE matched line — no per-hit cut. */ searchContent: FramedSource; /** Must hand back a FRESH stream per call: readers are replayable, not single-use. */ read(): Promise>; /** * Metadata, including the opaque change token. * * @remarks * `version` is compared for equality and never parsed, and only ONE direction is sound: a CHANGED * token is evidence the file may have changed, while an UNCHANGED token is NOT evidence it did not — * a same-size write inside the timestamp resolution preserves it. The suite asserts the safe * direction only. */ stat(): Promise<{ size: number; version: string; }>; } /** Optional mutation fixture for adapters that expose filesystem mutators. */ export interface ConformanceMutations { /** A fresh disposable path in the selected existing directory, so checks cannot collide with repository files. */ makeFile(text: string, options?: { directory?: 'default' | 'other'; }): Promise; /** A fresh absent path with an existing parent, allowing rename checks without requiring mkdir. */ freePath(options?: { directory?: 'default' | 'other'; }): Promise; /** Observe the post-mutation metadata, including entry kind for directory checks. */ stat(path: string): Promise<{ size: number; version: string; kind: string; }>; /** Read fixture content after a mutation, proving that the operation preserved or wrote the expected text. */ read(path: string): Promise; /** Replace fixture content and make the new text observable through a subsequent read. */ write(path: string, text: string): Promise; /** Remove a fixture; the optional operation must also resolve when the path is already absent. */ delete?(path: string): Promise; /** Move a fixture and overwrite an existing destination, matching the filesystem contract. */ rename?(from: string, to: string): Promise; /** Create the requested directory hierarchy and accept an already-existing directory. */ mkdir?(path: string): Promise; } /** Result metadata from mutation conformance, including operations that were not exercised. */ export interface SandboxConformanceReport { /** Names each skipped mutation group rather than silently presenting it as passed. */ skipped: string[]; } /** Run protocol and, when supplied, optional filesystem mutation checks. */ export declare function runSandboxConformance(sources: ConformanceSources): Promise; export declare function runSandboxConformance(sources: ConformanceSources, mutations: ConformanceMutations): Promise;