commonMain.com.episode6.redux.impl.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of core Show documentation
Show all versions of core Show documentation
Core implementation of Redux StoreFlow
The newest version!
package com.episode6.redux
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.Channel.Factory.UNLIMITED
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
/**
* Creates a new [StoreFlow], a redux store backed by a [kotlinx.coroutines.flow.StateFlow]
*/
@Suppress("FunctionName") fun StoreFlow(
scope: CoroutineScope,
initialValue: State,
reducer: Reducer,
middlewares: List> = emptyList(),
): StoreFlow = StoreFlowImpl(
scope = scope,
initialState = initialValue,
reducer = reducer,
middlewares = middlewares,
)
private class StoreFlowImpl(
scope: CoroutineScope,
override val initialState: T,
reducer: Reducer,
middlewares: List>,
private val stateFlow: MutableStateFlow = MutableStateFlow(initialState)
) : StoreFlow, Flow by stateFlow {
private val actionChannel: Channel = Channel(capacity = UNLIMITED)
init {
scope.launch {
val reduce: Dispatch = middlewares.foldRight(
initial = { action -> stateFlow.value = stateFlow.value.reducer(action) },
operation = { middleware, next -> with(middleware) { interfere(this@StoreFlowImpl, next) } }
)
try {
for (action in actionChannel) {
reduce(action)
}
} finally {
actionChannel.close()
}
}
}
override val state: T get() = stateFlow.value
override fun dispatch(action: Action) {
actionChannel.trySend(action)
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy