Black Lives Matter. Support the Equal Justice Initiative.

Robot

Fast 1kB functional library for creating Finite State Machines

Robot exports a variety of functions that compose to build state machines. Many of the functions, such as state and transition are variadic, meaning they can take any number of arguments and the order doesn't matter (much). This is a common pattern you'll notice in usage; the result is easier composition.

# Main exports

Table of Contents

# Debugging

Robot does not verify the correctness of the state machines you create by default. This is for bundle size purposes; in production you wouldn't want your machines to throw, and this code takes up valuable space.

Instead debugging messages are provided by the debug module, robot3/debug. Simply import the module anywhere before you call createMachine.

# Examples of excluding a debug module from a production build

# 1. dev.js

A common pattern is to have a dev.js that imports the debug module and your main. This way the dev.js is not included in your production build.

dev.js

import 'robot3/debug';
import './main.js';

# 2. Web Modules

If you're using web modules then include a script tag before your main:

<script type="module" src="https://unpkg.com/robot3/debug"></script>
<script type="module" src="./main.js"></script>

# 3. Logging

The logging module robot3/logging provides a helper function which logs state changes when entering a new state. It can be used as the debug module by importing it or including the script before the main.

<script type="module" src="https://unpkg.com/robot3/logging"></script>
<script type="module" src="./main.js"></script>

This method can also be overwritten with a more advanced solution.

import {d} from 'robot3';

d._onEnter = function(machine, to, state, prevState, event) {
// compare states and log the differences
}

# 4. Stripping with Module Bundler

# 4.1. Rollup

You can use some Rollup-plugins for excluding debug module from production bundle. The easiest option is to use rollup-plugin-strip-code.

rollup.config.js

import stripCode from 'rollup-plugin-strip-code';

// Assuming you'd run it with something like 'rollup -c --environment BUILD:production'
const isProduction = process.env.BUILD === 'production';

export default [
input: ...,
output: ...,
plugins: [
...,
isProduction && stripCode({
start_comment: 'START.DEBUG_ONLY',
end_comment: 'END.DEBUG_ONLY',
})
]
];

stateMachine.js

/*START.DEBUG_ONLY*/
import 'robot3/debug';
/*END.DEBUG_ONLY*/

import {...} from 'robot3';

Also you can use official @rollup/plugin-alias to mock import 'robot3/debug', but this approach needs empty mock-file for replacement, what is not so clean.

rollup.config.js

import alias from '@rollup/plugin-alias';

module.exports = {
input: ...,
output: ...,
plugins: [
...,
alias({
entries: [
{ find: 'robot3/debug', replacement: resolve(__dirname, './src/mocks/empty.js') },
]
})
]
};

mocks/empty.js is empty file.

# 4.2. Webpack

Similarly to Rollup you can use webpack-strip-block to strip debug module from production bundle.