Concepts
Rooms, primitives, and how people and agents share one room Durable Object.
FluxyChat is the realtime room for your product: a Cloudflare Durable Object plus D1. Chat and presence share a JSON WebSocket; Yjs uses a second binary connection to the same object. Your auth, your backend, your data model stay yours. We mint member JWTs (or a public-room guest session) and fan out events.
Think of a room as the artifact in your app: a document, a board, a deal, a classroom, a vehicle dispatch view. Map roomId to that artifact.
Building blocks
| Concept | FluxyChat |
|---|---|
| Project | Tenant. API keys (fc_…, server-only), rooms, agents, quotas. |
| Room | One Durable Object. Chat JSON WebSocket; Yjs is a second binary connection on the same /ws/room/:id route. |
| Primitives | Presence, Broadcast, Storage, Feeds, Threads, Chat, Polls, Derived, Visibility. |
| Users | Humans (member JWT or guest) and AI (copilot, room peer, workflow). |
| Features | Comments, multiplayer editors, notifications, copilots, AI collaboration. |
| Platform | Worker, dashboard, @fluxy-chat/sdk, react, ui, ui-kit, vue, svelte. |
Primitives (pick the right one)
| Primitive | Means | API | Stored? |
|---|---|---|---|
| Presence | Now: who is here, cursors, selections, agentStatus | sendCursor, useMyPresence / presence_patch, presenceMembers | No |
| Broadcast | Pulse: one-shot signals | sendClientEvent / useBroadcastEvent | No |
| Storage | The document | FluxyYjsProvider, useStorage, useMutation, LiveFile | Yes (Yjs on the room DO) |
| Feeds | Activity / agent / n8n logs | useFeeds, POST /rooms/:id/feeds | Yes (D1, ≠ chat) |
| Threads | Contextual comments | useThreads, /comment-threads | Yes |
| Chat | Timeline + nested replies | useChat, useThread, parentId | Yes |
| Polls | Ballots on the timeline (and /polls records) | createPoll / votePoll, POST /polls isAnonymous | Yes |
| Derived | Late-joiner JSON bag (not a CRDT) | setDerivedState / derivedState | Yes (DO storage) |
| Visibility | Who may see a chat line | visibility / visibleTo on send | Yes (D1) |
Do not put 60 Hz pointers on Broadcast. Do not mix Feeds with messages. Do not mix comment pins (useThreads) with chat parentId replies (useThread). Do not hide private lines only in the UI. Set visibility on send.
Wire limits and v1 non-goals: Wire protocol.
Two kinds of AI
| Kind | API | Writes |
|---|---|---|
| Copilot (side panel) | RegisterAiKnowledge + useAiChat + <AiChat /> | Local UI only (keyless mock) |
| Room peer | invokeAgent on useChat | Chat messages |
| Workflow | API key POST …/feeds/…/messages | Feed + server_event |
Auth
Browser: publishableKey (pk_) on FluxyRealtimeProvider (anonymous JWT via POST /tokens/anonymous), member JWT, or FluxyChatClient.joinPublicRoomAsGuest(workerUrl, publicRoomId) (stable guestKey in localStorage). Guest writes are on by default; set PUBLIC_GUEST_READ_ONLY=true to lock.
Server: project API key (fc_…) mints member JWTs (POST /auth/token). pk_ is rejected there (403). Never put fc_… in the client.
Verticals on the same bus
IoT, fleet, game ticks, voice stage, deal quorum: all server_event or chat on the same room WebSocket. Gallery has a copy-paste app for each.
Next: Getting started · CLI and examples