# iterate 中文文档

规范地址：https://npmcn.com/package/iterate/

版本：0\.4\.1-main\.20261103T213652Z-98a2f20
npm 元数据更新时间：2026-11-03T21:40:26.924Z
中文译文更新时间：2026-11-03T22:48:43.022Z
软件包许可：Apache-2\.0

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

原始 npm 页面：https://www.npmjs.com/package/iterate
原文对照：https://npmcn.com/package/iterate/?lang=original
项目主页：https://github.com/iterate/core#readme
源码仓库：https://github.com/iterate/core

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

- 包体积（解压后）：2.3 MB，124 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=22\.18
- 运行依赖：7 个
- peer 依赖：react ^19\.1\.0
- 首次发布：2012-07-22T17:25:11.247Z
- 最新版本发布：2026-11-03T21:40:26.749Z
- 已发布版本数：72（近 12 个月 68 个）

## 中文简介

用于迭代的SDK和CLI

## 安装

```sh
npm install iterate
```

也可以使用：`pnpm add iterate`、`yarn add iterate`、`bun add iterate`

## README

# 迭代

迭代的SDK`core/os`)：上下文api、流处理器、响应式客户端、React 绑定和OAuth应用会话 `iterate/*`． 包在此导出源代码 工作空间，并在打包时使用声明编译JavaScript。它的 `iterate` bin是命令行 （[src / cli / README.md](https://npmcn.com/package/iterate/src/cli/README.md)）.

## SDK/平台行

SDK保存了用户代码运行或说话的内容，平台是它的第一个用户：核心/操作系统构建 自己的实体 `iterate/sdk`，第一方应用程序的代码只使用 `iterate/*`． 每一个 子路径的 `package.json`的 `exports` 是一个公共模块；没有其他东西是可进口的。

-   当用户代码运行或调用它时，模块就属于这里：一个加载的worker、一个facet、一个 处理器、浏览器或Node客户端，或者它们和平台之间的有线契约。它 当只有平台的Worker运行时，它属于core/os；当有更多的Worker运行时，它属于packages/shared 一个应用程序需要它，而用户代码永远不需要。
-   在core/os之外，没有任何包和应用程序导入core/os。 `import-js/no-restricted-paths` 在 `.oxlintrc.json` 解析下的每个导入 `packages/**` 和 `internal-packages/**` 到一个文件，所以键入 进口，再出口，动态 `import()` 以及之后添加的应用程序 `lint/oxlintrc-platform-line.test.ts` 别针。该平台的测试在 `test/`,这 该规则没有涵盖：它们可以导入core/os，而core/os只保留简单的单元测试。
-   没有私有的核心包背后一个薄 `iterate`： core/os将会导入模块的用户代码 不能，而且SDK的类型无论如何都必须被捆绑或发布。

决定的原因，以及如何工作，代理SDK，凸， Supabase、tRPC、Hono和Wrangler划一条线：决策记录 `docs/2026-09-24-sdk-platform-line.md` 在迭代/迭代# 3018。

## 每个符号一条路径

平台为项目加载的代码（重写规则背后的配置入口点、面、工作器） 从一个路径中导入每个符号，然后加载器将其链接到这个部署自己的构建中：

| 路径 | 它包含什么 |
| --- | --- |
| `iterate/sdk` | 工人主持： `IterateConfigEntrypoint`， `FacetDurableObject`， `StreamProcessorDurableObject`，它们的类型，以及capnweb的构造函数 |
| `iterate/stream/processor` | 处理机表面： `StreamProcessor`， `defineProcessorContract`， `LiveState`，事件和合同类型。它也在Node中运行 |
| `iterate/stream/contract` | `defineProcessorContract` 单是合同类型 `iterate/stream/processor` 再出口。浏览器加载的代码会导入引擎需要的代码 `node:async_hooks` |
| `iterate/email` | 这个 `email` 方面的合同, `email/received` 和 `email/sent` 还有它们折叠成的线 |
| `iterate/agents` | 代理应用程序的两个类，其中一个是配置 `agents.ts` 再出口; `iterate/agents/install` 安装它([其自述](https://npmcn.com/package/iterate/src/agents/README.md)） |
| `zod` | 每个隔离一个副本，所以SDK检查的是模式用户代码生成的那个 |

```js
import { StreamProcessorDurableObject } from "iterate/sdk";
import { StreamProcessor, defineProcessorContract } from "iterate/stream/processor";
import { z } from "zod";

const Contract = defineProcessorContract({
  slug: "hoarder",
  version: "1.0.0",
  description: "keeps every blob it reduces",
  stateSchema: z.object({ blobs: z.array(z.string()).default([]) }),
  consumes: ["blob"],
  emits: [],
});
class Hoarder extends StreamProcessor {
  contract = Contract;
  reduce({ event, state }) {
    return { blobs: [...state.blobs, event.payload.blob] };
  }
}
export class HoarderDurableObject extends StreamProcessorDurableObject {
  processor = new Hoarder();
}
```

## 从加载的代码到达上下文

加载的代码到达它的上下文 `using itx = this.getItx()`：当块结束时，作用域； 通过它发出的每个调用和它等待的每个句柄都被释放。每一个加载 `WorkerEntrypoint` 有 `getItx`， SDK的主机(`IterateConfigEntrypoint`， `FacetDurableObject`， `StreamProcessorDurableObject`）.

```js
import { IterateConfigEntrypoint } from "iterate/sdk";

export default class extends IterateConfigEntrypoint {
  async fetch() {
    using itx = this.getItx();
    const { projectSlug } = await itx.whoami();
    return new Response(`Homepage of ${projectSlug}`);
  }
}
```

将每个作用域与 `using` 在保存调用的最小块中，等待内部的每个调用 它，和手数据，而不是句柄，从它：一个保留作用域，步骤或句柄保留上下文，和任何 Facet持有它，在项目闲置后驻留。需要到达的对象取An 访问器(`() => this.getItx()`)，而不是作用域；调用之后的工作在a下运行 处理器的 `runInBackground` 索赔。棉绒拒绝生毛 `ITX.get()` 和一个 `getItx()` 否 `using` 绑定在此存储库中(`iterate/no-raw-itx-get`）.

配置工作者的 `getItx()` 根的作用域是谁调用它：每个上下文链接到 根继承根的规则，所以脚本在 `/child` 调用 `itx.voice.setupVoiceAgent(…)` 作为根运行worker。在任何方法中 `fetch`， `this.callerPath()` 命名上下文 电话来自(`/child`)，因为平台标记了它，所以worker为调用者创建了什么 不能比呼叫者拥有更多的东西；

```js
async setupVoiceAgent({ streamPath }) {
  using itx = this.getItx();
  await itx.agents.at(this.callerPath()).create(streamPath); // linked to the caller, not to `/`
}
```

## 谁写了一个事件

项目中的任何人都可以将任何事件附加到任何上下文，并且每个事件都说明它来自何处。 月台邮票 `source.origin`，代码或会话编写它的上下文 `source.principal` （成员）及 `source.platform`． 作家自己的价值观被抛弃了。一个 一个作家所拥有的领域 `source.processor`，即处理器为其编写的引擎标签。

```js
// A script in /agents/a:
await itx.cd("/agents/b").append({
  type: "events.iterate.com/agent/context-added",
  payload: { role: "user", content: "hello" },
});
// Stamped { origin: "/agents/a" }. Agent b's model reads "[from /agents/a] hello",
// and the same from `itx.agents.get("/agents/b").message("hello")`.
```

单词 `/` （一个成员的会话，破折号）作为一个人的，没有发送者。 `origin` 是 运行代码的上下文，而不是谁要求它运行的上下文（core/os） `caller.ts` `stampCaller` 说为什么会这样 这是建议)。批写道: `append(...events)` 是一个提交，不管它包含多少事件。

失控反应自行停止：代码对其他代码的输出进行一轮又一轮的反应 两个代理相互应答，一个处理程序附加它所处理的内容，在几个之后停止 以一个错误命名开始反应链，上下文记录一个 `itx/loop-limit` 的事实。阅读仍然有效。

例外是监狱，一个带有裸的上下文 `itx ⇒ null` 行加上它旁边的授予权。一个光秃秃的 监狱是双向封闭的：它的代码没有附加到任何地方，也没有代码附加到它里面。赋予其 `itx.append` 每个上下文都可以附加到它里面；它自己的代码仍然不能解除null。一个 Jail限制的是运行在其中的代码，而不是它通过授权创建的上下文。

## 测试处理器

`iterate/stream/test-support` （Node）是SDK自己的引擎测试使用的线束：

```ts
import { reduceProcessor } from "iterate/stream/test-support";

// test/helpers/presence/processor.test.ts: durable ticks are reduced, ephemeral pokes are not
const state = reduceProcessor(new PresenceProcessor(), [{ type: "tick" }, { type: "poke" }]);
// state.ticks === 1
```

`memoryStream`， `memoryStorage` 和 `settle` 全程驾驶 `ProcessorEngine` 针对一个 内存日志(`src/stream/processor.test.ts` 显示)。

## 多步跑

其工作执行步骤（运行部署、创建项目）的处理器仍然是一个 契约，一个国家，一个 `reduce` 和一个 `processEvent`． 核心/ os `src/deployment/` 工作顺利吗？ 的例子。

1.  **这个要求是事实。** 动词追加 `<x>-requested` 然后回答它的偏移量，也就是 运行的id。fact保存运行所需的每个输入，或者命名facet为其保存的内容 它自己的存储（部署的配置）：下一个化身读取日志和存储， 从来没有电话。
2.  **每一步都有一个事实**，由请求的偏移量和尝试次数来指定 （`<slug>/<fact>:<requestOffset>:<attempt>`)，所以重复的追加操作只着陆一次。键控有效载荷 不保存值为的键 `undefined`：流将重复的追加对象与存储的追加对象进行比较 JSON，它没有这样的键。
3.  **州政府说了跑路的位置：** 请求、尝试、最后一步和偏移量 它的事实。 `snapshot()` 显示它，页面可以实时观看它。
4.  **`processEvent` 来自国家的预付款。** 在 `delivery.caughtUp`没有工作的跑步 这个化身的驱动器只有一个司机 `runInBackground`． 司机的索赔使 Facet，如果Facet死亡。中途发现的跑步失去了它的化身，或者它的司机自己的事实 没有着陆，所以司机立即开始下一次尝试：如果出了什么问题，工作是 再次运行。
5.  **重复每一步都是安全的。** 一次尝试从第一步重新开始，每一步都有效果 接受自己早期的成功。事实记录进步；他们不会跳过那些与死亡相伴的工作 化身(`/tmp`（开放式计划）。
6.  **尝试是以事实计算的，并且是有限制的。** 一个 `attempt-started` 事实摆在每个人面前 尝试。无论结果如何，结束的尝试立即解决了运行：没有重试等待 在处理器内部，调用者再次运行它。只有一次尝试在解决问题之前就结束了 Run（游戏邦注：它的化身已经死亡）将在引擎的5次下再次运行 死亡，这样一场尝试都失败了的赛跑还能复活下来。
7.  **最后一个事实是，** `<x>-settled { requestOffset, status, error? }`，按要求输入。它的 `status` 是四个中的一个： `succeeded`； `refused`，预期结果； `failed`，任何其他错误 （再运行一次）； `unavailable`，平台故障（再次运行）。未打开运行的请求被解决 `refused` 当它被处理时，在 `blockProcessorWhile`：没有状态会记住请求，所以没有 过一会儿就可以解决了。来电者接以下语句 `waitForEvent({ type, payload: { requestOffset }, afterOffset })`。
8.  **测试它作为表：** 事件通过 `reduceProcessor`，通过 `processEvent` 带着假的 对假时钟的影响，和一个重减行。

## 节点连接

`iterate/node` 为Iterate脚本和live公开一个连接所有者 提供者。它使用与CLI相同的协议和清理：

```js
import { connectIterate } from "iterate/node";

using connection = await connectIterate({
  baseUrl: "https://os.iterate.com",
  auth: { type: "bearer", token: process.env.ITERATE_BEARER_TOKEN },
});
using project = await connection.session.projects.get("my-project");
console.log(await project.run("async (itx) => await itx.whoami()"));
```

## 事件类型

平台事件类型为 `events.iterate.com/<namespace>/<event>`：一个命名空间段和一个 事件段，都是小写的kebab-case，没有第三段。

下面的每种类型 `events.iterate.com/` 遵循这些规则，包括测试类型。没有的类型 该前缀属于附加它的人，并且对平台不透明：测试使用类似的类型 `demo/ping` 并且一个项目可以使用它自己的域(`events.garple.com/sales/…`）.

### 名称空间

-   **`itx`** 保存上下文引擎自己的事件：核心契约的一切 （`core/os/src/stream/core-processor.ts`)减少，验证或拒绝，加上记录 流、上下文持久对象和SDK处理器主机自己编写。其中模式 reduce live决定它，而不是哪个上下文持有事件：fetch路由和顶点 入口目标是核心状态，所以它们是 `itx` 即使只读取项目根目录的副本。 域处理器可以使用一个 `itx` 事件（代理使用） `itx/run-*`、项目 处理器 `itx/ingress-configured`）; 它在它的 `processorDeps` 而不是 定义事件本身。核心的检查点是 `core`：它是一个存储键，而不是类型 前缀。
-   **域命名空间** 事件日志所属的上下文类型的单数名称 To，当有一个时，它是定义合同的段格： `account`， `organization`， `project`， `repo`， `workspace`， `sandbox`， `deployment`， `secret`， `agent`， `voice-agent`． 一个事实 交叉发布到另一个日志保留自己的命名空间： `repo/created` 在 `/` 仍然是回购事实。
-   **一个集成** 例如，使用自己的名称作为名称空间 `chrome`， `slack`， `google`， `github`。
-   **`test`** 保存仅测试追加的类型。产品代码永远不匹配 `test/*` 类型。一个 测试契约可以保留自己的段(`counter`)，但它的事件却悄无声息 `test/`． 测试必须 不要为不存在的类型借用生产名称空间。

### 事件名称

-   **事实是过去时**： `<object>-<verb-ed>`，或裸露的 `<verb-ed>` 当对象是 命名空间本身的主题(`itx/created` 是上下文， `agent/paused` 是代理)。的对象 出现在前面并且是单数。
-   **把单词拼出来。** 不允许使用缩略词(`spk`）; 一个真正的词是(`mic`)， an也是如此 API的首字母缩写是(`llm`， `rpc`， `itx`）.
-   **提问和回答。** `<x>-requested` 请求，其偏移量标识请求。答案 取三种形状之一：
    -   `<x>-settled` 是请求程序读取结果时的一个终端事实。它的名字 `requestOffset` 并携带结果：成功、失败或取消、状态或错误。 例子: `itx/run-*`， `agent/llm-request-*`， `project/hostname-add-*`， `deployment/run-*`。
    -   `<verb-ed>` 或 `<verb>-failed` 当成功是其他日志等待的事实时使用，例如 证书: `create-requested` → `created` 或 `create-failed`， `delete-requested` → `deleted`， `hostname-remove-requested` → `hostname-removed`． 重试失败，而不是失败 报告没有 `-failed` 的事实。
    -   这个答案本身就是一个事实，它的答案就是提问者的答案：助手的答案 `agent/context-added` 带着 `llmRequestOffset` 的 `llm-request-requested` 它的答案。
-   **一种变化对应一组动词：**
    -   `added` / `removed` 对于集合中的成员： `organization/member-added`， `organization/project-added`主机名。
    -   `created` / `deleted` 对于具有生命周期的实体：项目、仓库、工作区、沙盒、 部署,代理。
    -   `set` / `deleted` 对于键值： `secret/*`。
    -   `set` / `cancelled` 对于时间表： `itx/schedule-*`． 每次出现都是 `fired` 或 `failed`。
    -   `-configured` 用于设置一行或清除一行的一个事实 `null` （`itx/subscription-configured`， `itx/rewrite-rule-configured`， `itx/fetch-route-configured`）， 设置一个单例(`itx/ingress-configured`)，或者合并部分配置 （`agent/configured`：省略的键保留其值)。
-   **平台自己做的事情** 是关于物体的简单事实： `itx/schedule-fired`， `itx/schedule-failed`， `itx/subscription-delivery-halted`。
-   **短暂的事件。** 记录发生的事情的短暂事件与其他事件一样被命名 事实: `itx/rpc-stub-attached`， `itx/live-state-changed`， `chrome/navigated`． 可能有三种 单数名词：直播流的一个序列片段是a `<stream>-frame` （`voice-agent/mic-frame`， `agent/llm-response-frame`)，心跳(`voice-agent/keepalive`), 诊断记录(`itx/alarm-trace`）. 持久事件从来不是名词。
-   **家庭和前缀。** 代码通过前缀匹配某些家族： `…/itx/run-`， `…/itx/subscription-`， `…/itx/schedule-`， `…/project/hostname-`． 在命名新类型之前，请进行检查 它加入这些家庭不是偶然的。从来没有匹配 `…/itx/` 作为一个整体：它不是 权限边界，它捕获实时状态delta、存根存在和子节点 公告。
-   **代码遵循类型。** 从类型构建的常量、模式、测试fixture或等幂键 它的名字(`itx/child-created:<path>`）. 更广泛的概念、模块和工人日志 事件名称保持他们的：流，计划追加， `core`， `scheduled-append.completed`。
-   **重命名。** 重新命名必须符合这些规则之一，而不是口味。类之外存储类型 平台的持久对象（设备固件、发布的SDK、项目的配置repo）； 仅在迁移该存储的更改中重命名它。

| 名称空间 | 中定义的 |
| --- | --- |
| `itx` | `core/os/src/stream/core-processor.ts` （及其叶事件目录）， `stream.ts`， `scheduled-appends.ts`， `subscription-delivery.ts`， `core/os/src/context/built-ins.ts`， `core/os/src/fetch-routes.ts`， `core/os/src/iterate-context-durable-object.ts`， `core/lib/src/stream/{run,processor}.ts` |
| `account`， `organization`， `project`， `repo`， `workspace`， `sandbox`， `deployment`， `secret` | `core/os/src/<name>/contract.ts` (repo，工作区，沙盒和部署也使用 `project/entity-lifecycle.ts`） |
| `agent` | `core/lib/src/agents/contract.ts` |
| `voice-agent` | `packages/voice/src/voice-agent.ts`， `packages/voice/src/events.ts` |
| `chrome` | `packages/browser-extension/public/panel.js` |
| `email` | `core/lib/src/email.ts` |
| `integration` | `core/lib/src/integrations.ts` (项目的包写入的注册表；它的文件夹是 `core/os/src/integrations/registry.ts`） |
| `test` | 只测试 |

`note/added` 只是Agents composer中的一个例子；没有合同定义 `note`。

## 常见问题

### iterate 是什么？

用于迭代的SDK和CLI

### 如何安装 iterate？

在项目目录运行 npm install iterate，或使用 pnpm add / yarn add / bun add。它还提供命令行工具 iterate，可以用 npx iterate 直接运行。

### iterate 支持 TypeScript 吗？

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

### iterate 支持 ESM 还是 CommonJS？

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

### iterate 需要什么版本的 Node\.js？

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

### iterate 可以商用吗？

iterate 使用 Apache-2\.0 许可。宽松许可：允许商业使用、修改和再分发，并附带明确的专利授权；分发时需保留许可与 NOTICE 文件，修改过的文件要注明改动。以上为概括，不构成法律意见，请以许可原文为准。

### iterate 还在维护吗？

最新版本 0\.4\.1-main\.20261103T213652Z-98a2f20 发布于 2026/11/04（1 天前）；至今共发布 72 个版本，其中过去 12 个月发布了 68 个；首次发布于 2012/07/23。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

