Interpret SCXML state machines with XState
Published on
SCXML is an universal format to describe state machines. XState can be used to interpret them in JavaScript.
SCXML is a XML-based state machine language based on Harel statecharts. SCXML stands for State Chart XML. It is a specification strongly documented and that can be used to express state machines in an universal format, consumed by interpreters of any language, provided that they follow the specification. You can find some great samples of SCXML state machines on SCXML-tutorial.
We might want to interpret such state machines with the really great XState library. XState follows SCXML specification but is focused on writing state machines in plain JavaScript. A lesser-known feature of XState is its hability to take a SCXML state machine as a string, and compile it to a XState machine. After this compilation, the state machine can be used in JavaScript, as if it had been written from the beginning with XState.
permalinkSCXML machine to XState machine
XState exports a function toMachine
that transforms a SCXML state machine into a XState machine.
It can be used that way:
ts
import {toMachine } from 'xstate/lib/scxml';constscxmlMachine = `<scxml name="Scxml" version="1.0" xmlns="http://www.w3.org/2005/07/scxml"><state id="Level 1"/></scxml>`;// The second parameter is necessary.// It allows to define the delimiter of targets.// By default it's a dot `.` and there is no need to change it.//// We get a XState machine that can be used// for instance with `interpret`, `@xstate/react` or `@xstate/vue`.constmachine =toMachine (scxmlMachine , {});
Danger
toMachine
function uses xml-js
library but does not bundle it. You have to install it yourself.
It’s the perfect solution if you want to integrate a SCXML machine within an overall system. But if you just want to interpret the machine to see how it works, there is a simpler way…
permalinkOnline SCXML interpreter
I created an online interpreter for SCXML machines, powered by XState. The heart of the application is toMachine
function we introduced above that compiles the state machine written in the editor.
State machines are then interpreted by using @xstate/vue
library and I use @xstate/inspect
to have a visualization of the state machine in real time. This is a great solution if you want to try some SCXML state machines out, for example if you plan to learn SCXML with SCXML-tutorial.
permalinkSide Note: Final states
Some examples in SCXML-tutorial are state machines that immediately go to a finite state. It means that the XState service that interprets them will immediately be stopped. Therefore, the inspector will not be able to connect to them as they won’t exist anymore.
It happens with the following machine:
xml
<scxml name="Scxml" version="1.0" xmlns="http://www.w3.org/2005/07/scxml"><state id="Work"><transition event="done.state.Work" target="WorkFinished"/><state id="CompletingTask"><transition target="Completed"/></state><final id="Completed"/></state><final id="WorkFinished"/></scxml>
The default state of Work
state is CompletingTask
and it contains an eventless transition that causes transitioning to Completed
state immediately. Completed
state is a final state, which will cause a transition to WorkFinished
, the final state of the state machine. All these steps will occur sequentially and as a result in a very short time the state machine will be stopped.
To inspect this state machine we would have to replace the eventless transition with a plain transition triggered by an event, such as:
xml
<scxml name="Scxml" version="1.0" xmlns="http://www.w3.org/2005/07/scxml"><state id="Work"><transition event="done.state.Work" target="WorkFinished"/><state id="CompletingTask"><transition event="COMPLETE" target="Completed"/></state><final id="Completed"/></state><final id="WorkFinished"/></scxml>
It changes the behaviour of the state machine, but now we can inspect it.
permalinkSide Note: Support of SCXML specification
Currently, toMachine
does not support all SCXML features, such as cancel
. If you want to contribute to XState and understand SCXML deeper, it might be a good start!
permalinkConclusion
SCXML is an universal format that can be used to express state machine based on Harel statecharts. It is also a specification, followed by XState, which allows to interpret such machines with it. XState exports a toMachine
function from xstate/lib/scxml
to compile a SCXML state machine into a XState machine.
Check out the online interpreter I made, paste your SCXML machine and start interacting with it!