# @edium/fsm 中文文档

规范地址：https://npmcn.com/package/%40edium/fsm/

版本：3\.0\.2
npm 元数据更新时间：2026-04-22T21:24:31.697Z
中文译文更新时间：2026-11-13T07:08:22.938Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40edium/fsm
原文对照：https://npmcn.com/package/%40edium/fsm/?lang=original
项目主页：https://github.com/splayfee/fsm
源码仓库：https://github.com/splayfee/fsm

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：108 kB，6 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=18
- 运行依赖：1 个
- 首次发布：2019-07-22T15:47:46.781Z
- 最新版本发布：2026-04-22T21:24:31.566Z
- 近 30 天下载量：28771（2026-10-13 至 2026-11-11，npm 官方下载统计）
- 已发布版本数：21（近 12 个月 3 个）

## 中文简介

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

## 安装

```sh
npm install @edium/fsm
```

也可以使用：`pnpm add @edium/fsm`、`yarn add @edium/fsm`、`bun add @edium/fsm`

## README

# 有限国家机器

## 概览

**密克罗尼西亚联邦** 是一种用 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 版本(或更早)

你不需要改变任何事情:

```ts
import { State, StateMachine } from '@edium/fsm';

const machine = new StateMachine('My FSM');
machine.start(...);
machine.trigger('next');
```

这项工作继续如前.

### 使用新合成的密克罗尼西亚

切换到 :

```ts
import { AsyncState, AsyncStateMachine } from '@edium/fsm';

await asyncMachine.start(...);
await asyncMachine.trigger('next');
```

两种风格可以共存在同一工程中.

* * *

## 安装

```bash
pnpm install @edium/fsm
```

* * *

## 测试范围( S)

密码库全单位测试,覆盖率接近100%. 所有代码均被嵌入,预置并进行打字检查.

* * *

# 同步机器

### 导入

```ts
import { State, StateMachine } from '@edium/fsm';
```

```js
const { State, StateMachine } = require('@edium/fsm');
```

### 示例

```ts
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 ()**。一旦当前过渡完成,内部触发器将被排队和安全处理,而外部触发器将产生出错.

### 导入

```ts
import { AsyncState, AsyncStateMachine } from '@edium/fsm';
```

```js
const { AsyncState, AsyncStateMachine } = require('@edium/fsm');
```

### 示例

```ts
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\. 州卫队(即将过渡)

```ts
const guardedExit = (state, ctx) => {
  return ctx.isAllowed === true;
};
```

## 2\. 全球过渡

```ts
machine.addGlobalTransition('reset', startState);
machine.trigger('reset');
```

## 3\. 次级国家机器(等级构成)

```ts
const sub = new StateMachine('sub');
const parent = new StateMachine('parent');

parent.createState('run-sub', false, () => {
  sub.start();
});
```

## 4\. 协同工作流程

```ts
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 是什么？

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

### 如何安装 @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 和提交记录判断。

