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

chore(deps): update dependency xstate to v5 #154

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

renovate[bot]
Copy link
Contributor

@renovate renovate bot commented Dec 1, 2023

This PR contains the following updates:

Package Change Age Adoption Passing Confidence
xstate (source) ^4.13.0 -> ^5.0.0 age adoption passing confidence

Release Notes

statelyai/xstate (xstate)

v5.18.2

Compare Source

Patch Changes

v5.18.1

Compare Source

Patch Changes

v5.18.0

Compare Source

Minor Changes
  • #​5042 54c9d9e6a4 Thanks @​boneskull! - waitFor() now accepts a {signal: AbortSignal} in WaitForOptions

  • #​5006 1ab974547f Thanks @​davidkpiano! - The state value typings for setup state machine actors (setup({}).createMachine({ ... })) have been improved to represent the actual expected state values.

    const machine = setup({}).createMachine({
      initial: 'green',
      states: {
        green: {},
        yellow: {},
        red: {
          initial: 'walk',
          states: {
            walk: {},
            wait: {},
            stop: {}
          }
        },
        emergency: {
          type: 'parallel',
          states: {
            main: {
              initial: 'blinking',
              states: {
                blinking: {}
              }
            },
            cross: {
              initial: 'blinking',
              states: {
                blinking: {}
              }
            }
          }
        }
      }
    });
    
    const actor = createActor(machine).start();
    
    const stateValue = actor.getSnapshot().value;
    
    if (stateValue === 'green') {
      // ...
    } else if (stateValue === 'yellow') {
      // ...
    } else if ('red' in stateValue) {
      stateValue;
      // {
      //   red: "walk" | "wait" | "stop";
      // }
    } else {
      stateValue;
      // {
      //   emergency: {
      //     main: "blinking";
      //     cross: "blinking";
      //   };
      // }
    }
Patch Changes
  • #​5054 853f6daa0b Thanks @​davidkpiano! - The CallbackLogicFunction type (previously InvokeCallback) is now exported. This is the callback function that you pass into fromCallback(callbackLogicFn) to create an actor from a callback function.

    import { type CallbackLogicFunction } from 'xstate';
    
    // ...

v5.17.4

Compare Source

Patch Changes
  • #​5039 d6df8fb470 Thanks @​Andarist! - Fixed an inference issue that prevented emit used directly in setup (or bare createMachine) to benefit from types.emitted types.

v5.17.3

Compare Source

Patch Changes

v5.17.2

Compare Source

Patch Changes

v5.17.1

Compare Source

Patch Changes
  • #​5009 51d4c4fc5 Thanks @​davidkpiano! - The internal types for StateMachine<...> have been improved so that all type params are required, to prevent errors when using the types. This fixes weird issues like #​5008.

v5.17.0

Compare Source

Minor Changes
  • #​4979 a0e9ebcef Thanks @​davidkpiano! - State IDs are now strongly typed as keys of snapshot.getMeta() for state machine actor snapshots.

    const machine = setup({
      // ...
    }).createMachine({
      id: 'root',
      initial: 'parentState',
      states: {
        parentState: {
          meta: {},
          initial: 'childState',
          states: {
            childState: {
              meta: {}
            },
            stateWithId: {
              id: 'state with id',
              meta: {}
            }
          }
        }
      }
    });
    
    const actor = createActor(machine);
    
    const metaValues = actor.getSnapshot().getMeta();
    
    // Auto-completed keys:
    metaValues.root;
    metaValues['root.parentState'];
    metaValues['root.parentState.childState'];
    metaValues['state with id'];
    
    // @&#8203;ts-expect-error
    metaValues['root.parentState.stateWithId'];
    
    // @&#8203;ts-expect-error
    metaValues['unknown state'];
Patch Changes

v5.16.0

Compare Source

Minor Changes
  • #​4996 5be796cd2 Thanks @​ronvoluted! - The actor snapshot status type ('active' | 'done' | 'error' | 'stopped') is now exposed as SnapshotStatus

  • #​4981 c4ae156b2 Thanks @​davidkpiano! - Added sendParent to the enqueueActions feature. This allows users to enqueue actions that send events to the parent actor within the enqueueActions block.

    import { createMachine, enqueueActions } from 'xstate';
    
    const childMachine = createMachine({
      entry: enqueueActions(({ enqueue }) => {
        enqueue.sendParent({ type: 'CHILD_READY' });
      })
    });

v5.15.0

Compare Source

