class NumberRepo( scope: CoroutineScope, private val loadInitialValueFromDisk: suspend () -> Int ) : CoroutineScope by scope { private val intentions = Channel() private val reduce: (State, Intention) -> State = { state: State, intention: Intention -> when (intention) { Intention.Increment -> State(state.value + 1) Intention.Decrement -> State(state.value - 1) } } private val sharedStateFlow: SharedFlow = intentions.receiveAsFlow() .scan( runBlocking { // how can I avoid a runBlocking here? State(loadInitialValueFromDisk()) } ) { state: State, intention: Intention -> reduce(state, intention) } .shareIn( this, SharingStarted.Eagerly, // begin observing immediately! replay = 1 // so each subscriber gets the current state ) val states: Flow = sharedStateFlow suspend fun increment() { intentions.send(Intention.Increment) } suspend fun decrement() { intentions.send(Intention.Decrement) } private sealed class Intention { object Increment : Intention() object Decrement : Intention() } data class State(val value: Int) }