@cssints/machine

中文文档
0.36.0发布于 2026/11/12MITTypeScriptES Module零依赖构建来源已验证近 30 天下载 2147

用于UI协议的最小、无依赖、无类型安全的状态机器:作为数据的效果, Stale effect 无法完成,用一冲子、可注入的时钟和在没有浏览器的情况下加以证明的绳带来解开

中文使用文档
文档目录9 节
  1. 动画披露
  2. 5个地产
  3. API 密码
  4. 效果和手柄
  5. 时钟
  6. 绳子
  7. 实心桥
  8. 限制
  9. 测试

@ cssints/ 机器

用于 UI 协议的最小、无依赖、无类型安全的状态机器: 动画披露, 打开的菜单 盘旋并关闭在 休眠的假期, 敬酒 逆转中飞行.

信号控制状态,不是协议 组件动画的一瞬间,协议出现:a closing 还有一个 opening ; 已取消的动画仍然点出其完成; 中断的关闭必须倒转 从盒子所在的地方 pointerenter编号 :pointerleave 不得产生五种效果 吞下最后一个意图。 这些都无法作为信号表达。 这个软件包是运行时间的一半:最小的 可以驱动这些协议的机器, 和一种没有浏览器就能证明这些协议的管子.

无依取相. 核心是平版Script(它通过节点的类型去除:没有enums,没有命名空间,没有) 参数属性; @cssints/machine/solid 是唯一一个导入任何文件的文件,以及 solid-js 它是可选的 鼠标.

动画披露

import { createMachine, defineMachine } from "@cssints/machine";

type Events = { open: undefined; close: undefined; finish: { id: number } };

const disclosure = defineMachine<Events>()({
  start: "closed",
  initial: { progress: 0 },
  states: {
    closed: {
      on: { open: { target: "opening", effect: { type: "animate", to: "open" } } },
    },
    opening: {
      on: {
        finish: "open",
        close: { target: "closing", effect: { type: "animate", to: "closed" } },
      },
      after: { 400: "open" }, // an animation that never reports back still ends: no state is a trap
    },
    open: {
      on: {
        close: { target: "closing", effect: { type: "animate", to: "closed" } },
        tick: {
          target: "open",
          assign: (context, event) => ({
            progress: event.type === "tick" ? event.value : context.progress,
          }),
        },
      },
    },
    closing: {
      on: {
        finish: "closed",
        open: { target: "opening", effect: { type: "animate", to: "open" } },
      },
      after: { 400: "closed" },
    },
  },
});

const machine = createMachine(disclosure);

// The host runs the effects; the machine holds one handle per effect and cancels it when the state is left.
machine.onEffect((handle) => {
  const animation = box.animate(keyframes[handle.spec.to], { duration: 200 });
  animation.finished.then(() => machine.send({ type: "finish", id: handle.id }));
});

button.addEventListener("click", () => {
  machine.send(machine.getState().state === "closed" ? { type: "open" } : { type: "close" });
});

5个地产

  1. 由开口倒转而结束的关闭中断. 脱离短暂状态的过渡 就像 任何其它;反向效果取代了收尾效果.
  2. 被取消的动画完成被忽略. A 类 finish 携带寄存器所给出的手柄 ID。 离开 州取消手柄,所以晚到的完成会被扭曲并丢弃,不适用于新州.
  3. 一个框架的两个事件每个状态最多产生一个效果. 每次过渡都会取消状态的控件 离开; 主机只运行最后的意向 .
  4. 被解除的爆裂产生一种效果,具有最后的意向. send(event, { debounce }) (或机器一级) debounce 地图)按事件类型组合; flush() {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}最终的意向, cancel() 丢弃一个被取代的.
  5. 没有什么是永远卡住. 每个州都有出口; after 是一种从不报告的后果的倒置.

API 密码

