# @bumail/queue 中文文档

规范地址：https://npmcn.com/package/%40bumail/queue/

版本：0\.14\.2
npm 元数据更新时间：2026-11-05T09:22:59.410Z
中文译文更新时间：2026-11-08T19:37:33.496Z
软件包许可：MIT

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

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

弃用说明：moved to @softistx/bumail-queue \(private, GitHub Packages\)

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

- 包体积（解压后）：868 kB，199 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：0 个
- peer 依赖：typescript ^6\.0\.3 \|\| ^7\.0\.0，@bumail/mime ^0\.4\.0，@bumail/smtp ^0\.13\.0，@bumail/mta-sts ^0\.1\.0
- 首次发布：2026-10-03T23:55:07.243Z
- 最新版本发布：2026-11-05T04:17:02.345Z
- 近 30 天下载量：3495（2026-10-09 至 2026-11-07，npm 官方下载统计）
- 已发布版本数：22（近 12 个月 22 个）

## 中文简介

邮件服务器的外出邮件队列:每个收件人的状态,背靠背的重试,交付状态通知(RFC 3464),几个工人的租赁,以及一个内存,一个包:sqlite,一个PostgreSQL (Bun.sql)和一个 Redis (Bun.redis) 商店,交付th

## 安装

```sh
npm install @bumail/queue
```

也可以使用：`pnpm add @bumail/queue`、`yarn add @bumail/queue`、`bun add @bumail/queue`

## README

# @ bumail/ queue (英语)

邮件服务器的外出队列: 它保存您服务器的每封信 送去另一个,送过去 `@bumail/smtp/client`重试 现在的失败,并发出交货状态通知(RFC 3464) 当它放弃的时候 每个收件人都有自己的状态,队列 在重新启动中幸存下来 `bun:sqlite`, PostgreSQL 或 Redis, 以及多个 工人——用一台机器,或用PostgreSQL或Redis的许多人——可以 共享一个队列。 没有运行时间依赖性: 只有对等者.

## 安装

```sh
bun add @bumail/queue @bumail/smtp @bumail/mime
bun add @bumail/mta-sts   # a required peer (its types are in the API), used when you set mtaSts
bun add @bumail/dns   # for direct delivery by MX: the resolver
```

`@bumail/smtp` (客户), `@bumail/mime` (针对DSN)和 `@bumail/mta-sts` (计: `mtaSts`)是要求的同龄人. `@bumail/dns` 是可选的:其形状的任何解析器都会起作用,并且 a 只使用智能主机的队列不需要.

## 子路径

| 导入 | 它给的 |
| --- | --- |
| `@bumail/queue` | `createQueue`,则 `QueueStore` 合同, `QueueError` 类型 |
| `@bumail/queue/memory` | `MemoryQueueStore`:在记忆中,在重启时丢失——用于规格和试验 |
| `@bumail/queue/sqlite` | `SqliteQueueStore`: 磁盘 `bun:sqlite`,由一台机器的流程共享 |
| `@bumail/queue/postgres` | `PostgresQueueStore`:通过 Bun 自己的 PostgreSQL `Bun.sql`,由多个机器上的实例共享 |
| `@bumail/queue/redis` | `RedisQueueStore`: 在Redis上通过 Bun 自己 `Bun.redis`,由多个机器上的实例共享 |
| `@bumail/queue/conformance` | `describeQueueStore`页:1 `QueueStore` 合同套房,与 `bun test` 针对包外写的商店 |

## 使用量

