# @alxia/events 中文文档

规范地址：https://npmcn.com/package/%40alxia/events/

版本：0\.2\.0
npm 元数据更新时间：2026-11-05T17:49:17.001Z
中文译文更新时间：2026-11-08T10:00:22.198Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%40alxia/events
原文对照：https://npmcn.com/package/%40alxia/events/?lang=original
源码仓库：https://github.com/softistx/alxia

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

- 包体积（解压后）：118 kB，35 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：0 个
- peer 依赖：zod ^4\.6\.5，mongodb ^7\.7\.0，typescript ^6\.0\.3 \|\| ^7\.0\.0，@alxia/modules ^0\.4\.0，@alxia/tenancy ^0\.6\.0，@softistx/mongo ^0\.27\.0，@softistx/redis ^0\.14\.0
- 首次发布：2026-10-31T16:35:22.327Z
- 最新版本发布：2026-11-05T17:49:16.845Z
- 近 30 天下载量：1810（2026-10-06 至 2026-11-04，npm 官方下载统计）
- 已发布版本数：11（近 12 个月 11 个）

## 中文简介

用于在 @softistx/mongo 和 @softistx/redis 上应用的事件总线: 将事件写入交易输出框, 并更改域名, 转发到队列, 至少发送一次, 通过收件箱应用一次

## 安装

```sh
npm install @alxia/events
```

也可以使用：`pnpm add @alxia/events`、`yarn add @alxia/events`、`bun add @alxia/events`

## README

# @alxia/活动

用于应用程序的事件总线 `@softistx/mongo` 财务报告和审定财务报表 `@softistx/redis`,基于 交易发件箱。 模块在同一 MongoDB 交易中写入事件 作为导致它的变化, 所以两个站在一起或跌倒在一起。 一个接力手 每个事件通过队列订阅的模块; 每个订阅者 施用一次,无论交付多次.

```sh
bun add @alxia/events @alxia/modules @alxia/tenancy @softistx/mongo @softistx/redis mongodb zod
bun add -d typescript
```

`@softistx/mongo` 财务报告和审定财务报表 `@softistx/redis` 是私人的,在 GitHub 包。 绘制范围 项目的 `bunfig.toml` 和导出 `GITHUB_TOKEN`,与 `read:packages`数字 :

```toml
[install.scopes]
"@softistx" = { url = "https://npm.pkg.github.com/", token = "$GITHUB_TOKEN" }
```

