TypeScript SDK
@flockfs/sdk (in sdk/, not published) uses native fetch; works in browsers and Node.
import { Flockfs, decode } from './sdk/dist/index.js';
const fs = new Flockfs({ url: 'http://127.0.0.1:4317', token: process.env.FLOCKFS_TOKEN, actor: 'research-agent' });
const file = await fs.create('research/notes.md', '# Notes\n'); // parents created
await fs.write(file.id, '# Updated notes\n', file.revision); // stale revision → merge or 409
await fs.append(file.id, '- another finding\n');
console.log(await fs.read(file.id));
for await (const change of fs.watch({ after: 0, prefix: 'research' })) console.log(change.path, change.kind);watch resumes from its cursor and retries network errors and HTTP 408/429/5xx with
exponential backoff (retry: {initialDelayMs, maxDelayMs, jitterRatio, maxRetries}, or
retry: false); auth and other client errors are thrown as FlockfsError with status. A
prefix matches a folder (and everything in it) or an exact path, including moves into or out
of it (previous_path); it is a filter, not a permission boundary.
Example agent: examples/index-agent.ts keeps research/index.md
listing every file in research/, live:
npm install --prefix examples # type-checking only (npm run typecheck --prefix examples)
FLOCKFS_URL=http://127.0.0.1:4317 node examples/index-agent.ts research # token: FLOCKFS_TOKEN or data/tokenThe Rust Client bounds every request (5 s to connect, 35 s in total, enough for a 25 s
long-poll; Client::with_timeouts to change them) and never retries on its own.
Transport options: headers, fetch, session
Three client options apply to every request the client makes: JSON calls, raw downloads and exports, streamed uploads, and watch() long-polls. Clients derived with drive(ref) and withSession(id) keep them.
| Option | Type | Effect |
|---|---|---|
headers | Record<string, string> | Extra headers on every request. Authorization: Bearer <token> is still sent unless you set Authorization yourself. |
fetch | typeof fetch | Used instead of the global fetch for every request, e.g. a Cloudflare service binding. |
session | string | Sent as X-Flockfs-Session: groups this client's changes into one run on the timeline (and for undo by session). |
import {Flockfs} from '@flockfs/sdk';
// Inside a Cloudflare Worker with a service binding `FLOCKFS` to the flockfs server:
const fs = new Flockfs({
url: 'https://flockfs.internal', // any origin; the binding routes it
token: env.FLOCKFS_TOKEN,
actor: 'nightly-indexer',
session: `nightly-${Date.now()}`, // every change below is one run on the timeline
fetch: env.FLOCKFS.fetch.bind(env.FLOCKFS),
headers: {'X-Request-Id': crypto.randomUUID()},
});
const research = fs.drive('research'); // same session, headers and fetch
await research.write((await research.byPath('index.md')).id, '# Index\n');
for await (const change of research.watch()) console.log(change.path); // long-polls via the binding tooThe REST API is documented in API.md.