import { LostPaths, OpRecord, RecordIndex, type Recorder, type RevisionsState } from './record.ts';
import type { PathSpec } from '../types.ts';
import { type Clock } from '../utils/clock.ts';
declare module '../context/session_context.ts' {
    interface Caller {
        readonly recording: Recorder | null;
        readonly revisions: RevisionsState | null;
    }
}
/**
 * Collect the records the running command itself emits.
 *
 * `fn` gets a fresh list that {@link record} and {@link recordStream}
 * append to, beside the line's records, while it runs. A nested call opens
 * its own list, and where async context isolates tasks (node) a concurrent
 * task keeps its own, so a pipeline stage never sees a sibling stage's
 * records; the browser's shared frame stack cannot promise that (see
 * `asyncContextIsolatesTasks`). Nothing is collected outside a recording
 * scope. Each record also reaches the list of the nearest call made with
 * `own`: a command's, which the dispatcher calls under it add to too, and
 * which takes nothing for the call around it, so a command reading
 * another's output is not charged with that command's reads. Mirrors
 * python's `command_records`.
 */
export declare function commandRecords<T>(fn: (records: OpRecord[]) => Promise<T>, own?: boolean): Promise<T>;
/**
 * The version the running line itself names for `key`, with whether the line
 * knows `key` at all. A lost path names the version its write lost on;
 * otherwise the newest version record does, a stamp its token and a
 * retraction none. Mirrors Python's `line_version`.
 */
export declare function lineVersion(index: RecordIndex, lost: LostPaths | null, key: string): [boolean, string | null];
/** The version index of the line whose records these are; one per line. */
export declare function recordIndex(records: readonly OpRecord[]): RecordIndex;
/** The lost paths of the line whose records these are, null outside a line. */
export declare function lostPaths(records: readonly OpRecord[] | undefined): LostPaths | null;
/** Mark `key` lost on the running line, if one is recording. */
export declare function markLost(path: PathSpec, version?: string | null): void;
/** The running line's marks so far, for a later `liftLost`. Mirrors Python's `lost_count`. */
export declare function lostCount(): number;
/** Lift the running line's marks a removal or move of `key` ended. Mirrors Python's `lift_lost`. */
export declare function liftLost(path: PathSpec, upto: number, subtree?: boolean): void;
export declare function activeRecords(): readonly OpRecord[] | undefined;
/**
 * Run `fn` recording its calls, and answer what it returned with what it
 * recorded. `ledger` is the workspace ledger a line hands its records to,
 * which a file call of that workspace made on the line joins; `clock` is
 * the workspace clock its ops are timed and stamped on.
 */
export declare function runWithRecording<T>(fn: () => Promise<T>, ledger?: OpRecord[] | null, clock?: Clock): Promise<[T, OpRecord[]]>;
/**
 * Run `fn` with `mountId` as the mount its records belong to.
 *
 * Derives a state for this async branch and shares only the records array,
 * so two mounts consumed concurrently (`cat /s3/a & cat /db/b`) cannot see
 * or clobber each other's mount. Mirrors python's `push_mount_context`,
 * whose `Recorder` is frozen and re-set per task for the same reason.
 * An undefined `mountId` inherits the enclosing frame's.
 *
 * Inert (runs `fn` unchanged) when no recording context is active.
 */
export declare function runWithMountContext<T>(fn: () => Promise<T>, mountId?: string | null): Promise<T>;
/**
 * Wrap a stream so `mountId` is the active mount during each pull from the
 * underlying source. A command may return a stream that defers its backend
 * read to the first chunk request, by which point the mount's own scope has
 * already exited, so without this the record lands under whatever frame
 * drains it. An iterator rather than a generator: a generator queues `return`
 * behind a pull waiting for the next chunk, so the close of an idle follow
 * would never reach the source whose own close ends that wait. Mirrors
 * python's `with_mount_context`.
 */
export declare function withMountContext(it: AsyncIterable<Uint8Array>, mountId?: string | null): AsyncIterableIterator<Uint8Array>;
export declare function recordingActive(): boolean;
export interface RecordOptions {
    fingerprint?: string | null;
    revision?: string | null;
}
/**
 * A running stopwatch for one op, owned by the record path.
 *
 * Opened where the backend work begins and read once when the op
 * finishes, so an op module hands this around instead of reading a
 * clock of its own. The wall-clock stamp the record carries is taken at
 * finish time, not here, on the same clock. Mirrors python's `OpTimer`.
 */
export declare class OpTimer {
    readonly clock: Clock;
    private readonly startMs;
    constructor(clock: Clock);
    /** Milliseconds elapsed since the timer was opened. */
    get elapsedMs(): number;
}
/**
 * Open the record path's stopwatch for one op. Hand the timer to
 * {@link record} or {@link finishRecord} when the op completes. The timer
 * runs on the clock of the line recording the op; outside a recording
 * nothing keeps the record, and the system clock times it.
 */
export declare function startOp(): OpTimer;
/**
 * Close `timer` and build the finished record.
 *
 * The one place an op's duration and wall-clock stamp are read, both on the
 * timer's clock, shared
 * by the recorder sink ({@link record}) and by the `Files` facade's own
 * ledger, so the two cannot disagree about what a duration measures.
 * `path` is stored as given.
 */
export declare function finishRecord(op: string, path: string, source: string, nbytes: number, timer: OpTimer, options?: RecordOptions): OpRecord;
/**
 * Append a finished record to the active recording, if any.
 *
 * `path`: the full virtual path.
 */
export declare function record(op: string, path: string, source: string, nbytes: number, timer: OpTimer, options?: RecordOptions): void;
/**
 * Append a streaming record whose bytes are filled in as it drains.
 * Set `complete` after normal exhaustion, never after failure or early close.
 *
 * `path`: the full virtual path.
 */
export declare function recordStream(op: string, path: string, source: string, options?: RecordOptions): OpRecord | null;
/**
 * Run `fn` inside a revisions context. Backend read functions inside
 * `fn` (or any async chain it starts) can consult {@link revisionFor}
 * to look up a pin. Independent of {@link runWithRecording} so that
 * direct {@link Workspace.dispatch} calls (which don't open a recording
 * scope) still honour installed pins.
 *
 * Task-isolated via AsyncLocalStorage: concurrent runs on different
 * mounts each see their own pin map.
 */
export declare function runWithRevisions<T>(revisions: Map<string, string> | null, fn: () => Promise<T>): Promise<T>;
/**
 * Look up the active revision pin for `path`, or null if no pin is
 * installed (or no revisions context is active).
 *
 * Every live frame's map is searched, because pins are mount state
 * threaded through the context only for reach: each bind hands over
 * the mount's own map, keyed by full virtual path, so a hit is never
 * another task's different pin — the same mount binds the same map,
 * and another mount's map cannot hold this path. On the fallback
 * storage this is what keeps a pinned read pinned while an unpinned
 * op's frame shadows the newest slot.
 */
export declare function revisionFor(path: string): string | null;
//# sourceMappingURL=context.d.ts.map