xstate

Actor-based state management & orchestration for complex app logic.

MIT License

Downloads
14.3M
Stars
26.2K
Committers
362

Bot releases are visible (Hide)

xstate - [email protected]

Published by github-actions[bot] 11 months ago

Patch Changes

xstate - [email protected]

Published by Andarist 11 months ago

Major Changes

Minor Changes

  • #4480 3e610a1f3 Thanks @Andarist! - Children IDs in combination with setup can now be typed using types.children:

    const machine = setup({
      types: {} as {
        children: {
          myId: 'actorKey';
        };
      },
      actors: {
        actorKey: child
      }
    }).createMachine({});
    
    const actorRef = createActor(machine).start();
    
    actorRef.getSnapshot().children.myId; // ActorRefFrom<typeof child> | undefined
    

Patch Changes

xstate - [email protected]

Published by github-actions[bot] 11 months ago

Minor Changes

  • #4488 9ca3c3dcf Thanks @davidkpiano! - The spawn(...) action creator has been renamed to spawnChild(...) to avoid confusion.

    import { spawnChild, assign } from 'xstate';
    
    const childMachine = createMachine({
      on: {
        someEvent: {
          actions: [
            // spawnChild(...) instead of spawn(...)
            spawnChild('someSrc'),
    
            // spawn() is used inside of assign()
            assign({
              anotherRef: ({ spawn }) => spawn('anotherSrc')
            })
          ]
        }
      }
    });
    
  • #4488 9ca3c3dcf Thanks @davidkpiano! - The stop(...) action creator is renamed to stopChild(...), to make it clear that only child actors may be stopped from the parent actor.

xstate - [email protected]

Published by github-actions[bot] 11 months ago

Minor Changes

  • #4467 3c71e537d Thanks @Andarist! - The state.configuration property has been renamed to state._nodes.

    - state.configuration
    + state._nodes
    
  • #4467 3c71e537d Thanks @Andarist! - The state.meta getter has been replaced with state.getMeta() methods:

    - state.meta
    + state.getMeta()
    
  • #4353 a3a11c84e Thanks @davidkpiano! - You can now use the setup({ ... }).createMachine({ ... }) function to setup implementations for actors, actions, guards, and delays that will be used in the created machine:

    import { setup, createMachine } from 'xstate';
    
    const fetchUser = fromPromise(async ({ input }) => {
      const response = await fetch(`/user/${input.id}`);
      const user = await response.json();
      return user;
    });
    
    const machine = setup({
      actors: {
        fetchUser
      },
      actions: {
        clearUser: assign({ user: undefined })
      },
      guards: {
        isUserAdmin: (_, params) => params.user.role === 'admin'
      }
    }).createMachine({
      // ...
      invoke: {
        // Strongly typed!
        src: 'fetchUser',
        input: ({ context }) => ({ id: context.userId }),
        onDone: {
          guard: {
            type: 'isUserAdmin',
            params: ({ context }) => ({ user: context.user })
          },
          target: 'success',
          actions: assign({ user: ({ event }) => event.output })
        },
        onError: {
          target: 'failure',
          actions: 'clearUser'
        }
      }
    });
    

Patch Changes

xstate - [email protected]

Published by github-actions[bot] 11 months ago

Major Changes

  • #4448 9c4353020 Thanks @Andarist! - isState/isStateConfig were replaced by isMachineSnapshot. Similarly, AnyState type was deprecated and it's replaced by AnyMachineSnapshot type.

Patch Changes

  • #4463 178deadac Thanks @Andarist! - invoke and spawn will now require input to be provided if the used actor requires it.

  • #4464 5278a9895 Thanks @Andarist! - Fixed an issue with not being able to target actors registered with systemId from within initial actions.

xstate - [email protected]

Published by github-actions[bot] 11 months ago

Major Changes

  • #4451 21f18b54b Thanks @Andarist! - Removed the ability to configure input within the implementations object. You no longer can do this:

    createMachine(
      {
        invoke: {
          src: 'child'
        }
      },
      {
        actors: {
          child: {
            src: childMachine,
            input: 'foo'
          }
        }
      }
    );
    

    The input can only be provided within the config of the machine.

xstate - @xstate/[email protected]

Published by github-actions[bot] 11 months ago

Major Changes

  • #4288 cfdf754f8 Thanks @davidkpiano! - The useMachine(machine) hook now returns { snapshot, send, service } instead of { state, send, actorRef }:

    const {
    - state,
    + snapshot,
      send,
    - actorRef
    + service
    } = useMachine(machine);
    

Minor Changes

  • #4288 cfdf754f8 Thanks @davidkpiano! - The useInterpret(machine) and useSpawn(machine) hooks have been removed; use the useActorRef(machine) hook instead.
xstate - [email protected]

Published by github-actions[bot] 11 months ago

