Skip to content

Releases: cassiozen/useStateMachine

1.0.0

14 Jan 23:37
Compare
Choose a tag to compare

No changes, just re-released as 1.0.0 and out of Beta.

1.0.0-beta.4

10 Oct 16:01
Compare
Choose a tag to compare

Api changes for sendT (#72)

1.0.0-beta.3

06 Oct 13:46
Compare
Choose a tag to compare

feat(dx): instantiate all boundary types (#76 )

The one with txstate

28 Jul 19:51
a10dfcc
Compare
Choose a tag to compare

This release contains a implementation, porting and expanding on txstate library. It provides:

  • better error messages:

    Scenario 1


    Before -
    image
    image

    After -
    image
    image

    Scenario 2


    Before -
    image
    image

    After -
    image
    image

  • Typed guards hence inferring context typestates

    Example
    // example picked from xstate docs
    let [flightMachine] = useStateMachine<FlightMachineContext>({ trip: 'oneWay' })({
      initial: 'editing',
      states: {
        editing: {
          on: {
            SUBMIT: {
              target: 'submitted',
              guard: (context): context is FlightMachineSubmittedContext => {
                if (context.trip === 'oneWay') {
                  return !!context.startDate;
                } else {
                  return (
                    !!context.startDate &&
                    !!context.returnDate &&
                    context.returnDate > context.startDate
                  );
                }
              }
            }
          }
        },
        submitted: {}
      }
    })
    
    type FlightMachineEditingContext =
      { trip: 'oneWay' | 'roundTrip'
      , startDate?: Date
      , returnDate?: Date
      }
    type FlightMachineSubmittedContext =
      | { trip: 'oneWay'
        , startDate: Date
        }
      | { trip: 'roundTrip'
        , startDate: Date
        , returnDate: Date
        }
    
    type FlightMachineContext =
      | FlightMachineEditingContext
      | FlightMachineSubmittedContext
    
    expectType<FlightMachineContext>(flightMachine.context);
    if (flightMachine.value === 'submitted') {
      expectType<FlightMachineSubmittedContext>(flightMachine.context);
      
      if (flightMachine.context.trip === 'oneWay') {
        expectError(flightMachine.context.returnDate)
      }
    }
  • New API, without the curried function workaround and with better support for typed events.

Credits: This was possible by the amazing effort of @devanshj

1.0.0-beta.1

14 Jun 17:08
Compare
Choose a tag to compare
  • Grouped verbose log (#43)
  • Top-level transitions (#49)
  • New param signature for effects & guards (#48)
  • Added inline docs (#47)

0.4.1

06 Jun 15:57
Compare
Choose a tag to compare
  • Fixed a bug where events sent in object format were not properly logged in verbose mode (@arthurdenner)
  • Allow self-transitions (transitioning to the same state, will re-run effects)

0.4.0

03 Jun 02:56
Compare
Choose a tag to compare

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 });

0.3.2

17 May 20:59
8989095
Compare
Choose a tag to compare

Provides a stable send method.

0.3.1

17 May 14:44
Compare
Choose a tag to compare

Fixes ESM configuration

0.3.0

15 May 15:45
Compare
Choose a tag to compare
  • Added verbose mode (#13 )
  • Huge typing refactor (#11)