core/client/src/jsMain/kotlin/dev/inmo/postssystem/client/OneStateUIFSMStatesRepo.kt

64 lines
2.0 KiB
Kotlin

package dev.inmo.postssystem.client
import dev.inmo.postssystem.client.ui.fsm.*
import dev.inmo.micro_utils.fsm.common.managers.DefaultStatesManagerRepo
import kotlinx.serialization.StringFormat
import org.w3c.dom.*
class OneStateUIFSMStatesRepo(
private val serialFormat: StringFormat,
private val storage: Storage,
private val initialState: UIFSMState = DefaultAuthUIFSMState
) : DefaultStatesManagerRepo<UIFSMState> {
private val String.storageKey
get() = "${FSMStateSettingsFieldPrefix}$this"
private val String.UIFSMState
get() = runCatching {
serialFormat.decodeFromString(UIFSMStateSerializer, this)
}.onFailure { it.printStackTrace() }.getOrNull()
init {
if (states().isEmpty()) {
setState(initialState)
}
}
private fun setState(state: UIFSMState) {
storage[state.context.storageKey] = serialFormat.encodeToString(UIFSMStateSerializer, state)
}
override suspend fun getContextState(context: Any): UIFSMState? {
return when (context) {
is String -> storage[context.storageKey] ?.UIFSMState ?: return DefaultAuthUIFSMState
else -> null
}
}
override suspend fun contains(context: Any): Boolean = when (context) {
is String -> storage.get(context) ?.UIFSMState != null
else -> super.contains(context)
}
private fun states(): List<UIFSMState> = storage.iterator().asSequence().mapNotNull { (k, v) ->
if (k.startsWith(FSMStateSettingsFieldPrefix)) {
v.UIFSMState
} else {
null
}
}.toList()
override suspend fun getStates(): List<UIFSMState> = states()
override suspend fun removeState(state: UIFSMState) {
storage.removeItem((state.context as? String) ?.storageKey ?: return)
}
override suspend fun set(state: UIFSMState) {
setState(state)
}
companion object {
private const val FSMStateSettingsFieldPrefix = "UIFSMState_"
}
}