statelyai / xstate

Actor-based state management & orchestration for complex app logic.
https://stately.ai/docs
MIT License
26.79k stars 1.23k forks source link

Can we populate history after the machine has been initialised? #197

Closed rodinhart closed 5 years ago

rodinhart commented 5 years ago

Bug or feature request?

Feature request, unless it can already be done

Description:

I would like to populate history after the machine has been initialised. The user will pass through some states (login for instance), and select a workspace. This workspace contains information where the user left off, which should end up in history, so that when the user makes certain state transition they end up where they left off.

(Feature) Potential implementation:

I found some related methods in the API, such as inert and new State(..., history, ...), but they didn't really seem to fit this use-case. I could fake it by going through the transitions whilst ignoring the actions (side-effects), but I'd rather just populate directly.

davidkpiano commented 5 years ago

Seems like the use case(s) outlined here: #https://github.com/davidkpiano/xstate/issues/185 would apply here too, where you'd serialize the state in JSON and have it deserialized.

Let me know if that's off.

rodinhart commented 5 years ago

That is certainly part of it, but with a few crucial differences I think?

  1. I would like to set the history state over and over again, as the user can quit the current workspace and open another one, but the application (and therefore the state machine) will keep running.

  2. I'd like to apply history only to a branch of the statechart, as the flow of login and localisation for instance is fixed.

  3. I'd like to apply history to a part of the statechart that I am not in at the moment.

I guess the API I'm looking for would be something like this simplified example:

const machine = XState(config)
let state = machine.initialState // state is "start"

// load locale
state = machine.transition(state, "locale-loaded") // state is "localised"

// user logs in
state = machine.transition(state, "login-successful") // state is "authorised"

// user opens workspace
machine.setHistory({"main": {"filter": {"hist": <historyFromIndexedDB>} } }) // set the deep history state "hist"
state = machine.transition(state, "open-workspace") // state is now {"main": {"filter": ..., "search": ...} }

Hope this makes sense?

davidkpiano commented 5 years ago

This is in master - see #185 (and its referenced commit) for more details.

If it doesn't fit your history use case, can you please open a new ticket with that specifically?