Channels

A channel is a named stream of events. Clients subscribe to channels, and your server publishes events to them. Channels exist as soon as someone uses them: there is nothing to create.

Channel types

The prefix of a channel's name decides what it does:

PrefixTypeWho can subscribe
nonePublicAnyone with your public key
private-PrivateClients holding a token your server issued
presence-PresenceLike private, and members see each other
cache-, private-cache-, presence-cache-CacheAs above, and new subscribers get the last event

Names use letters, digits and _ - = @ , . ;, from 1 to 164 characters.

Subscribe

client.ts
const room = thunderclap.subscribe("room-42");

room.bind("message", (data, meta) => render(data));
room.bindAll((event, data) => console.log(event, data)); // every event
room.on("subscribed", () => console.log("ready"));
room.on("error", ({ code, message }) => console.error(code, message));

thunderclap.unsubscribe("room-42");

bind and bindAll return a function that removes the listener. Subscriptions made before the connection is ready are sent once it is, and every subscription is restored after a reconnect.

Typed events

With TypeScript, describe a channel's events and the data each one carries:

client.ts
type RoomEvents = { message: { text: string; author: string }; typing: { user: string } };

const room = thunderclap.subscribe<RoomEvents>("room-42");
room.bind("message", (data) => data.text); // data is { text: string; author: string }

Publish

server.ts
await thunderclap.publish({ channel: "room-42", data: { text: "Hello!" } });

Each event has a name, which clients bind to. It's message unless you pass event:

server.ts
await thunderclap.publish({ channel: "room-42", event: "typing", data: { user: "ada" } });

A publish counts once however many subscribers receive it. Data must be JSON-serializable, up to 10 KB. Event names are up to 200 characters, and names starting with tc: are reserved.

Several channels, several events

Publish one event to up to 100 channels, or up to 10 events in order in one request:

server.ts
await thunderclap.publish({ channel: ["room-42", "room-43"], event: "announcement", data });

await thunderclap.batch([
  { channel: "room-42", data: { text: "first" } },
  { channel: "room-42", data: { text: "second" } },
]);

Sequence numbers

Each publish returns the sequence number the event got on each channel:

{ "seq": { "room-42": [1, 128] } }

Store it with your own copy of the message: it's how clients backfill what they missed.