Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 

README.md

@catmint-fs/core

A copy-on-write virtual filesystem layer over a pluggable backing store. Reads fall through to the underlying adapter; writes are captured in memory until explicitly applied or discarded.

Features

  • Copy-on-write semantics -- modifications are staged in memory, leaving the backing store untouched until you call apply()
  • Pluggable adapters -- swap between local disk, SQLite, or your own FsAdapter implementation
  • Browser-compatible public API -- uses Uint8Array instead of Buffer, ReadableStream instead of Node streams
  • POSIX-like interface -- readFile, writeFile, mkdir, rm, stat, chmod, chown, symlink, rename, and more
  • Change tracking -- inspect pending changes via getChanges() and getChangeDetail()
  • Atomic apply -- commit all pending changes to the backing adapter in one operation, with per-file error reporting

Installation

pnpm add @catmint-fs/core

Quick start

import { createLayer } from "@catmint-fs/core";

// Create a layer backed by the local filesystem
const layer = await createLayer({ root: "/path/to/project" });

// Read a file (falls through to disk)
const data = await layer.readFile("/src/index.ts");

// Write a file (captured in memory)
await layer.writeFile("/src/index.ts", "export default 42;\n");

// Inspect what changed
const changes = layer.getChanges();
// [{ type: "update", path: "/src/index.ts" }]

// Apply all pending changes to disk
const result = await layer.apply();
console.log(result.applied); // number of changes written

// Or discard everything
layer.reset();

API

createLayer(options): Promise<Layer>

Factory function that creates a Layer instance.

interface CreateLayerOptions {
  root: string;          // Absolute path for the layer root
  adapter?: FsAdapter;   // Defaults to LocalAdapter (Node.js only)
}

Layer

Reading

Method Signature
readFile (path: string) => Promise<Uint8Array>
createReadStream (path: string) => ReadableStream<Uint8Array>
readdir (path: string) => Promise<DirentEntry[]>
stat (path: string) => Promise<StatResult>
lstat (path: string) => Promise<StatResult>
readlink (path: string) => Promise<string>
exists (path: string) => Promise<boolean>

Writing

Method Signature
writeFile (path: string, data: string | Uint8Array, options?: WriteOptions) => Promise<void>
mkdir (path: string, options?: MkdirOptions) => Promise<void>
rm (path: string, options?: RmOptions) => Promise<void>
rmdir (path: string) => Promise<void>
rename (from: string, to: string) => Promise<void>
symlink (target: string, path: string) => Promise<void>

Permissions

Method Signature
chmod (path: string, mode: number) => Promise<void>
chown (path: string, uid: number, gid: number) => Promise<void>
lchown (path: string, uid: number, gid: number) => Promise<void>
getOwner (path: string) => Promise<{ uid: number; gid: number }>

Change tracking

Method Signature
getChanges () => ChangeEntry[]
getChangeDetail (path: string) => Promise<ChangeDetail | null>

Lifecycle

Method Description
apply(options?) Commits all pending changes to the backing adapter. Returns ApplyResult.
reset() Discards all pending changes.
dispose() Releases resources. The layer is unusable after this call.

FsAdapter

Implement this interface to create a custom backing store:

interface FsAdapter {
  readFile(path: string): Promise<Uint8Array>;
  createReadStream(path: string): ReadableStream<Uint8Array>;
  readdir(path: string): Promise<DirentEntry[]>;
  stat(path: string): Promise<StatResult>;
  lstat(path: string): Promise<StatResult>;
  readlink(path: string): Promise<string>;
  exists(path: string): Promise<boolean>;
  writeFile(path: string, data: Uint8Array, options?: WriteOptions): Promise<void>;
  mkdir(path: string, options?: MkdirOptions): Promise<void>;
  rm(path: string, options?: RmOptions): Promise<void>;
  rmdir(path: string): Promise<void>;
  rename(from: string, to: string): Promise<void>;
  symlink(target: string, path: string): Promise<void>;
  chmod(path: string, mode: number): Promise<void>;
  chown(path: string, uid: number, gid: number): Promise<void>;
  lchown(path: string, uid: number, gid: number): Promise<void>;
  checkPermission(path: string, op: PermissionOp): Promise<void>;
  capabilities(): AdapterCapabilities;
  initialize?(root: string): Promise<void>;
}

Built-in adapters

  • LocalAdapter -- Delegates to Node.js fs module. Used by default when no adapter is specified. Node.js only.

Browser compatibility

The Layer class and the FsAdapter interface use only browser-safe types (Uint8Array, ReadableStream). To use @catmint-fs/core in a browser, provide a custom FsAdapter implementation -- LocalAdapter is Node.js only.

License

GPL-2.0 -- see LICENSE for details.