Realtime
OpenCloud Realtime is a private broadcast API. The SDK constructs the app-scoped topic, joins with a current user token, sends heartbeats, and reconnects.
js
const channel = opencloud.realtime.channel("items");
const stopState = channel.onStateChange((state) => {
renderConnectionState(state);
});
const stopBroadcast = channel.onBroadcast(({ event, payload }) => {
if (event === "changed") void reloadItems(payload);
});
await channel.connect();
await channel.broadcast("changed", { reason: "item-created" });Methods
| Method | Result |
|---|---|
channel(name, options?) | Creates a private logical channel |
onStateChange(handler) | Returns an unsubscribe function |
onBroadcast(handler) | Returns an unsubscribe function |
connect() | Resolves after the channel joins |
broadcast(event, payload) | Sends after ensuring the channel is joined |
close() | Stops heartbeat and reconnect, then closes the socket |
States are idle, connecting, joined, reconnecting, and closed.
Do not use Supabase-style .on(...).subscribe() calls or implement the Phoenix wire protocol yourself.
Receiver-safe timers in 0.2.1
SDK 0.2.1 calls heartbeat and reconnect timers through receiver-safe wrappers. Do not rebind browser globals when runtime config advertises 0.2.1 or later.
Pinned 0.2.0 compatibility
Frozen SDK 0.2.0 stored browser-native timers without their global receiver. Only an application deliberately pinned to 0.2.0 should bind them before importing that old module:
js
globalThis.setTimeout = globalThis.setTimeout.bind(globalThis);
globalThis.clearTimeout = globalThis.clearTimeout.bind(globalThis);
const { createOpenCloudClient } = await import(
"/_opencloud/sdk/js/v0.2.0/index.js"
);This preserves the immutable old release; prefer runtime discovery and 0.2.1.