FluxyChat

Platform

Realtime modules

Composable platform modules on one Worker and room kernel.

All modules share the same Worker, Durable Object rooms, D1 persistence, and WebSocket transport.

Chat (core)

import { useChat } from "@fluxy-chat/react";

const { messages, sendMessage, connectionState } = useChat({ roomId: "general" });

Stream

import { createWorkerFluxyStreamClient } from "@fluxy-chat/sdk";

const stream = createWorkerFluxyStreamClient({ baseUrl, token: jwt });

Live event messages: POST /api/live/events/:eventId/messages.

Agents

Configure agents on the Worker (dashboard or POST /agents). Invoke from clients:

const { invokeAgent } = useChat({ roomId, client });
await invokeAgent(agentId, "Summarize this thread");

Mention handles (@assistant) trigger background invoke with streaming edits.

Platform clients

ModuleFactory
StreamcreateWorkerFluxyStreamClient
GamecreateWorkerFluxyGameClient
IoTcreateWorkerFluxyIoTClient
Agents (platform)createWorkerAgentPlatformClient

See Platform index and Packages: SDK.

Live room events (server_event + capability_event)

Vertical and labs modules fan out typed frames on the same room WebSocket as chat. Subscribe with:

const conn = client.connectRoom("classroom:42");
conn.connect();

conn.onServerEvent(({ name, data }) => {
  if (name === "poll.voted") console.log(data);
});

conn.onCapabilityEvent((event) => {
  console.log(event.type, event.payload);
});

React hook:

import { useServerEvents } from "@fluxy-chat/react";

const { lastEvent, connected } = useServerEvents({
  client,
  roomId: "classroom:42",
  filter: (name) => name.startsWith("poll."),
});

server_event catalog (Worker → room)

NameSourcePayload (summary)
game.match_startedFluxyGame{ matchId, lobbyId }
game.tickFluxyGame{ matchId, tick, state }
iot.readingFluxyIoT{ deviceId, sensor, value, unit }
live.event_createdLive streaming{ eventId, title, status, roomId }
live.event_live / live.event_endedLive streaming{ eventId, status }
live.viewer_joined / live.viewer_leftLive streaming{ eventId, userId, viewerCount }
live.chat_messageLive streaming{ eventId, messageId, content }
fleet.gps_updateFleet GPS ingest{ vehicleId, lat, lng, speed, heading, ts }
poll.created / poll.voted / poll.closedPolls (edu/events){ pollId, … }
form.created / form.submittedForms{ formId, … }
spatial.scene_created / spatial.entity_addedDigital twin{ sceneId, entityId, position, … }
collab.crdt_updateYjs CRDT (Room DO){ byteLength, channel: "yjs" } — throttled metadata; binary sync unchanged
collab.awarenessYjs awareness{ byteLength, channel: "yjs" }
collab.noteCollab (client_event){ id, text, x, y, color, authorId } — fan-out via room WS, not server_event

Yjs CRDT documents use binary frames on the same room WebSocket (type bytes 0/1/2). See /collab dashboard.

Industry workflows use capability_event with typed event.type (e.g. edu.session.started, event.stage.live) via POST /capabilities/events — see Vertical platform.

On this page