UNPKG

@struktoai/mirage-core

Version:

A Unified Virtual Filesystem For AI Agents

101 lines • 3.52 kB
import { type RuntimeFiles } from '../../../files.ts'; import type { SetAttrFields } from '../../../../types.ts'; /** * One guest change to names or metadata, recorded in the order the script * performed it. A file's bytes are not here: its stream writes through * its core handle (`SyncVFS.pwrite`). */ export type MirageMutation = { readonly kind: 'create'; readonly path: string; } | { readonly kind: 'truncate'; readonly path: string; readonly length: number; } | { readonly kind: 'mkdir'; readonly path: string; } | { readonly kind: 'unlink'; readonly path: string; } | { readonly kind: 'rmdir'; readonly path: string; } | { readonly kind: 'rename'; readonly path: string; readonly dst: string; } | { readonly kind: 'symlink'; readonly path: string; readonly target: string; } | { readonly kind: 'setattr'; readonly path: string; readonly attrs: SetAttrFields; }; /** * The write-ahead log a pyodide guest records into. * * Every mark is deliberately synchronous: the guest's os.mkdir() and * os.rename() run inside sync WASM frames where awaiting a mount op * needs JSPI stack switching, which most engines do not enable. The guest * records here and the runtime replays after the script returns, where * awaiting is free. This is the one thing pyodide needs that the other * runtimes do not: quickjs suspends at the call and monty runs the op on * its own worker. */ export interface MutationJournal { markCreate(path: string): void; /** * Take back the create of `path` the journal ends with, which the open * right after it makes instead; false when it ends with no such create. */ takeCreate(path: string): boolean; /** * Args: * path: mount-prefixed path the mutation names. * length: the length the file is left at. */ markTruncate(path: string, length: number): void; markMkdir(path: string): void; markUnlink(path: string): void; markRmdir(path: string): void; markRename(src: string, dst: string): void; /** * Args: * path: guest-absolute path of the link. * target: what it points at, stored verbatim. */ markSymlink(path: string, target: string): void; /** * Args: * path: guest-absolute path whose metadata changed. * attrs: only the fields the guest wrote, already in the op's own * terms (ISO stamps), because the unit Emscripten passes is the * caller's fact and not the journal's. */ markSetattr(path: string, attrs: SetAttrFields): void; /** Drain the journal: every mutation in guest order, cleared. */ takeMutations(): MirageMutation[]; /** * Record nothing more until `reopen`: the guest called `os._exit`, and * a process that exited writes nothing after it, even when the guest * catches the exit and runs on. */ seal(): void; /** Whether the guest exited since the last `reopen`: its streams read and write nothing more either. */ readonly sealed: boolean; /** Record again, for the next run. */ reopen(): void; } export declare function createJournal(): MutationJournal; /** * Replay one recorded guest mutation against the mounts. * * Args: * files: the runtime's mount vocabulary to apply through. * mutation: the journal entry to apply. */ export declare function applyMutation(files: RuntimeFiles, mutation: MirageMutation): Promise<void>; //# sourceMappingURL=journal.d.ts.map