Live events (SSE)
mero-kotlin streams a node’s real-time context events over Server-Sent Events,
exposed as a Kotlin Flow. The task-oriented walkthrough is the
live events guide; this page is the API surface.
mero.events(contextIds)
Section titled “mero.events(contextIds)”fun events(contextIds: List<String>): Flow<ContextEvent>Opens GET /sse and subscribes to the given context ids via
POST /sse/subscription, then emits a ContextEvent per node emission. The
returned Flow is cold — collecting it opens the connection; cancelling the
collecting coroutine closes it. It reconnects automatically ~3s after a drop and
re-subscribes (the node persists session subscriptions).
val job = scope.launch { mero.events(listOf(contextId)).collect { event -> println("${event.contextId} · ${event.kind}") }}// later:job.cancel() // closes the SSE streamGroup events (core 0.11.0-rc.83)
Section titled “Group events (core 0.11.0-rc.83)”fun groupEvents(groupIds: List<String>): Flow<GroupEvent>fun nodeEvents(contextIds: List<String>, groupIds: List<String>): Flow<NodeEvent>Subscribing with groupIds delivers group-keyed frames — membership changes and
migration progress, result.groupId rather than result.contextId — as
GroupEvent(groupId, kind, payload). Roles in them may read RelayTee. The node
silently drops ids the token may not observe. groupIds is sent only when
non-empty, so a context-only subscription is byte-identical to before.
The stream authenticates with an Authorization: Bearer header on /sse, like
every other call. Core rc.83 also accepts a ?token= query on /ws, /sse and
/sse/* (for browsers), but a token in a URL ends up in proxy logs.
ContextEvent
Section titled “ContextEvent”data class ContextEvent( val contextId: String, val kind: String, // "StateMutation" | "SyncStatus" | … val payload: JsonElement, // the raw event JSON)The discriminator is the frame’s result.type. A live merod 0.11.0-rc.32 sends
StateMutation (the context state moved) and SyncStatus
(syncing / waitingForPeers / …). It does not send ExecutionEvent, which
earlier versions of this page named — a when branching on it never fired.
A presence update (kind == "Ephemeral") carried by a relay for an account
names that account; read it as event.presenceAccount (null for a node’s own
presence).
For a contract emission (kind == "StateMutation") the encoded contract events
live under payload’s data.events[].data, each with its own kind.
SseClient
Section titled “SseClient”mero.events(...) builds an SseClient for you; use it directly only to manage
the connection yourself.
class SseClient( baseUrl: String, token: suspend () -> String?, client: OkHttpClient = OkHttpClient(), json: Json = Json { ignoreUnknownKeys = true },) { fun events(contextIds: List<String>): Flow<ContextEvent>}