diff --git a/README.md b/README.md index 0a26e45..92fde3d 100644 --- a/README.md +++ b/README.md @@ -86,13 +86,11 @@ Another approach is to avoid the _machine_ object and use this library in a pipe ```ts const { - nextState, + fsm, markInput, } = fsmHelpersFactory(transitions); -const state$ = input$.pipe( - scan(nextState, initialState), -); +const state$ = input$.pipe(fsm(initialState)); state$.subscribe(console.log); ``` diff --git a/examples/example-1.ts b/examples/example-1.ts index 2b93538..9352030 100644 --- a/examples/example-1.ts +++ b/examples/example-1.ts @@ -2,21 +2,22 @@ import { Subject, merge, scan } from 'rxjs'; import { fsmHelpersFactory } from '../lib'; -import { Input, State, transitions } from './state.config'; +import { Input, State, initialState, transitions } from './state.config'; /** * Example 1 * Demonstrates creating a FSM only by using RxJs operators. */ -const { nextState, markInput } = fsmHelpersFactory(transitions); +const { + nextState, + markInput, +} = fsmHelpersFactory(transitions); // Define inputs const toggle$ = new Subject(); const hide$ = new Subject(); -const initialState: State = 'hidden'; - // Use helper functions const input$ = merge( toggle$.pipe(markInput('toggle')), diff --git a/examples/example-2.ts b/examples/example-2.ts index 132f1a6..7227df8 100644 --- a/examples/example-2.ts +++ b/examples/example-2.ts @@ -1,7 +1,7 @@ -import { Observable, Subject, merge } from 'rxjs'; +import { Subject, merge } from 'rxjs'; import { fsmHelpersFactory, rxjsFsmFactory } from '../lib'; -import { Input, State, transitions } from './state.config'; +import { Input, State, initialState, transitions } from './state.config'; /** * Example 2 @@ -12,8 +12,6 @@ import { Input, State, transitions } from './state.config'; const toggle$ = new Subject(); const hide$ = new Subject(); -const initialState: State = 'hidden'; - const { markInput } = fsmHelpersFactory(transitions); // Use helper functions diff --git a/examples/example-3.ts b/examples/example-3.ts new file mode 100644 index 0000000..026f242 --- /dev/null +++ b/examples/example-3.ts @@ -0,0 +1,41 @@ +import { Subject, merge } from 'rxjs'; + +import { fsmHelpersFactory } from '../lib'; + +import { Input, State, initialState, transitions } from './state.config'; + +/** + * Example 3 + * Demonstrates creating a FSM using by the `fsm` operator. + */ + +const { + markInput, + fsm, +} = fsmHelpersFactory(transitions); + +// Define inputs +const toggle$ = new Subject(); +const hide$ = new Subject(); + +// Use helper functions +const input$ = merge( + toggle$.pipe(markInput('toggle')), + hide$.pipe(markInput('hide')), +); + +const state$ = input$.pipe(fsm(initialState)); + +// Listen +state$.subscribe((newState) => console.log('New state:', newState)); + +console.log('Initial state:', initialState); +console.log('Input: toggle'); +toggle$.next(); +console.log('Input: toggle'); +toggle$.next(); +console.log('Input: toggle'); +toggle$.next(); + +console.log('Input: hide'); +hide$.next(); diff --git a/examples/state.config.ts b/examples/state.config.ts index 193517e..8a07228 100644 --- a/examples/state.config.ts +++ b/examples/state.config.ts @@ -3,6 +3,8 @@ import { StateTransitions } from '../lib'; export type Input = 'toggle' | 'hide'; export type State = 'hidden' | 'shown'; +export const initialState: State = 'hidden'; + export const transitions: StateTransitions = { hidden: { toggle: 'shown', diff --git a/lib/rxjs-fsm/helpers.ts b/lib/rxjs-fsm/helpers.ts index b16d334..e022279 100644 --- a/lib/rxjs-fsm/helpers.ts +++ b/lib/rxjs-fsm/helpers.ts @@ -1,4 +1,4 @@ -import { markInput, nextState } from '../utils'; +import { fsm, markInput, nextState } from '../utils'; import { BaseInput, BaseState, StateTransitions } from '../models'; /** @@ -6,4 +6,8 @@ import { BaseInput, BaseState, StateTransitions } from '../models'; */ export const fsmHelpersFactory = ( transitions: StateTransitions, -) => ({ markInput: markInput(), nextState: nextState(transitions) }); +) => ({ + markInput: markInput(), + nextState: nextState(transitions), + fsm: fsm(transitions), +}); diff --git a/lib/utils/fsm.ts b/lib/utils/fsm.ts new file mode 100644 index 0000000..506b178 --- /dev/null +++ b/lib/utils/fsm.ts @@ -0,0 +1,12 @@ +import { pipe, scan, startWith } from 'rxjs'; +import { BaseInput, BaseState, StateTransitions } from '../models'; +import { nextState } from './next'; + +export const fsm = ( + transitions: StateTransitions, +) => ( + initialState: S, +) => pipe( + scan(nextState(transitions), initialState), + startWith(initialState), +); diff --git a/lib/utils/index.ts b/lib/utils/index.ts index 8ce6202..21b5572 100644 --- a/lib/utils/index.ts +++ b/lib/utils/index.ts @@ -1,2 +1,3 @@ export * from './mark-input'; export * from './next'; +export * from './fsm';