UNPKG

mini-state-machine

Version:
48 lines (47 loc) 1.74 kB
import { cloneArray } from "./clone.js"; import { createEventsInterface } from "./events.js"; import { getState } from "./state.js"; import { generatePaths, getPath, transition, verifyTransitions } from "./transition.js"; /** * Create a state machine instance * @param config Configuration for the new state machine * @returns A state machine instance */ export function createStateMachine({ initial, transitions }) { if (!initial || initial.length <= 0) { throw new Error(`Invalid initial state: ${initial}`); } verifyTransitions(transitions); const context = { events: createEventsInterface(), paths: generatePaths(transitions), pending: false, state: initial, next: null, history: [] }; const sm = { get pending() { return context.pending; }, get state() { return getState(context); }, can: transition => !!getPath(context, transition), cannot: transition => !sm.can(transition), getHistory: () => cloneArray(context.history), is: state => sm.state === state, off: (event, stateOrTransition, cb) => context.events.remove(event, stateOrTransition, cb), on: (event, stateOrTransition, cb) => context.events.add(event, stateOrTransition, cb), once: (event, stateOrTransition, cb) => context.events.add(event, stateOrTransition, cb, { once: true }), onIdle: cb => { const handler = context.events.addIdle(cb); if (!context.pending) { context.events.emitIdle(cb); } return handler; }, transition: action => transition(context, action) }; return sm; }