# @ai-matrx/realtime 中文文档

规范地址：https://npmcn.com/package/%40ai-matrx/realtime/

版本：0\.10\.9
npm 元数据更新时间：2026-10-15T19:32:21.825Z
中文译文更新时间：2026-11-05T19:16:12.688Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%40ai-matrx/realtime
原文对照：https://npmcn.com/package/%40ai-matrx/realtime/?lang=original
项目主页：https://github.com/AI-Matrix-Engine/aidream/tree/main/apps/shared/realtime#readme
源码仓库：https://github.com/AI-Matrix-Engine/aidream

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

- 包体积（解压后）：2.4 MB，38 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=20
- 运行依赖：1 个
- peer 依赖：yjs \>=13\.6\.0，react \>=18\.0\.0，y-protocols \>=1\.0\.5，react-native \>=0\.76\.0
- 首次发布：2026-08-31T07:14:43.600Z
- 最新版本发布：2026-10-15T19:32:21.611Z
- 近 30 天下载量：42278（2026-10-05 至 2026-11-03，npm 官方下载统计）
- 已发布版本数：43（近 12 个月 43 个）

## 中文简介

Matrx 客户端的 ONE Supabase 实时层: 频道命名注册、 强制频道生命周期、 默认情况下的回声压制、 以 idepotent dedup 发送后最少的一次发送、 解接命令的处理器队列、 重新连接到 shitted backoff和 a

## 安装

```sh
npm install @ai-matrx/realtime
```

也可以使用：`pnpm add @ai-matrx/realtime`、`yarn add @ai-matrx/realtime`、`bun add @ai-matrx/realtime`

## README

# `@ai-matrx/realtime`

**Matrx客户端的 ONE Supabase 实时层.** 手写 `.channel(` 在一个 消费应用是一个代码审查缺陷.

```bash
pnpm add @ai-matrx/realtime
```

* * *

## 此软件包为何存在

> "我们整个系统都为此而奋斗" 我们一直挣扎着想建立它 给留言,尝试设置笔记。 直到今天,经过数百小时 ——亚鲁曼,2026-08-29

实时不难,因为签名难。 下结为四行. 很难 因为有8个东西是无形的,直到它们受伤为止 每一个东西都是在这里学的 昂贵的方式——一个被冻结的浏览器,一个失去编辑的注释,一个显示"Ada"的聊天 打了一个小时 这个软件包写下OnCE的八件事,作为代码 让每个消费者都使用.

下面列举的是理论。 它取代了以前生活于 垫口前端 `supabase-realtime` 技能;技能现在指向这里.

* * *

## 学说

### 1\. 压制你自己的回声——修正-发音

**Supabase给你发了自己的信.** Postgres 更改没有“ 无法自我” 选项 。 这个 你的回声 `UPDATE` 来了 **50至500毫秒后** 您的 REST 响应已经返回了新的 排队 降落时,任何"在飞行中拯救"的旗帜已经清除. **仅使用国旗的压制 总是想念回声.**

未压制回放的回放能做什么: 保存 N 的回放在用户输入 N+1 时到达 ~ 脏-局部服务器 - 假冲突 - 冲突 UI 做 O( n2) diff work each compare- 下一个拯救它 —— 它的回声重新武装它。 自我维持主行道饱和.

Over-suppression所做的(幻相冲突,2026-09-13):每个平台表的 `version` 在 Every 更新上移动——桌面同步印章 `file_path`,一个食用的工作写作 元数据。 同样的演员,相同的内容, 我们的写待: 旧分类账称之为回声, 客户端保留了旧的号码, 而它的下个比较和扫描丢失了 用于文本等于客户端自身基础的行. **客户已经压制了一个事件 上面有它需要的号码.**

包的书写分类账 分类每个有效载荷, **第一修订版** (这行的) `version`,从 `revisionField`默认值 `version`:

-   R1. 比我们持有的旧版本 **暂停**。 。 。 .
-   R2. 修订我们未解决的书写将产生匹配的内容 **拥有- echo** (比REST反应的回声,以数字识别).
-   R3. 与匹配内容相匹配的已经确定的修订 **拥有- echo**; 差异 ; 偏僻.
-   R4型导弹. **任何更新的 总是遥远的** ——同一演员,内容相同,待写与否. 交付是无害的;吞食是下一场幽灵冲突.

只有当没有修订时,时间戳原则才适用:

