Skip to content

floschu/store

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

30 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.

Check out the store skill to implement and test store with your AI agents.

author

visit my website.

About

🔁 opinionated kmp library to manage state

Topics

Resources

License

Stars

Watchers

Forks

Contributors