Head to Pika
Here is an example with XState:
import { Machine, interpret } from 'https://cdn.skypack.dev/xstate'; type State = { value: string; }; // Stateless machine definition // machine.transition(...) is a pure function used by the interpreter. const toggleMachine = Machine({ id: 'toggle', initial: 'inactive', states: { inactive: { on: { TOGGLE: 'active' } }, active: { on: { TOGGLE: 'inactive' } }, }, }); // Machine instance with internal state const toggleService = interpret(toggleMachine) .onTransition((state: State) => console.log(state.value)) .start(); // => 'inactive' toggleService.send('TOGGLE'); // => 'active' toggleService.send('TOGGLE'); // => 'inactive'