//#region ../fs/types.d.ts
/** Inode identifier — unique within a filesystem */
type Ino = string;
/** Byte-level offset */
type Off = bigint;
/** File type — kept minimal. Numeric values are the wire format; do not reorder. */
declare const FileType: {
  readonly Regular: 0;
  readonly Directory: 1;
  readonly Symlink: 2;
};
type FileType = (typeof FileType)[keyof typeof FileType];
/** Minimal stat — what the FS actually stores per inode */
interface Stat {
  ino: Ino;
  type: FileType;
  size: Off;
  mode: number;
  mtimeNs: bigint;
  ctimeNs: bigint;
  /**
   * Hash of the file's current content (e.g. SHA-256, hex-encoded).
   * Promoted from backend-private InodeMeta to the public Stat surface
   * because upper layers need it as a change
   * signal without reading file content.
   */
  contentHash?: string;
}
/** Directory entry — what you get when reading a directory */
interface Dirent {
  ino: Ino;
  name: string;
  type: FileType;
}
//#endregion
//#region ../fs/volume.d.ts
/**
 * Path-based filesystem interface built on top of Storage.
 *
 * Design principles:
 * - All paths are absolute (start with '/').
 * - No encoding at this layer — I/O is always Uint8Array. The caller decodes.
 * - No hidden cursor state — readdir returns the full list, scan streams via
 *   a visitor.
 * - Symlinks are followed by default (stat, readFile, etc). Use lstat to
 *   inspect a symlink itself.
 * - Errors follow POSIX naming (ENOENT, EEXIST, ENOTDIR, EISDIR, ENOTEMPTY)
 *   thrown as plain Error objects with the code at the start of the message.
 */
