Skip to content

Subscriptions

The node pushes events as your application’s state changes. Mero.js exposes two transports for them: SSE (sdk.events, recommended) and WebSocket (sdk.ws, experimental). Both share the same shape — register handlers with on(...), open the stream with connect(), then subscribe([...]) to the contexts you care about.

import { MeroJs } from '@calimero-network/mero-js';
const sdk = new MeroJs({ baseUrl: 'http://localhost:2428' });
await sdk.authenticate({ username: 'admin', password: 'pass' });
const sse = sdk.events;
sse.on('event', (e) => {
console.log(e.contextId, e.type, e.data);
});
sse.on('connect', (sessionId) => console.log('connected', sessionId));
sse.on('error', (err) => console.error('sse error', err));
await sse.connect(); // open the stream
await sse.subscribe(['ctx-id-1']); // start receiving that context's events
// later…
await sse.unsubscribe(['ctx-id-1']);
sdk.close(); // closes SSE (and WS) connections

The SSE client auto-reconnects (fixed delay, default 3s) and re-subscribes your contexts after a reconnect, so a dropped connection heals itself. Event payloads that arrive as byte arrays are decoded to JSON for you.

interface SseEventData {
contextId: string; // which context the event came from
type?: string; // event type, when present
data: unknown; // the payload emitted by the WASM app
}

A dedicated helper fires when a context’s application version changes (e.g. after an upgrade). It returns an unsubscribe function:

const off = sse.onAppVersionChanged((e) => {
console.log(`${e.contextId}: ${e.fromVersion} → ${e.toVersion}`);
});
// off(); // stop listening

Pass several context IDs to one subscribe call — a single connection carries them all, and event.contextId tells you which one fired:

await sse.subscribe(['ctx-1', 'ctx-2', 'ctx-3']);
sse.on('event', (e) => {
console.log(`event from ${e.contextId}`);
});

sdk.ws mirrors the SSE surface over a WebSocket. It logs a one-time console warning on first access — prefer SSE in production.

const ws = sdk.ws; // ⚠ logs an experimental warning
ws.on('event', (e) => console.log(e.contextId, e.data));
await ws.connect();
ws.subscribe(['ctx-id']); // note: synchronous on WS (unlike SSE)

Don’t wire this by hand in a component. @calimero-network/mero-react provides a useSubscription hook that manages the lifecycle — subscribing on mount, unsubscribing on unmount, and re-subscribing when the context IDs change:

import { useSubscription } from '@calimero-network/mero-react';
useSubscription([contextId], (event) => {
handleEvent(event); // auto-unsubscribes on unmount
});