Skip to content

0.4.0

Compare
Choose a tag to compare
@cassiozen cassiozen released this 03 Jun 02:56
· 50 commits to main since this release

This versions solves two issues:

  1. Returns send from update:
    A Common pattern is to update the context then immediately send an event to transition as illustrated by the async example). With this PR, the following two lines:
update(context => ({ data: coffees, ...context }));
send('SUCCESS');

Can now be written as:

update(context => ({ data: coffees, ...context })).send('SUCCESS');
  1. Allows events to contain arbitrary payload:
    Until now there was no simple way to bring outside data into the state machine context (like a form or a subscription). With this PR, events can be sent in an object notation in addition to the string notation: (e.g. send("TOGGLE") or send({ type: "TOGGLE" }). The latter accepts arbitrary keys and values that can be accessed inside effects and guards.
const [machine, send] = useStateMachine<{ time: number }>({ time: 0 })({
  initial: 'idle',
  verbose: true,
  states: {
    idle: {
      on: {
        START: 'running',
      },
      effect(_, update, event) {
        update(() => ({ time: event?.resetTime }));
      },
    },
    running: {
      on: {
        STOP: 'idle',
      },
      effect(_, update) {
        // ...
      },
    }
  },
});

send({ type: 'STOP', resetTime: 10 });

By default all additional values are typed as any, but the user can provide custom types as a generic:

const [machine, send] = useStateMachine<{ time: number }, { type: 'START' } | { type: 'STOP'; resetTime: number }>({
  time: 0,
})({
  initial: 'idle',
  verbose: true,
  states: {
    idle: {
      on: {
        START: 'running',
      },
      effect(_, update, event) {
        if (event?.type === 'STOP') update(() => ({ time: event?.resetTime }));
      },
    },
    running: {
      on: {
        STOP: 'idle',
      },
      effect(_, update) {
        // ...
      },
    },
  },
});

send({ type: 'STOP', resetTime: 10 });