Releases: cassiozen/useStateMachine
Releases · cassiozen/useStateMachine
1.0.0
1.0.0-beta.4
Api changes for sendT (#72)
1.0.0-beta.3
feat(dx): instantiate all boundary types (#76 )
The one with txstate
This release contains a implementation, porting and expanding on txstate library. It provides:
-
better error messages:
-
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
0.4.1
- 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
This versions solves two issues:
- Returns
send
fromupdate
:
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');
- 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")
orsend({ 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 });