成员它会做什么
defineMachine(config)定义 : { initial, states, start?, debounce? }事件是工会 on 键,从 initial;没有状态接受的事件是类型错误.
defineMachine<Payloads>()(config)与打出的有效载荷相同: { close: undefined; finish: { id: number } }警卫或 assign 缩入 event.type。 。 。 .
createMachine(definition, options?)一个例子。 选项 : clock, (中文(简体) ), autoStart, (中文(简体) ), onEffect, (中文(简体) ), onCancel, (中文(简体) ), onTransition。 。 。 .
machine.getState(){ state, context };每个转换时新对象,旧对象仍可读取.
machine.subscribe(listener)每一个过渡和每分出一分.
machine.subscribe(selector, listener)只有改变 selector' 值 (e)Object.is),商店桥 一个主机读取一个切片.
machine.send(event, { debounce? })现在就交货,或者安排一个连结交货.
machine.flush() 编号 : machine.cancel(type?)瞷祇瞷 瞷 斌.
machine.effects()活柄:已发,未完成,未取消.
machine.onEffect 编号 : onCancel 编号 : onTransition宿主侧:跑出一出效果,停止,观察一出送出.
machine.start() 编号 : machine.destroy()输入起始状态( 参数) / 清除每个计时器, 取消每个手柄, 丢弃每个收听器 .
harness(definition)假钟上的机器: advance(ms),队列(enqueue, (中文(简体) ), deliver, (中文(简体) ), deliverAll, (中文(简体) ), race, (中文(简体) ), interleave, (中文(简体) ), flushEffects现场直播 cancelled() 编号和编号 log。 。 。 .

过渡是一个目标字符串(open: "opening")或(或) { target, guard?, effect?, assign? }; 一个州的 on 值为 1 过渡或名单, 第一个其警卫通过. after 映射 ms 到一个过渡; 离开状态清除计时器. assign 是一个 Partial<context> 或者说 (context, event) => Partial<context>。 。 。 .

效果和手柄

效果是数据,而不是回调 : { type: "animate", to: "open", duration: 200 }该机器发行a 控件 (单位:千美元){ id, type, spec, state }对于州条目或过渡声明的每一项效果,当州为时取消 左侧或过渡取代它。 完成事件是指任何带有数字的事件 id: 已丢弃了 stale id(和 登录为 cancelled),活人完成手柄而无需取消. effects() 应该是主机 现在运行.

超过州命的效应被取消;宿主停止(onCancel)及其延迟完成 无法移动机器 .

时钟

createMachine(definition, { clock }) 带 { now(), setTimeout(callback, ms), clearTimeout(handle) }; 默认为 systemClock。同一时钟驱动器 after,解跳和过渡的时间戳, 所以测试驱动时间与 advance(ms) 和主机使用实时.

绳子

import { harness } from "@cssints/machine";

const h = harness(disclosure);
h.send({ type: "open" });
const animation = h.machine.effects().at(-1);

h.send({ type: "close" }); // the open's animation is cancelled, the close's is issued
h.send({ type: "finish", id: animation.id }); // stale: ignored
assert.equal(h.machine.getState().state, "closing");

h.advance(400); // the `after` fallback settles it
assert.equal(h.machine.getState().state, "closed");

h.log 每交付一行(及其发布的一行效果): { at, event, from, to, effect, context, cancelled }。 。 。 . h.race(...events) 在一个瞬间传递一个帧的事件; h.interleave(...sequences) 圆相罗宾数令. h.flushEffects() 返回当前主机要运行的控点,而不是在同一框架中已经取消的控点.

实心桥

@cssints/machine/solid (solid-js是同级)将机器曝光为Solid的存储层:

import { createMachineStore } from "@cssints/machine/solid";

const store = createMachineStore(machine, {
  settled: (phase) => phase === "open" || phase === "closed",
  intent: (event) =>
    event.type === "close" ? "closed" : event.type === "open" ? "open" : undefined,
});
const view = store.projection(
  (draft, from) => {
    draft.visible = from.phase !== "closed";
  },
  { visible: false },
);
  • store.state 是一个 createStore 联 合 国 { ...context, phase },每个转换时一个设置调用,只写字段 改变了: state.phase 仅在时不重运行 progress 变化.
  • store.optimistic 是同一字段的第二个商店: state,而意向书写它的阶段 向上飞去。 过渡一到解决阶段,铅就会被丢弃,因此,观点恢复到 刻不容缓的快照——这一意图在完成前被取而代之,而不是坚持下去.
  • store.projection(compute, seed) 是一个 createProjection 结束 state:只有已改变的字段通知,所以读取 view.visible 不重运行当 progress 变化。 预测读取承诺的框架,而不是乐观 超接( Solid holds the overer),因此视相被读取 optimistic 直接说.
  • store.send(event) 是机器的发送与乐观的引导;发送到机器上直接跳过.

一个 setState 每一次过渡都是同样的原子性 反应性运行时间从一次冲出 (单位:千美元)packages/reactive/src/runtime.ts, (中文(简体) ), packages/apg-specs/specs/patterns/reactive.qnt:读者从未看到从 一个转变,一个进步.

限制

  • 相克一州:无相克相克相克相克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克 两个独立的协议 区域是两台机器,是寄给两者的主机.
  • 效果是数据,由主机运行;机器不等待承诺,拥有动画或调用回调. 一个从未到达的完成由 after (或由取消的东道主).
  • 数字 id 在事件上保留一个效果控点:一个带有 stale id 的事件被丢弃.
  • 按事件类型排列的解跳组合;同一事件类型的两个不同来源共享一个待决意图.
  • 商店桥的乐观取向只取自一个固定阶段(协调员的) settled);新的意图 过渡的中间卷起以前的铅,而不是叠起第二个铅.
  • 这个运行时间还没有昆特谱; 绳子的五个属性是神谕(test/machine.mjs) (中文(简体) ).

测试

cd packages/machine && bun run test   # node test/machine.mjs, then node test/store.mjs (Solid's client build)
cd packages/machine && bun run typecheck   # src and test/types (the @ts-expect-error cases)

仓库测试在纯节点运行 --conditions=browser --conditions=development索利德的店层不需要DOM, 但节点默认是SSR构建,商店的客户端交易不在此地活. 包裹 test 脚本 带着旗帜.

版本与发布记录

@cssints/machine 共发布 13 个版本,首次发布于 2026/11/02;过去 12 个月发布了 13 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.36.0latest2026/11/121 天前
0.35.12026/11/075 天前
0.35.02026/11/076 天前
0.34.02026/11/076 天前
0.33.02026/11/049 天前
0.32.02026/11/049 天前

关于 @cssints/machine 的常见问题

@cssints/machine 是什么?

用于UI协议的最小、无依赖、无类型安全的状态机器:作为数据的效果, Stale effect 无法完成,用一冲子、可注入的时钟和在没有浏览器的情况下加以证明的绳带来解开

如何安装 @cssints/machine?

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

@cssints/machine 支持 TypeScript 吗?

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

@cssints/machine 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@cssints/machine 需要什么版本的 Node.js?

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

@cssints/machine 可以商用吗?

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

@cssints/machine 的下载量有多少?

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

@cssints/machine 还在维护吗?

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