蒙戈DB必须运行为 **复制集** (交易需要一个). 见 [排除出问题](https://github.com/softistx/alxia/blob/develop/packages/events/docs/troubleshooting.md#transaction-numbers-are-only-allowed-on-a-replica-set-member-or-mongos)。 。 。 .

## 30秒内

```ts
import { collectionsOf, defineModule } from '@alxia/modules';
import {
    createEvents,
    eventsModule,
    type EventEnvelope,
    type SubscriberContext,
} from '@alxia/events';
import { single } from '@alxia/tenancy';
import { connectMongo, defineMongo, openMongo } from '@softistx/mongo';

// `Tenant` and `Core` are your tenant and core collection wirings
// (see the guide, "Write a subscriber").

// 1. Declare what a module emits and what it subscribes to.
export const shop = defineModule({
    name: 'shop',
    emits: ['shop.order.placed'],
});

export const billing = defineModule({
    name: 'billing',
    subscribers: {
        'shop.order.placed': async (
            event: EventEnvelope,
            context: SubscriberContext<'billing', Tenant, Core>,
        ) => {
            // `context.mongo` is in the transaction that records the inbox row,
            // and narrowed to billing's collections and those of its dependsOn.
            const { mongo } = context;
            await mongo.db.invoices.create({ orderId: event.aggregate.id });
        },
    },
});

// 2. Put the kernel module in the registry you give the tenant store,
//    then build the bus from that store.
const modules = [eventsModule, shop, billing];
const { client } = await connectMongo(process.env.MONGO_URI!);
const mongo = await openMongo(
    defineMongo({ client, database: 'app', collections: collectionsOf(modules) }),
);
const tenancy = single({
    mongo,
    modules,
    tenant: { id: 'main', slug: 'main', name: 'Main' },
}); // or perOrganization(...), see @alxia/tenancy
const events = createEvents({ store: tenancy });
// `request` and `viewer` are the HTTP request and its signed-in account
const scope = await tenancy.scope(request, viewer);

// 3. Emit inside the transaction of the change.
await scope.mongo.transaction(async (tx) => {
    const order = await tx.db.orders.create({ label: 'Ada' });
    await events.emit(
        { tenant: scope.tenant, mongo: tx },
        {
            type: 'shop.order.placed',
            aggregate: { type: 'order', id: order.id },
            payload: { label: 'Ada' },
        },
    );
});
```

## 交付

在生产中,一个继电器和工人运行在应用程序旁边. 每个模块 订阅者得到一个队列, `events.<module>`数字 :

```ts
import { bindQueue, connectRedis } from '@softistx/redis';
import { createEvents, eventsQueue } from '@alxia/events';

const redis = await connectRedis(process.env.REDIS_URL!);
const queues = { billing: bindQueue(redis.client, eventsQueue('billing')) };
const events = createEvents({ store: tenancy, queues }); // `tenancy` from above

const relay = events.relay({ redis: redis.client }); // one leader per deployment
relay.start();
const workers = events.work();

// on shutdown
await relay.stop();
await workers.stop();
```

没有Redis(dev,测试),您会按以下顺序运行您的进程订阅者:

```ts
await events.drain(scope.tenant.id); // omit the tenant to drain every tenant
```

## 保证

-   **原子发射.** 该活动是在 `_outbox` 如果且只有在交易中 释放了它.
-   **起码一次.** 中继器为每个任务( 事件, 订阅者) 排入 `jobId = <eventId>:<module>:<type>`,然后标记已发送的事件。 撞车 在再次排入同一编号之间,队列忽略了这些编号.
-   **申请一次.** 用户的效果及其 `_inbox` 单行执行 交易; 第二次发送找到行并什么都不做.
-   **肃静.** 每个租户,中继发送事件 `_id` 秩序。 秩序。 没有 全球秩序,一个用户必须容忍重订顺序.
-   **每家店都一样.** 释放、中继和 `drain` 运行不变 `perOrganization` 财务报告和审定财务报表 `single` (一个数据库,一个固定租户).

## API 密码

| 导出 | 它会做什么 |
| --- | --- |
| `eventsModule` | 拥有内核模块 `_outbox` (发送后7天TTL)和 `_inbox` (30天);加入登记册 |
| `createEvents({ store, queues?, batchSize? })` | 总线; 立即检查登记簿 |
| `events.emit(source, event, options?)` | 将事件写入 `source.mongo`,交易的手柄 |
| `events.drain(tenant?)` | 在这个过程中通过用户管理待办活动 |
| `events.relay(options)` | `tick()`, (中文(简体) ), `start()`, (中文(简体) ), `stop()`: 以领袖为主的民意调查 |
| `events.work(options?)` | 一个 `@softistx/redis` 每个签名模块的工人队列 |
| `events.deadLetters({ limit? })` | 使用他们所有尝试的工作 |
| `eventsQueue(module, options?)`, (中文(简体) ), `queueName(module)`, (中文(简体) ), `EventsQueueOptions`, (中文(简体) ), `EventQueue`, (中文(简体) ), `EventJob` | 定义 `events.<module>`,它的选项,绑定队列的类型和任务的有效载荷 |
| `deliver(store, mongo, tenant, event, subscription)`, (中文(简体) ), `Delivery` | 一个用户,一次: 收件箱行加交易处理器, 交出其模块的收缩范围 |
| `emittedTypes(modules)`, (中文(简体) ), `subscriptionsOf(modules)`, (中文(简体) ), `Subscription` | 检查靴子后面的注册读取器和一个模块的处理器 |
| `outbox`, (中文(简体) ), `inbox`, (中文(简体) ), `OUTBOX_TTL`, (中文(简体) ), `INBOX_TTL` | 收集定义和TTL |
| `EventsError`, (中文(简体) ), `EventsErrorCode` | 拒绝,有稳定的 `code` 名称空格 `events.` (单位:千美元)`events.undeclared-type`, (中文(简体) ), `events.missing-queue`, (...) (中文(简体) ) |
| `EventEnvelope`, (中文(简体) ), `EventInput`, (中文(简体) ), `EmitOptions`, (中文(简体) ), `EventWorkers`, (中文(简体) ), `EmitSource`, (中文(简体) ), `EventsMongo`, (中文(简体) ), `Subscriber`, (中文(简体) ), `SubscriberContext`, (中文(简体) ), `DeadLetter`, (中文(简体) ), `Relay`, (中文(简体) ), `RelayOptions`, (中文(简体) ), `Events`, (中文(简体) ), `EventsOptions` | 类型 |

端点 : `@alxia/modules`, (中文(简体) ), `@alxia/tenancy`, (中文(简体) ), `@softistx/mongo`, (中文(简体) ), `@softistx/redis`, (中文(简体) ), `mongodb`, (中文(简体) ), `zod`, (中文(简体) ), `typescript`。 。 。 .

## 文档

-   [指南](https://github.com/softistx/alxia/blob/develop/packages/events/docs/guide.md)信封、发包箱、订户、继电器和工人, `drain`死信 房客 测试.
-   [解决问题](https://github.com/softistx/alxia/blob/develop/packages/events/docs/troubleshooting.md):一个错误消息,以及该如何应对.
-   [路线图](https://github.com/softistx/alxia/blob/develop/packages/events/docs/roadmap.md):即将到来的,以及没有计划的.

## 许可证

麻省理工学院

## 常见问题

### @alxia/events 是什么？

用于在 @softistx/mongo 和 @softistx/redis 上应用的事件总线: 将事件写入交易输出框, 并更改域名, 转发到队列, 至少发送一次, 通过收件箱应用一次

### 如何安装 @alxia/events？

在项目目录运行 npm install @alxia/events，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：zod（^4\.6\.5）、mongodb（^7\.7\.0）、typescript（^6\.0\.3 \|\| ^7\.0\.0）、@alxia/modules（^0\.4\.0）、@alxia/tenancy（^0\.6\.0）、@softistx/mongo（^0\.27\.0）、@softistx/redis（^0\.14\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @alxia/events 支持 TypeScript 吗？

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

### @alxia/events 支持 ESM 还是 CommonJS？

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

### @alxia/events 可以商用吗？

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

### @alxia/events 的下载量有多少？

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

### @alxia/events 还在维护吗？

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

