2 of 5

Listeners

Beyond class-based listeners — inline handlers, one-shots, catch-all, and bulk registration.

Lambda listeners

Register inline handlers without creating a class. The on method returns a Subscription you can cancel later:

kotlin
val subscription = bus.on<UserCreated> { event ->
    println("New user: ${event.name}")
}

// later...
subscription.cancel()

One-shot listeners

Listeners that fire once and auto-unsubscribe. Works with both lambdas and classes:

kotlin
// Lambda one-shot
bus.once<UserCreated> { event ->
    println("First user: ${event.name}")
}

// Class-based one-shot
bus.once<UserCreated, SendWelcomeEmail>()

One-shot listeners are guaranteed to fire at most once, even under concurrent or reentrant emit. See Advanced → Once guarantees.

Catch-all listener

Receive every event regardless of type — useful for logging, metrics, or debugging:

kotlin
bus.onAny { event ->
    println("Event emitted: ${event::class.simpleName}")
}

Multiple listeners

Register several listener classes for the same event in one call:

kotlin
bus.subscribe<UserCreated>(
    SendWelcomeEmail::class,
    AuditLogListener::class,
    AnalyticsListener::class,
)

Registration DSL

Bulk-register event-listener mappings with a DSL block:

kotlin
bus.register {
    UserCreated::class mappedTo listOf(SendWelcomeEmail::class, LogNewUser::class)
    OrderPlaced::class mappedTo listOf(NotifyWarehouse::class)
}

Unsubscribe and clear

Remove a specific class-based listener or clear everything:

kotlin
// Remove a specific listener
bus.unsubscribe<UserCreated, SendWelcomeEmail>()

// Remove all listeners and middleware
bus.clear()

Next steps

Learn how to intercept dispatch with middleware and handle errors gracefully.