Minor Changes
  • #​4976 452bce71e Thanks @​with-heart! - Added exports for actor logic-specific ActorRef types: CallbackActorRef, ObservableActorRef, PromiseActorRef, and TransitionActorRef.

    Each type represents ActorRef narrowed to the corresponding type of logic (the type of self within the actor's logic):

    • CallbackActorRef: actor created by fromCallback

      import { fromCallback, createActor } from 'xstate';
      
      /** The events the actor receives. */
      type Event = { type: 'someEvent' };
      /** The actor's input. */
      type Input = { name: string };
      
      /** Actor logic that logs whenever it receives an event of type `someEvent`. */
      const logic = fromCallback<Event, Input>(({ self, input, receive }) => {
        self;
        // ^? CallbackActorRef<Event, Input>
      
        receive((event) => {
          if (event.type === 'someEvent') {
            console.log(`${input.name}: received "someEvent" event`);
            // logs 'myActor: received "someEvent" event'
          }
        });
      });
      
      const actor = createActor(logic, { input: { name: 'myActor' } });
      //    ^? CallbackActorRef<Event, Input>
    • ObservableActorRef: actor created by fromObservable and fromEventObservable

      import { fromObservable, createActor } from 'xstate';
      import { interval } from 'rxjs';
      
      /** The type of the value observed by the actor's logic. */
      type Context = number;
      /** The actor's input. */
      type Input = { period?: number };
      
      /**
       * Actor logic that observes a number incremented every `input.period`
       * milliseconds (default: 1_000).
       */
      const logic = fromObservable<Context, Input>(({ input, self }) => {
        self;
        // ^? ObservableActorRef<Event, Input>
      
        return interval(input.period ?? 1_000);
      });
      
      const actor = createActor(logic, { input: { period: 2_000 } });
      //    ^? ObservableActorRef<Event, Input>
    • PromiseActorRef: actor created by fromPromise

      import { fromPromise, createActor } from 'xstate';
      
      /** The actor's resolved output. */
      type Output = string;
      /** The actor's input. */
      type Input = { message: string };
      
      /** Actor logic that fetches the url of an image of a cat saying `input.message`. */
      const logic = fromPromise<Output, Input>(async ({ input, self }) => {
        self;
        // ^? PromiseActorRef<Output, Input>
      
        const data = await fetch(`https://cataas.com/cat/says/${input.message}`);
        const url = await data.json();
        return url;
      });
      
      const actor = createActor(logic, { input: { message: 'hello world' } });
      //    ^? PromiseActorRef<Output, Input>
    • TransitionActorRef: actor created by fromTransition

      import { fromTransition, createActor, type AnyActorSystem } from 'xstate';
      
      /** The actor's stored context. */
      type Context = {
        /** The current count. */
        count: number;
        /** The amount to increase `count` by. */
        step: number;
      };
      /** The events the actor receives. */
      type Event = { type: 'increment' };
      /** The actor's input. */
      type Input = { step?: number };
      
      /**
       * Actor logic that increments `count` by `step` when it receives an event of
       * type `increment`.
       */
      const logic = fromTransition<Context, Event, AnyActorSystem, Input>(
        (state, event, actorScope) => {
          actorScope.self;
          //         ^? TransitionActorRef<Context, Event>
      
          if (event.type === 'increment') {
            return {
              ...state,
              count: state.count + state.step
            };
          }
          return state;
        },
        ({ input, self }) => {
          self;
          // ^? TransitionActorRef<Context, Event>
      
          return {
            count: 0,
            step: input.step ?? 1
          };
        }
      );
      
      const actor = createActor(logic, { input: { step: 10 } });
      //    ^? TransitionActorRef<Context, Event>
  • #​4949 8aa4c2b90 Thanks @​davidkpiano! - The TypeGen-related types have been removed from XState, simplifying the internal types without affecting normal XState usage.

v5.14.0

Compare Source

Minor Changes
  • #​4936 c58b36dc3 Thanks @​davidkpiano! - Inspecting an actor system via actor.system.inspect(ev => …) now accepts a function or observer, and returns a subscription:

    const actor = createActor(someMachine);
    
    const sub = actor.system.inspect((inspectionEvent) => {
      console.log(inspectionEvent);
    });
    
    // Inspection events will be logged
    actor.start();
    actor.send({ type: 'anEvent' });
    
    // ...
    
    sub.unsubscribe();
    
    // Will no longer log inspection events
    actor.send({ type: 'someEvent' });
  • #​4942 9caaa1f70 Thanks @​boneskull! - DoneActorEvent and ErrorActorEvent now contain property actorId, which refers to the ID of the actor the event refers to.

  • #​4935 2ac08b700 Thanks @​davidkpiano! - All actor logic creators now support emitting events:

    Promise actors

    const logic = fromPromise(async ({ emit }) => {
      // ...
      emit({
        type: 'emitted',
        msg: 'hello'
      });
      // ...
    });

    Transition actors

    const logic = fromTransition((state, event, { emit }) => {
      // ...
      emit({
        type: 'emitted',
        msg: 'hello'
      });
      // ...
      return state;
    }, {});

    Observable actors

    const logic = fromObservable(({ emit }) => {
      // ...
    
      emit({
        type: 'emitted',
        msg: 'hello'
      });
    
      // ...
    });

    Callback actors

    const logic = fromCallback(({ emit }) => {
      // ...
      emit({
        type: 'emitted',
        msg: 'hello'
      });
      // ...
    });
Patch Changes

v5.13.2

Compare Source

Patch Changes

v5.13.1

Compare Source

Patch Changes
  • #​4905 dbeafeb25 Thanks @​davidkpiano! - You can now use a wildcard to listen for any emitted event from an actor:

    actor.on('*', (emitted) => {
      console.log(emitted); // Any emitted event
    });

v5.13.0

Compare Source

Minor Changes
  • #​4832 148d8fcef Thanks @​cevr! - fromPromise now passes a signal into its creator function.

    const logic = fromPromise(({ signal }) =>
      fetch('https://api.example.com', { signal })
    );

    This will be called whenever the state transitions before the promise is resolved. This is useful for cancelling the promise if the state changes.

Patch Changes
  • #​4876 3f6a73b56 Thanks @​davidkpiano! - XState will now warn when calling built-in actions like assign, sendTo, raise, emit, etc. directly inside of a custom action. See https://stately.ai/docs/actions#built-in-actions for more details.

    const machine = createMachine({
      entry: () => {
        // Will warn:
        // "Custom actions should not call \`assign()\` directly, as it is not imperative. See https://stately.ai/docs/actions#built-in-actions for more details."
        assign({
          // ...
        });
      }
    });

v5.12.0

Compare Source

Minor Changes
  • #​4863 0696adc21 Thanks @​davidkpiano! - Meta objects for state nodes and transitions can now be specified in setup({ types: … }):

    const machine = setup({
      types: {
        meta: {} as {
          layout: string;
        }
      }
    }).createMachine({
      initial: 'home',
      states: {
        home: {
          meta: {
            layout: 'full'
          }
        }
      }
    });
    
    const actor = createActor(machine).start();
    
    actor.getSnapshot().getMeta().home;
    // => { layout: 'full' }
    // if in "home" state

v5.11.0

Compare Source

Minor Changes
  • #​4806 f4e0ec48c Thanks @​davidkpiano! - Inline actor logic is now permitted when named actors are present. Defining inline actors will no longer cause a TypeScript error:

    const machine = setup({
      actors: {
        existingActor: fromPromise(async () => {
          // ...
        })
      }
    }).createMachine({
      invoke: {
        src: fromPromise(async () => {
          // Inline actor
        })
        // ...
      }
    });

v5.10.0

Compare Source

Minor Changes
  • #​4822 f7f1fbbf3 Thanks @​davidkpiano! - The clock and logger specified in the options object of createActor(logic, options) will now propagate to all actors created within the same actor system.

    import { setup, log, createActor } from 'xstate';
    
    const childMachine = setup({
      // ...
    }).createMachine({
      // ...
      // Uses custom logger from root actor
      entry: log('something')
    });
    
    const parentMachine = setup({
      // ...
    }).createMachine({
      // ...
      invoke: {
        src: childMachine
      }
    });
    
    const actor = createActor(parentMachine, {
      logger: (...args) => {
        // custom logger for args
      }
    });
    
    actor.start();

v5.9.1

Compare Source

Patch Changes

v5.9.0

Compare Source

Minor Changes
  • #​4746 b570ba20d Thanks @​davidkpiano! - The new emit(…) action creator emits events that can be received by listeners. Actors are now event emitters.

    import { emit } from 'xstate';
    
    const machine = createMachine({
      // ...
      on: {
        something: {
          actions: emit({
            type: 'emitted',
            some: 'data'
          })
        }
      }
      // ...
    });
    
    const actor = createActor(machine).start();
    
    actor.on('emitted', (event) => {
      console.log(event);
    });
    
    actor.send({ type: 'something' });
    // logs:
    // {
    //   type: 'emitted',
    //   some: 'data'
    // }
  • #​4777 4abeed9df Thanks @​Andarist! - Added support for params to enqueueActions

v5.8.2

Compare Source

Patch Changes
  • #​4772 9a0120901 Thanks @​Andarist! - Fixed a type issue that prevent sendParent to be accepted by setup when delays stayed not configured.

v5.8.1

Compare Source

Patch Changes

v5.8.0

Compare Source

Minor Changes

v5.7.1

Compare Source

Patch Changes
  • #​4739 15b7dd1f0 Thanks @​devanfarrell! - Removed this from machine snapshot methods to fix issues with accessing those methods from union of actors and their snapshots.

v5.7.0

Compare Source

Minor Changes
  • #​4290 7a8796f80 Thanks @​davidkpiano! - An error will now be thrown if an incompatible state value is passed to machine.resolveState({ value }).

  • #​4693 11b6a1ae1 Thanks @​davidkpiano! - You can now inspect microsteps (@xstate.microstep) and actions (@xstate.action):

    const machine = createMachine({
      initial: 'a',
      states: {
        a: {
          on: {
            event: 'b'
          }
        },
        b: {
          entry: 'someAction',
          always: 'c'
        },
        c: {}
      }
    });
    
    const actor = createActor(machine, {
      inspect: (inspEvent) => {
        if (inspEvent.type === '@&#8203;xstate.microstep') {
          console.log(inspEvent.snapshot);
          // logs:
          // { value: 'a', … }
          // { value: 'b', … }
          // { value: 'c', … }
    
          console.log(inspEvent.event);
          // logs:
          // { type: 'event', … }
        } else if (inspEvent.type === '@&#8203;xstate.action') {
          console.log(inspEvent.action);
          // logs:
          // { type: 'someAction', … }
        }
      }
    });
    
    actor.start();
    
    actor.send({ type: 'event' });

v5.6.2

Compare Source

Patch Changes
  • #​4731 960cdcbcb Thanks @​davidkpiano! - You can now import getInitialSnapshot(…) from xstate directly, which is useful for getting a mock of the initial snapshot when interacting with machines (or other actor logic) without createActor(…):

    import { getInitialSnapshot } from 'xstate';
    import { someMachine } from './someMachine';
    
    // Returns the initial snapshot (state) of the machine
    const initialSnapshot = getInitialSnapshot(
      someMachine,
      { name: 'Mateusz' } // optional input
    );

v5.6.1

Compare Source

Patch Changes

v5.6.0

Compare Source

Minor Changes
  • #​4704 78699aef6 Thanks @​Andarist! - createActor will now error if the required input is not given to it.

  • #​4688 14902e17a Thanks @​Andarist! - The schemas property in setup(...) is now passed through to the resulting machine. This property is meant to be used with future developer tooling, and is typed as unknown for now.

Patch Changes

v5.5.2

Compare Source

Patch Changes
  • #​4685 e43eab144 Thanks @​davidkpiano! - State IDs that have periods in them are now supported if those periods are escaped.

    The motivation is that external tools, such as Stately Studio, may allow users to enter any text into the state ID field. This change allows those tools to escape periods in state IDs, so that they don't conflict with the internal path-based state IDs.

    E.g. if a state ID of "Loading..." is entered into the state ID field, instead of crashing either the external tool and/or the XState state machine, it should be converted by the tool to "Loading\\.\\.\\.", and those periods will be ignored by XState.

v5.5.1

Compare Source

Patch Changes

v5.5.0

Compare Source

Minor Changes
  • #​4596 6113a590a Thanks @​davidkpiano! - Introduce getNextSnapshot(...), which determines the next snapshot for the given actorLogic based on the given snapshot and event.

    If the snapshot is undefined, the initial snapshot of the actorLogic is used.

    import { getNextSnapshot } from 'xstate';
    import { trafficLightMachine } from './trafficLightMachine.ts';
    
    const nextSnapshot = getNextSnapshot(
      trafficLightMachine, // actor logic
      undefined, // snapshot (or initial state if undefined)
      { type: 'TIMER' }
    ); // event object
    
    console.log(nextSnapshot.value);
    // => 'yellow'
    
    const nextSnapshot2 = getNextSnapshot(
      trafficLightMachine, // actor logic
      nextSnapshot, // snapshot
      { type: 'TIMER' }
    ); // event object
    
    console.log(nextSnapshot2.value);
    // =>'red'
Patch Changes

v5.4.1

Compare Source

Patch Changes

v5.4.0

Compare Source

Minor Changes
  • #​4616 e8c0b15b2 Thanks @​Andarist! - context factories receive self now so you can immediately pass that as part of the input to spawned actors.

    setup({
      /* ... */
    }).createMachine({
      context: ({ spawn, self }) => {
        return {
          childRef: spawn('child', { input: { parent: self } })
        };
      }
    });

v5.3.1

Compare Source

Patch Changes
  • #​4597 ae0b05f11 Thanks @​davidkpiano! - Update the argument object of enqueueActions(...) to include the self and system properties:

    // ...
    entry: enqueueActions(({ self, system }) => {
      // ...
    });

v5.3.0

Compare Source

Minor Changes
  • #​4547 8e8d2ba38 Thanks @​davidkpiano! - Add assertEvent(...) to help provide strong typings for events that can't be easily inferred, such as events in entry and exit actions, or in invoke.input.

    The assertEvent(event, 'someType') function will throw if the event is not the expected type. This ensures that the event is guaranteed to have that type, and assumes that the event object has the expected payload (naturally enforced by TypeScript).

    // ...
    entry: ({ event }) => {
      assertEvent(event, 'greet');
      // event is { type: 'greet'; message: string }
    
      assertEvent(event, ['greet', 'notify']);
      // event is { type: 'greet'; message: string }
      // or { type: 'notify'; message: string; level: 'info' | 'error' }
    },
    exit: ({ event }) => {
      assertEvent(event, 'doNothing');
      // event is { type: 'doNothing' }
    }
Patch Changes
  • #​4586 97f1cbd5f Thanks @​Andarist! - Fixed an issue with ancestors of the default history target that lie outside of the transition domain being incorrectly entered.

v5.2.1

Compare Source

Patch Changes

v5.2.0

Compare Source

Minor Changes
  • #​4198 ca58904ad Thanks @​davidkpiano! - Introduce toPromise(actor), which creates a promise from an actor that resolves with the actor snapshot's output when done, or rejects with the actor snapshot's error when it fails.

    import { createMachine, createActor, toPromise } from 'xstate';
    
    const machine = createMachine({
      // ...
      states: {
        // ...
        done: { type: 'final', output: 42 }
      }
    });
    
    const actor = createActor(machine);
    
    actor.start();
    
    const output = await toPromise(actor);
    
    console.log(output);
    // => 42
Patch Changes
  • #​4568 a5c55fae2 Thanks @​Andarist! - Fixed an issue with spawn within assign not returning a narrowed down ActorRef type on TypeScrip 5.0

  • #​4570 c11127336 Thanks @​Andarist! - Fixed an issue that caused a complete listener to be called instead of the error one when the actor was subscribed after being stopped.

v5.1.0

Compare Source

Minor Changes
Patch Changes

v5.0.2

Compare Source

Patch Changes

v5.0.1

Compare Source

Patch Changes

v5.0.0

Compare Source

Major Changes
  • d3d6149: If context types are specified in the machine config, the context property will now be required:

    // ❌ TS error
    createMachine({
      types: {} as {
        context: { count: number };
      }
      // Missing context property
    });
    
    // ✅ OK
    createMachine({
      types: {} as {
        context: { count: number };
      },
      context: {
        count: 0
      }
    });
  • d3d6149: - The third argument of machine.transition(state, event) has been removed. The context should always be given as part of the state.

    • There is a new method: machine.microstep(snapshot, event) which returns the resulting intermediate MachineSnapshot object that represents a single microstep being taken when transitioning from snapshot via the event. This is the MachineSnapshot that does not take into account transient transitions nor raised events, and is useful for debugging.
    • The state.events property has been removed from the State object
    • The state.historyValue property now more closely represents the original SCXML algorithm, and is a mapping of state node IDs to their historic descendent state nodes. This is used for resolving history states, and should be considered internal.
    • The stateNode.isTransient property is removed from StateNode.
    • The .initial property of a state node config object can now contain executable content (i.e., actions):
    // ...
    initial: {
      target: 'someTarget',
      actions: [/* initial actions */]
    }
    • Assign actions (via assign()) will now be executed "in order", rather than automatically prioritized. They will be evaluated after previously defined actions are evaluated, and actions that read from context will have those intermediate values applied, rather than the final resolved value of all assign() actions taken, which was the previous behavior.

    This shouldn't change the behavior for most state machines. To maintain the previous behavior, ensure that assign() actions are defined before any other actions.

  • d3d6149: An error will be thrown if an initial state key is not specified for compound state nodes. For example:

    const lightMachine = createMachine({
      id: 'light',
      initial: 'green',
      states: {
        green: {},
        yellow: {},
        red: {
          // Forgotten initial state:
          // initial: 'walk',
          states: {
            walk: {},
            wait: {}
          }
        }
      }
    });

    You will get the error:

    No initial state specified for state node "#light.red". Try adding { initial: "walk" } to the state config.
    
  • d3d6149: IDs for delayed events are no longer derived from event types so this won't work automatically:

    entry: raise({ type: 'TIMER' }, { delay: 200 });
    exit: cancel('TIMER');

    Please use explicit IDs:

    entry: raise({ type: 'TIMER' }, { delay: 200, id: 'myTimer' });
    exit: cancel('myTimer');
  • d3d6149: Removed State#toStrings method.

  • d3d6149: The machine's context is now restricted to an Record<string, any>. This was the most common usage, but now the typings prevent context from being anything but an object:

    const machine = createMachine({
      // This will produce the TS error:
      // "Type 'string' is not assignable to type 'object | undefined'"
      context: 'some string'
    });

    If context is undefined, it will now default to an empty object {}.

  • d3d6149: Actors are now always part of a "system", which is a collection of actors that can communicate with each other. Systems are implicitly created, and can be used to get and set references to any actor in the system via the systemId prop:

    const machine = createMachine({
      // ...
      invoke: {
        src: emailMachine,
        // Registers `emailMachine` as `emailer` on the system
        systemId: 'emailer'
      }
    });
    const machine = createMachine({
      // ...
      entry: assign({
        emailer: (ctx, ev, { spawn }) =>
          spawn(emailMachine, { systemId: 'emailer' })
      })
    });

    Any invoked/spawned actor that is part of a system will be able to reference that actor:

    const anotherMachine = createMachine({
      // ...
      entry: sendTo(
        (ctx, ev, { system }) => {
          return system.get('emailer');
        },
        { type: 'SEND_EMAIL', subject: 'Hello', body: 'World' }
      )
    });

    Each top-level createActor(...) call creates a separate implicit system. In this example example, actor1 and actor2 are part of different systems and are unrelated:

    // Implicit system
    const actor1 = createActor(machine).start();
    
    // Another implicit system
    const actor2 = createActor(machine).start();
  • d3d6149: external property on transitions has been renamed to reenter

  • d3d6149: The interpreter.onStop(...) method has been removed. Use an observer instead via actorRef.subscribe({ complete() { ... } }) instead.

  • d3d6149: Removed MachineSnapshot['nextEvents'].

  • d3d6149: Renamed machine.withConfig(...) to machine.provide(...).

  • d3d6149: Removed third parameter (context) from Machine's transition method. If you want to transition with a particular context value you should create appropriate MachineSnapshot using machine.resolveState. So instead of this - machine.transition('green', { type: 'TIMER' }, { elapsed: 100 }), you should do this - machine.transition(machine.resolveState({ value: 'green', context: { elapsed: 100 } }), { type: 'TIMER' }).

  • d3d6149: Sending a string event to actorRef.send('some string') will now throw a proper error message.

  • d3d6149: The self actor reference is now available in all action metas. This makes it easier to reference the "self" ActorRef so that actions such as sendTo can include it in the event payload:

    // Sender
    actions: sendTo('somewhere', (ctx, ev, { self }) => ({
      type: 'EVENT',
      ref: self
    })),
    
    // ...
    
    // Responder
    actions: sendTo((ctx, ev) => ev.ref, ...)
  • d3d6149: isState/isStateConfig were replaced by isMachineSnapshot. Similarly, AnyState type was deprecated and it's replaced by AnyMachineSnapshot type.

  • d3d6149: All actor snapshots now have a consistent, predictable shape containing these common properties:

    • status: 'active' | 'done' | 'error' | 'stopped'
    • output: The output data of the actor when it has reached status: 'done'
    • error: The error thrown by the actor when it has reached status: 'error'
    • context: The context of the actor

    This makes it easier to work with actors in a consistent way, and to inspect their snapshots.

    const promiseActor = fromPromise(async () => {
      return 42;
    });
    
    // Previously number | undefined
    // Now a snapshot object with { status, output, error, context }
    const promiseActorSnapshot = promiseActor.getSnapshot();
    
    if (promiseActorSnapshot.status === 'done') {
      console.log(promiseActorSnapshot.output); // 42
    }
  • d3d6149: Restoring persisted state is now done by passing the state into the snapshot: ... property of the createActor options argument:

    -interpret(machine).start(state);
    +createActor(machine, { snapshot }).start();

    The persisted snapshot is obtained from an actor by calling actor.getPersistedSnapshot():

    const actor = createActor(machine).start();
    
    const persistedSnapshot = actor.getPersistedSnapshot();
    
    // ...
    
    const restoredActor = createActor(machine, {
      snapshot: persistedSnapshot
    }).start();
  • d3d6149: - The execute option for an interpreted service has been removed. If you don't want to execute actions, it's recommended that you don't hardcode implementation details into the base machine that will be interpreted, and extend the machine's options.actions instead. By default, the interpreter will execute all actions according to SCXML semantics (immediately upon transition).

    • Dev tools integration has been simplified, and Redux dev tools support is no longer the default. It can be included from xstate/devTools/redux:
    import { createActor } from 'xstate';
    import { createReduxDevTools } from 'xstate/devTools/redux';
    
    const service = createActor(someMachine, {
      devTools: createReduxDevTools({
        // Redux Dev Tools options
      })
    });

    By default, dev tools are attached to the global window.__xstate__ object:

    const service = createActor(someMachine, {
      devTools: true // attaches via window.__xstate__.register(service)
    });

    And creating your own custom dev tools adapter is a function that takes in the actorRef:

    const myCustomDevTools = (actorRef) => {
      console.log('Got a actorRef!');
    
      actorRef.subscribe((state) => {
        // ...
      });
    };
    
    const actorRef = createActor(someMachine, {
      devTools: myCustomDevTools
    });
    • These handlers have been removed, as they are redundant and can all be accomplished with .onTransition(...) and/or .subscribe(...):

      • actorRef.onEvent()
      • actorRef.onSend()
      • actorRef.onChange()
    • The actorRef.send(...) method no longer returns the next state. It is a void function (fire-and-forget).

    • The actorRef.sender(...) method has been removed as redundant. Use actorRef.send(...) instead.

  • d3d6149: The output data on final states is now specified as .output instead of .data:

    const machine = createMachine({
      // ...
      states: {
        // ...
        success: {
    -     data: { message: 'Success!' }
    +     output: { message: 'Success!' }
        }
      }
    })
  • d3d6149: Support for getters as a transition target (instead of referencing state nodes by ID or relative key) has been removed.

    The Machine() and createMachine() factory functions no longer support passing in context as a third argument.

    The context property in the machine configuration no longer accepts a function for determining context (which was introduced in 4.7). This might change as the API becomes finalized.

    The activities property was removed from State objects, as activities are now part of invoke declarations.

    The state nodes will not show the machine's version on them - the version property is only available on the root machine node.

  • d3d6149: The in: ... property for transitions is removed and replaced with guards. It is recommended to use stateIn() and not(stateIn()) guard creators instead:

    + import { stateIn } from 'xstate/guards';
    
    // ...
    on: {
      SOME_EVENT: {
        target: 'somewhere',
    -   in: '#someState'
    +   guard: stateIn('#someState')
      }
    }
    // ...
  • d3d6149: Removed Actor['status'] from publicly available properties.

  • d3d6149: All builtin action creators (assign, sendTo, etc) are now returning functions. They exact shape of those is considered an implementation detail of XState and users are meant to only pass around the returned values.

  • d3d6149: Autoforwarding events is no


Configuration

📅 Schedule: Branch creation - "after 9pm,before 6am" in timezone Europe/Zurich, Automerge - At any time (no schedule defined).

🚦 Automerge: Enabled.

Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate bot added the dependencies label Dec 1, 2023
Copy link
Contributor Author

renovate bot commented Dec 1, 2023

⚠ Artifact update problem

Renovate failed to update an artifact related to this branch. You probably do not want to merge this PR as-is.

♻ Renovate will retry this branch, including artifacts, only when one of the following happens:

  • any of the package files in this branch needs updating, or
  • the branch becomes conflicted, or
  • you click the rebase/retry checkbox if found above, or
  • you rename this PR's title to start with "rebase!" to trigger it manually

The artifact failure details are included below:

File name: package-lock.json
npm warn ERESOLVE overriding peer dependency
npm warn While resolving: @xstate/graph@1.3.0
npm warn Found: xstate@5.13.0
npm warn node_modules/xstate
npm warn   dev xstate@"^5.0.0" from the root project
npm warn
npm warn Could not resolve dependency:
npm warn peer xstate@"^4.9.0" from @xstate/graph@1.3.0
npm warn node_modules/@xstate/graph
npm warn   @xstate/graph@"^1.1.0" from @xstate/test@0.4.1
npm warn   node_modules/@xstate/test
npm warn
npm warn Conflicting peer dependency: xstate@4.38.3
npm warn node_modules/xstate
npm warn   peer xstate@"^4.9.0" from @xstate/graph@1.3.0
npm warn   node_modules/@xstate/graph
npm warn     @xstate/graph@"^1.1.0" from @xstate/test@0.4.1
npm warn     node_modules/@xstate/test
npm error code ERESOLVE
npm error ERESOLVE could not resolve
npm error
npm error While resolving: @xstate/test@0.4.1
npm error Found: xstate@5.13.0
npm error node_modules/xstate
npm error   dev xstate@"^5.0.0" from the root project
npm error
npm error Could not resolve dependency:
npm error peer xstate@"^4.9.0" from @xstate/test@0.4.1
npm error node_modules/@xstate/test
npm error   dev @xstate/test@"^0.4.1" from the root project
npm error
npm error Conflicting peer dependency: xstate@4.38.3
npm error node_modules/xstate
npm error   peer xstate@"^4.9.0" from @xstate/test@0.4.1
npm error   node_modules/@xstate/test
npm error     dev @xstate/test@"^0.4.1" from the root project
npm error
npm error Fix the upstream dependency conflict, or retry
npm error this command with --force or --legacy-peer-deps
npm error to accept an incorrect (and potentially broken) dependency resolution.
npm error
npm error
npm error For a full report see:
npm error /tmp/renovate/cache/others/npm/_logs/2024-05-08T21_50_58_223Z-eresolve-report.txt

npm error A complete log of this run can be found in: /tmp/renovate/cache/others/npm/_logs/2024-05-08T21_50_58_223Z-debug-0.log

@renovate renovate bot force-pushed the renovate/major-xstate-monorepo branch 5 times, most recently from 02caf15 to 6b5cf9c Compare December 8, 2023 01:45
@renovate renovate bot force-pushed the renovate/major-xstate-monorepo branch 4 times, most recently from 7ccdbdc to 520d6c6 Compare December 18, 2023 03:48
@renovate renovate bot force-pushed the renovate/major-xstate-monorepo branch from 520d6c6 to bd98580 Compare December 19, 2023 00:58
@renovate renovate bot force-pushed the renovate/major-xstate-monorepo branch 2 times, most recently from 64bc682 to 986bc3e Compare December 30, 2023 09:03
@renovate renovate bot force-pushed the renovate/major-xstate-monorepo branch 3 times, most recently from cfcf15c to dac8610 Compare January 8, 2024 01:07
@renovate renovate bot force-pushed the renovate/major-xstate-monorepo branch 5 times, most recently from ce6aec0 to 523b356 Compare January 16, 2024 00:48
@renovate renovate bot force-pushed the renovate/major-xstate-monorepo branch 4 times, most recently from 78f7676 to d0120a1 Compare January 23, 2024 00:15
@renovate renovate bot force-pushed the renovate/major-xstate-monorepo branch 4 times, most recently from d1b3f19 to 398b446 Compare January 29, 2024 02:56
@renovate renovate bot force-pushed the renovate/major-xstate-monorepo branch 10 times, most recently from a34a0b2 to bf61857 Compare November 1, 2024 04:43
@renovate renovate bot force-pushed the renovate/major-xstate-monorepo branch 3 times, most recently from c4f2a29 to 26cf503 Compare November 5, 2024 05:20
@renovate renovate bot force-pushed the renovate/major-xstate-monorepo branch 2 times, most recently from daf79a5 to 59d2409 Compare November 19, 2024 00:37
@renovate renovate bot force-pushed the renovate/major-xstate-monorepo branch 5 times, most recently from 71dd85c to d9120b3 Compare November 26, 2024 05:03
@renovate renovate bot force-pushed the renovate/major-xstate-monorepo branch 3 times, most recently from b4c4a90 to 5941b7b Compare December 3, 2024 01:10
@renovate renovate bot force-pushed the renovate/major-xstate-monorepo branch 3 times, most recently from d5f6011 to 5e1ba30 Compare December 17, 2024 09:39
@renovate renovate bot force-pushed the renovate/major-xstate-monorepo branch 2 times, most recently from bf6f0b2 to dd6fd67 Compare January 3, 2025 01:49
@renovate renovate bot force-pushed the renovate/major-xstate-monorepo branch from dd6fd67 to c7a815b Compare January 3, 2025 21:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

0 participants