Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unify state (snapshot) access and parameters in DSL #631

Open
gabrielittner opened this issue Dec 20, 2023 · 0 comments
Open

Unify state (snapshot) access and parameters in DSL #631

gabrielittner opened this issue Dec 20, 2023 · 0 comments
Milestone

Comments

@gabrielittner
Copy link
Member

gabrielittner commented Dec 20, 2023

Just a random thought about something for a potential v2, I haven't fully thought through all use cases yet.

We currently have our State class looking like this:

public class State<InputState : Any>(
    public val snapshot: InputState,
) {
   fun mutate(reducer: InputState.() -> InputState): ChangedState<InputState>
   fun <S : Any> override(reducer: InputState.() -> S): ChangedState<S>
   fun <S : Any> noChange(): ChangedState<S>
}

In the DSL we when have

onEnter { state -> 
onEnterEffect { stateSnapshot -> 
on<...> { action, state -> 
onActionEffect<...> { action, stateSnapshot -> 
collectWhileInState { item, state -> 
collectWhileInStateEffect { item, stateSnapshot -> 

This has 2 inconsistencies:

  • for effect merhods you get the snapshot directly instead of something that allows you to access the snasphot (as a side effect there is nothing that enforces how you call the parameter which makes it easy to just call it state and forget that it's a snapshot)
  • for enter you only get the state/snapshot and could use it for it while for the others you get 2 parameters which need to be written out

We could make 2 changes for v2:

  1. Split State into 2 classes. The first class only has snapshot access and the other one extends that one and offers our mutation methods. This way we can always use one of these 2 classes as parameter to the DSL builders and you always call state.snapshot to access the snapshot.

    public open class State<InputState : Any> internal constructor(
        public val snapshot: InputState,
    )
    
    public class MutableState<InputState : Any>(snapshot: InputState) : State(snapshot) {
       fun mutate(reducer: InputState.() -> InputState): ChangedState<InputState>
       fun <S : Any> override(reducer: InputState.() -> S): ChangedState<S>
       fun <S : Any> noChange(): ChangedState<S>
    }
    
    onEnter { state -> 
    onEnterEffect { state -> 
    on<...> { action, state -> 
    onActionEffect<...> { action, state -> 
    collectWhileInState { item, state -> 
    collectWhileInStateEffect { item, state -> 
    
  2. Building on top of that the DSL blocks can use State or MutableState as a receiver which unifies the state access between onEnter(Effect) and the others. For those that previously had 2 parameters it's up to the caller whether to be explicit with the remaining parameter like below or to just use it.

    onEnter { 
    onEnterEffect {  
    on<...> { action -> 
    onActionEffect<...> { action -> 
    collectWhileInState { item -> 
    collectWhileInStateEffect { item -> 
    
@gabrielittner gabrielittner added this to the 2.0 milestone Dec 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant