sonntam / node-red-contrib-xstate-machine

A xstate-based state machine implementation using state-machine-cat visualization for node red.
MIT License
22 stars 8 forks source link

Error when rendering state machine using smcat #100

Closed patmalcolm91 closed 1 year ago

patmalcolm91 commented 1 year ago

I'm receiving a strange syntax error when trying to render my state machine using smcat. Only the rendering is affected, and the machine node works perfectly otherwise. Since the error message doesn't seem to relate in any meaningful way to my machine definition code, my guess is that the error has something to do with the way that the code is converted into the right format for smcat, hence why I am posting the issue here rather than smcat's repo. Here is my code:

// Import shorthands from xstate object
const { assign } = xstate;

return {
  machine: {
    context: {
      door: "open",
    },
    initial: "Unoccupied",
    states: {
      Unoccupied: {
        on: {
          buzz: [
            {
              target: "Occupied",
              cond: "door_is_closed",
            },
            {
              target: "Tentatively Occupied",
            },
          ],
          door_opened: {
            actions: {
              type: "mark_door_open",
              params: {}
            },
            internal: true,
          },
          door_closed: {
            actions: {
              type: "mark_door_closed",
              params: {}
            },
            internal: true,
          }
        }
      },
      Occupied: {
        on: {
          door_opened: {
            target: "Tentatively Occupied",
            actions: {
              type: "mark_door_open",
              params: {}
            }
          }
        }
      },
      "Tentatively Occupied": {
        after: {
          "60000": [
            {
              target: "Unoccupied",
              actions: []
            },
            {
              internal: false,
            }
          ],
        },
        on: {
          buzz: [
            {
              target: "Occupied",
              cond: "door_is_closed",
            },
            {
              internal: true,
            }
          ],
          door_closed: {
            actions: {
              type: "mark_door_closed",
              params: {}
            },
            internal: true,
          },
          door_opened: {
            actions: {
              type: "mark_door_open",
              params: {}
            },
            internal: true,
          }
        }
      }
    },
    predictableActionArguments: true,
    preserveActionOrder: true
  },
  config: {
    actions: {
      mark_door_open: assign({door: (context, event) => 'open'}),
      mark_door_closed: assign({door: (context, event) => 'closed'}),
    },
    services: { },
    guards: { door_is_closed: (context, event) => context.door == 'closed' },
    delays: { }
  }
};

And here is the error message from the console log:

Rendering of state machine failed: Render process returned error code 1: file:///data/node_modules/state-machine-cat/src/parse/smcat/smcat-parser.mjs:14
  var self = Error.call(this, message);
                   ^

peg$SyntaxError: Expected comment, end of input, line end, statemachine, or whitespace but "e" found.
    at new peg$SyntaxError (file:///data/node_modules/state-machine-cat/src/parse/smcat/smcat-parser.mjs:14:20)
    at peg$buildStructuredError (file:///data/node_modules/state-machine-cat/src/parse/smcat/smcat-parser.mjs:556:12)
    at peg$parse (file:///data/node_modules/state-machine-cat/src/parse/smcat/smcat-parser.mjs:2686:11)
    at Object.getAST (file:///data/node_modules/state-machine-cat/src/parse/index.mjs:22:22)
    at Object.render (file:///data/node_modules/state-machine-cat/src/index-node.mjs:58:24)
    at file:///data/node_modules/state-machine-cat/src/cli/actions.mjs:37:29
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  expected:...

Any help in solving this issue would be greatly appreciated!

sonntam commented 1 year ago

Thank you for taking the time to post an issue and providing an example. From first looks it could definitely be the code that transforms xstate to smcat/dot.

Lately I’m also having trouble with rendering some FSM graphs but haven’t had the time to look into it.

I’ll look into it but you have to give me some time.

patmalcolm91 commented 1 year ago

Thanks for the quick response, @sonntam. That's no problem, it is not an urgent issue since it's only the visualization and not the functionality which is affected.

sonntam commented 1 year ago

So I took a quick look at the output of the smcat code generator and fed it to the online viewer.

It seems smcat cannot handle the space character in your state "Tentatively Occupied". So I think I just have to do some kind of identifier sanitation. Should be no problem.

A workaround for you for the time being: Delete all whitespace characters from your state names.

patmalcolm91 commented 1 year ago

I can confirm that the workaround does indeed work. Thanks a lot for the quick solution!

sonntam commented 1 year ago

You're welcome. It should also be now fixed in V1.3.2.