v1.0.0 on Maven Central

kotlin-events

Type-safe event bus for Kotlin. DI-resolved listeners, middleware, coroutines — lightweight and thread-safe.

implementation("com.cristianllanos:events:1.0.0")

Features

Quick Start

Define events as data classes, listeners with injected dependencies, and emit.

kotlin
data class UserCreated(val name: String) : Event

class SendWelcomeEmail(private val mailer: Mailer) : Listener<UserCreated> {
    override fun handle(event: UserCreated) {
        mailer.send("Welcome, ${event.name}!")
    }
}

val container = Container()
EventServiceProvider().register(container)

val bus = container.resolve<EventBus>()
bus.subscribe<UserCreated, SendWelcomeEmail>()
bus.emit(UserCreated("Alice"))

Lambda & One-Shot Listeners

Inline handlers without creating a class. One-shots auto-unsubscribe after the first invocation.

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

bus.once<UserCreated> { event ->
    println("First user only: ${event.name}")
}

bus.onAny { event -> println("All events: $event") }

Middleware

Intercept event dispatch for cross-cutting concerns like timing, logging, or tracing.

kotlin
bus.use { event, next ->
    val start = System.nanoTime()
    next(event) // call next to continue the pipeline
    println("${event::class.simpleName} in ${System.nanoTime() - start}ns")
}

Coroutines

Suspending listeners and emit — mix sync and async handlers on the same bus.

kotlin
class AsyncWelcomeEmail(private val mailer: SuspendingMailer) : SuspendingListener<UserCreated> {
    override suspend fun handle(event: UserCreated) {
        mailer.send("Welcome, ${event.name}!")
    }
}

val bus = SuspendingEventBus(container)
bus.subscribeSuspending<UserCreated, AsyncWelcomeEmail>()
bus.on<UserCreated> { event -> delay(100); println(event.name) }

coroutineScope { bus.emit(UserCreated("Alice")) }

Learn

Get started in seconds

Add the dependency, subscribe a listener, and emit. That's it.