```ts
import { nodeResolver } from '@bumail/dns';
import { createQueue } from '@bumail/queue';
import { SqliteQueueStore } from '@bumail/queue/sqlite';

const queue = createQueue({
    store: SqliteQueueStore.open({ directory: '/var/lib/bumail/queue' }),
    hostname: 'mail.example.net', // your public name: EHLO, and the DSN's Reporting-MTA
    resolver: nodeResolver(),
});
queue.start();

// The message as it leaves: whole, headers first, CRLF, already DKIM-signed
// (with @bumail/auth's signDkim, say).
const signedMessage = await Bun.file('outgoing.eml').bytes();
const item = await queue.enqueue(signedMessage, {
    from: 'mary@example.net',
    to: ['joe@example.com', 'ann@example.org'],
});
item.recipients; // [{ address: 'joe@example.com', status: 'pending' }, …]

process.on('SIGTERM', () => queue.stop()); // lets deliveries under way end
```

信息是一个 `Uint8Array`,字符串或 `ReadableStream<Uint8Array>`, (中文(简体) ), 带有 CRLF 线末端: 拒绝使用空 CR 或 LF , 如 `sendMail` 将 拒绝 每个地址都是一个的 `sendMail` 带 (单位:千美元)`@bumail/smtp/client`是因为 `isMailbox`: 无源的 RFC 5321 邮箱 路径,没有控制字符(C0,DEL或C1),没有 `>`,没有U+2028或U+2029, 无 Unicode 格式字符 (E)`\p{Cf}`),没有单独代孕和IPv4 255以上字节,所以一个坏字被拒绝 `enqueue`,从来没有 交货. 交付按域分类:每个域一次 尝试,提供STATLS.

## 反弹和反弹

4xx, 连接出错或超时离开收件人 `deferred`· ; 30分钟后队列再试一次 1小时 2 4 每4次 5天后放弃 (RFC 5321 第4.5.4.1节)。 A 5xx 一次失败接收者.

```ts
import { nodeResolver } from '@bumail/dns';
import { createQueue } from '@bumail/queue';
import { MemoryQueueStore } from '@bumail/queue/memory';

const queue = createQueue({
    store: new MemoryQueueStore(),
    hostname: 'mail.example.net',
    resolver: nodeResolver(),
    retry: { first: 15 * 60_000, giveUpAfter: 3 * 24 * 3_600_000 },
    dsn: { delayAfter: 4 * 3_600_000, returnContent: 'headers' },
});
```

失败的接收者会得到一个 DSN 返回发送者, a `multipart/report` 与原始标题字段; 接收者在 `delayAfter` 得到一个"延迟"警告。 一个 DSN 被从空中排出 发送者 `<>`,以及来自 `<>` 从来没有造成一个.

信封可以携带发送者的DSN参数(RFC 3461),即: SMTP 服务器按原样交接,队列传递到下一个 跳动:

```ts
await queue.enqueue(message, {
    from: 'mary@example.net',
    to: ['joe@example.com'],
    ret: 'HDRS', // what a DSN returns: the headers only (FULL: the whole message)
    envid: 'QQ314159', // echoed as Original-Envelope-Id
    recipients: [
        { address: 'joe@example.com', notify: ['SUCCESS', 'FAILURE'], orcpt: { type: 'rfc822', address: 'joe@old.example.org' } },
    ],
});
```

