# @cssints/machine 中文文档

规范地址：https://npmcn.com/package/%40cssints/machine/

版本：0\.36\.0
npm 元数据更新时间：2026-11-11T17:49:47.840Z
中文译文更新时间：2026-11-13T06:32:48.754Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%40cssints/machine
原文对照：https://npmcn.com/package/%40cssints/machine/?lang=original
项目主页：https://cssints.dev/
源码仓库：https://github.com/alexeiaccio/css-in-ts-compiler

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

- 包体积（解压后）：47.5 kB，8 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=22
- 运行依赖：0 个
- peer 依赖：solid-js ^2\.0\.0-rc\.21
- 首次发布：2026-11-02T09:21:23.179Z
- 最新版本发布：2026-11-11T17:49:47.369Z
- 近 30 天下载量：2147（2026-10-11 至 2026-11-09，npm 官方下载统计）
- 已发布版本数：13（近 12 个月 13 个）

## 中文简介

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

## 安装

```sh
npm install @cssints/machine
```

也可以使用：`pnpm add @cssints/machine`、`yarn add @cssints/machine`、`bun add @cssints/machine`

## README

# @ cssints/ 机器

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

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

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

## 动画披露

```ts
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)` 和主机使用实时.

## 绳子

```ts
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的存储层:

```ts
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`) (中文(简体) ).

## 测试

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

用于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 和提交记录判断。