Major Changes

  • #4438 7bbf41d7d Thanks @Andarist! - Removed State#toStrings method.

  • #4443 18862e53c Thanks @Andarist! - State class has been removed and replaced by MachineSnapshot object. They largely have the same properties and methods. On of the main noticeable results of this change is that you can no longer check state instanceof State.

  • #4444 d6e41a923 Thanks @Andarist! - Removed mapState utility function.

Minor Changes

  • #4440 10d95393a Thanks @Andarist! - State.from, StateMachine#createState and StateMachine#resolveStateValue were removed. They largely served the same purpose as StateMachine#resolveState and this is the method that is still available and can be used instead of them.
xstate - @xstate/[email protected]

Published by github-actions[bot] 12 months ago

Minor Changes

xstate - [email protected]

Published by github-actions[bot] 12 months ago

Major Changes

Minor Changes

xstate - [email protected]

Published by github-actions[bot] 12 months ago

Minor Changes

  • #4414 26fbc6c85 Thanks @davidkpiano! - All inspector events (snapshot, event, actor) now have a common actorRef property. This makes it easier to discern which inspection event is for which actor:

    const actor = createActor(someMachine, {
      inspect: (event) => {
        // Was previously a type error
        if (event.actorRef === actor) {
          // This event is for the root actor
        }
    
        if (event.type === '@xstate.event') {
          // previously event.targetRef
          event.actorRef;
        }
      }
    });
    

    In the 'xstate.event' event, the actorRef property is now the target actor (recipient of the event). Previously, this was the event.targetRef property (which is now removed).

Patch Changes

xstate - [email protected]

Published by github-actions[bot] 12 months ago

Minor Changes

  • #4407 c46a80015 Thanks @davidkpiano! - Internal: changed the actor context type from ActorContext to ActorScope to mitigate confusion.

Patch Changes

  • #4404 a91fdea06 Thanks @Andarist! - Fixed an issue that caused non-active children to be rehydrated.

  • #4368 5393e82df Thanks @Andarist! - Fixed an issue with parallel regions sometimes not being correctly reentered when taking transitions targeting other parallel regions.

xstate - [email protected]

Published by github-actions[bot] 12 months ago

Minor Changes

  • #4329 41f5a7dc5 Thanks @davidkpiano! - You can now spawn(...) actors directly outside of assign(...) action creators:

    import { createMachine, spawn } from 'xstate';
    
    const listenerMachine = createMachine({
      // ...
    });
    
    const parentMachine = createMachine({
      // ...
      on: {
        'listener.create': {
          entry: spawn(listenerMachine, { id: 'listener' })
        }
      }
      // ...
    });
    
    const actor = createActor(parentMachine).start();
    
    actor.send({ type: 'listener.create' });
    
    actor.getSnapshot().children.listener; // ActorRefFrom<typeof listenerMachine>
    
  • #4257 531a63482 Thanks @Andarist! - Action parameters can now be directly accessed from the 2nd argument of the action implementation:

    const machine = createMachine(
      {
        // ...
        entry: {
          type: 'greet',
          params: { message: 'hello' }
        }
      },
      {
        actions: {
          greet: (_, params) => {
            params.message; // 'hello'
          }
        }
      }
    );
    
  • #4257 531a63482 Thanks @Andarist! - Guard parameters can now be directly accessed from the 2nd argument of the guard implementation:

    const machine = createMachine(
      {
        // ...
        on: {
          EVENT: {
            guard: {
              type: 'isGreaterThan',
              params: { value: 10 }
            }
          }
        }
      },
      {
        guards: {
          isGreaterThan: (_, params) => {
            params.value; // 10
          }
        }
      }
    );
    

Patch Changes

  • #4405 a01169eb2 Thanks @Andarist! - Fixed crash on a systemId synchronous re-registration attempt that could happen, for example, when dealing with reentering transitions.

  • #4401 eea74c594 Thanks @Andarist! - Fixed the issue with stopped state machines not updating their snapshots with that information.

  • #4403 3f84bba72 Thanks @Andarist! - Fixed an issue with rehydrated actors not registering themselves in the system.

xstate - [email protected]

Published by github-actions[bot] 12 months ago

Major Changes

  • #4234 57814f46d Thanks @Andarist! - Atomic and parallel states should no longer be reentered when the transition target doesn't escape them. You can get the reentering behavior by configuring reenter: true for the transition.

Patch Changes

  • #4387 0be0ef015 Thanks @Andarist! - Added support to stateIn guard for checking a combination of an ID and a path, eg. stateIn('#b.B1').

  • #4384 e0bbe3397 Thanks @Andarist! - Fixed an issue that caused parallel states with direct final children to be completed without all regions being in their final states.

xstate - [email protected]

Published by github-actions[bot] 12 months ago

Patch Changes

  • #4380 e9e065822 Thanks @Andarist! - Fixed an issue with exit actions sometimes being called twice when a machine reaches its final state and leads its parent to stopping it at the same time.
