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

Eventless transitions #10

Open
kenkunz opened this issue Sep 8, 2022 · 5 comments
Open

Eventless transitions #10

kenkunz opened this issue Sep 8, 2022 · 5 comments

Comments

@kenkunz
Copy link
Owner

kenkunz commented Sep 8, 2022

Opening a new issue to consider / discuss the possibility of adding Eventless Transitions, as proposed by @morungos:

Originally posted by @morungos in #8 (comment)

I'm just following up on my to-do list. Turns out, that second commit I removed earlier, which was about adding eventless transitions, has been incredibly useful (aka, more or less essential) to our project, and they weren't hard to add in. If you're interested, check out: morungos@0955042 I'd be more than happy to make that a pull request too (we don't really want to maintain a fork), but if not, it can stay independently where it is.

Proposed feature / API change

The proposed change is to allow _enter lifecycle actions to return a new state, which may result is a chain of synchronous state changes from a single event invocation. Subscribers would only be notified after the final state change (and only if the resulting state is different that the pre-event state).

@kenkunz
Copy link
Owner Author

kenkunz commented Sep 8, 2022

I am open to considering this, but I have some initial hesitancy and would like to understand the potential use case(s) better.

My hesitancy is that this adds a lot of complexity and (imho) makes an fsm more difficult to reason about. With the current behavior, an event invocation results in 0 or 1 state changes, and it's easy to follow the causal sequence. With this change, an event invocation could result in arbitrarily many state changes, making it far more difficult to follow the causal chain.

This also opens the door to strange edge cases that would need to be dealt with – e.g., an infinite state change loop.

@morungos (or anyone else interested in this feature) – can you share more about the use cases / scenarios that are driving this request?

Thanks!

@morungos
Copy link
Contributor

Sure. Our main use case was the navigation state in a component. We want the application to be able to, for example, go to the login state, but if it is already logged in, to automatically transition to that state without some derived store having to somehow to swallow the additional states, which might trigger fast renders of components before it settled into a final state. In effect, directing to a login state might transiently flash a login screen even if you're already logged in. We did attempt to use a derived store to skip transitional states but turned out to be somewhat more complex than the entire FSM, and it required unpacking the states into pre-states so we'd know when to ignore. In effect, we would have needed to restructure the state design significantly to make it possible, and even then we'd have a substantially more complex system, with very tight coupling between these two components, when really all we needed was to hide transitory states from the application.

There are other examples, but they were more or less equivalent -- in every case we wanted to be able to request a state, and then, if certain guard conditions were met, eventlessly fall through into a more appropriate state (each state more or less corresponded to a screen) without rendering all the screens along the way.

xstate, for example, does have eventless transitions -- in its full version -- and they are an accepted part of state charts.

Our logic pretty much followed the state charts description: we always need to guarding against certain conditions. And yes, there absolutely is the risk of creating an infinite loop if you get it wrong. There's a warning to that effect on the xstate pages. In fact, there is anyway, even if you attempt to achieve that with a derived store. In fact, it's worse with a derived store because you're now fighting Svelte's stores as well as the FSM.

But, of course, we'd far rather use this module than xstate, which would more or less double our deployment footprint for this one small requirement.

@jakubdonovan
Copy link

I am open to considering this, but I have some initial hesitancy and would like to understand the potential use case(s) better.

My hesitancy is that this adds a lot of complexity and (imho) makes an fsm more difficult to reason about. With the current behavior, an event invocation results in 0 or 1 state changes, and it's easy to follow the causal sequence. With this change, an event invocation could result in arbitrarily many state changes, making it far more difficult to follow the causal chain.

This also opens the door to strange edge cases that would need to be dealt with – e.g., an infinite state change loop.

@morungos (or anyone else interested in this feature) – can you share more about the use cases / scenarios that are driving this request?

Thanks!

Hi, has there been any movement towards implementing eventless transitions?

@kenkunz
Copy link
Owner Author

kenkunz commented Oct 2, 2022

@morungos thanks for sharing the details above – this was very helpful.

I'm working to implement this. For consistency, you will be able to return a state from _exit or _enter. Transitions will be followed until no transitions are returned, so you could transition through many states from a single event invocation. I am leaning towards also supporting internal transitions (i.e., transitioning to the current state will still invoke _exit and _enter).

I'll push a public branch soon for feedback.

@morungos
Copy link
Contributor

morungos commented Oct 2, 2022

@kenkunz You might want to look at: morungos@0955042, which was my implementation. There's also a few tests. It might give you some ideas.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants