Xstate inspect状态图的使用 和 原理

状态图的好处之一是,在将状态图组合在一起的过程中,您可以探索流程中所有可能的状态。这种探索将帮助您避免代码中的错误和错误,因为您更有可能涵盖所有可能发生的情况。

因为状态图是可执行的,所以它们既可以表现为图,也可以表现为代码,这样就不太可能在图环境和编码环境之间引入差异或错误解释。

原理解析

状态图iframe展示页面是xstate官方提供的未开源,基本原理就是通过receptor监听发来的消息,进行状态图绘制。

xstate inspect检查器代理生成状态图:

Xstate提供俩中模式:postMessage或ws 。 进行inspect检查器和iframe内receptor的通讯

状态图页面是xstate官方提供的未开源,基本原理就是通过receptor监听发来的消息,进行状态图重新绘制。

Iframe中receptor接受到传来的序列化消息后,只用基本信息数据做状态图绘制和节点高亮,不涉及逻辑执行。逻辑执行还是由xstate中service执行,执行完转换state后传递state给状态图做高亮。点击状态图的事件节点也是触发service.send()方法让xstate执行send事件。

向iframe中发送消息:iframe.window.postMessage({ type: "xxx",    data: {} });        

监听postMessage的消息事件:window.addEventListener("message", (e) => {  console.log(e.data.type);    } });

一。postMessage模式:源码文件browser.ts

1.执行inspect()

1-1.执行inspect()创建了一个检查器inspector(如下inspect函数代码)。创建了一个InspectMachine,创建了一个devTools复制给全局变量:getGlobal().__xstate__ = devTools。

    InspectMachine监听响应的xstate.event等事件调用iframe.postMessage触发状态图的更新。 devTools维护listener(主要是代理service的send subsribe onStop)。)和service集合。

1-2.渲染iframe.src https://stately.ai/viz?inspect , 此iframe由xstate官方创建了receptor接受postMesage消息进行对应的视图重新渲染。同时会在receptor创建完成后向parent.window发出'xstate.inspect'消息,parent会将devTools.services全部发送给iframe进行'xstate.register'注册和初始化。

2.然后创建开启devTools的service,interpret(machine,{devTools:true});

2-1.开启了devTools的service start启动时会获取到devTools(getGlobal().__xstate__),

2-2.将service注册register到devTools中(注册时会执行listener(service),代理service的send subsribe onStop,同时会向InspectMachine发出'xstate.register'事件)。

之后service状态再改变,会自动走代理方法InspectMachine.send()触发iframe状态图更新。

二。Ws模式:源码文件server.ts

inspect(); //ws server端,接收iframe的消息,发送给inspectMachine处理【同时发送事件到iframe中(通过ws send),进行状态机初始化 渲染状态图】

创建devTools,并注册listener对service进行代理,send subscribe stop时自动通过ws session 发送事件到iframe中。

渲染iframe src。

iframe中链接到inspect(ws server),作为client发送'xstate.inspecting'初始化完成事件,然后接受inspect发来的ws消息'xstate.register',进行注册状态机初始化 渲染状态图。

interpret(machine,{devTools:true}); 开启dev模式后,通过global.__xstate__将machine注册到devTools中(注册时会执行listener(machine),对machine进行代理,send subscribe stop时自动通过ws session 发送事件到iframe中的ws client端)。

Iframe中receptor接受到传来的序列化消息后,只用基本信息数据做状态图绘制和节点高亮,不涉及逻辑执行。逻辑执行还是由xstate中service执行,执行完转换state后传递state给状态图做高亮。点击状态图的事件节点也是触发service.send()方法让xstate执行send事件。

{     
      type: 'service.register',
      machine: stringifyMachine(service.machine),  // 
      state: stringifyState(state),
      sessionId: service.sessionId,
}
{
      type: 'service.event',
      event: stringifyWithSerializer(state._event),
      sessionId: service.sessionId
}
{
 	type: 'service.state',
        // TODO: investigate usage of structuredClone in browsers if available
        state: stringifyState(state, options?.serialize),
        sessionId: service.sessionId
}

通过inspect可视化绘制状态图

简单演示使用(在前端直接启动的状态机):  

 ps:正常还是建议在后端启动状态机

<template>
<iframe onload="this.height=document.body.scrollHeight-30" width="100%" scrolling="no" frameborder="0" data-xstate></iframe>
</template>
<script>
import { inspect } from "@xstate/inspect";
  async mounted() {
this.subMqtt();
    this.init(); // 此处为启动状态机逻辑: interpret(deviceMachine, {devTools:true}).start(); 
    inspect({
      iframe: () => document.querySelector("iframe[data-xstate]"),
    });
  },
}

  • 22
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李庆政370

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值