Store
PulseStore is the core building block of PulseMVI. It manages the UI state for a single screen or section of your app.
Creating a Store
Extend PulseStore with your four type parameters:
class MyStore : PulseStore<MyState, MyAction, MyEvent, MyBroadcast>(
initialUiState = MyState(),
) {
override fun onSetup() { /* start coroutines here */ }
override fun onAction(uiAction: MyAction) { /* handle user intents */ }
override fun onReceive(broadcast: MyBroadcast) { /* react to broadcasts */ }
}Lifecycle Hooks
onSetup()
Called once when the Store's state is first collected. Use this to start long-running coroutines such as repository flows:
override fun onSetup() {
coroutineScope.launch {
repository.data.collect { data ->
update { copy(items = data) }
}
}
}WARNING
onSetup() is also called after cancel() (i.e., after a view refresh). Coroutines launched here are automatically cancelled when cancel() is called.
onAction(uiAction)
Called each time the UI dispatches an action. Keep this non-blocking — launch coroutines for async work:
override fun onAction(uiAction: MyAction) {
coroutineScope.launch {
when (uiAction) {
MyAction.Load -> loadData()
is MyAction.Select -> selectItem(uiAction.id)
}
}
}onReceive(broadcast)
Called when the parent Container delivers a broadcast. You can update state or emit events:
override fun onReceive(broadcast: MyBroadcast) {
when (broadcast) {
MyBroadcast.Refresh -> update { copy(isRefreshing = true) }
is MyBroadcast.UserChanged -> update { copy(userId = broadcast.id) }
}
}Updating State
Use update { } to produce the next immutable state. The lambda receives the current state as this:
update { copy(count = count + 1, isLoading = false) }Emitting Events
Use event() to send a one-time side effect to the UI:
event(MyEvent.NavigateTo(Screen.Detail))
event(MyEvent.ShowError("Something went wrong"))Accessing Current State
Read the latest state snapshot synchronously via currentState:
override fun onAction(uiAction: MyAction) {
if (currentState.isLoading) return // guard check
coroutineScope.launch { /* ... */ }
}