1.  严格年龄 `updated_at` 而不是我们所持有的 **暂停**,丢入(合并) _倒退_ `updated_at`,它失败了下一个保存的乐观锁入了粘滞的虚假冲突.
2.  内容我们已知已经写出来但尚未解决 **拥有- echo**。 。 。 .
3.  平等 `updated_at` - 只有内容指纹也匹配时,才能自选;a 同一兆位合作者 写着仍然土地.
4.  无法解开的时间戳 – 交付. **屈从于送货,从不默不作声地下降.**

使用自己的写作号码注册: `ledger.begin({ …, revision: expectedVersion + 1 })`, (中文(简体) ), `ledger.settle(ticket, { revision: response.version })`, (中文(简体) ), `ledger.observe({ …, revision })`。 。 。 . 和它配对 `@ai-matrx/data`是因为 `guardedUpdate({ rebase })`{\\fn黑体\\fs22\\bord1\\shad0\\3ahbe\\4ah00\\fscx67\\fscy66\\2chffffff\\3ch808080}所以客户还是有点颠簸 已丢失( 已睡标签) 将按当前数字重试, 而不是显示为冲突 .

广播回声由信封处理: 每封信封都带有客户端的会话 ID 和 接收器会自己掉下来.

### 2\. 默认执行回声抑制;选择退出是抑制路径

`echoSuppression: false` 对于真正需要回溯自身事件的稀有消费者来说 在电线上。 这绝不是默认的,也绝不是其他事情的补救.

### 3\. 至少一进一出

重新订阅、重新加入 以及一个播放一行节目的消费者 同时INSERT也提供 同一逻辑事件两次。 供应a `eventKey` (或接受默认)和包拆分.

### 4\. 手提箱从不运行在套接字路径上

一个Supabase频道在套接字的回调路径上呼叫您的处理器. 发送的处理器 至 Redux , diffs 内容, 或使 RPC 背向执行, 当一个 暴风雨来了 标签也冻结了 每个历史 Matrx 浏览器锁定是一个变体 此; 以500个已排队事件唤醒的背景标签是经典触发 .

软件包在套接字和您的处理器之间设置了有边框的、命令的和出让的队列 . 每个频道都保留顺序(在下次事件开始前等待一个自动处理器) 每几毫秒向事件循环排出量,深度被封顶——溢出 **流出最古老的活儿,说得没错,并引发和解**,这是正确的恢复 因为"我们跟不上".

### 5\. 重联是指READ. 实时没有重播 .

插座倒下时发生的每起事件 都会永远消失 没有连接 重新读取会留下一个永久错误的屏幕,看起来完全健康. 所以每个频道 声明 `onBackfill`,而包 调用它 **每个** 恢复路径: 重新连接, 标签 醒来,网络恢复,队列排出。 无频道 `onBackfill` 得到一个大声的警告.

后退是焦躁不安的,有一个 **稳定重设**: 仅在 频道有 _举行_ 30多岁,永远不要 `SUBSCRIBED`。在订阅器上重置会扇动 1s层的频道循环将永远进行,每个周期都会发射一个完整的接取.

### 6\. Tab睡眠和app背景是正常的失败,而不是异域的失败

一个背景标签被拖住, 直到套接字闲置; 一个被悬停的电话又回来了 还有一个WebSocket _看着_ 并且永远不会再出现。 两张地图都进入 同样的醒悟之路: 和解,并重新加入任何不明显健康的东西。 网络使用 `visibilitychange`; 反应原生用途 `AppState` (单位:千美元)`@ai-matrx/realtime/native`) (中文(简体) ).

### 7\. 一个地名渠道

苏帕克的 `client.channel(topic)` **按专题分列的去向**: 两个都选择的特性 `"messages"` 默默地分享一道并失去对方的束缚. 宣布一个命名空间 相反的,对同名的另一种不同的声明会抛出.

另外,反应19双进取效应和 `removeChannel` 是aync,所以可以重载 交出了上一个挂载的仍然连接的通道 `.on(...)` 掷出 _"不能添加 posgres changes 订阅后的回调( )_。 。 。 .

**——TOPIC-SEMANTICS SPLIT——两种运输方式的"主题"并非同一种意思,而且 软件包对他们不同.**

-   **Postgres Changes:该话题只是客户端的连接密钥.** 服务器推着 已声明过滤器, 无论频道名称如何 。 所以,每一个连接尝试得到一个 **独一无二 实例主题** (单位:千美元)`mx:notes:u1#7`)),这使得重载碰撞无法免费上方.
-   **广播和现场:主题是会议室.** 是服务器粉丝的路由键 发送消息。 一个独特的实例主题并不花费什么——它花费 _所有的东西_数字 : 两个同时声明的浏览器 `mx:room:1` 土地在 `#1` 财务报告和审定财务报表 `#2` 而永不相见. (以0.1.x为单位发运,由 `@ai-matrx/messaging`; 固定在0.2.0. (中文(简体) )

因此,一个频道 携带广播或存在,它的 **在线上逐字宣布主题**,以及 管理者保留 **每个已宣布的题目,一个基本通道,重新计算**: 秒数 `open()` 联 合 国 主题将其绑定在同一个频道上,频道只有在 最后一个持有人关闭。 重载碰撞是在那里通过推迟真正的拆卸来处理的 转身,所以React的清理 时再运行 重接 而不是赛跑一个Aync `removeChannel`。 。 。 .

在你打开两个持有者关于一个话题之前,值得知道的后果:

-   他们共享一个频道的配置。 第一个 `echoSuppression` 和存在键胜出,和 a 分歧很大 `channel.room.config-mismatch` 诊断——并不是一个默默的惊喜.
-   **他们在当地互相听到.** 同为 Tab 的持有者共享一个客户端 ID 并打开频道 `broadcast.self:false`所以电线从不回响一个持枪者的相框到它的兄弟姐妹身上 经理 手数 `send()` 直接发送给该主题的其他开放持有者(相同的信封,相同) dadup; 永不返回发送方; 不包括生电路通道). 跨塔布交付不变.
-   **其中一个就是幕后主使.** `handle.isLocalLeader()` 对 仅开放时间最长的持有人,以及 `onLeaderChange(isLeader)` 领导力移动时点火,因为 头儿关门了 在领导人身上进行一次性工作(自选、CRDT东道主选举)——两次 持有者每个结论 "我是孤独的,我是东道主" 是两个自动的,最后的snapshot-wins bug.
-   他们共享一个存在条目(每个频道一个密钥),所以一个话题需要完全一个存在 出版社。 只读取名册的表面——打字员标签、在线点名单——通过 `presence: { publish: false }` (或 `publish: false` 改为 `useTyping`它看到每个人,停下来 争取进入。 两个出版商很吵 `channel.room.presence.multiple-publishers` 警告,不是一个谜.
-   每个客户端仍然使用回声抑制,所以一个持有者使用 **没有** 看它的兄弟们自己的 `send()` ——这是回声压制的要点,不是房间故障. 两个持有者所看到的 每个 _远程_ 同行信息 .
-   将 Postgres 带入已合并房间的持单人更改绑定符迫使重建(那些 装订在JOIN有效载荷上,以后无法添加). 现通知如下: `channel.room.rebuild`,每个持有者通过回填门调节. 打开混合 {\\fn黑体\\fs22\\bord1\\shad0\\3ahbe\\4ah00\\fscx67\\fscy66\\2chffffff\\3ch808080}频道的持有者一起在山上 {\\fn黑体\\fs22\\bord1\\shad0\\3ahbe\\4ah00\\fscx67\\fscy66\\2chffffff\\3ch808080}绝对不会发生.

### 8\. 选择运输

-   **邮资变化** ——RLS必须出闸送出(注,文件,任务)的可持久行. 这个 默认实体同步 .
-   **广播** - 无授权微分的电平或高频数据(CRDT更新, 打字、信号. **永远不要手动播放一行您同时INSERT** ——每个订阅者 得到它两次.
-   **出席情况** - 谁来了 唯以法相为相.
-   **每个功能一个频道.** Postgres 更改、广播和存在可共享一个;不 运行3.
-   如果桌子上有的话 `updated_by` (平台) `_stamp_actor` 触发器),每个更新已 识别它的编辑器——你可能根本不需要在场.

### 9\. 外国同行拥有其电线——用 `wire: {mode:"raw"}`

每一次播放这个软件包都用 Matrx 信封包 (单位:千美元)`{v, cid, eid, ts, data}`),而这个信封使得回声抑制和去除成为可能 一点也不 有些频道无法选择: 另一端是 a **单独发布的程序** 它读取了它定义的有效载荷形状, 并重塑它下面的电线 只会阻止对等 在两端都听到我们的声音 产生这种模式的案例是: Chrome 扩展名 `matrx-extension-bridge:<userId>` 频道 - 已部署的扩展解析 a 赤线 `BridgeEnvelope` (单位:千美元)`{direction, action, requestId, payload, timestamp}`)有"佐德计划".