interface Volume {
  /**
   * Stat a path, following symlinks.
   * Throws ENOENT if the path does not exist.
   */
  stat(path: string): Promise<Stat>;
  /**
   * Stat a path without following the final symlink component.
   * Useful for inspecting symlinks themselves.
   */
  lstat(path: string): Promise<Stat>;
  /** Returns true if the path exists (any file type). Never throws. */
  exists(path: string): Promise<boolean>;
  /** Read a single xattr from a path, following the final symlink. */
  getXattr(path: string, name: string): Promise<Uint8Array | null>;
  /** Write or replace a single xattr on a path, following the final symlink. */
  setXattr(path: string, name: string, value: Uint8Array): Promise<void>;
  /** List all xattr names currently set on a path. */
  listXattr(path: string): Promise<string[]>;
  /** Remove a single xattr from a path. */
  removeXattr(path: string, name: string): Promise<void>;
  /**
   * Read the entire contents of a file into memory.
   * Throws ENOENT if the file does not exist.
   * Throws EISDIR if the path is a directory.
   */
  readFile(path: string): Promise<Uint8Array>;
  /**
   * Write (create or overwrite) a file.
   * Parent directory must exist.
   * Throws ENOENT if a parent directory is missing.
   * Throws EISDIR if the path refers to a directory.
   *
   * A CREATE is ATOMIC: the path does not exist, and then it exists holding exactly
   * `data`. A concurrent reader never resolves it and finds a prefix (#324) — the
   * bytes and the name commit as one fact, so a reader needs no retry, no deadline
   * and no way to tell "still being written" from "corrupt". It cannot have one: the
   * intermediate states a torn writer exposes are not enumerable from the reader's
   * side, and the last of them (a prefix that happens to parse) is silent.
   *
   * An OVERWRITE is NOT atomic, deliberately. Making it atomic means publishing a
   * new inode under the same name, which churns everything keyed by inode (the
   * native backend's path map, `metaCache`, and `watch`'s change feed) and defeats
   * `putBlob`'s check that the inode it opened is still the
   * one the name points at. So a reader concurrent with an overwrite observes the
   * old bytes or the new ones, and on a backend that fills in place (native) a torn
   * state in between — the same as POSIX, and as Node's `fs.writeFile`. Order it, or
   * write to a fresh name and `rename`.
   *
   * Atomicity here is about VISIBILITY, not durability: nothing is fsynced.
   *
   * Moves the file's `mtimeNs`/`ctimeNs` to now, so mtime means "when these bytes
   * last changed" and an app can sort by recency. A write with an imported timestamp
   * keeps that time because it is the same edit, not a new one. Directory
   * mtime is NOT maintained — no caller reads it.
   *
   * `exclusive` and `update` are the two ends of one question — what must be true of
   * the path before these bytes land — and this call is the only place it can be
   * asked without a gap, because it is the call that resolves the path.
   *
   * With `exclusive: true` this is a CREATE, not a write: it throws EEXIST if the
   * path is already taken. That makes it a *claim* on a name rather than a probe —
   * `exists()` followed by `writeFile` is a TOCTOU, and the loser of the race has
   * its file overwritten. The check, the create and the content are one operation in
   * the backend (`atomicCreate`: `O_EXCL` + `link`, a single IndexedDB transaction, a
   * synchronous map check), so concurrent writers are decided by the storage and the
   * loser can read the winner back immediately. A backend without that capability
   * falls back to a best-effort pre-check.
   *
   * With `update: true` it is an EDIT, not a create: ENOENT if nothing is there
   * (`open` without `O_CREAT`). A plain write brings a file into being, and with it
   * every missing parent folder — so a caller holding a path that has since been
   * moved or deleted silently *recreates* the tree it remembers instead of failing.
   * An editor autosaving to the note it has open wants this: the write is where the
   * path is proven still real, so it cannot be stale by the time the bytes land.
   */
  writeFile(path: string, data: Uint8Array, opts?: {
    exclusive?: boolean;
    update?: boolean;
  }): Promise<void>;
  /**
   * Append data to a file, creating it if it does not exist.
   * Parent directory must exist.
   */
  appendFile(path: string, data: Uint8Array): Promise<void>;
  /**
   * Create a directory.
   * With recursive: silently succeeds if the directory already exists and
   * creates all missing parent directories.
   * Without recursive (default): throws EEXIST if the path exists, throws
   * ENOENT if a parent is missing.
   */
  mkdir(path: string, opts?: {
    recursive?: boolean;
    mode?: number;
  }): Promise<void>;
  /**
   * List the contents of a directory.
   * Returns one Dirent per entry (name + type + ino).
   * Throws ENOENT if the directory does not exist.
   * Throws ENOTDIR if the path is not a directory.
   */
  readdir(path: string): Promise<Dirent[]>;
  /**
   * Remove a file, symlink, or directory.
   * - recursive: remove non-empty directories (like rm -r).
   * - force: silently succeed if the path does not exist (like rm -f).
   * Throws ENOTEMPTY if the path is a non-empty directory and recursive is
   * not set.
   */
  rm(path: string, opts?: {
    recursive?: boolean;
    force?: boolean;
  }): Promise<void>;
  /**
   * Move or rename a file, symlink, or directory.
   * If newPath already exists it is replaced atomically (POSIX rename
   * semantics). Throws ENOENT if oldPath does not exist.
   *
   * There is NO exclusive form, and that is a decision about where a guarantee can live
   * rather than an omission. POSIX `rename` replaces, and no atomic no-replace rename is
   * reachable from Node (`renameat2(RENAME_NOREPLACE)` and `renamex_np(RENAME_EXCL)` are
   * not bound), so on a real filesystem "refuse a taken destination" could only ever be a
   * check before the act. `writeFile`'s `exclusive` is different in KIND: `O_EXCL` is a
   * primitive every backend already has, so there the check IS the operation.
   *
   * Offering the flag anyway would mean a promise whose strength varied by backend —
   * settled by one store's transaction, guessed at by a filesystem — and a call site
   * cannot reason about that. So claiming a name is the CALLER's policy, held in one
   * place, which is what every system in this position does: git takes a lock it owns
   * (`index.lock`, `O_CREAT|O_EXCL`), Maildir gives files names that cannot collide, dpkg
   * writes `.dpkg-tmp` and moves it. Here it is app-notes' `claimPath` — order the claims,
   * check the destination, number up on EEXIST (its DESIGN.md §1b records why).
   *
   * What the backends owe REGARDLESS, and honour without being asked, is not corrupting
   * the tree while replacing: a displaced inode is freed only when no other directory
   * entry still names it (`Storage.deleteInode`'s rule), so a name that survives the move
   * still resolves.
   */
  rename(oldPath: string, newPath: string): Promise<void>;
  /**
   * Copy a file or directory.
   * - recursive: required when src is a directory; copies the entire subtree.
   * If dest already exists it is overwritten for files; for directories the
   * contents are merged.
   * Throws EISDIR / ENOTDIR on type mismatches.
   */
  cp(src: string, dest: string, opts?: {
    recursive?: boolean;
  }): Promise<void>;
  /**
   * Create a symbolic link at path pointing to target.
   * Argument order mirrors POSIX ln -s: symlink(target, path).
   * Throws EEXIST if path already exists.
   */
  symlink(target: string, path: string): Promise<void>;
  /**
   * Read the raw target string of a symbolic link.
   * Throws ENOENT if path does not exist.
   * Throws EINVAL if path is not a symlink.
   */
  readlink(path: string): Promise<string>;
  /**
   * Change the permission mode bits of a file or directory.
   * Follows symlinks (acts on the target, not the link itself).
   */
  chmod(path: string, mode: number): Promise<void>;
  /**
   * Set the modification time of a file or directory.
   * Expressed in nanoseconds since the Unix epoch.
   * Useful for preserving mtimes when syncing or copying.
   */
  utimes(path: string, mtimeNs: bigint): Promise<void>;
  /**
   * Walk the subtree rooted at path, calling visitor once per node
   * (including the root itself).
   *
   * Directories are visited before their contents. Paths passed to the
   * visitor are absolute and normalised.
   *
   * Delegates to Storage.caps.fullScan() when available —
   * O(pages) round trips for cloud backends. Falls back to recursive readdir.
   *
   * Throws ENOENT if path does not exist.
   */
  scan(path: string, visitor: (path: string, stat: Stat) => Promise<void>): Promise<void>;
  /**
   * Watch a single path for changes — an inotify-style primitive.
   *
   * The listener fires after a change to the path commits, coalesced per
   * microtask (one logical write = several storage ops = one event). Like
   * real inotify it tracks both the resolved inode (content/meta edits) AND
   * the parent dentry, so a delete+recreate or rename/replace that rebinds
   * the path to a fresh inode still fires (and the next event re-resolves).
   *
   * The event carries the `source` the write was tagged with, so callers can
   * ignore their own writes. The path need not exist yet — once a dentry binds it,
   * the watch picks it up.
   *
   * With `{ recursive: true }` the watch instead reports STRUCTURAL changes
   * — entries created/removed/renamed — at or under `path`, plus a rebind of
   * `path` itself or of any ancestor (which takes the whole subtree with it);
   * pair it with a `scan` of the same path to rebuild the listing. Content/meta
   * edits to existing files do NOT fire — watch the concrete file for those. That
   * also holds when another writer updates a path that already exists: it is an
   * edit, not structure. This is the
   * substrate for a directory browser's auto-refresh.
   *
   * A recursive delivery is a WAKE, not a log: it says the listing is stale and
   * carries no per-change detail, so events are coalesced into at most one delivery
   * per `WATCH_BURST_MS` with a guaranteed trailing one. A bulk operation therefore
   * wakes a consumer a bounded number of times, not once per entry.
   *
   * Requires `Storage.caps.subscribe`; without it the watch is inert and the
   * returned unsubscribe is a no-op. Returns a promise of the unsubscribe.
   */
  watch(path: string, listener: (event: WatchEvent) => void, opts?: {
    recursive?: boolean;
  }): Promise<() => void>;
}
/** Payload delivered to a `volume.watch` listener. */
interface WatchEvent {
  /** The `MutationOptions.origin` the triggering write was tagged with. */
  source?: string;
}
//#endregion
export { Volume as t };
//# sourceMappingURL=volume-C3ZPZJ79.d.ts.map