statelyai / xstate

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

Bug: invoked service stuck when uninvoked switching from invoking state #3611

Closed gh0stonio closed 2 years ago

gh0stonio commented 2 years ago

Description

Sorry for the title that is a bit odd.

First of all thanks to all the maintainers of both the xState library and the Vue module.

disclaimer: I'm coming from the React world and start playing with Vue so maybe what I'm doing here is all wrong

First some background, so I'm trying to build an app that rely only on xState to handle all the logic part. At the beginning I was doing a huge uniq machine but the compound states and matches began to be way too complex, so based on this https://xstate.js.org/docs/guides/communication.html#the-invoke-property I've decided to split on several machines.

The machine was working fine on the xState visualiser but the issue started when I've tried to plug it to the Vue project.

I've already struggled a bit when I wanted to use a machine in several components but this help me a lot https://github.com/statelyai/xstate/discussions/1479.

Then the issue was to be able to listen to the state of the invoked machine, obviously using an actor directly on the machine was not working as the invoked machine reside inside the parent one. So I've tried several things and succeed on having something working by creating an actor based on the child but I'm afraid that this might be "hacky" and the root cause of the issue.

Now the issue, based on my "hacky" hooks (don't know if we call that like that for Vue) the state of the invoked machine is up to date but when the parent machine switch to another state from the one invoking the machine the state is no updated. The invoked machine being now on a final state since not related to anything it should not be stuck to the previous working state.

Here a recording of the issue I've made to easily see the problem:

https://user-images.githubusercontent.com/1764557/191586000-6d5f69d9-35b0-401b-81c0-38f1cdec74a8.mov

I've made a CodeSandbox that reproduce the issue here.

Expected result

I'm expected to not being able to match any state of my invoked machine or if one should be matching maybe the initial state then.

Actual result

The state is stuck to the previous one even though I can't send an event triggering a transaction as the invoked machine reached its final state.

Reproduction

https://codesandbox.io/s/xstate-vue-issue-9xo5vn

Additional context

No response

gh0stonio commented 2 years ago

👋 Hi, I believe I found a solution by understanding more the Vue composition API.

I've forked the CodeSandbox and here the "fixed version" link.

In this version I can use different Composables function all synced properly to each machines (main one or invoked ones).

Closing the issue but maybe it will help others 🤷

Thanks