```ts
const bridge = defineChannelNamespace({
  namespace: "extension-bridge",
  parts: ["userId"],
  description: "matrx-extend ↔ matrx-frontend RPC bridge (foreign wire).",
  foreignTopic: "matrx-extension-bridge", // the peer's topic root, used verbatim
});

manager.open({
  topic: bridge.topic({ userId }),
  wire: { mode: "raw", acceptEchoFromSelf: true },
  broadcast: [{ event: "FRONTEND_RPC", onMessage: ({ data }) => route(data) }],
  eventKey: (_source, payload) => `${payload.direction}:${payload.requestId}`,
  onBackfill: () => {},
});
```

原始模式在两个方向上都意味着两件事: **把你的有效载荷放在电线上 逐字记录** (与手卷相同的字节) `channel.send`),以及 **从不读取 信封** 甚至连装满外壳的载荷 都不行. `BroadcastMessage.enveloped` 总是 `false` 在这里.

**这是一个命名的降级,它从来不沉默.** 信封上有两个保护装置:

-   **回声抑制** 使用过的 `cid`生线没有 供应 `wire.isOwnMessage` 当 等同位素形状识别它的发送者; 否则设置 `wire.acceptEchoFromSelf: true` 状态 服务器的代码 `broadcast.self:false` 这是唯一的保护。 供应既不合法 并产生 `channel.raw.echo-unguarded` (警告);明确选择退出者仍宣布自己为 `channel.raw.echo-accepted` (info),因为诊断流必须显示运行的频道 无人守护.
-   **编剧** 键入已关闭 `eid`没有它,每一次到达都是个明显的关键 供应 `eventKey` - 这个 接受原始有效载荷——或 `channel.raw.dedup-unguarded` (标.

**`foreignTopic` 是同一个想法的主题的一半.** 名称空间仍然被宣布 已检查相撞;只有 `mx:` 根被对等者所取代。 将一个外国主题重命名为 `mx:…` 不迁移任何东西——它把客户端放在一个房间里,而对等者则保持 总是在听.

原始模式为 **自愿过渡**它的存在是为了让外国铁丝网的两端可以骑着它 今天的软件包。 当同龄人发回信封时,更改将删除 `wire` 从 spec ——协调两版,并记录同行频道合同中的顺序.

### 静态零事件核对表

编译但一无所获的订阅有:

1.  这表不在 `supabase_realtime` **出版物**。 。 。 .
2.  RLS 过滤事件( 实时是 RLS 授权的 ) , 这是一种功能, 但授予门 (b) 交付).
3.  `REPLICA IDENTITY FULL` 缺少, 您需要旧行数据 或 RLS- on- DELETE .
4.  表格尚未在 PostgREST/实时缓存中(`notify pgrst, 'reload schema'`) (中文(简体) ).

* * *

## 用这个

### 反应

```tsx
import { RealtimeProvider, useChannel } from "@ai-matrx/realtime/react";
import { defineChannelNamespace } from "@ai-matrx/realtime";

// Once, beside the feature. Declaring twice with a different shape throws.
export const notesChannel = defineChannelNamespace({
  namespace: "notes",
  parts: ["userId"],
  description: "Note rows for one user",
});

function App({ supabase, userId }) {
  return (
    <RealtimeProvider client={supabase} actorId={userId}>
      <Notes userId={userId} />
    </RealtimeProvider>
  );
}

function Notes({ userId }) {
  const { status } = useChannel({
    topic: notesChannel.topic({ userId }),
    postgresChanges: [
      {
        event: "*",
        schema: "workbench",
        table: "notes",
        rowId: (row) => String(row.id),
        fingerprint: (row) => String(row.content),
        onChange: ({ row }) => applyNote(row),
      },
    ],
    // Realtime has no replay. This is how the gap gets closed.
    onBackfill: () => refetchNotes(userId),
  });

  return <StatusDot status={status} />;
}
```

掌上电脑可能是新关闭的每一个渲染器——订阅在频道的键上 _形状_,而不是处理器的身份, 最新的处理器总是运行的.

