statelyai / xstate-tools

Public monorepo for XState tooling
183 stars 40 forks source link

Bug: [parser] Parser don't parse template strings containing variables #117

Open SteamWind opened 2 years ago

SteamWind commented 2 years ago

Description

Using the vscode extension with the inspector, I would like to be able to use template strings for complex targets. But the parser doesn't understand them. You can try this snippet in the parser tester and toggle the comments to try out.

import { createMachine } from 'xstate';

const machineId = 'dontwork';
const templateString = `#${machineId}.b`; // don't work
//const templateString = `#dontwork.b`; // don't work
//const templateString = '#dontwork.b'; // works

const machine = createMachine({
  id: machineId,
  initial: "a",
  states: {
    a: {
      on: {
        FOO: {
          target: templateString,
        },
      },
    },
    b: {
      always: {
        target: "#dontwork.a",
      },
    },
  },
});

Expected result

Using this kind of template string should work:

const machineId = 'dontwork';
const templateString = `#${machineId}.b`; 

And give this result:

[
  {
    "id": "dontwork",
    "initial": "a",
    "states": {
      "a": {
        "on": {
          "FOO": {
            "target": "#dontwork.b"
          }
        }
      },
      "b": {
        "always": {
          "target": "#dontwork.a"
        }
      }
    }
  }
]

Actual result

[
  {
    "id": "dontwork",
    "initial": "a",
    "states": {
      "a": {
        "on": {
          "FOO": {}
        }
      },
      "b": {
        "always": {
          "target": "#dontwork.a"
        }
      }
    }
  }
]

Reproduction

https://xstate-parser-example-site.vercel.app/

Additional context

Weird thing is that it works in the online visualizer. https://stately.ai/registry/machines/945f4fa9-375c-4e8a-9eae-8dd620916b97.png

Andarist commented 2 years ago

Weird thing is that it works in the online visualizer.

That is because the viz doesn't use static analysis to extract configs.


Have you tried our editor? What do you think about it? I'm asking because this pattern won't work with it - so while there is some room for improvement here to handle this for the viz, using this pattern will lock you out of our other tooling.

SteamWind commented 2 years ago

Yes I have, I like to use it to make the architecture of my new state machines but I can't rely on it in this state to use it for my actual state machines. I don't use TS in my project and typegen is too complicated to use in this environment.

Andarist commented 2 years ago

Could you expand on this a little bit? If you don't use TS then typegen shouldn't be printed for you. Or are you saying that you'd like to get some benefits of the typegen but you are currently not able to use it because it's complicated + you are not using TS at all?

SteamWind commented 2 years ago

XState is going away from the js compatibility as I can see. Without TS, no typegen, without typegen, you better have to use things like js enums and template strings, but those doesn't work well with the inspector's parser. So using js prevent us to be able to use part of the new tools XState can provide.

Anyway, in between my last message and this one, we decided to migrate to TS (XState being part of our decision). So we should have less problems in the future with this kind of situation. (Hoping that we will successfully migrate to TS haha) 😄

Andarist commented 2 years ago

We would really love to support "all of the JS" if we could - but that's just a really hard problem. By limiting the allowed patterns we can build much better tooling around XState - so it's a tradeoff. In a way, we treat XState configs as mostly self-contained and serializable stuff, like a YAML config. It just happens to live in your JavaScript file for convenience :sweat_smile:

The rules are not as strict as those for YAML configs (or similar) - but there are still limits to what we can handle. Different tools could have different requirements, like for example rules for the visualizer could be loosened up but then I feel like it would be much harder to educate people what is allowed in what context. I don't see having a "compat table" that you would have to reference/learn for each tool as being a good DX - so, personally, I think that all of our tooling should be restricted using the very same set of rules.