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';
 
const scxmlMachine = `
<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`.
const machine = 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!

Join my mailing list

Get new articles directly in your inbox.

I value your privacy and will never share your email address.