This package provides a set of tools for utilizing complete deterministic finite automata (Finite state machine) in RxJS with a focus on functional programming. Allowing developers to efficiently manage complex state machines in context of reactive programming.
✅ Tree Shakeable (ES modules)
✅ Fully Typed
✅ Unit Tests
✅ Documentation
npm i @jkba/rxjs-fsm
Let's consider the following use-case as an example. It is discussed in detail in a dedicated blog post.
In the very first step, let's represent this automata:
export type Input = 'toggle' | 'hide';
export type State = 'hidden' | 'shown';
export const transitions: StateTransitions<State, Input> = {
hidden: {
toggle: 'shown',
hide: 'hidden',
},
shown: {
toggle: 'hidden',
hide: 'hidden',
},
};
Suppose we represent inputs as Observables and the initial state as a constant:
const toggle$ = new Subject<void>();
const hide$ = new Subject<void>();
const initialState: State = 'hidden';
It is necessary to create a single input Observable and mark individual values in order to retain proper types. For this purpose, let's use fsmHelpersFactory
function.
const { markInput } = fsmHelpersFactory<State, Input>(transitions);
const input$ = merge(
toggle$.pipe(markInput('toggle')),
hide$.pipe(markInput('hide')),
);
Finally, we can create the machine object:
const machine = rxjsFsmFactory(transitions, input$, initialState);
Listen to the current state:
machine.selectState().subscribe(console.log);
// Emits only on `hidden` state
machine.selectState('hidden').subscribe(console.log);
Another approach is to avoid the machine object and use this library in a pipe with an existing Observable:
const {
fsm,
markInput,
} = fsmHelpersFactory<State, Input>(transitions);
const state$ = input$.pipe(fsm(initialState));
state$.subscribe(console.log);
Use npm link
and then npm link @jkba/rxjs-fsm
in your project.
Use npm version
, don't forget to push the tag and the CI will take care of the rest.
This project is licensed under MIT License. For the full text of the license, see the LICENSE file.