When some one complains about how async nodejs and callback are hells. I smile. FSM are notoriously hard to write, manage and debug. Because they are async by design.
In one of my prev workplaces we worked on state machines. Few good takeaways was to design state transition functions in a large array laid out with all possible hooks in order. And document the hell out ofit. Another approach was to generate boiler plate out of fsm given its grammar.