aifsmjs — 狀態機
This content is not available in your language yet.
import { Aside } from ‘@astrojs/starlight/components’;
aifsmjs 是一個小型、嚴格的 FSM(有限狀態機)函式庫。核心哲學是定義與實作分離:狀態圖是純 JSON 資料,guards/actions/effects 在 runtime 注入,因此整個 machine definition 可以被序列化、跨 Worker 傳輸,或存進資料庫。
生命週期是一個純函數:step() 按固定順序執行 guards → exit → action → entry,不可中斷、可確定性重放。
pnpm add aifsmjsimport { setup, createRuntime, assign } from "aifsmjs";
type Ctx = { ticks: number };type Evt = { type: "NEXT" };
// 1. 定義是純資料:setup<Ctx, Evt>() 讓 States 從 states 的 key 自動推斷const trafficLight = setup<Ctx, Evt>().defineMachine({ id: "trafficLight", initial: "red", context: { ticks: 0 }, states: { red: { on: { NEXT: { target: "green", actions: ["bump"] } } }, green: { on: { NEXT: { target: "yellow", actions: ["bump"] } } }, yellow: { on: { NEXT: { target: "red", actions: ["bump"] } } }, },});
// 2. 實作在 runtime 注入const runtime = createRuntime(trafficLight, { actions: { bump: assign(({ context }) => ({ ticks: context.ticks + 1 })), },});
// 3. 發送事件runtime.send({ type: "NEXT" });console.log(runtime.getSnapshot().value); // "green"console.log(runtime.getSnapshot().context); // { ticks: 1 }MachineDefinition(純資料)+ Implementations(runtime 注入) ↓step(def, snapshot, event, impl) → guards → exit → action → entry → 回傳新 snapshot(不可變)Subpath exports
Section titled “Subpath exports”| Subpath | 用途 |
|---|---|
aifsmjs | 核心:setup、createRuntime、assign、step |
aifsmjs/guards | and、or、not guard 組合器 |
aifsmjs/effects | 副作用雙軌道 enq.effect() |
aifsmjs/inspect | Koa-style 只觀察、不修改轉移的 middleware |
aifsmjs/replay | 事件序列回放 |
aifsmjs/pbt | fast-check fc.commands 整合,屬性測試 |
aifsmjs/timer | tick-based timer hooks |
- 遊戲場景切換:FSM 管理
lobby → game → paused → gameOver,emit 事件到渲染層 - 多步驟表單:每個步驟是一個 state,guards 驗證欄位再允許 NEXT 轉移
- 與
aiecsjs搭配:ECS 裡的 entity 可以帶一個 FSM snapshot 管理行為狀態(例如角色的idle / walk / attack) - 與
aibridgejs搭配:machine definition 可直接 JSON 序列化後透過 bridge 傳到另一個 context