> I'm mostly concerned about visualization

Almost all of the finite state machines use the same underlying graphing tool, "GraphViz," to do their rendering. It sounds like you might want that.

There is an emscripten transcompile for the web called viz.js.

.

> if you have actions/guards that don't appear on the visualization

Actions do appear on the visualization. I'm still not sure what you mean by guards.

.

> imilarly, by recursion I meant putting states inside states (from a behavior perspective you would call them compound states); Both PlantUML and XState supports that. Parallel states [1] are compound states with multiple distinct regions

It looks like one of XState or PlantUML tried to rename Heirarchical Orthogonal State Regions, and the other copied the first one.

.

What you're calling "recursion" is called a Heirarchical State Machine. It appears that XState uses the regular name for these:

https://xstate.js.org/docs/guides/hierarchical.html

External reference:

https://barrgroup.com/embedded-systems/how-to/introduction-h...

.

What you're calling Parallel States is properly called an Orthogonal Region. It's problematic to call these parallel for exactly the following statement, where you suggest that this "doesn't necessarily imply threading;" this wrong name that XState and PlantUML has used has confused you.

*All state machines are by definition single threaded single context. This may not and will never be implemented with threading, nor actors. This has nothing to do with process parallelism. This cannot be implemented in a parallel way by any machine, ever.*

External reference:

https://www.boost.org/doc/libs/1_47_0/libs/msm/doc/HTML/ch02....

https://en.wikipedia.org/wiki/UML_state_machine#Orthogonal_r...

It looks like neither PlantUML nor XState allow for orthogonal regions in a way that copes with superstates, which is a very serious limitation. Their orthogonal regions seem to just subdivide whatever nested state you're currently in. This defies the core concept of an orthogonal region, which is to allow unrelated parallel pseudostates. If the context dominates which pseudostates are actually available, then this is little better than a tagged record.

Respectfully, XState and PlantUML seem to have produced the wrong tool, here. Please look to Boost, instead, which gets this very right.

I'll give two examples: one a silly one, to make what the difference actually is make sense, then a better one, to explain why it should matter.

The silly one is an extension of the keyboard example used in Wikipedia's UML state machine orthogonal region discussion. In brief, they propose a state for a keyboard which treats the main keyboard effectively separately of the numeric keypad. There are relevant separate state bits for each, eg caps lock on left and num lock on right.

To extend this, consider the APL keyboard, which is a programmer's keyboard which can switch between two layouts on the left. One is whatever your local natural language is; the other is a special layout for the programming language APL, which uses a bunch of novelty symbols. You need an actual layout switch because the control keys aren't just in different positions, but are actually different control keys (it uses meta and opt.)

In a UML state machine, the natural thing to do is:

1) Model each language's keyboard left as its own machine;
2) same thing for the APL keyboard;
3) also the keypad;
4) create an orthogonal region with the keypad on the right
5) put an HFSM in the left to swap between APL and whatever natural language(s) you're using

The problem is, if the orthogonal region is just a subdivision of your bottom level organization, step 5 isn't possible.

Worse still, this even still implies a pretty clean division of what's "on the left" and what's "on the right." They're modules that snap together and don't talk to each other.

What if these are power plants? These two over here go down, this one over here has to start up. They have to be able to synchronize (it's a wave, waves cancel.)

When one of these plants goes up and down, it might have multiple reactors. Some of those reactors might have multiple engagements. They might have differential backup. If the coal plant nearby is running, when solar comes online it doesn't need its LNG backup because there's already in-fill.

If these so-called "orthogonal states" are just being able to track several state elements and a contemporary context bit, as this appears to be, then you can't have them switching independently in any meaningful way.

I wish tools like XState and PlantUML wouldn't change the name of primary tools. If they used the correct name for this, you'd realize how wildly limited the thing you're looking at is as compared to what it's supposed to be.

.

Now that I understand where you're getting your terms, I assume that when you say "guards," you mean what XState calls "guarded transitions." That's a simple case of returning 0 from any hook.

Yes, JSSM does this. No, it doesn't render that on the visualization. I'm not sure what that ought to look like, to be frank.

.

With regards to HSMs, I do have a mechanism of this form, but, something significantly more powerful. It is as yet incomplete and as such unreleased. If you need that in your visualization, you're better off with XState (or GraphViz directly, more likely.)