https://github.com/floschu/store
🔁 opinionated kmp library to manage state
https://github.com/floschu/store
coroutines kmp kotlin library multiplatform store
Last synced: 4 months ago
JSON representation
🔁 opinionated kmp library to manage state
- Host: GitHub
- URL: https://github.com/floschu/store
- Owner: floschu
- License: apache-2.0
- Created: 2021-10-23T23:04:20.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2025-11-22T13:00:29.000Z (6 months ago)
- Last Synced: 2026-01-11T18:31:12.336Z (5 months ago)
- Topics: coroutines, kmp, kotlin, library, multiplatform, store
- Language: Kotlin
- Homepage:
- Size: 738 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README

## installation
``` groovy
repositories {
mavenCentral()
}
dependencies {
implementation("at.florianschuster.store:store:$version")
}
```
see [changelog](https://github.com/floschu/store/blob/main/CHANGELOG.md) for versions
## usage
Go to [store](https://github.com/floschu/store/blob/main/lib/src/commonMain/kotlin/at/florianschuster/store/Store.kt) as entry point for more information.
```kotlin
class LoginEnvironment(
val authenticationService: AuthenticationService,
val tokenRepository: TokenRepository,
)
sealed interface LoginAction {
data class EmailChanged(val value: String): LoginAction
data class PasswordChanged(val value: String): LoginAction
data object Login: LoginAction
data class LoginResult(val result: Result): LoginAction
}
data class LoginState(
val emailAddress: String = "",
val password: String = "",
val loading: Boolean = false,
val displayLoginError: Boolean = false,
) {
val isInputValid = emailAddress.isNotEmpty() && password.isNotEmpty()
}
val LoginReducer = Reducer { previousState, action ->
when(action) {
is LoginAction.EmailChanged -> previousState.copy(emailAddress = action.value)
is LoginAction.PasswordChanged -> previousState.copy(password = action.value)
is LoginAction.Login -> {
if(!previousState.isInputValid) return@Reducer previousState
cancelEffect(id = LoginAction.Login) // if an authentication is already in progress, we cancel it
effect(id = LoginAction.Login) {
val result = environment.authenticationService.authenticate(
previousState.emailAddress,
previousState.password,
)
dispatch(LoginAction.LoginResult(result))
}
previousState.copy(
loading = true,
displayLoginError = false
)
}
is LoginAction.LoginResult -> {
action.result.onSuccess { token ->
effect(id = LoginAction.LoginResult::class) {
environment.tokenRepository.store(token)
}
}
previousState.copy(
loading = false,
displayLoginError = action.result.isFailure
)
}
}
}
class LoginStore(
effectScope: CoroutineScope,
environment: LoginEnvironment,
): Store by Store(
initialState = LoginState(),
environment = environment,
effectScope = effectScope,
reducer = LoginReducer,
)
```
A more complex [Compose Multiplatform](https://www.jetbrains.com/compose-multiplatform/) example can be found in the [example directory](https://github.com/floschu/store/blob/main/example).
## author
visit my [website](https://florianschuster.at/).