有限国家机器
概览
密克罗尼西亚联邦 是一种用 TypeScript 书写的轻量级、灵活的有限状态机器。 它同时在浏览器和Node.js中工作,支持本地和全局的过渡,出入口/决定动作,阻断了过渡,可选的上下文对象传递到所有的状态动作.
版本 3.x 运算 全面介绍 同步状态机器,用于客户端/服务器应用程序,工作流程系统,同声游戏逻辑,以及任何需要的 await 国家行动.
重要性 3.x版本为 100%后相兼容 与更早的版本. 原同步API不变——新Aync API可选.
特征
- 无所限制之州.
- 一个或多个已完成的州.
- 可选的“回到以前的国家”行为.
- 对无效的转换投出错误 .
- 进出,并决定行动.
- 退出动作可以阻挡过渡.
- 重置和可选重启行为 .
- 地方过渡(具体国家).
- 全球过渡(通过州规则).
- 触发驱动的状态变化.
- 可选上下文对象传递给所有动作 .
- Async 密克罗尼西亚选项 页:1
await- 驱动逻辑.
迁移到 3.x
3.x版本增加了同步的密克罗尼西亚类(AsyncState, (中文(简体) ), AsyncStateMachine, (中文(简体) ), AsyncTransition(中文(简体) ) 不更改 现有的同步 API.
如果使用 2.x 版本(或更早)
你不需要改变任何事情:
import { State, StateMachine } from '@edium/fsm';
const machine = new StateMachine('My FSM');
machine.start(...);
machine.trigger('next');
这项工作继续如前.
使用新合成的密克罗尼西亚
切换到 :
import { AsyncState, AsyncStateMachine } from '@edium/fsm';
await asyncMachine.start(...);
await asyncMachine.trigger('next');
两种风格可以共存在同一工程中.
安装
pnpm install @edium/fsm
测试范围( S)
密码库全单位测试,覆盖率接近100%. 所有代码均被嵌入,预置并进行打字检查.
同步机器
导入
import { State, StateMachine } from '@edium/fsm';
const { State, StateMachine } = require('@edium/fsm');
示例
const entryAction = (state, context) => {
state.trigger('next');
};
const exitAction = (state, context) => {
return true;
};
const decideAction = (state, context) => {
const index = context.randomize();
if (index === 0) {
state.trigger('gotoThree');
} else if (index === 1) {
state.trigger('gotoFour');
}
};
const finalAction = (state) => {};
const context = {
randomize: () => Math.floor(Math.random() * 2)
};
const stateMachine = new StateMachine('My first state machine', context);
const s1 = stateMachine.createState('My first state', false, entryAction);
const s2 = stateMachine.createState('My second state', false, decideAction, exitAction);
const s3 = stateMachine.createState('My third state', false, entryAction);
const s4 = stateMachine.createState('My fourth state', false, entryAction);
const s5 = stateMachine.createState('My fifth and final state', true, finalAction);
s1.addTransition('next', s2);
s2.addTransition('gotoThree', s3);
s2.addTransition('gotoFour', s4);
s3.addTransition('next', s5);
s4.addTransition('next', s5);
stateMachine.start(s1);
同步机器
此示例执行安全的同步状态机器,不允许用户在运行工作时直接改变状态.
重要性 不要打电话 asyncStateMachine.trigger () 请检查url=中的日期值 (帮助) 从内部的出入境行动。 相反,你必须使用 状态。触发 Internal ()。一旦当前过渡完成,内部触发器将被排队和安全处理,而外部触发器将产生出错.
导入
import { AsyncState, AsyncStateMachine } from '@edium/fsm';
const { AsyncState, AsyncStateMachine } = require('@edium/fsm');
示例
const entryAction = async (state, context) => {
// Safe: internal triggers are queued if the machine is already busy.
await state.triggerInternal('next');
};
const exitAction = async (state, context) => {
return true;
};
const decideAction = async (state, context) => {
const index = context.randomize();
if (index === 0) {
await state.triggerInternal('gotoThree');
} else if (index === 1) {
await state.triggerInternal('gotoFour');
}
};
const finalAction = async (state) => {};
const context = {
randomize: () => Math.floor(Math.random() * 2)
};
const asyncStateMachine = new AsyncStateMachine('My first async state machine', context);
const s1 = asyncStateMachine.createState('My first state', false, entryAction);
const s2 = asyncStateMachine.createState('My second state', false, decideAction, exitAction);
const s3 = asyncStateMachine.createState('My third state', false, entryAction);
const s4 = asyncStateMachine.createState('My fourth state', false, entryAction);
const s5 = asyncStateMachine.createState('My fifth and final state', true, finalAction);
s1.addTransition('next', s2);
s2.addTransition('gotoThree', s3);
s2.addTransition('gotoFour', s4);
s3.addTransition('next', s5);
s4.addTransition('next', s5);
await asyncStateMachine.start(s1);
常见模式
1. 州卫队(即将过渡)
const guardedExit = (state, ctx) => {
return ctx.isAllowed === true;
};
2. 全球过渡
machine.addGlobalTransition('reset', startState);
machine.trigger('reset');
3. 次级国家机器(等级构成)
const sub = new StateMachine('sub');
const parent = new StateMachine('parent');
parent.createState('run-sub', false, () => {
sub.start();
});
4. 协同工作流程
const entry = async (s, ctx) => {
const data = await fetch('/api/data').then((r) => r.json());
ctx.data = data;
// Safe: internal triggers are queued if the machine is already busy.
await s.triggerInternal('next');
};
5. 处理错误
所有内部错误都抛出为 StateMachineError数字 :
error.message- 前缀消息:State Machine (My Machine) - …error.machine- 国家机器名称error.state- 当前状态名称(如果有的话)error.trigger- 触发 id (如果有的话)
你们可以 instanceof StateMachineError 以区分密克罗尼西亚的错误和其他错误.
由Edium Interactive LLC创建.