Zero-dependency state machines, saga orchestration, and immutable containers built for financial-grade reliability and clean architecture.
Every feature designed for zero-error-tolerance environments with comprehensive testing and thread safety.
Declarative DSL with sealed classes for compile-time state transition verification. Guards, side effects, and lifecycle hooks built-in.
Distributed transactions with automatic LIFO compensation. Smart compensation sees state from later steps for intelligent rollback.
Thread-safe containers with atomic operations. State corruption is impossible by construction.
Fully suspend-aware API for non-blocking operations. Perfect integration with Kotlin's structured concurrency.
Custom validators enforce business rules before state transitions. Failed validations are caught, not exceptions.
Observer pattern, saga monitors, and lifecycle events integrate with any logging or telemetry system.
A conversational DSL that reads like documentation
val paymentMachine = stateMachine<PaymentState, PaymentEvent> { initially at Pending during(Pending) { on<Authorize> first do { auditLog.record(it) } then go to Authorized } during(Authorized) { on<Capture> only if { amount > 0 } then go to Captured on<Void> go to Voided } watching changes { old, new -> logger.info("$old -> $new") } }
// Smart compensation: Step 1's undo sees state from Step 3! val saga = sagaExecutor<Cart, Transaction, PaymentState>(PaymentState()) { first `do` "Take Payment" with { cart -> val payment = cashManager.takePayment(cart.total) updateState { it.copy(paymentAmount = payment.amount) } createTransaction(cart, payment) } and undo { // `state.escrowCaptured` is from Step 3! when { state.escrowCaptured -> cashManager.dispenseCashRefund(state.paymentAmount) state.paymentAmount > 0 -> cashManager.returnEscrow() else -> cashManager.disableAcceptors() } } then `do` "Capture Escrow" with { cart -> cashManager.captureEscrow() updateState { it.copy(escrowCaptured = true) } result!! } }
// Thread-safe, validated state container data class AccountState( val balance: BigDecimal, val frozen: Boolean = false ) val account = stateContainer( initialState = AccountState(balance = 1000.0.toBigDecimal()), validator = { state -> if (state.balance < BigDecimal.ZERO) ValidationResult.Invalid("Negative balance") else ValidationResult.Valid } ) // Safe atomic updates val result = account.updateState { state -> state.copy(balance = state.balance - 50.toBigDecimal()) } when (result) { is StateUpdateResult.Success -> println("New balance: ${result.newState.balance}") is StateUpdateResult.ValidationFailure -> println("Rejected: ${result.errors}") }
Pick what you need. Both integrate seamlessly.
Pure Kotlin state management with immutable containers, event-driven state machines, validation pipelines, and the observer pattern.
Coroutine-friendly saga orchestration for distributed transactions with automatic compensation and smart state-aware rollback.
Available on Maven Central. Add to your project in seconds.
dependencies { // Core state management implementation("ca.acendas:kstate:1.5.3") // Saga module (optional) implementation("ca.acendas:kstate-saga:1.5.3") }
dependencies { // Core state management implementation 'ca.acendas:kstate:1.5.3' // Saga module (optional) implementation 'ca.acendas:kstate-saga:1.5.3' }
<dependencies> <!-- Core state management --> <dependency> <groupId>ca.acendas</groupId> <artifactId>kstate</artifactId> <version>1.5.3</version> </dependency> <!-- Saga module (optional) --> <dependency> <groupId>ca.acendas</groupId> <artifactId>kstate-saga</artifactId> <version>1.5.3</version> </dependency> </dependencies>
Join developers building mission-critical applications with KState