import type { OpRecord } from '../observe/record.ts'; import { type NamespaceLinks } from './config.ts'; import type { FileStat, SetAttrFields } from '../types.ts'; import type { DispatchFn } from '../runtime/types.ts'; export type OpSink = (rec: OpRecord) => Promise; interface MountOwner { readonly prefix: string; readonly kind: string; } export type OwnerOf = (path: string) => MountOwner | null; /** * The typed op facade FUSE and programmatic embedders call. * * Every op delegates to the workspace dispatcher, so `ws.fs` walks the * same pipeline as a shell command: link follow, session grants, * admission policies, cache read-through, namespace structure, and * post-write invalidation all fire once, at that one door. The facade * keeps only what is its own: the typed surface and the op ledger * (`records`, with the network/cache split derived from it) — the * ledger lives here, not on the workspace, which is what lets * `MountCore` take one `Ops` instead of reaching through a whole * `Workspace`. Mirrors Python's `Ops`. */ export declare class Ops { private readonly dispatch; private readonly sink; readonly links: NamespaceLinks | null; private readonly ownerOf; /** * The op ledger: every facade op lands here, and the executor * appends each shell line's ops too, so this is the one * workspace-wide account (python's `Ops.records`). */ readonly records: OpRecord[]; constructor(dispatch: DispatchFn, sink?: OpSink | null, links?: NamespaceLinks | null, ownerOf?: OwnerOf); /** Ops that moved bytes over the network, in arrival order. */ get networkRecords(): OpRecord[]; get networkBytes(): number; /** Ops a warm cache answered, in arrival order. */ get cacheRecords(): OpRecord[]; get cacheBytes(): number; private record; /** * Run one op through the workspace dispatcher and record it. * * The door owns the whole pipeline (follow, grants, gates, cache, * structure, invalidation); the facade's own share is the record. The * path is link-followed here first so the record carries the resolved * path; the door's second follow of an already-resolved path is a * no-op. Mirrors Python's Ops._through_door. */ private through; /** * Record one op from the door's report of who served it. * * The door names the server when it was not the owning mount (a warm * cache hit, a synthetic namespace answer): neither moved bytes over * the network, and 'ram' is what OpRecord.isCache reads. It names the * moved bytes when the delivered result no longer measures them, * because a cap truncated it or a refusal withheld it entirely. */ private recordOp; readFile(path: string, options?: { raw?: boolean; offset?: number; size?: number | null; }): Promise; readFileText(path: string, encoding?: string): Promise; writeFile(path: string, data: Uint8Array | string): Promise; /** * Append bytes to a file through the mount's append op (the python * facade's `append`). No whole-file fallback here: that is * RuntimeVFS's business, where a guest holds the full buffer; an * embedder calling the facade gets the mount's real answer. */ append(path: string, data: Uint8Array): Promise; readdir(path: string): Promise; stat(path: string): Promise; exists(path: string): Promise; isDir(path: string): Promise; isFile(path: string): Promise; mkdir(path: string): Promise; create(path: string): Promise; /** * Create a namespace symlink at `path`. * * Routed through the door like every write: session grants and * admission policies fire on the link's turf, and the write lands on * the ledger. The target is stored verbatim as typed. Throws EEXIST * when something is already at `path` (a file, a directory, another * link, a mount root): symlink(2) never overwrites, and the door is * the layer that can see both planes to tell. Mirrors Python's * Ops.symlink. */ symlink(path: string, target: string): Promise; /** The stored target of the link at `path`; EINVAL when not a link. */ readlink(path: string): Promise; /** * Write metadata fields, natively where the backend can hold them. * * Every field is passed, unset ones as undefined, because the door * reads the whole set and stores in the namespace overlay whatever * the backend cannot keep. A mount with no setattr op therefore still * answers: a chmod on an s3 or dropbox mount lands in the name plane * and stat reports it back. Stored, not enforced; the mount mode is * the access control. Returns what the backend could not keep. * Mirrors Python's Ops.setattr. */ setattr(path: string, attrs?: SetAttrFields): Promise>; truncate(path: string, length: number): Promise; unlink(path: string): Promise; rmdir(path: string): Promise; /** * Rename a file or directory within one mount. * * Both ends must resolve to the same mount: a mount is a filesystem * boundary, and the facade is where a kernel-facing whole-workspace * FUSE mount needs the refusal, so `mv` between two backends falls * back to its copy+unlink path instead of corrupting one backend's * key space with the other's path. Mirrors Python's Ops.rename. */ rename(src: string, dst: string): Promise; cat(path: string): Promise; listFiles(path: string): Promise; } export {}; //# sourceMappingURL=ops.d.ts.map