An open API service indexing awesome lists of open source software.

https://github.com/corca-ai/cf-vfs

Virtual file-system for Cloudflare Durable Objects and R2
https://github.com/corca-ai/cf-vfs

cloudflare-workers durable-objects r2 sqlite virtual-filesystem

Last synced: 2 days ago
JSON representation

Virtual file-system for Cloudflare Durable Objects and R2

Awesome Lists containing this project

README

          

# cf-vfs

`cf-vfs` is a tree-shakable byte-oriented virtual filesystem and Bash-compatible
runtime for Cloudflare Workers. The default shell API executes independent,
complete source units; an optional `/shell/interactive` entry point preserves
shell state between units. One SQLite-backed Durable Object owns a strongly
consistent pathname namespace. Files up to 8 MiB can be stored inline and read
by shell utilities; large payloads live as immutable R2 objects and are
intentionally opaque to the shell.

```ts
import { DurableObject } from "cloudflare:workers";
import { Shell, type RemoteExecuteTextOptions } from "@corca-ai/cf-vfs/shell";
import { defaultShellCommands } from "@corca-ai/cf-vfs/shell/commands/default";
import { DurableObjectFileSystem } from "@corca-ai/cf-vfs/storage/do-sql";
import { R2OpaqueStore } from "@corca-ai/cf-vfs/storage/r2";

interface Env {
WORKSPACES: DurableObjectNamespace;
FILE_BODIES: R2Bucket;
}

export class WorkspaceFiles extends DurableObject {
private readonly fileSystem: DurableObjectFileSystem;
private readonly shell: Shell;

constructor(ctx: DurableObjectState, env: Env) {
super(ctx, env);
this.fileSystem = new DurableObjectFileSystem(ctx.storage, {
opaqueStore: new R2OpaqueStore(env.FILE_BODIES),
workspaceId: ctx.id.toString(),
});
this.shell = new Shell({
fileSystem: this.fileSystem,
commands: defaultShellCommands,
});
}

executeText(options: RemoteExecuteTextOptions) {
return this.shell.executeText(options);
}

override async alarm() {
await this.fileSystem.drainGarbage();
}
}

export async function execute(env: Env, workspaceId: string) {
const workspace = env.WORKSPACES.getByName(workspaceId);
return workspace.executeText({
script: `find src -name '*.ts' | sort > files.txt`,
cwd: "/workspace",
});
}
```

`WorkspaceFiles` extends only Cloudflare's required `DurableObject`; the cf-vfs
parts are composed normally. `DurableObjectFileSystem` stores paths and inline
bytes in `ctx.storage` (SQLite), while `R2OpaqueStore` connects the `FILE_BODIES`
R2 binding for opaque-body verification and garbage collection. `WORKSPACES`
routes each workspace to its Durable Object. See [Getting
started](docs/getting-started.md) for the Wrangler bindings, migration, and
direct-to-R2 upload path.

From a repository checkout, run `npm run repl` for a local line-oriented
session backed by the in-memory VFS. `npm run repl:sqlite` runs the same
terminal UI against a disposable SQLite-backed Durable Object in local
workerd.

This is an application runtime, not an operating-system shell or POSIX ABI. It
does not launch processes, mount a host filesystem, or provide OS TTY/job
control. The supported language is an explicit versioned subset, and every
parser, execution, stream, mutation, and storage boundary is bounded.

The pre-1.0 stream-first redesign is intentionally breaking. The old
`{ command, input }` structured executor and text/binary storage split have
been removed.

Read [docs/index.md](docs/index.md) for setup, language and command semantics,
the SQLite/R2 lifecycle, limits, benchmarks, and compatibility details.

## License

MIT