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

Bug: Parallel states transitions behave differently on V5 #4793

Open
gastonfartek opened this issue Mar 10, 2024 · 2 comments
Open

Bug: Parallel states transitions behave differently on V5 #4793

gastonfartek opened this issue Mar 10, 2024 · 2 comments
Assignees
Labels

Comments

@gastonfartek
Copy link

XState version

XState version 5

Description

Example:

{
  id: "question-flow",
  initial: "value1",
  type: "parallel",
  states: {
    value1: {
      type: "final",
      on: {
        NEXT: {
          target: "#question-flow.value2.shown",
        },
      },
    },
    value2: {
      id: "value2",
      initial: "hidden",
      states: {
        shown: {
          on: {
            NEXT: {
              target: "#question-flow.value3.shown",
            },
          },
        },
        hidden: {},
      },
    },
    value3: {
      id: "value3",
      initial: "hidden",
      states: {
        hidden: {},
        shown: {
          type: "final",
        },
      },
    },
  },
}

on the state machine above I used to be able to send aNEXT event and it would toggle value2 on the first call and value3 on the second call, however since upgrading to v5 only the NEXT from value1 is being called, is this expected behavior now?

Here is a codesandbox with this machine and xstate v5

Here is a codesandbox for xstate V4

Expected result

it should call NEXT on value2.shown

Actual result

only NEXT from value1 is ever triggered

Reproduction

https://codesandbox.io/p/sandbox/test-xstate-4xcj29?file=%2Fsrc%2FApp.js%3A10%2C14

Additional context

No response

@Andarist
Copy link
Member

This works as expected according to the SCXML semantics of conflicting transitions (see removeConflictingTransitions.

However, we have tweaked rules around reentrancy of source states (see here). Essentially, for many purposes we are using LCA over LCCA algorithms to detect "transitions containment". This makes this part of the mentioned removeConflictingTransitions algorithm outdated for us:

Transitions that aren't contained within a single child force the state machine to leave the ancestor (even if they reenter it later).

Our own implementation is still using our own computeExitSet though so it could work correctly already - maybe there is a small bug there. I'm still trying to think through this case but it feels like - given the above - you are right that this should work.

Note though that:

  • respective source regions are still exited here (and reentered). It's just that the parallel region itself isn't reentered here whereas in SCXML it would be
  • using on in a final state is forbidden by SCXML but it turns out that we don't quite enforce this

@davidkpiano
Copy link
Member

We're going to look into this a bit more... may be a bug.

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

No branches or pull requests

3 participants