Skip to content

floschu/store

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

20 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

flow

version

build last commit license

installation

repositories {
    mavenCentral()
}

dependencies {
    implementation("at.florianschuster.store:store:$version")
}

see changelog for versions

usage

Go to store as entry point for more information.

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<Token>): 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<LoginEnvironment, LoginAction, LoginState> { 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<LoginEnvironment, LoginAction, LoginState> by Store(
    initialState = LoginState(),
    environment = environment,
    effectScope = effectScope,
    reducer = LoginReducer,
)

A more complex Compose Multiplatform example can be found in the example directory.

author

visit my website.

About

๐Ÿ” opinionated kmp library to manage state

Topics

Resources

License

Stars

Watchers

Forks