import { AtomicStateNodeConfig , StatesConfig , Event , EventObject , StateSchema , StateNodeConfig } from './types' ; import { toEventObject } from './utils' ; export function toggle < TEventType extends string = string > ( onState , offState , eventType ) { return { [ onState ] : { on : { [ eventType ] : offState } } , [ offState ] : { on : { [ eventType ] : onState } } } as Record < string , AtomicStateNodeConfig < any , { type : TEventType ; } > > ; } interface SequencePatternOptions < TEvent extends EventObject > { nextEvent : Event < TEvent > | undefined ; prevEvent : Event < TEvent > | undefined ; } const defaultSequencePatternOptions = { nextEvent : 'NEXT' , prevEvent : 'PREV' } ; export function sequence < TStateSchema extends StateSchema , TEvent extends EventObject > ( items , options ? ) { const resolvedOptions = { ... defaultSequencePatternOptions , ... options } ; const states = { } as Record < keyof TStateSchema [ 'states' ] , any > ; const nextEventObject = resolvedOptions . nextEvent === undefined ? undefined : toEventObject ( resolvedOptions . nextEvent ) ; const prevEventObject = resolvedOptions . prevEvent === undefined ? undefined : toEventObject ( resolvedOptions . prevEvent ) ; items . forEach ( ( item , i ) => { const state = { on : { } } ; if ( i + 1 === items . length ) { state . type = 'final' ; } if ( nextEventObject && i + 1 < items . length ) { state . on ! [ nextEventObject . type ] = items [ i + 1 ] ; } if ( prevEventObject && i > 0 ) { state . on ! [ prevEventObject . type ] = items [ i - 1 ] ; } states [ item ] = state ; } ) ; return { initial : items [ 0 ] as keyof TStateSchema [ 'states' ] , states : states as StatesConfig < any , TStateSchema , TEvent > } ; }