Javascript State Machine
Tags: fsm, statemachine
Published: 2023-05-21 14:07:29

State Machines are awesome tools, every developpers should know them.

[JavascriptStateMachine](https://github.com/jakesgordon/javascript-state-machine) have a nice implementation and is simple to use.

Here is an exemple [Melting](https://flems.io/#0=N4IgtglgJlA2CmIBcAWAHAOgGwFYA0IAZhAgM7IDaoAdgIZiJIgYAWALmLCAQMYD21NvEHIQAHWoAeFgEYAfBIAEigFK0AbrVI8AThAAObRQGU2tIYoCytHiwjV4EyQHpZC6k8KkwAWlJmhdxcvX39zeHcnKAh1RWgAXjEQWn19JPdlSVJ4HjYIAQzlIskAIwBXNjYBRSUi5ShzWh82HVpqUgg8gUTweFg2JJrqOuUBHlgIHgBrHpT9DBCMBn6ACgBKdNq6yz6B4eLncsqCrcVSiqrh0-rG5tb2zvzqHsIdeHgAL0cQIZHFMYm01mqQW3gWb0+8HWm32dQAYhCvqcXEdLoVMqjqtdFA0zHc2h0us8kpp9Hw9EifspsQDJjMknNQWAMKTyRAvtCQOiigA1FJspGws6HC4nIXnY5XIU3PEtAmPbpJfjUKDCbKDanS-7UcZ04HzRbK1XtKEbLnYgDCAmN6vFIslhRc2VyT0iUmc0XU7m4IGyCBdAnITBwSBkMhAAF88DR6IxwDY7A4MAArci8ARCERMCBgMk6IzJjRaXQGNimcLWWz2eCKV58MCKADk7DY+lISGczh4UGoGFIUwAnvobFMMKr1M5C5ptHpDH4AvAfGAE9XGwBuCQSZX+EwLyuJmvxRRT4uzst7lcODceaiEMo6olWS81lZlfS4+A8iDwADua0UwC1JoOi1t4ihHg4P67hWz4rIB+z2J0SBNqQfATFAjZ4LUcoPES7aKBQ2LAIodAMMhjbLGwmEjHWYDkah6HUYoVTkRMACOZTQI2ihRkRJGxuRrzvF8TG1jo9asRAHFcXgzF8PRaFccovFasRpHwORrIUvA1G0ZJ0kYbJLFNgA5lo3FFCpfxqQJTZGmqOmyXppnmbJRTGY27GcRhPGnAAulhQoMGwLB8FApCKMh8F-AIACChBCDoAAq9yEk8kWKCsIT-vEcjKNFfyZYsOFpdUACER5JIhAwgP+ABkdWKG+H5fr+6y-CMEanF1+wRms16KG8bBlDowwhNePWbg4AAeeZGMR+7VjxPp+jkeGiDIKBIAATAA7D4m1IAAzAADJG0YgOpogpmmIDKpmbCiDmc0Aaci0OBIEZifWNTMM4y5VkmqZJFNP72FAfA-hgczgUV94BsMsWpIC5hPO18GnNuRiYu0sOxTorQDuC9YrBDPBlAwggYBx8A6AOxh9Gt5KxbAsArEkONJGs-WnJjgZGOo34-mEFhHmTFPCGw1NlLT9OM7k5Ls0Q3jzuEXO80Kd4Pul0SkLQJQIAAQqK1ArLs-4FXUuxjhAesG-AUCwy0MvdRrdRawjg3wNkbDG5KEXo9iyg46QCzkgAogmpO2-rRsmzzQqTZr8OPtVcLGJYgdasoQ0jcM71Qs14StX+A2WVNdRY6BDZHmnGfrGXmp1KcHuPiXmUW0HiiC7+IvwBg9gODoAASSWWAAMrDix913Idhzoke2CsJTgXlxFd8oECEEVYIlQq7TrAPOqwGUqqkMvY6ND7GB70S3NFBvRQlDbdsII7R6ELQsDZB1hU8RsicK5FFbulIuQgS5Zz+G8H2ftLjnwAX8CBCDy43jqGAz8QsG5uwfqgooudRqvWztXV2N4+pYOoD6fguYSC01ECUfWfQVry3WkwAAnKgc6MYGDXR4KQW691JZ0LCgOQhwcRwmXEveKASADYjjLvwWA5IkA-jsEICaU1ZCiOYvAaabAfBfwgCZagyEeCS1pmuJuihlw6BMvYZofB9DIW2idE6+hprqJvDjLRw4YD2BMshGQrj3G1EIBmPw7INKKG2igNx8iRqoR0MhMk9hEpl3odMCRfApFIAke8agZcwZQBCgE5xsTagsHgIY9gJSglpPJKqHQPhWjRDKPhHAJ0ACk8i0JKMUCozo8Ay4lVCToOiihtBfyhCdDAaAE5JxxkgXWscHZaPSVMTJ2S3hQE+lNAAxDDAqhTimKCwC4sp+w1kbJVMhckbQTKDNqLrfQsBaADiQIQBAwT9jJlaXkQgA4fACMEEgUgw5TH6MkSqMu1jbHGJOooWgFQ+AeIkKQKAzROgIC0U8l5byDZ8GmCi28Ks+7Ytts815yF8WEuwjovRBijFIFMYIcxISwk-kqSZapigShoSgGXUJghwlfGQkdba5yIxMP9CwkAKBtqhjQJGAKl1YyiB2P0Px6dLCRiAA)

The machine definition
```js
import javascriptStateMachine from 'https://cdn.skypack.dev/javascript-state-machine';

const StateMachine = javascriptStateMachine;

function Machine (updateView) {
  var fsm = new StateMachine({
  init: 'solid',
  transitions: [
      { name: 'melt',     from: 'solid',  to: 'liquid' },
      { name: 'freeze',   from: 'liquid', to: 'solid'  },
      { name: 'vaporize', from: 'liquid', to: 'gas'    },
      { name: 'condense', from: 'gas',    to: 'liquid' }
    ],
    methods : {
      onAfterTransition : (fsm) =>  {
        (fsm.transition != "init") && updateView() 
      }
    }
  });
 return fsm;
}


export { Machine }
```

It's use :

```js
import {
    Machine
} from "./machine.js"

window.app = (function Application() {

    const buttons = Array.from(document.querySelectorAll("button"));
    
    function disableButton(elt) {
      elt.disabled = true
    }
    
    function resetButtons () {
        buttons.forEach(disableButton);
    }

    function initFSM() {
        return Machine(updateView);
    }

    const fsm = initFSM();
    
    function View () {
        buttons.forEach(b => { 
          if (fsm.transitions().includes(b.dataset.transition))   
            b.disabled = false 
          })
    }

    function updateView() {
      resetButtons()
      View()
    }

    updateView();

    return {
        fsm
    }

})();
```