`notify: 'NEVER'` 不发送 DSN; 一如既往的缺席、 失败和延迟; a 列表,只有那些事件。 升级共享商店:停止所有老工人 在开始新的工作之前(一个老工人不断跑动,无视 DSN参数并从它完成的项目中掉出. `SUCCESS` 带有不提供 DSN 的下个 hop 发送一个 `relayed` DSN (英语). 对于所递交的电文, `deliveredDsn()` 写入 `delivered` 一个,和 `failedDsn()` 页:1 `failed` 给接收者一个它无法提供.

## 路线

```ts
import { createQueue } from '@bumail/queue';
import { MemoryQueueStore } from '@bumail/queue/memory';

const smtpPassword = (await Bun.file('/run/secrets/smtp').text()).trim(); // from your secrets
createQueue({
    store: new MemoryQueueStore(),
    hostname: 'mail.example.net',
    // Port 25 blocked? Everything through a provider's submission port:
    route: {
        host: 'smtp.provider.example',
        port: 587,
        auth: { username: 'mary@example.net', password: smtpPassword },
    },
    // …or only some domains, the rest by MX (which needs the resolver):
    routes: { 'partner.example': { host: 'relay.partner.example' } },
    // …or by MX, with a smarthost only as the way out when MX fails:
    // fallback: { host: 'smtp.provider.example', port: 587, auth: { username: 'mary@example.net', password: smtpPassword } },
});
```

`route` 默认为 `'mx'`:每个收件人域自己的邮件主机. 证书只通过 TLS 检查: `createQueue` 拒绝 `auth` 带有 `tls` 其他 `'required'`检查港口, tLS 模式和超时 `sendMail` 会的 路线 `sendMail` 仍然拒绝(`INVALID_OPTION`(b) 推迟接收者,因为 `4.3.5` 财务报告和审定财务报表 这么说的 `error` 事件,它不反弹,直到 `retry.giveUpAfter`当它们失败时 `4.4.7` 和任意的DSN一样 推迟接收者.

与 `fallback` (a smarthost),一个被 MX 的会话失败的收受者 连接失败, 超时或拒绝名声都会经历 一次智能主机( 不在最后点之后 ) `DATA`,其中MX可能接收到消息:每个接收者MX没有拒绝 `RCPT` 标记 `mayHaveReachedMx` 绝不退缩,被拒绝者可以退缩。 如果智能主机自己的会话在最后点后结束,则收件人会被标记 `mayHaveReachedFallback` 而后来的尝试再次去 聪明的宿主,而不是MX [回到一个聪明的宿主](https://npmcn.com/package/%40bumail/queue/docs/guide.md#falling-back-to-a-smarthost)。 。 。 .

## 技术

打开 `mtaSts` (关闭,除非给出;智能主线和 `fallback` 永远不要用它). MX 路线上的每个收件人域都读取队列 `_mta-sts.<domain>` 并获取保险单(RFC 8461) `@bumail/mta-sts`保持它在一个 `PolicyCache` 直至 `max_age` 结束。 带有模式 `enforce` 它发送与 `tls: 'required'` 到 MX 仅主机政策名称 `testing` 它一如既往地只发送报告 `enforce` 推迟到 `4.7.5` 弹出为 `5.7.5` 仅在 `retry.giveUpAfter`,在再次获取保险单之后。 下 `enforce` 什么都没有 `fallback`: 连接失败延迟 . `mtaSts.skip(item, domain)` 免除一个会话(一个被邮寄的TLS-RPT报告,一个在进程中发送的域). 每一个尝试都被告知 `tls` 活动,用于 RFC 8460 报告.

```ts
import { nodeResolver } from '@bumail/dns';
import { createMemoryPolicyCache, createQueue } from '@bumail/queue';
import { MemoryQueueStore } from '@bumail/queue/memory';

const resolver = nodeResolver(); // has txt
const queue = createQueue({
    store: new MemoryQueueStore(),
    hostname: 'mail.example.net',
    resolver,
    mtaSts: { cache: createMemoryPolicyCache() }, // fetch: globalThis.fetch; resolver: the queue's
});
queue.on('tls', ({ domain, policy, mxHost, ok, tlsResult }) => {});
```

这个 `tls` 事件还携带 `kind` (单位:千美元)`'try'` 或者说 `'policy'`, (中文(简体) ), `at` (队列的时钟,ms), `sendingAddress` 财务报告和审定财务报表 `reused`A级 `send` 自己接收的 `mxNames`, (中文(简体) ), `tls`, (中文(简体) ), `onAttempt` 财务报告和审定财务报表 `onSkip` 并且必须传递给 `sendMail`。见 [技术](https://npmcn.com/package/%40bumail/queue/docs/guide.md#mta-sts)。 。 。 .

## 重用连接

没有 `send` ,队列通过 SMTP 池发送 连接它拥有的: 多个信件到一个服务器共享连接 (最多100个,闲出5秒),和 `stop()` 关闭了游泳池. `reuse` 曲调 这, `reuse: false` 每个会话打开一个连接, a `send` 你给 从来没有包裹。 活动 `reused` 当发送者说. 这个 `bumail serve` 队列 `@bumail/server` 从同一个游泳池发出 没有设置。 见 `createSmtpPool` 输入 `@bumail/smtp` 读取.

```ts
createQueue({
    store: new MemoryQueueStore(),
    hostname: 'mail.example.net',
    resolver: nodeResolver(),
    reuse: { maxMessages: 50, idleSeconds: 10 }, // default { 100, 5 }; or false
});
```

见 [重用连接](https://npmcn.com/package/%40bumail/queue/docs/guide.md#reusing-connections)。 。 。 .

## 若干工人

```ts
import { nodeResolver } from '@bumail/dns';
import { createQueue } from '@bumail/queue';
import { SqliteQueueStore } from '@bumail/queue/sqlite';

// In each process, on the same directory: a claim leases an item to one worker.
const queue = createQueue({
    store: SqliteQueueStore.open({ directory: '/var/lib/bumail/queue' }),
    hostname: 'mail.example.net',
    resolver: nodeResolver(),
});
queue.start();
```

工人要求有租约的到期物品,在交货时延长租约 随其结果而去;失败的续约将被告知 `error` 并再次尝试。 如果撞倒了, 另一工人一旦抢走 租赁期满(`leaseMs`,默认为10分钟). 存储目录 makes is 0700; 一个存在它的模式. `concurrency` (20) 将一个工人一并交付的物品捆绑起来——每人 条目打开每个收件人域的会话——和 `perDomain` (二) 联合国 会话到一个收件人域.

## PostgreSQL, 用于多台机器

```ts
import { nodeResolver } from '@bumail/dns';
import { createQueue } from '@bumail/queue';
import { PostgresQueueStore } from '@bumail/queue/postgres';

// In each instance, on the same database. A Bun.SQL client of your own works too:
// PostgresQueueStore.open({ sql: new Bun.SQL({ url, max: 10 }) }).
const store = PostgresQueueStore.open({
    sql: Bun.env['DATABASE_URL'] ?? 'postgres://bumail@localhost:5432/mail',
    tablePrefix: 'bumail_queue_', // the default: bumail_queue_items, …_messages, …_schema
});
await store.migrate(); // makes the tables; the first call would anyway
const queue = createQueue({ store, hostname: 'mail.example.net', resolver: nodeResolver() });
queue.start();

process.on('SIGTERM', async () => {
    await queue.stop();
    await store.close(); // closes the client it opened for the URL, never yours
});
```

一项索赔就是一项 `UPDATE … RETURNING` 其项目 a `SELECT … FOR UPDATE SKIP LOCKED` 选择:两例从不采用同一项, 无 等待着对方正在承受。 撞出东西的事故 当他们的租约到期时 `bun:sqlite`。每封信都运行在 `READ COMMITTED`,因此其会话默认为 `repeatable read` 或者说 `serializable` 服务队列。 无驱动程序安装 : `Bun.sql` 这是邦的.

## Redis, 用于几台机器

```ts
import { nodeResolver } from '@bumail/dns';
import { createQueue } from '@bumail/queue';
import { RedisQueueStore } from '@bumail/queue/redis';

// In each instance, on the same Redis. A Bun.RedisClient of your own works too:
// RedisQueueStore.open({ client: new Bun.RedisClient(url) }).
const store = RedisQueueStore.open({
    url: Bun.env['REDIS_URL'] ?? 'redis://localhost:6379',
    keyPrefix: 'bumail:queue:', // the default: bumail:queue:items, …:item:<id>, …
});
const queue = createQueue({ store, hostname: 'mail.example.net', resolver: nodeResolver() });
queue.start();

process.on('SIGTERM', async () => {
    await queue.stop();
    await store.close(); // closes the client it opened for the URL, never yours
});
```

每个写作的操作都是一个Lua脚本,Redis运行整个: 两起案件从不带走同一物品,一起坠毁的案件的物品 一旦租约到期,将再次提出索赔。 信件为 字节。 一个Redis,或一个有复制品的初级-不是Redis集群. 重写 在记忆中承认写入: `appendfsync everysec` 崩溃会损失一秒钟的写作, 和失败的复制品可以 失去承认的,所以保持 `appendonly yes`, (中文(简体) ), `appendfsync always` 财务报告和审定财务报表 `maxmemory-policy noeviction` 如果丢失的信息很重要 指南的 Redis 部分)。 无驱动程序安装 : `Bun.redis` 这是邦的.

## 事件和管理

```ts
// queue: the one created under Usage.
queue.on('delivered', ({ id, recipient, reply }) => console.info({ id, recipient, reply }));
queue.on('deferred', ({ recipient, reply, nextAttemptAt }) => {});
queue.on('failed', ({ recipient, reply }) => {}); // reply: { code?, status?, text, host? }
queue.on('dsn', ({ kind, of, to }) => {});
queue.on('tls', ({ domain, policy, mxHost, address, ok, tlsResult }) => {}); // with mtaSts
queue.on('error', ({ error, id }) => console.error(id, error)); // the store, a lost lease, a bad route

const [next] = await queue.list({ limit: 50 }); // the next due first
if (next) await queue.retryNow(next.id); // false while a worker delivers it
if (next) await queue.cancel(next.id); // no DSN
```

## 你自己的店铺

`QueueStore` 可能以 0.x 的小型版本(方法,字段)生长;您自己的商店也遵循它.

拿着 `QueueStore` 你给同样的测试 店铺在这里通过. 光谱运行于 `bun test` (套房进口) `bun:test`:

```ts
// my-store.spec.ts
import { describeQueueStore } from '@bumail/queue/conformance';
import { MyQueueStore } from './my-store';

describeQueueStore('MyQueueStore', {
    create: () => MyQueueStore.open({ url: process.env.MY_STORE_URL }),
    share: (store) => (store as MyQueueStore).connectAgain(), // a second handle on the same queue
    dispose: (store) => (store as MyQueueStore).close(),
});
```

无 `share` 两个数个工人的测试被跳过 一个商店 在一个网络上共享,应该通过真正的第二次连接。 见 [拥有自己的商店与合同](https://github.com/softistx/bumail/blob/develop/packages/queue/docs/guide.md#holding-your-own-store-to-the-contract)。 。 。 .

## 测试

```ts
import { createQueue, type Sender } from '@bumail/queue';
import { MemoryQueueStore } from '@bumail/queue/memory';

let now = Date.UTC(2026, 0, 1);
const send: Sender = async (_message, options) => ({
    accepted: [options.to].flat().map((recipient) => ({ recipient, reply: { code: 250, text: 'OK' } })),
    rejected: [],
    reply: { code: 250, text: 'Queued' },
    host: 'mx.test',
    port: 25,
    tls: false,
    authenticated: false,
});
const queue = createQueue({
    store: new MemoryQueueStore(),
    hostname: 'mail.test',
    route: { host: 'mx.test' },
    clock: { now: () => now },
    send,
});
await queue.enqueue('Subject: hi\r\n\r\nhello\r\n', { from: 'a@test', to: 'b@test' });
await queue.deliverDue(); // one pass, by hand: no timer, no network
now += 30 * 60_000;
```

## 限制

```ts
import { nodeResolver } from '@bumail/dns';
import { createQueue } from '@bumail/queue';
import { MemoryQueueStore } from '@bumail/queue/memory';

createQueue({
    store: new MemoryQueueStore(),
    hostname: 'mail.example.net',
    resolver: nodeResolver(),
    limits: { maxMessageSize: 10 * 1024 * 1024, maxRecipients: 50, maxItems: 100_000 },
});
```

万事俱备,万事俱备 `limits`: 信息(25个米B) 每个信件的收件人(100),存储中的项目(默认无), 每个收件人保存的回复文本( 512个字符, 控制字符) 替换为空格),原始的 DSN 返回(64 KiB,每行剪接 以998字节表示). 没什么 远程服务器说用 CR 、 LF 或 a 到达 DSN 头字段 控制其中的字符.

## 陷阱

-   **仅存一文.** 仓库用 `bun:sqlite`, (中文(简体) ), `Bun.sql` 财务报告和审定财务报表 `Bun.redis`, (中文(简体) ), 所以包裹在1.4.2号机上运行 或晚于节点运行.
    
-   **它向任何人发出你所发出的声音.** 队列不是中继 策略:只排入经认证的用户提交的内容,或您的 自己的服务器写,从来没有什么 未经认证的客户端给你.
    
-   **习惯 `QueueStore` 必须移植 `complete` (0.11,断裂).** `complete(id, owner, result, dsns)` 带 DSN 项 结果 请求和返回 `{ item, dsns }`,或 `undefined` 失去的租约. 将结果和 DSN 保存在一个步骤中, 所以崩溃不能留下一个 没有另一个;返回裸体物品的商店仍然工作,但是 队列报告 `Queue store outdated` 编辑 `error` 事件和添加 每个 DSN 有 `add`在楼梯外 这个软件包的存储是 原子 DSN 忽略 `limits.maxItems`: 整队仍会弹出 计数可能超过它持有的DSN的限制. 它们至少交付一次;见 [写入 a 存储](https://npmcn.com/package/%40bumail/queue/docs/guide.md#writing-a-store)编辑 `this.*` 电话: 你店里的帮手,一张素描.
    
    ```ts
    async complete(id, owner, result, dsns) {
      // refuse a bad DSN (INVALID) before opening a connection or a transaction
      for (const dsn of dsns) this.check(dsn);
      return this.transaction(async () => {
          const item = await this.apply(id, owner, result); // undefined on a lost lease
          if (!item) return undefined; // writes no DSN
          const stored = [];
          for (const dsn of dsns) stored.push(await this.insert(dsn)); // in order
          return { item, dsns: stored };
      });
    }
    ```
    

## 升级

与MTA-STS(添加的版本) `mtaSts`:

-   **`@bumail/mta-sts` 是需要的对等点.** 安装它即使当 `mtaSts` 未使用 : `bun add @bumail/mta-sts`。 。 。 .
-   **`QueueEvents` 有一个新的 `tls` 事件类型**为TLS -RPT计数。 A 类 在事件类型上切换的收听器应该处理或者忽略它.
-   **`SmtpErrorCode` 已经 `MX_NOT_ALLOWED`** (单位:千美元)`X.7.5`从 `@bumail/smtp`),用于 mX 主机 a `enforce` 政策不允许。 A 类 `switch` 超过代码 需要这个案子.
-   **习惯 `send` 必须通过 `mxNames`, (中文(简体) ), `tls` 财务报告和审定财务报表 `onAttempt` 改为 `sendMail`**,或一个 `enforce` 未执行政策 `tls` 事件 保持安静.
-   `QueueStore` 不变.

## API 密码

| 导出 |  |
| --- | --- |
| `createQueue(options)`, (中文(简体) ), `Queue` | 队列 : `enqueue`, (中文(简体) ), `deliverDue`, (中文(简体) ), `start`, (中文(简体) ), `stop`, (中文(简体) ), `on`, (中文(简体) ), `list`, (中文(简体) ), `get`, (中文(简体) ), `retryNow`, (中文(简体) ), `cancel`, (中文(简体) ), `owner` |
| `QueueOptions` (单位:千美元)`route`, (中文(简体) ), `routes`, (中文(简体) ), `fallback`, (中文(简体) ), `reuse`, (中文(简体) ), `mtaSts`, (中文(简体) ), `Route`, (中文(简体) ), `Smarthost`, (中文(简体) ), `RetrySchedule`, (中文(简体) ), `DsnOptions`, (中文(简体) ), `ReuseOptions`, (中文(简体) ), `QueueLimits`, (中文(简体) ), `Clock`, (中文(简体) ), `Sender` | 什麽 `createQueue` 带 |
| `MessageSource`, (中文(简体) ), `QueueEnvelope` (单位:千美元)`ret`, (中文(简体) ), `envid`, (中文(简体) ), `recipients`, (中文(简体) ), `RecipientDsn`, (中文(简体) ), `RecipientNotify`, (中文(简体) ), `NotifyEvent`, (中文(简体) ), `OriginalRecipient`, (中文(简体) ), `RetMode` | 什麽 `enqueue` 带 DSN 参数 |
| `describeQueueStore`, (中文(简体) ), `QueueStoreHarness`, (中文(简体) ), `CreateQueueStore`, (中文(简体) ), `ShareStore` | 从 `@bumail/queue/conformance`数字 : `describeQueueStore(name, { create, share?, dispose? })`,运行在 `bun test`; 无 `share` 两个多工人的测试被跳过 |
| `deliveredDsn(input)`, (中文(简体) ), `DeliveredDsnInput`, (中文(简体) ), `DeliveredRecipient` | 页:1 `delivered` 本地发送的 DSN: 要排队的字节, 或 `undefined` 当没有收件人要求时 `SUCCESS` |
| `failedDsn(input)`, (中文(简体) ), `FailedDsnInput`, (中文(简体) ), `FailedRecipient`, (中文(简体) ), `DEFAULT_MAX_RETURN` | 页:1 `failed` 对接收者的 DSN 应用程序无法在当地交付: 要排队的字节, 或 `undefined` (一) 无效反向路径,或当没有收件人要求失败时; `DEFAULT_MAX_RETURN` 默认为 64 KiB 的 DSN 返回 |
| `QueueEvents`, (中文(简体) ), `QueueListener`, (中文(简体) ), `RecipientEvent` (单位:千美元)`route`, (中文(简体) ), `fallback`, (中文(简体) ), `mxReply`, (中文(简体) ), `mayHaveReachedMx`, (中文(简体) ), `mayHaveReachedFallback`, (中文(简体) ), `DeferredEvent`, (中文(简体) ), `DsnEvent`, (中文(简体) ), `TlsEvent`, (中文(简体) ), `TlsPolicyReport`, (中文(简体) ), `QueueErrorEvent` | 事件 |
| `MtaStsOptions`, (中文(简体) ), `StsResolver`, (中文(简体) ), `PolicyCache`, (中文(简体) ), `PolicyCacheEntry`, (中文(简体) ), `createMemoryPolicyCache()` | MTA-STS: 联合国 `mtaSts` 选项,其政策缓存(`get`, (中文(简体) ), `set`, (中文(简体) ), `delete?`)和内存中的缓存 |
| `QueueStore` | 合同中的商店回答: `add`, (中文(简体) ), `get`, (中文(简体) ), `list`, (中文(简体) ), `count`, (中文(简体) ), `readMessage`, (中文(简体) ), `claim`, (中文(简体) ), `renew`, (中文(简体) ), `complete(id, owner, result, dsns)`, (中文(简体) ), `reschedule`, (中文(简体) ), `cancel` |
| `Completed` (单位:千美元)`item`, (中文(简体) ), `dsns`(中文(简体) ) | 什麽 `complete` 返回:当前项目,以及按给定顺序在同一步骤储存的DSN项目; `undefined` 当租赁丢失时 |
| `QueueItem`, (中文(简体) ), `RecipientState`, (中文(简体) ), `RecipientStatus`, (中文(简体) ), `FinalStatus`, (中文(简体) ), `Diagnostic`, (中文(简体) ), `Lease` | 和每个收件人的位置 |
| `NewQueueItem`, (中文(简体) ), `AddOptions`, (中文(简体) ), `ClaimRequest`, (中文(简体) ), `AttemptResult`, (中文(简体) ), `RecipientUpdate`, (中文(简体) ), `QueueListOptions` | 商店要买什么 |
| `QueueError`, (中文(简体) ), `QueueErrorCode` | `INVALID`, (中文(简体) ), `MESSAGE_TOO_BIG`, (中文(简体) ), `TOO_MANY_RECIPIENTS`, (中文(简体) ), `QUEUE_FULL`, (中文(简体) ), `CLOSED`, (中文(简体) ), `LEASE_LOST`, (中文(简体) ), `MESSAGE_UNREADABLE` |
| `MemoryQueueStore` | 从 `@bumail/queue/memory` |
| `SqliteQueueStore`, (中文(简体) ), `SqliteQueueStoreOptions` | 从 `@bumail/queue/sqlite`数字 : `SqliteQueueStore.open({ directory, busyTimeout? })`, (中文(简体) ), `close()` |
| `PostgresQueueStore`, (中文(简体) ), `PostgresQueueStoreOptions`, (中文(简体) ), `PostgresClient`, (中文(简体) ), `PostgresQueryable` | 从 `@bumail/queue/postgres`数字 : `PostgresQueueStore.open({ sql, tablePrefix? })`, (中文(简体) ), `migrate()`, (中文(简体) ), `close()`· ; `sql` (单位:千美元) `Bun.SQL` 客户端或一个 `postgres://` 網址 |
| `RedisQueueStore`, (中文(简体) ), `RedisQueueStoreOptions`, (中文(简体) ), `RedisQueueClientOptions`, (中文(简体) ), `RedisQueueUrlOptions`, (中文(简体) ), `RedisQueueClient` | 从 `@bumail/queue/redis`数字 : `RedisQueueStore.open({ client | url, keyPrefix? })`, (中文(简体) ), `close()`· ; `client` (单位:千美元) `Bun.RedisClient`, (中文(简体) ), `url` (单位:千美元) `redis://` 網址 |

## 文档

这些页面在包里,在下 `docs/`。 。 。 .

-   [指数](https://github.com/softistx/bumail/blob/develop/packages/queue/docs/README.md):各页,何时读出.
-   [指南](https://github.com/softistx/bumail/blob/develop/packages/queue/docs/guide.md):排队,送货和出行,重试时间表,DSN,几个工人和租赁,事件和管理员,商店(包括PostgreSQL和Redis),测试,并写出自有的商店.
-   [解决问题](https://github.com/softistx/bumail/blob/develop/packages/queue/docs/troubleshooting.md): 每一个 `QueueError`,怎么办呢.
-   [路线图](https://github.com/softistx/bumail/blob/develop/packages/queue/docs/roadmap.md):即将到来的,以及没有计划的.

## 常见问题

### @bumail/queue 是什么？

邮件服务器的外出邮件队列:每个收件人的状态,背靠背的重试,交付状态通知\(RFC 3464\),几个工人的租赁,以及一个内存,一个包:sqlite,一个PostgreSQL \(Bun\.sql\)和一个 Redis \(Bun\.redis\) 商店,交付th注意：该包已被作者标记为弃用——moved to @softistx/bumail-queue \(private, GitHub Packages\)

### 如何安装 @bumail/queue？

在项目目录运行 npm install @bumail/queue，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：@bumail/mime（^0\.4\.0）、@bumail/smtp（^0\.13\.0）、@bumail/mta-sts（^0\.1\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @bumail/queue 支持 TypeScript 吗？

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

### @bumail/queue 支持 ESM 还是 CommonJS？

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

### @bumail/queue 可以商用吗？

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

### @bumail/queue 的下载量有多少？

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

### @bumail/queue 还在维护吗？

最新版本 0\.14\.2 发布于 2026/11/05（3 天前）；至今共发布 22 个版本，其中过去 12 个月发布了 22 个；首次发布于 2026/10/04。作者已将其标记为弃用，新项目建议寻找替代方案。

