statelyai / xstate

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

Bug: SendTo doesn't see local actors when combined with "target" transition #5051

Open niba opened 3 months ago

niba commented 3 months ago

XState version

XState version 5

Description

When combining the target property in your event with the sendTo action, you're unable to send an event to your local state actor.

On my machine, I want to first clear all of my callbacks/subscriptions and then transition to another state. However, when I try to achieve this, I get the following error: Unable to send event to actor 'ACTOR_NAME' from machine 'MACHINE_NAME'.

Here is the section of my machine

   recording: {
        invoke: {
          id: "listeningOnEvents",
          src: "listenOnSteps",
        },
       on: {
          STOP: {
            target: "stoping",
            actions: sendTo("listeningOnEvents", { type: "STOP" }),
         },
    }}

Xstate searches for actors in children array which is empty (it is only empty when event has target property) targetActorRef = snapshot.children[resolvedTarget.slice(2)];

As a workaround, I can use the raise action to trigger another event that only performs the state transition. Why doesn't the original approach work?

Expected result

My event can communicate with a local actor

Actual result

SendTo doesn't see a local actor

Reproduction

https://stackblitz.com/edit/github-ntq4he-jy7jad?file=src%2FfeedbackMachine.ts

Additional context

No response

Andarist commented 2 months ago

The execution order of actions is roughly always this:

[...exitActions, ...transitionActions, ...entryActions]

And in this example, a transition action tries to send an event to an actor that was just stopped by an exit action.