xstate - [email protected]

Published by github-actions[bot] 12 months ago

Major Changes

  • #4372 c19e6fb1e Thanks @Andarist! - Removed State['_internalQueue'].

  • #4371 8b3f6647c Thanks @Andarist! - Changed behavior of always transitions. Previously they were always selected after selecting any transition (including the always transitions). Because of that it was relatively easy to create an infinite loop using them.

    Now they are no longer selected if the preceeding transition doesn't change the state of a machine.

  • #4377 14cb2ed0c Thanks @Andarist! - exit actions of all states are no longer called when the machine gets stopped externally. Note that they are still called when the machine reaches its final state.

Patch Changes

  • #4376 078eaaddd Thanks @Andarist! - Fixed an issue with exit actions being called twice when machine reached its final state.
xstate - [email protected]

Published by github-actions[bot] almost 1 year ago

Major Changes

  • #4363 3513280db Thanks @Andarist! - Removed the ability to target deep descendants with the initial property.

  • #4363 3513280db Thanks @Andarist! - Removed the ability to target multiple descendants with the initial property.

  • #4216 04cad53e0 Thanks @Andarist! - Removed the ability to define delayed transitions using an array. Only object variant is supported now:

    createMachine({
      initial: 'a',
      states: {
        a: {
          after: {
            10000: 'b',
            noon: 'c'
          }
        }
        // ...
      }
    });
    
  • #3921 0ca1b860c Thanks @davidkpiano! - Spawned actors that have a referenced source (not inline) can be deeply persisted and restored:

    const machine = createMachine({
      context: ({ spawn }) => ({
        // This will be persisted
        ref: spawn('reducer', { id: 'child' })
    
        // This cannot be persisted:
        // ref: spawn(fromTransition((s) => s, { count: 42 }), { id: 'child' })
      })
    }).provide({
      actors: {
        reducer: fromTransition((s) => s, { count: 42 })
      }
    });
    

Minor Changes

  • #4358 03ac5c013 Thanks @Andarist! - xstate.done.state.* events will now be generated recursively for all parallel states on the ancestors path.

Patch Changes

  • #4361 1a00b5a54 Thanks @Andarist! - Fixed a runtime crash related to machines with their root state's type being final (createMachine({ type: 'final' })).

  • #4357 84c46c1ae Thanks @Andarist! - Fixed an issue with not all actions of initial transitions resolving to the initial state of the machine itself being executed.

  • #4356 81b6edafd Thanks @Andarist! - Fixed an issue with actions of initial transitions being called too many times.

xstate - [email protected]

Published by github-actions[bot] about 1 year ago

Patch Changes

  • #4351 6f1818365 Thanks @Andarist! - Fixed an issue that prevented invoke.input from seeing the context updated by the same-level entry actions.

  • #4344 f9b17f1e9 Thanks @davidkpiano! - Inspection events are now exported:

    import type {
      InspectedActorEvent,
      InspectedEventEvent,
      InspectedSnapshotEvent,
      InspectionEvent
    } from 'xstate';
    
xstate - [email protected]

Published by github-actions[bot] about 1 year ago

Minor Changes

  • #4082 13480c3a9 Thanks @davidkpiano! - You can now inspect actor system updates using the inspect option in createActor(logic, { inspect }). The types of inspection events you can observe include:

    • @xstate.actor - An actor ref has been created in the system
    • @xstate.event - An event was sent from a source actor ref to a target actor ref in the system
    • @xstate.snapshot - An actor ref emitted a snapshot due to a received event
    import { createMachine } from 'xstate';
    
    const machine = createMachine({
      // ...
    });
    
    const actor = createActor(machine, {
      inspect: (inspectionEvent) => {
        if (inspectionEvent.type === '@xstate.actor') {
          console.log(inspectionEvent.actorRef);
        }
    
        if (inspectionEvent.type === '@xstate.event') {
          console.log(inspectionEvent.sourceRef);
          console.log(inspectionEvent.targetRef);
          console.log(inspectionEvent.event);
        }
    
        if (inspectionEvent.type === '@xstate.snapshot') {
          console.log(inspectionEvent.actorRef);
          console.log(inspectionEvent.event);
          console.log(inspectionEvent.snapshot);
        }
      }
    });
    

Patch Changes

  • #4336 17da18692 Thanks @Andarist! - Invoked actors will no longer be automatically started (added to .children) when those children are missing in the persisted state.
xstate - [email protected]

Published by github-actions[bot] about 1 year ago

Patch Changes

  • #4335 ba111c32c Thanks @davidkpiano! - Composable (e.g. higher-order) logic should now work as expected for state machine logic, as well as all other types of logic.

  • #4330 9f69d46a6 Thanks @Andarist! - Fixed an issue with rehydrated actors not having their internal reference to the parent set correctly.