contributor-context
Contributor context for coding agents working in this repository. Human contributors should start with `README.md` and…
<!-- GENERATED from docs/api/filesystem.md by scripts/build-agent-skill.mjs. Do not edit. -->
$ npx -y skills add crossbind/crossbind --agent claude-codeHow it fires
How this agent gets triggered: by you, by Claude, or both.
Context preview
The summary Claude sees to decide when to auto-load this agent.
<!-- GENERATED from docs/api/filesystem.md by scripts/build-agent-skill.mjs. Do not edit. -->
<!-- GENERATED from docs/api/filesystem.md by scripts/build-agent-skill.mjs. Do not edit. -->
> Where do files live in crossbind? Depends on the runtime and your `init` options. This doc maps every combination.
Are you on the browser?
├── No (Node.js)
│ └── m.FS reads/writes the host filesystem via fs-node adapter.
│ No /opfs vs /memfs distinction; paths are real filesystem paths.
│
├── No (Cloudflare Worker / Deno Deploy / Vercel Edge)
│ └── m.FS is in-memory only.
│ No persistence across invocations.
│ No useWorker available (edge runtimes don't have Web Workers).
│ No OPFS available (browser-only API).
│
└── Yes (browser)
│
├── Need persistence across page reloads?
│ ├── No → fs: { opfs: false } → mount under /memfs/<app>/
│ │
│ └── Yes → REQUIRES useWorker: true and fs.opfs (on by default in mt builds) → mount under /opfs/<app>/
│ ├── Browser supports OPFS? (Chrome 86+, FF 111+, Safari 15.2+)
│ │ ├── Yes → runtime preflight: getDirectory() actually works?
│ │ │ ├── Yes → real persistence
│ │ │ └── No → logs error + falls back to /memfs/<app>/
│ │ │ (broken/blocked backends, e.g. Playwright WebKit)
│ │ └── No → crossbind logs error + redirects to /memfs/<app>/
│ │
│ └── Mounted from main thread (no useWorker)?
│ → throws: "OPFS is only available inside a Worker scope"
│
└── Need to mount user-provided files?
→ Use m.autoMountFiles(files, parentPath?) with File[] from <input type=file>crossbind mounts two namespaces under the Wasm filesystem root:
| Mount | Backed by | Persistence | Available when | |-------|-----------|-------------|----------------| | `/opfs/<app>/` | Browser's Origin Private File System | Survives page reloads, browser restarts | `useWorker: true` + `fs.opfs` (the default in `mt` builds) + browser support | | `/memfs/<app>/` | In-memory (Emscripten MEMFS) | Tab session only | Always |
`<app>` is `general.name` from `crossbind.config.js` (the same name the CLI uses for `lib<name>.a`).
m.getDefaultPath() // → '/opfs' or '/memfs' depending on config
m.getFinalPath(path) // validate + auto-fallback if OPFS unavailable
m.getRandomPath(startPath?) // → '<startPath>/<app>/automounted/<random>'
// (creates the dir tree)
m.autoMountFiles(files, parentPath?)
// files: File[] (e.g. from <input type=file>)
// parentPath: optional; if omitted, uses getRandomPath()
// Streams each file into the Wasm fs, returns the mount paths.
// Returns: Promise<string[]> (the resolved paths of each mounted file)
m.getFileBytes(path) // → Uint8Array
m.getFileList(startPath?) // → [{ path, size }, ...] (recursive)Use `m.FS` directly (Emscripten's standard API):
m.FS.mkdirTree('/memfs/myapp/cache')
m.FS.writeFile('/memfs/myapp/cache/data.bin', new Uint8Array([1, 2, 3]))
const bytes = m.FS.readFile('/memfs/myapp/cache/data.bin')If you write to `/opfs/...` without `useWorker: true`, this throws. If OPFS isn't supported by the browser, the path is auto-redirected to `/memfs/...` (with a `console.error`).
const fileInput = document.querySelector('input[type=file]')
fileInput.addEventListener('change', async () => {
const paths = await m.autoMountFiles(Array.from(fileInput.files))
// `paths` is e.g. ['/opfs/myapp/automounted/123456/photo.jpg', …]
for (const p of paths) {
m.processImage(p) // call into your C++
}
})To put them in a known location instead of an auto-random dir:
await m.autoMountFiles(files, '/opfs/myapp/uploads')
m.processImage('/opfs/myapp/uploads/photo.jpg') // C++ writes /opfs/myapp/uploads/photo.processed.jpg
const bytes = m.getFileBytes('/opfs/myapp/uploads/photo.processed.jpg')
const blob = new Blob([bytes], { type: 'image/jpeg' })
const url = URL.createObjectURL(blob)
imgEl.src = url1. **Mounting `/opfs` from main thread without `useWorker: true`** → throws synchronously inside `m.getFinalPath()`. The error message tells you to enable `useWorker` or mount under `/memfs/` instead. 2. **Forgetting the `<app>` prefix** → crossbind auto-creates `/memfs/<app>/automounted` at startup. If you write to `/memfs/foo` (no `<app>`) it works but won't be cleaned up on `terminate`. 3. **Assuming OPFS persists across origins** — it doesn't. Files written from `app.example.com` are invisible to `other.example.com`. Standard origin isolation. 4. **Using `m.FS` from before `onRuntimeInitialized`** — `m.FS` is undefined until init completes. Use the `onRuntimeInitialized: (m) => {…}` hook or await the `initNative(...)` promise first. 5. **Mounting `/opfs/...` with OPFS off**, by `fs: { opfs: false }` or in an `st` build that does not set `fs: { opfs: true }` → throws: "OPFS is disabled. Enable fs.opfs in config to mount under /opfs/."
| Runtime | `useWorker` | `/opfs/...` | `/memfs/...` | Notes | |---------|-------------|-------------|--------------|-------| | Browser (no worker) | n/a | ❌ throws | ✅ | Tab-session memory only | | Browser + `useWorker: true` | ✅ | ✅ if browser supports OPFS, else fallback to `/memfs/` | ✅ | Persistent option | | Node.js | n/a | n/a | n/a (uses host fs) | `m.FS` reads real disk via fs-node adapter; `fsync` on a host file returns once the OS has the data, without forcing it to disk | | Cloudflare Worker / edge | ❌ unavailable | ❌ unavailable | ✅ in-memory equivalent | No persistence; per-invocation memory | | React Native (CLI / Expo) | n/a (uses JSI brid
Import C++ and Rust like JavaScript modules (WebAssembly & React Native)
Contributor context for coding agents working in this repository. Human contributors should start with `README.md` and…
<!-- GENERATED from docs/api/app.md by scripts/build-agent-skill.mjs. Do not edit. -->
<!-- GENERATED from docs/api/build-state.md by scripts/build-agent-skill.mjs. Do not edit. -->
<!-- GENERATED from docs/api/conan.md by scripts/build-agent-skill.mjs. Do not edit. -->
<!-- GENERATED from docs/api/cpp-binding-rules.md by scripts/build-agent-skill.mjs. Do not edit. -->