useRealtime
Receive the messages a handler of this install pushes with ctx.realtime.push(topic, payload). Server functions (query() / mutation() / action()) and bot-module handlers can push. Every rendered surface of the install receives the message: the editor panel in the dashboard and every overlay or widget that shows the extension.
Signature
useRealtime<T = unknown>(topic: string, cb: (payload: T) => void): void;
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
topic | string | Yes | The topic to listen to. Messages on other topics are ignored. |
cb | (payload: T) => void | Yes | Called with the payload of each message on topic. It may change between renders without re-subscribing. |
Example
A poll overlay that updates when a chat vote comes in:
// server/handler.ts - a viewer types "!vote 2" in chat
import { command } from "@zaflun/lumio-sdk/server";
export const vote = command("vote", async (ctx, args) => {
await ctx.db.insert("votes", { choice: args[0] });
const votes = await ctx.db.list("votes");
ctx.realtime.push("poll:votes", { total: votes.length });
return null;
});
// layer.tsx
import { useState } from "react";
import { Text, useRealtime } from "@zaflun/lumio-sdk";
export default function PollLayer() {
const [total, setTotal] = useState(0);
useRealtime<{ total: number }>("poll:votes", (payload) => setTotal(payload.total));
return <Text>{total} votes</Text>;
}
Delivery
- The host subscribes to the install's WebSocket channel
extension_install:{install_id}with its own credential: the dashboard session in the editor, the overlay or widget token in OBS. - Messages arrive in the order the handler pushed them.
- Nothing is stored or replayed. A message pushed while the surface is not open, or before the extension has started, is not delivered. Load the current state with
useQuerywhen the surface starts, and useuseRealtimefor changes after that. - A message is sent only when the handler that pushed it did not throw.
Push rules
| Rule | Value |
|---|---|
| Topic | 1-64 characters of A-Z a-z 0-9 _ . : -, starting with a letter or digit |
| Payload | Any JSON value, at most 16 KiB serialized (omitted = null) |
| Pushes per handler run | 32 |
| Pushes per install and minute | 300; more are dropped |
| Published bytes per install and minute | 1 MiB of serialized { topic, payload } messages; more are dropped |
A push that breaks the topic, payload or per-run rule throws inside the handler. REALTIME_LIMITS in @zaflun/lumio-protocol holds these values.