### 每个应用程序一个供应商,一个兄弟包如何搭载它

`<RealtimeProvider>` 准确的构建一个经理, 经理拥有写分类账 让乐观写作的回声可以识别 树上的第二个供货商是 第二分类账和第二套频道, 所以一个经理自己写的字看起来REMOTE到 其他费用。 Apps挂载一个.

自己做实时工作的包(PACAGE)`@ai-matrx/messaging`, (中文(简体) ), `@ai-matrx/meet`必须 因此,当主机拥有一个时,骑乘主机的经理,只用一个应用程序上载它自己的 无线 :

```tsx
const hostProvidesRealtime = useIsRealtimeProviderMounted();
if (hostProvidesRealtime) return <Runtime {...props} />;
return <RealtimeProvider client={client}><Runtime {...props} /></RealtimeProvider>;
```

询问 `useIsRealtimeProviderMounted()`永远 `useRealtimeManager() !== null` - 经理是 当挂载的提供者等待它的 Supabase 客户端时, 和一个猜测到的软件包, 也是无效的 从它上起一个供货商 然后撕裂它, 和它下面的每一个通道 即时主持人的客户端到来.

### Redux 中间软件、 tunks 和其他非反应所有者

规则 第4条 偏好使用 Redux 中间软件作为特性的订阅所有者——组件效果 重新订阅身份churn和乘以跨挂载的频道。 中间软件无法调用 钩子,所以提供者 **发表** 它的经理和非反应所有者阅读它。 这是一个 指向供应商所建的 ONE 管理器; 在中间软件中构建自己的是第二个 写分类账,你每写一个乐观的字 就会归类为 `remote` 费用a 补补.

```ts
import { subscribeToRealtimeManager } from "@ai-matrx/realtime";

// Opens on arrival, closes on departure, RE-OPENS on the new manager when the
// provider rebuilds one (the signed-in user changed). Returns a stop function.
const stop = subscribeToRealtimeManager(() => ({
  topic: notesChannel.topic({ userId: currentUserId() }),
  postgresChanges: [ /* … */ ],
  onBackfill: () => store.dispatch(fetchNotes()),
}));
```

`currentRealtimeManager()` 财务报告和审定财务报表 `onRealtimeManagerChange(listener)` 是下面的原始人. 阅读 `currentRealtimeManager()` **一次** 模块负载几乎总是错误:是 `null` 在裁决之前,管理者将被重建 当签名用户更改时。 偏爱 `subscribeToRealtimeManager`。 。 。 .

光谱是 **工厂** 因此所有者会抓取当前用户 id / `dispatch` 开放时间 而不是在舱载.

### 私人频道(数据库广播)

授权反对的主题 `realtime.messages` RLS - 如何实现 `realtime.broadcast_changes()` 从 Postgres 触发器只向有资格的用户发送行—— 声明 `private`数字 :

```ts
manager.open({
  topic: schedulerChannel.topic({ userId }),
  private: true,
  broadcast: [{ event: "UPDATE", onMessage: ({ data }) => apply(data) }],
  onBackfill: () => refetchSchedules(),
});
```

软件包创建频道 `config.private: true` **财务报告和审定财务报表** 授权套接字 (单位:千美元)`client.realtime.setAuth()`签署前。 第二步不是可选的,而是 整个地表最安静的失败:没有它,就拒绝加入,就是频道 永远得不到任何东西, 它报告自己完全健康。 客户端不能 授权获得 `channel.private.unsupported`; 不附加的符号得到 `channel.private.auth-failed`。 。 。 .

### 自动保存共存

在共享分类账上注册写入 **在此之前** 乐观的更新,和回声是 一个真正的合作者写着:

```ts
const manager = useRealtimeManager();
const ticket = manager.ledger.begin({
  table: "workbench.notes",
  id: note.id,
  fingerprint: draft.content,
});
try {
  const saved = await saveNote(draft);
  manager.ledger.settle(ticket, { updatedAt: saved.updated_at, fingerprint: saved.content });
} catch (error) {
  manager.ledger.abandon(ticket);
  throw error;
}
```

`ledger.classify(...)` 返回时 `own-echo | remote | stale` 加号 `localWritePending`,所以一个 乐观的写作,它的回声,和真正的远程写作都是可以区分的.

### 出席和打字

