Implementation with the yEd graph editor

In the previous sections, we specified, designed, and implemented a password meter. In this section, we are going to reach the same implementation but this time, instead of writing the machine’s transitions manually, we are going to draw them in a graph editor and convert the drawing to a standard JavaScript function.

This section aims at showcasing the yEd graph editor which is the preferred tool to create and maintain Kingly state machines. yEd is simple to use, offers a series of automatic layouts, allows us to zoom in and out of compound states, and can save the machine graph in an XML textual format that can be versioned on GitHub.

Install yEd

For more detailed information about the graph editor and its usage, please refer to the Tooling section.

Creating a graph

To make it easy to start drawing a graph representing a Kingly machine behavior, we recommend to open a template file that will contain the four elements that you will need in any graph:

drawing template with basic elements

The template file can be downloaded from GitHub.

Your editor should then look like this:

editor with template file open

yEd has many interesting options that we will explain later. For now, let’s reproduce the graph for our password meter:

We are now ready to edit:

We have our initial pseudo-state! Let’s draw now the nodes:

You should now have:

editor with template file open

Let’s now do the edges:

You can move nodes here and there to make space for you to drag the arrow.

Your graph at this moment is probably not well laid out. We are going to ask yEd to lay it out for us:

You should now see this:

editor with template file open

Now let’s do the labels. The labels must follow the event [guard] / action format. Here, we are going again to copy from the previously-made modeling:

\n represents a new line and can be introduced by clicking Shift-Enter

The result is not very readable:

editor with template file open

Let’s adjust the layout by modifying a setting:

The layout reruns:

editor with template file open

The final result is as follows:

editor with template file open

Et voila! With this, we have recreated the modeling for the password meter behavior that we have shown in previous sections. We let yEd do the layout for us. Drawing a graph is as simple as copy-pasting-dragging nodes.

yEd has far more options that are very useful and other insightful layouts, but we will not introduce them at this stage of the tutorial.

Let’s now use our graph in order to create our machine in JavaScript.

Converting to JavaScript

We now have a graph, but what we need is a machine that we can use from JavaScript (we often call that an executable version of the machine). To achieve that, we will now showcase the yed2kingly utility script. That script will take a .graphml file and turn into a JavaScript file that can be used to derive an executable state machine.

To do so:

This should create two files in the same directory:

We are going to import the file that corresponds to our running environment to create the machine:

import { NO_STATE_UPDATE, createStateMachine } from "kingly";
import { tracer } from "courtesan";
import {
  createStateMachineFromGraph
} from "./password-meter.graphml.fsm";
    
// -----Guards------
const guards = {
  "!letter and numbers?": isPasswordWeak,
  "letter and numbers?": isPasswordStrong
};

//-----Actions------
const actionFactories = {
  "display initial screen": displayInitScreen,
  "display weak password screen": displayInputInRed,
  "display strong password screen": displayInputInGreen,
  "display password submitted screen": displaySubmittedPassword
};

const pwdFsmDef = {
  initialExtendedState,
  updateState,
  guards,
  actionFactories
};

window.pwdFsm = createStateMachineFromGraph(pwdFsmDef, {
  debug: { console },
  devTool: { tracer }
});

In this code, you can observe that:

You can have a look at the resulting reimplementation in the following playground:

To check that nothing has changed vs. the previous implementation, we rerun the same command sequences in the playground as before:

pwdFsm()
pwdFsm({})
pwdFsm({rqwe: 314})
pwdFsm({"start": void 0})
pwdFsm({"clicked submit":void 0})
pwdFsm({"clicked submit":void 0})
pwdFsm({"typed":'a'})
pwdFsm({"clicked submit":void 0})
pwdFsm({"typed":'a2'})
pwdFsm({"clicked submit":void 0})

We can also check in the dev tool that we produce the same results, and that the machine ends in the done control state:

editor with template file open

Given that we reproduced the exact same Kingly machine, albeit from a yEd file, the rest of the user interface implementation for the password meter is exactly the same: you can reuse the previous view implementation with no changes.

This is it! We successfully modeled a password meter behavior, we implemented that behavior with a Kingly state machine by two methods: first, directly implementing the machine manually; second, using a professional graph editor with automatic layouting.

It is important that you review carefully what we have done here, as all the examples in this documentation are indeed produced with the yEd editor; and it is a great productivity saving tool. One best practice when it comes to state machine implementation is to model the machine first in a graph editor, not write code by hand. The automated tooling that Kingly provides ensures that there are no mistakes made when translating the graph into code. You can focus afterward on implementing the guards and actions with JavaScript. If you configure a watcher to automatically convert .graphml files into JavaScript, this gives for a fairly smooth implementation process. The hardest part will always be to design the machine.