@edium/fsm

中文文档
3.0.2发布于 2026/04/23MITTypeScriptESM + CJS近 30 天下载 2.9万

简单的有限度状态的机器框架,可用于客户端或服务器.

中文使用文档
文档目录16 节
  1. 概览
  2. 特征
  3. 迁移到 3.x
  4. 如果使用 2.x 版本(或更早)
  5. 使用新合成的密克罗尼西亚
  6. 安装
  7. 测试范围( S)
  8. 导入
  9. 示例
  10. 导入
  11. 示例
  12. 1. 州卫队(即将过渡)
  13. 2. 全球过渡
  14. 3. 次级国家机器(等级构成)
  15. 4. 协同工作流程
  16. 5. 处理错误

有限国家机器

概览

密克罗尼西亚联邦 是一种用 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创建.

版本与发布记录

@edium/fsm 共发布 21 个版本,首次发布于 2019/07/22;过去 12 个月发布了 3 个版本。

版本发布日期距今
3.0.2latest2026/04/236 个月前
3.0.12025/11/2611 个月前
3.0.02025/11/2611 个月前
2.1.52024/07/052 年前
2.1.42022/11/153 年前
2.1.32022/06/234 年前

关于 @edium/fsm 的常见问题

@edium/fsm 是什么?

简单的有限度状态的机器框架,可用于客户端或服务器.

如何安装 @edium/fsm?

在项目目录运行 npm install @edium/fsm,或使用 pnpm add / yarn add / bun add。

@edium/fsm 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@edium/fsm 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@edium/fsm 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@edium/fsm 可以商用吗?

@edium/fsm 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@edium/fsm 的下载量有多少?

根据 npm 官方下载统计,@edium/fsm 在 2026/10/13 – 2026/11/11 这 30 天内被下载 28,771 次,日均约 959 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@edium/fsm 还在维护吗?

最新版本 3.0.2 发布于 2026/04/23(6 个月前);至今共发布 21 个版本,其中过去 12 个月发布了 3 个;首次发布于 2019/07/22。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。