```tsx
const { others } = usePresence({
  topic: roomChannel.topic({ roomId }),
  presence: { state: { userId, name } },
});

const { typists, onKeystroke, stopTyping } = useTyping({
  topic: chatChannel.topic({ conversationId }),
  identity: { userId, name },
});
```

坠机客户端不能离开幽灵参与者(心跳+本地时长过期) "X在打字..."不能坚持(打字是续租,从来不是等待停站的锁) 可能永远到不了的信息.

### 反应原生/博览会

```tsx
import { NativeRealtimeProvider, useChannel } from "@ai-matrx/realtime/native";

<NativeRealtimeProvider client={supabase} actorId={userId}>
  {children}
</NativeRealtimeProvider>;
```

相同的钩子,与 `AppState` 已接通的接合:背景 = 前景调节 和复相会. `react-native` 是一个可选的对等点;网络条目从不加载.

### 诊断

```ts
import { realtimeDiagnostics } from "@ai-matrx/realtime";
// or: const snapshot = useRealtimeDiagnostics();
```

直播频道,订阅状态,事件/分钟,以及从未有过的数字: `suppressedEcho`, (中文(简体) ), `deduped`, (中文(简体) ), `stale`, (中文(简体) ), `queueDepth`, (中文(简体) ), `queueDropped`, (中文(简体) ), `handlerErrors`, (中文(简体) ), `backfills`。实时错误的意思是 _观察_,没有猜测.

* * *

## 入境点

| 条目 | 包含 | `"use client"` |
| --- | --- | --- |
| `@ai-matrx/realtime` | 无框架核心:管理器,写出分类账,话题,存在/打字运行时间,队列,后退,脱发,诊断 | 否(不受RSC、Redux中间软件、工人、节点的保险) |
| `@ai-matrx/realtime/react` | `RealtimeProvider`, (中文(简体) ), `useChannel`, (中文(简体) ), `usePresence`, (中文(简体) ), `useTyping`, (中文(简体) ), `useRealtimeDiagnostics`, (中文(简体) ), `useRealtimeHealth` - 加上整个核心 | 对 |
| `@ai-matrx/realtime/native` | `NativeRealtimeProvider`, (中文(简体) ), `createReactNativeEnvironment` 加上整个反应绑定 | 对 |

零运行时间依赖关系. `react` 财务报告和审定财务报表 `react-native` 是可选的同龄人。 包裹从来没有 进口 `@supabase/supabase-js`: 客户端在结构上被接受, 以及编译时间证明 人民群众群众 `src/core/supabase-shape.test.ts`。 。 。 .

* * *

## 移动手卷频道

1.  声明特性的命名空间;删除手写的主题字符串.
2.  替换 `.channel(...)` 块为 `useChannel` (或 `manager.open` 在中间软件.
3.  将读取的快取移动到 `onBackfill` 如果模块没有,这就是你的错误 修复.
4.  删除模块本身的回声/dedup/后退代码. 将第二个副本保存在包边 是命名失败,而不是安全选项.
5.  `uniqueChannelTopic` 住在这里. `@ai-matrx/data/db` 其再出口(数据为0.6.3) 现有呼叫站点继续工作,但移徙功能完全停止呼叫:a 命名空格名称 频道和管理者按主题语义决定有线主题 第7条之分. **一个手卷广播或现场频道正在呼叫 `uniqueChannelTopic` 自己却在自己的房间里分道扬镳** - 这是你正在修理的虫子,不是 行为要保护.

## 许可证

麻省理工学院

## 常见问题

### @ai-matrx/realtime 是什么？

Matrx 客户端的 ONE Supabase 实时层: 频道命名注册、 强制频道生命周期、 默认情况下的回声压制、 以 idepotent dedup 发送后最少的一次发送、 解接命令的处理器队列、 重新连接到 shitted backoff和 a

### 如何安装 @ai-matrx/realtime？

在项目目录运行 npm install @ai-matrx/realtime，或使用 pnpm add / yarn add / bun add。

### @ai-matrx/realtime 支持 TypeScript 吗？

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

### @ai-matrx/realtime 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @ai-matrx/realtime 需要什么版本的 Node\.js？

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

### @ai-matrx/realtime 可以商用吗？

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

### @ai-matrx/realtime 的下载量有多少？

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

### @ai-matrx/realtime 还在维护吗？

最新版本 0\.10\.9 发布于 2026/10/16（21 天前）；至今共发布 43 个版本，其中过去 12 个月发布了 43 个；首次发布于 2026/08/31。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

