UNPKG

@struktoai/mirage-core

Version:

A Unified Virtual Filesystem For AI Agents

154 lines • 8.22 kB
import type { Context } from '../../config.ts'; import type { FollowOperands, LinkView, MountView } from '../../../view/types.ts'; import type { DispatchFn } from '../../../runtime/types.ts'; import type { FileStat, Limit } from '../../../types.ts'; import { PathSpec } from '../../../types.ts'; import type { ByteSource } from '../../../io/types.ts'; import { type Files } from '../../../workspace/files.ts'; /** * Where a name stands as lstat reaches it: every link above its final name * followed, the name itself kept. * * The walk the kernel gives a path before a call that does not follow its * final name, and the key the table files a link under, since every link is * keyed by its resolved parent. A path ending in a slash resolves whole: * POSIX reads `dlink/` as `dlink/.`. Throws CycleError on a loop. Mirrors * Python's link_location. */ export declare function linkLocation(links: LinkView, virtual: string): string; /** * Where the name an operand was typed as stands, as lstat reaches it. * * Every component but the last resolves through the links, as the kernel * walks any path, so `dl/tl.gz` with `dl` a link to `dir` stands at * `dir/tl.gz`: the table keys every link by that resolved parent. Null where * the last component resolves as well, which is a name typed with a trailing * slash or ending in a dot, and where the walk already failed. Mirrors * Python's name_location. */ export declare function nameLocation(links: LinkView, path: PathSpec, cwd: string): string | null; /** * The link standing at the name an operand was typed as, its own row. * * The router follows an operand through its link before the command runs, * which leaves `virtual` at the target and the name in `rawPath`; a command * that acts on the name itself (cp -P, gzip's O_NOFOLLOW open) asks here. * Null where no link stands at the name. Mirrors Python's typed_link. */ export declare function typedLink(links: LinkView, path: PathSpec, cwd: string): FileStat | null; /** * The namespace's links as a command meets a name, and the dispatcher past them. * * A link is invisible to every backend, so a command bound to one mount needs * the links to tell a name that stands on one, and the dispatcher to act where * the link leads or where it stands: the target may live on any mount, and so * may the link. Mirrors Python's LinkResolver. */ export declare class LinkResolver { readonly links: LinkView; readonly dispatch: DispatchFn; readonly cwd: string; constructor(links: LinkView, dispatch: DispatchFn, cwd: string); /** Where the link standing at an operand's name sits, null where no link * stands there. */ linkAt(path: PathSpec): string | null; /** * Whether the link the router followed an operand through is gone. * * The router follows every operand before the command runs, so an earlier * operand that removed the link (`gunzip -f l.gz l.gz`) leaves a later one * at the old target: GNU opens each name when it reaches it, and finds * nothing there. */ vanished(path: PathSpec): boolean; /** * Where a link leads, every link on the way followed. A chain that loops * throws ELOOP, an error a walker reports as it reports any failed stat. */ target(link: string): string; /** What a name leads to, its stat through the dispatcher, on any mount. */ stat(virtual: string): Promise<FileStat>; /** A directory's entries through the dispatcher, links among them. */ readdir(virtual: string): Promise<string[]>; /** A name's own stat through the dispatcher: a link's, not its target's. */ lstat(path: PathSpec): Promise<FileStat>; /** What a name leads to, read through the dispatcher, which follows it. */ read(virtual: string): AsyncIterable<Uint8Array>; /** Write a file on the mount that owns the name. */ write(virtual: string, data: ByteSource): Promise<void>; /** Remove the name itself, a link rather than what it leads to. */ unlink(virtual: string): Promise<void>; } /** Whether the mount at `prefix` is the one serving `virtual`; every path is * where no mount table says otherwise. Mirrors Python's serves. */ export declare function serves(mounts: MountView | undefined, prefix: string, virtual: string): boolean; /** * The mount a walked path lands on, every link on it followed. A mount is * mirage's filesystem, so this stands for the device stat(2) reports, which * `find -xdev` compares with the start point's: a link onto another mount * leaves it as a mount root does (findutils 4.10). `virtual` is a directory * the walk reached, which resolves. Mirrors Python's landing_root. */ export declare function landingRoot(mounts: MountView, links: LinkView | null, virtual: string): string; /** * The symlink facts a walk goes by, read off the session's files, or * undefined outside a workspace. * * The dispatcher's reader answers (`NamespaceReader`), filtered by the rule * it refuses a call by: a hidden link, or one that leads where the session * cannot see, has no row, no listing entry and no target. Resolving a hidden * path leaves it as typed, for the dispatcher to refuse; a visible one * resolves, so a walker judges where it lands. Mirrors Python's link_view. */ export declare function linkView(files: Files | undefined): LinkView | undefined; /** * Where the mount boundaries are, read off the session's files, or undefined * outside a workspace. Every mount below a path, hidden or not, is a boundary * a backend's own walk stops at; only the visible ones are ever named. A walk * through the dispatcher (`crossing`) has no boundary to stop at * (`NamespaceReader.mounts`). Mirrors Python's mount_view. */ export declare function mountView(files: Files | undefined, crossing?: boolean, command?: string | null, profile?: Readonly<Record<string, Limit>>): MountView | undefined; /** * The names a directory holds only as namespace structure, as the session * sees them: the mounts below it and its links, each by its first segment * under the directory. * * No backend can list either, and the first may be one no backend serves at * all (a link made below a directory chain that holds no key); these are the * names the dispatcher merges into its own listing, from the same tables. * Mirrors Python's owed_names. */ export declare function owedNames(files: Files | undefined, directory: string): string[]; /** The workspace's links as the command's session sees them, read off its * files; undefined outside a workspace. Mirrors Python's links_of. */ export declare function linksOf(ctx: Context): LinkView | undefined; /** * Whether the command walks across mounts: it runs on the session's files * with no mount's command scope bound, as a cross-mount run does, so every * call it makes reaches whichever mount serves the path. Mirrors Python's * crosses_mounts. */ export declare function crossesMounts(ctx: Context): boolean; /** * The prefix of the mount the command runs on, without its trailing slash: * what a path the command makes up (an output name, a file a list names) is * keyed below. '' for a run across mounts, which keys every path by its * whole virtual path, and outside a workspace. Mirrors Python's mount_root. */ export declare function mountRoot(ctx: Context): string; /** * Where the mount boundaries are for the command's walk, read off its files; * undefined outside a workspace. A run across mounts (`crossesMounts`) has * the dispatcher descend into every mount, so it has no boundary to stop at. * Mirrors Python's mounts_of. */ export declare function mountsOf(ctx: Context): MountView | undefined; /** The link resolver an invocation carries: null outside a workspace. * Mirrors Python's link_resolver. */ export declare function linkResolver(ctx: Context): LinkResolver | null; /** The dispatcher a command's files run on. Mirrors Python's dispatch_of. */ export declare function dispatchOf(ctx: Context): DispatchFn | undefined; /** The line's operand resolution its files carry. Mirrors Python's follow_of. */ export declare function followOf(ctx: Context): FollowOperands | undefined; //# sourceMappingURL=links.d.ts.map