HardPro challengeJavaScriptTypeScript

State Machine with Guards

ReactState MachinesPatterns

Extend a finite state machine with guards: a transition only fires if
its guard predicate returns true.

Config: { initial, transitions: { state: { event: { target, guard? } } } }.
Guards are expression strings like '(ctx) => ctx.canGo === true'. Compile
each via new Function('return (' + guard + ');')(). Initial context provided.

solve(config, events, context) returns the state after each event.

Sample tests

Test #1No guard, transition fires
Input: [{"initial":"a","transitions":{"a":{"go":{"target":"b"}}}},["go"],{}]
Output: ["a","b"]
Test #2Guard passes
Input: [{"initial":"a","transitions":{"a":{"go":{"guard":"(c) => c.canGo === true","target":"b"}}}},["go"],{"canGo":true}]
Output: ["a","b"]
Test #3Guard fails, stay
Input: [{"initial":"a","transitions":{"a":{"go":{"guard":"(c) => c.canGo === true","target":"b"}}}},["go"],{"canGo":false}]
Output: ["a","a"]
Test #4Unknown event, stay
Input: [{"initial":"idle","transitions":{"idle":{"start":{"target":"running"}}}},["unknown"],{}]
Output: ["idle","idle"]
Test #5Two transitions
Input: [{"initial":"a","transitions":{"a":{"go":{"target":"b"}},"b":{"go":{"target":"c"}}}},["go","go"],{}]
Output: ["a","b","c"]