尝试使用 xstate-plantuml 可视化 FSM 图时出现类型错误

type error when trying to use xstate-plantuml to visualise the FSM diagram

我正在尝试创建一个脚本来自动化 xstate FSM 的可视化。由于目前有向 xstate-visualiser 发出 http 请求的方法。我正在使用 xstate-plantuml 制作图表。因为它需要 JSON 作为输入,所以我在我的机器对象上使用了 JSON.stringify() 并将代码传递给 visualize

import visualize from "xstate-plantuml";
import encoder from "plantuml-encoder";

import machine from "./machine.json";

const puml = visualize(machine);
const url = "http://www.plantuml.com/plantuml/svg/" + encoder.encode(puml);

const img = document.createElement("img");
img.src = url;

document.querySelector("#app").appendChild(img);
console.log(puml);

我一直收到 TypeError: value.replace is not a function 错误,我怀疑这是我的 JSON 结构的问题,因为它似乎适用于它附带的原始示例。不幸的是,除了 npm 包中的一行之外,该错误没有提及位置。

{
    "id": "runner",
    "initial": "setup",
    "strict": true,
    "states": {
        "setup": {
            "entry": [],
            "on": {
                "ERROR": {
                    "target": "error"
                },
                "TERMINATED": {
                    "target": "terminated"
                },
                "RUNNING": {
                    "target": "running"
                },
                "HANDLER_EXIT": {
                    "target": "handleExit"
                }
            },
            "id": "runTaskFSM",
            "initial": "pullPackage",
            "states": {
                "pullPackage": {
                    "entry": ["reportMachineStart", "pullPackage"],
                    "on": {
                        "MAKE_IO_DIR": {
                            "target": "mkIODir"
                        }
                    }
                },
                "mkIODir": {
                    "entry": ["mkIODir"],
                    "on": {
                        "WRITE_TASK_JSON": {
                            "target": "writeTaskDataJSON"
                        }
                    }
                },
                "writeTaskDataJSON": {
                    "entry": ["writeTaskDataJSON"],
                    "on": {
                        "DOWNLOAD_INPUTS": {
                            "target": "downloadInputs"
                        }
                    }
                },
                "downloadInputs": {
                    "entry": ["downloadInputs"],
                    "on": {
                        "LINK_INPUTS": {
                            "target": "linkInputs"
                        }
                    }
                },
                "linkInputs": {
                    "entry": ["linkInputs"],
                    "on": {
                        "DOWNLOAD_RESOURCES": {
                            "target": "downloadResources"
                        }
                    }
                },
                "downloadResources": {
                    "entry": ["downloadResources"],
                    "on": {
                        "TASKDIR_PERMISSIONS": {
                            "target": "chmodTaskDir"
                        }
                    }
                },
                "chmodTaskDir": {
                    "entry": ["chmodTaskDir"],
                    "on": {
                        "JOB_TIMEOUT": {
                            "target": "jobTimeout"
                        }
                    }
                },
                "jobTimeout": {
                    "entry": ["jobTimeout"],
                    "on": {
                        "INIT_HANDLER": {
                            "target": "initHandler"
                        }
                    }
                },
                "initHandler": {
                    "entry": ["initHandler"],
                    "on": {
                        "START_JOB": {
                            "target": "startJob"
                        }
                    }
                },
                "startJob": {
                    "entry": ["reportUserStart", "taskRunning", "startJob"],
                    "on": {
                        "TASK_RUNNING": {
                            "target": "taskRunning"
                        }
                    }
                },
                "taskRunning": {
                    "entry": [{
                        "type": "xstate.send",
                        "event": {
                            "type": "RUNNING"
                        },
                        "id": "RUNNING"
                    }]
                }
            }
        },
        "running": {
            "entry": [],
            "on": {
                "HANDLER_EXIT": {
                    "target": "handleExit"
                },
                "ERROR": {
                    "target": "error"
                },
                "TERMINATED": {
                    "target": "terminated"
                }
            }
        },
        "handleExit": {
            "entry": ["reportUserStop", "taskHandleExit"],
            "on": {
                "COMPLETE": {
                    "target": "complete"
                },
                "ERROR": {
                    "target": "error"
                }
            }
        },
        "complete": {
            "entry": ["taskComplete"],
            "on": {
                "DESTROY": {
                    "target": "destroy"
                }
            }
        },
        "error": {
            "entry": ["taskError"],
            "on": {
                "DESTROY": {
                    "target": "destroy"
                }
            }
        },
        "terminated": {
            "entry": ["reportUserStop", "terminate"],
            "on": {
                "DESTROY": {
                    "target": "destroy"
                }
            }
        },
        "destroy": {
            "entry": ["reportMachineStop", "destroyTask"],
            "type": "final"
        }
    }
}

似乎库无法处理您的 json 表示中的入口节点,例如,如果我以您的示例为例,并删除所有入口属性,那么它就可以工作,这就是它看起来像:

{
  "id": "runner",
  "initial": "setup",
  "states": {
    "setup": {
      "on": {
        "ERROR": {
          "target": "error"
        },
        "TERMINATED": {
          "target": "terminated"
        },
        "RUNNING": {
          "target": "running"
        },
        "HANDLER_EXIT": {
          "target": "handleExit"
        }
      },
      "id": "runTaskFSM",
      "initial": "pullPackage",
      "states": {
        "pullPackage": {
          "on": {
            "MAKE_IO_DIR": {
              "target": "mkIODir"
            }
          }
        },
        "mkIODir": {
          "on": {
            "WRITE_TASK_JSON": {
              "target": "writeTaskDataJSON"
            }
          }
        },
        "writeTaskDataJSON": {
          "on": {
            "DOWNLOAD_INPUTS": {
              "target": "downloadInputs"
            }
          }
        },
        "downloadInputs": {
          "on": {
            "LINK_INPUTS": {
              "target": "linkInputs"
            }
          }
        },
        "linkInputs": {
          "on": {
            "DOWNLOAD_RESOURCES": {
              "target": "downloadResources"
            }
          }
        },
        "downloadResources": {
          "on": {
            "TASKDIR_PERMISSIONS": {
              "target": "chmodTaskDir"
            }
          }
        },
        "chmodTaskDir": {
          "on": {
            "JOB_TIMEOUT": {
              "target": "jobTimeout"
            }
          }
        },
        "jobTimeout": {
          "on": {
            "INIT_HANDLER": {
              "target": "initHandler"
            }
          }
        },
        "initHandler": {
          "on": {
            "START_JOB": {
              "target": "startJob"
            }
          }
        },
        "startJob": {
          "on": {
            "TASK_RUNNING": {
              "target": "taskRunning"
            }
          }
        },
        "taskRunning": {}
      }
    },
    "running": {
      "on": {
        "HANDLER_EXIT": {
          "target": "handleExit"
        },
        "ERROR": {
          "target": "error"
        },
        "TERMINATED": {
          "target": "terminated"
        }
      }
    },
    "handleExit": {
      "on": {
        "COMPLETE": {
          "target": "complete"
        },
        "ERROR": {
          "target": "error"
        }
      }
    },
    "complete": {
      "on": {
        "DESTROY": {
          "target": "destroy"
        }
      }
    },
    "error": {
      "on": {
        "DESTROY": {
          "target": "destroy"
        }
      }
    },
    "terminated": {
      "on": {
        "DESTROY": {
          "target": "destroy"
        }
      }
    },
    "destroy": {
      "type": "final"
    }
  }
}

这里的沙箱处于工作状态:

现在棘手的部分是判断你对库的使用是否正确,或者库是否缺少实现,错误发生在库中this line