@yjsync/cloudflare
v0.2.0
Published
Cloudflare Durable Object adapter for Yjs rooms: WebSocket-friendly DO with storage-backed persistence.
Maintainers
Readme
@yjsync/cloudflare
Cloudflare Durable Object adapter for collaborative Yjs rooms: YjsRoom hosts one RoomSession per DO, with storage-backed DurableObjectPersistence.
Use this when you deploy on Workers + Durable Objects and want WebSocket upgrades handled in the platform.
Install
bun add @yjsync/cloudflareWrangler bindings
In wrangler.toml:
[[durable_objects.bindings]]
name = "YJS_ROOM"
class_name = "YjsRoom"
[[migrations]]
tag = "v1"
new_classes = ["YjsRoom"]Worker entry:
import { YjsRoom, type YjsRoomNamespace } from '@yjsync/cloudflare'
export { YjsRoom }
export type Env = { YJS_ROOM: YjsRoomNamespace }
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const room = new URL(request.url).pathname.split('/').filter(Boolean)[0] ?? 'default'
const id = env.YJS_ROOM.idFromName(room)
const stub = env.YJS_ROOM.get(id)
const headers = new Headers(request.headers)
headers.set('X-Yjs-Room', room)
return stub.fetch(new Request(request.url, { method: request.method, headers }))
},
}Clients using y-websocket should connect to wss://host/<roomPath> (same path the Worker uses to name the DO).
Environment (Durable Object)
| Variable | Purpose |
|----------|---------|
| EXPORT_INTERVAL_MS | Alarm interval for compaction / export |
| OPEN_API_URL | Optional URL for exportJsonToApi |
| INTERNAL_SNAPSHOT_SECRET | Sent as X-Internal-Secret on export |
| COMPACT_AFTER_TAIL | Tail length before compaction (default 256) |
Example apps
- Minimal: examples/cloudflare
- TipTap + auth + D1 snapshots: examples/collab-demo
Develop
bun run build
bun run typecheck