The JavaScript SDK is in pre-release and not on npm yet. Install it from source.
FolkwaysDocs

Connection and reconnects

Connection states, what the SDK does when the network drops, and how to show it in your UI.

A client has one connection for its whole segment, shared by every topic. You connect once; the SDK keeps it alive.

const client = new Folkways.Realtime({ url: 'https://rte.example.com', authUrl: '/api/realtime-token' });

client.connection.on('change', ({ current, previous, reason }) => {
  setStatus(current); // 'connecting', 'connected', 'reconnecting', …
});

const session = await client.connect();

States

StateMeaning
idleCreated, connect() not called yet
connectingOpening the first connection
connectedLive: publishes and events flow
reconnectingThe connection dropped; the SDK is retrying. Publishes are queued
offlineReconnecting has failed for 2 minutes (offlineAfterMs). Retries go on, but new publishes fail at once with NotConnected
failedA problem retrying can't fix, such as a revoked key. See connection.error; call connect() again once fixed
closedYou called close()
idle → connecting → connected ⇄ reconnecting → offline
                        │                          │
                        └──────── failed ◄─────────┘   (fatal error; connect() again)

What happens when the network drops

You don't need any code for this:

  • The SDK reconnects with exponential backoff and jitter, from 0.5 seconds up to 30 seconds between attempts. In a browser, coming back online or returning to the tab retries at once.
  • After reconnecting it resubscribes every topic from the last event you handled, and sends queued publishes.
  • If WebSockets fail to open twice in a row (blocked by a proxy, for example), it switches to HTTP long-polling, and tries WebSockets again every 5 minutes. The API is the same on both.
  • It sends heartbeats and replaces a connection that has gone silent.

The connection fails for good, with state failed, only when retrying can't help: an invalid token twice in a row, a suspended segment or revoked publishable key, or the same user signed in from too many devices (Replaced).

connect()

client.connect() resolves with the session once connected.

  • Temporary failures are retried quietly. If it takes longer than 15 seconds (connectTimeoutMs), connect() rejects with Timeout, but the client keeps trying in the background.
  • A fatal error rejects at once with a RealtimeError.
try {
  await client.connect();
} catch (err) {
  if (isRealtimeError(err) && err.codeName === 'Timeout') showBanner('Still connecting…');
  else throw err;
}

To wait for the connection elsewhere, use await client.connection.whenConnected().

Show it in the UI

client.connection is a live value, so it plugs straight into React:

import { useSyncExternalStore } from 'react';

function ConnectionBadge({ client }: { client: Realtime }) {
  const { state, transport } = useSyncExternalStore(client.connection.subscribe, client.connection.getSnapshot);
  return <span>{state}{transport ? ` via ${transport}` : ''}</span>;
}

Errors that aren't tied to one call, such as a failed token refresh, arrive on the connection's error event:

client.connection.on('error', (err) => reportToMonitoring(err));

Signed in elsewhere

A segment can limit how many connections one user may have. When a user opens one too many, the oldest connection is closed with Replaced and its client goes to failed. Show "You're signed in elsewhere" and reconnect only when the user asks, otherwise the two devices keep replacing each other.

Closing

await client.close();               // stop for good; queued publishes fail with ClientClosed
await client.close({ clear: true }); // also wipe this user's local data, e.g. on sign-out

Tuning

The defaults suit most apps. Every timing option is listed in Client options.

new Folkways.Realtime({
  url,
  authUrl,
  reconnect: { initialDelayMs: 1_000, maxDelayMs: 60_000 },
  offlineAfterMs: 60_000,
  transports: ['websocket'], // never fall back to HTTP
  logger: consoleLogger('debug'),
});

On this page