@xbibzlibrary/telebibz 0.2.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,20 @@
1
1
  # Changelog
2
2
 
3
- ## 0.2.0 — 2026-08-29
3
+ ## 0.3.0 — 2026-08-29
4
+
5
+ ### Added
6
+
7
+ - Concurrent update processing built for 1000+ message bursts: updates run in parallel across chats while staying ordered within a single chat, so a slow handler never blocks other chats, sessions never lose writes, and a concurrent burst triggers exactly one `getMe` initialization. `bot.handleUpdates(updates)` processes a whole batch at once and the polling loop uses it for every `getUpdates` batch. Cap simultaneous work with `updates: { concurrency }` (default `Infinity`).
8
+ - `bot.broadcast(chatIds, send, options)` for sending to 1000+ users at once: every chat is attempted immediately (no proactive cooldown, configurable `concurrency`), 429 answers are retried automatically after exactly the `retry_after` delay Telegram ordered, and the returned `BroadcastReport` lists delivered/failed counts with per-chat failure details plus `onProgress` streaming.
9
+ - `FetchTransport` flood gate (`floodGate`, default on): when Telegram answers 429, new requests wait out the `retry_after` window Telegram ordered — the only delay ever introduced, never a proactive cooldown.
10
+ - `Limiter` and `mapWithConcurrency` concurrency primitives (promise semaphore and ordered concurrent mapping) exported for applications.
11
+
12
+ ### Fixed
13
+
14
+ - A burst of concurrent updates no longer races `init()`: initialization is memoized, so 1000 simultaneous updates trigger exactly one `getMe` call instead of one per update.
15
+ - Session writes are no longer lost when one chat sends several messages at once: same-chat updates are serialized in arrival order, so each update reads the session state written by the previous one.
16
+
17
+ ## 0.2.1 — 2026-08-29
4
18
 
5
19
  ### Breaking
6
20
 
package/README.id.md CHANGED
@@ -122,6 +122,25 @@ const handler = createWebhookHandler(bot, {
122
122
 
123
123
  `createWebhookHandler` menerima Request Web standar dan menghasilkan Response. Secret token, ukuran body, parsing JSON, dan penanganan update duplikat diverifikasi oleh handler.
124
124
 
125
+ ## Update beban tinggi dan broadcast
126
+
127
+ telebibz dibangun untuk burst 1000+ pesan tanpa cooldown buatan:
128
+
129
+ - **Paralel antar chat, berurutan per chat.** Setiap batch `getUpdates` (dan setiap request webhook) diproses secara konkuren — update dari chat berbeda tidak pernah saling mengantre, sementara update dari chat yang sama menjaga urutan kedatangannya sehingga session, wizard, dan conversation tetap benar dan penulisan session tidak pernah hilang. Burst konkuren hanya memicu satu inisialisasi `getMe`.
130
+ - **Tidak ada throttling proaktif.** Permintaan keluar tidak pernah ditunda oleh library. Ketika Telegram menjawab 429, transport menunggu tepat jendela `retry_after` yang diperintahkan Telegram ("flood gate" global melindungi seluruh trafik) lalu otomatis retry — sehingga burst tetap terkirim lengkap, bukan gagal.
131
+ - **Broadcast ke 1000+ user sekaligus.** `bot.broadcast()` langsung mencoba semua chat, me-retry 429 sesuai `retry_after` dari Telegram sendiri, dan mengembalikan laporan lengkap.
132
+
133
+ ```ts
134
+ const report = await bot.broadcast(
135
+ subscriberIds,
136
+ (chatId) => bot.api.methods.sendMessage({ chat_id: chatId, text: "Newsletter #42" }),
137
+ { onProgress: (p) => console.log(`${p.delivered}/${p.total} terkirim`) },
138
+ );
139
+ console.log(`Terkirim ${report.delivered}/${report.total} dalam ${report.durationMs}ms`);
140
+ ```
141
+
142
+ Batasi pekerjaan simultan dengan `new Bot({ ..., updates: { concurrency: 64 } })` atau `broadcast(..., { concurrency: 64 })` jika downstream Anda (database, API) membutuhkannya — secara default keduanya berjalan sepenuhnya paralel.
143
+
125
144
  ## State, queue, scheduler, dan cache
126
145
 
127
146
  Paket menyediakan `MemoryStorage` dengan TTL dan pembaruan atomik, `JsonFileStorage`, `RedisStorage`, `SqlStorage`, `MongoStorage`, persistent application state storage, session bot, conversation dan form berbasis Storage, menu berbasis permission, pagination `MenuController`, `MemoryCache`, token-bucket limiter, task queue dengan retry/backoff/concurrency/delay/cancel, serta scheduler interval, one-shot, dan cron lima field lengkap. Adapter Redis, SQL, dan Mongo memakai driver kecil sehingga core package tetap tanpa runtime dependency vendor.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # telebibz
2
2
 
3
- ![telebibz logo](https://cdn.jsdelivr.net/npm/@xbibzlibrary/telebibz@latest/assets/telebibz-logo.png)
3
+ ![telebibz logo](https://imgbs.com/uploads/telebibz-d7b30671.png)
4
4
 
5
5
  [![CI](https://github.com/XbibzOfficial777/telebibz/actions/workflows/ci.yml/badge.svg)](https://github.com/XbibzOfficial777/telebibz/actions/workflows/ci.yml)
6
6
  [![npm version](https://img.shields.io/npm/v/@xbibzlibrary/telebibz)](https://www.npmjs.com/package/@xbibzlibrary/telebibz)
@@ -150,6 +150,25 @@ const handler = createWebhookHandler(bot, {
150
150
 
151
151
  `createWebhookHandler` accepts a standard Web `Request` and returns a `Response`. It verifies the optional secret token, body size, JSON payload, and update shape before calling `bot.handleUpdate()`.
152
152
 
153
+ ## High-load updates and broadcast
154
+
155
+ telebibz is built for bursts of 1000+ messages with no artificial cooldown:
156
+
157
+ - **Parallel across chats, ordered per chat.** Every `getUpdates` batch (and every webhook request) is processed concurrently — updates from different chats never queue behind each other, while updates from the same chat keep their arrival order so sessions, wizards, and conversations stay correct and session writes are never lost. A concurrent burst triggers exactly one `getMe` initialization.
158
+ - **No proactive throttling.** Outgoing requests are never delayed by the library. When Telegram answers 429, the transport waits exactly the `retry_after` window Telegram ordered (a global "flood gate" protects all in-flight traffic) and retries automatically — so bursts deliver completely instead of failing.
159
+ - **Broadcast to 1000+ users at once.** `bot.broadcast()` attempts every chat immediately, retries 429s per Telegram's own `retry_after`, and returns a full report.
160
+
161
+ ```ts
162
+ const report = await bot.broadcast(
163
+ subscriberIds,
164
+ (chatId) => bot.api.methods.sendMessage({ chat_id: chatId, text: "Newsletter #42" }),
165
+ { onProgress: (p) => console.log(`${p.delivered}/${p.total} delivered`) },
166
+ );
167
+ console.log(`Delivered ${report.delivered}/${report.total} in ${report.durationMs}ms`);
168
+ ```
169
+
170
+ Cap simultaneous work with `new Bot({ ..., updates: { concurrency: 64 } })` or `broadcast(..., { concurrency: 64 })` when your own downstream (database, API) needs it — by default both run fully parallel.
171
+
153
172
  ## State, queue, scheduler, and cache
154
173
 
155
174
  The package provides `MemoryStorage` with TTL and serialized per-key updates, `JsonFileStorage`, `RedisStorage`, `SqlStorage`, `MongoStorage`, persistent application state storage, bot sessions, storage-backed conversations and forms, permission-aware menus, `MenuController` pagination, `MemoryCache`, a token-bucket limiter, a task queue with retry/backoff/concurrency/delay/cancel, and schedulers for intervals, one-shot tasks, and full five-field cron expressions. Redis, SQL, and Mongo adapters use small driver interfaces so the core package remains free of vendor runtime dependencies.
package/README.zh-CN.md CHANGED
@@ -122,6 +122,25 @@ const handler = createWebhookHandler(bot, {
122
122
 
123
123
  `createWebhookHandler` 接受标准 Web `Request` 并返回 `Response`。处理程序会验证 secret token、body 大小、JSON 解析以及重复更新处理。
124
124
 
125
+ ## 高负载更新与广播
126
+
127
+ telebibz 为 1000+ 条消息的突发场景而生,没有任何人为冷却:
128
+
129
+ - **跨 chat 并行,同一 chat 内按序。** 每个 `getUpdates` 批次(以及每个 webhook 请求)都并发处理——不同 chat 的 update 不会互相排队,而同一 chat 的 update 保持到达顺序,因此会话、wizard 和 conversation 始终正确,会话写入永不丢失。并发突发只触发一次 `getMe` 初始化。
130
+ - **没有主动限流。** 库永远不会延迟外发请求。当 Telegram 返回 429 时,transport 会严格按照 Telegram 指定的 `retry_after` 窗口等待(全局 "flood gate" 保护所有进行中的流量)并自动重试——因此突发流量会完整送达而不是失败。
131
+ - **一次性向 1000+ 用户广播。** `bot.broadcast()` 立即尝试所有 chat,按照 Telegram 自己的 `retry_after` 重试 429,并返回完整报告。
132
+
133
+ ```ts
134
+ const report = await bot.broadcast(
135
+ subscriberIds,
136
+ (chatId) => bot.api.methods.sendMessage({ chat_id: chatId, text: "Newsletter #42" }),
137
+ { onProgress: (p) => console.log(`${p.delivered}/${p.total} delivered`) },
138
+ );
139
+ console.log(`Delivered ${report.delivered}/${report.total} in ${report.durationMs}ms`);
140
+ ```
141
+
142
+ 当你自己的下游(数据库、API)需要时,可以用 `new Bot({ ..., updates: { concurrency: 64 } })` 或 `broadcast(..., { concurrency: 64 })` 限制并发——默认情况下两者都完全并行。
143
+
125
144
  ## 状态、队列、调度器和缓存
126
145
 
127
146
  该包提供带 TTL 和原子更新的 `MemoryStorage`、`JsonFileStorage`、`RedisStorage`、`SqlStorage`、`MongoStorage`、bot session、基于 Storage 的 conversation/form、基于 permission 的菜单、`MenuController` 分页、`MemoryCache`、令牌桶限流器、支持重试/退避/并发/延迟/取消的任务队列,以及间隔、一次性和完整五字段 cron 的调度器。Redis、SQL 和 Mongo 适配器使用小型 driver interface,因此 core package 不需要 vendor runtime dependency。
@@ -23,6 +23,14 @@ export interface FetchTransportOptions {
23
23
  maxBackoffMs?: number;
24
24
  jitter?: number;
25
25
  headers?: HeadersInit;
26
+ /**
27
+ * When Telegram answers 429 (rate limit), pause NEW requests until the
28
+ * `retry_after` window Telegram ordered has elapsed. Default `true`.
29
+ * This is never a proactive cooldown: the only waiting ever done is the
30
+ * delay Telegram itself demands, so a flood on one method protects the rest
31
+ * of the traffic instead of every request hitting the same 429 wall.
32
+ */
33
+ floodGate?: boolean;
26
34
  }
27
35
  export declare class FetchTransport implements Transport {
28
36
  private readonly baseUrl;
@@ -33,7 +41,14 @@ export declare class FetchTransport implements Transport {
33
41
  private readonly maxBackoffMs;
34
42
  private readonly jitter;
35
43
  private readonly headers;
44
+ private readonly floodGate;
45
+ /** Timestamp (ms) until which Telegram asked us to stop sending. */
46
+ private floodUntil;
36
47
  constructor(options?: FetchTransportOptions);
48
+ /** Waits out the remainder of a Telegram-ordered flood window, if any. */
49
+ private waitForFloodWindow;
50
+ /** Extends the flood window when Telegram answers 429 or sends retry_after. */
51
+ private recordFloodWindow;
37
52
  request<T>({ method, payload, signal, timeoutMs }: TransportRequest): Promise<TransportResponse<T>>;
38
53
  }
39
54
  //# sourceMappingURL=transport.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../../src/api/transport.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAa,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAG9D,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC,GAAG,OAAO;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC;CAC3B;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;CACtE;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AAED,qBAAa,cAAe,YAAW,SAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;IACpD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;gBAE1B,OAAO,GAAE,qBAA0B;IAYzC,OAAO,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,OAAY,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;CA+E/G"}
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../../src/api/transport.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAa,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAG9D,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC,GAAG,OAAO;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC;CAC3B;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;CACtE;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,qBAAa,cAAe,YAAW,SAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;IACpD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAU;IACpC,oEAAoE;IACpE,OAAO,CAAC,UAAU,CAAK;gBAEX,OAAO,GAAE,qBAA0B;IAa/C,0EAA0E;YAC5D,kBAAkB;IAMhC,+EAA+E;IAC/E,OAAO,CAAC,iBAAiB;IAOnB,OAAO,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,OAAY,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;CAiF/G"}
@@ -10,6 +10,9 @@ export class FetchTransport {
10
10
  maxBackoffMs;
11
11
  jitter;
12
12
  headers;
13
+ floodGate;
14
+ /** Timestamp (ms) until which Telegram asked us to stop sending. */
15
+ floodUntil = 0;
13
16
  constructor(options = {}) {
14
17
  this.baseUrl = (options.baseUrl ?? "https://api.telegram.org").replace(/\/$/, "");
15
18
  this.fetchImpl = options.fetch ?? globalThis.fetch;
@@ -21,6 +24,24 @@ export class FetchTransport {
21
24
  this.maxBackoffMs = options.maxBackoffMs ?? 8_000;
22
25
  this.jitter = options.jitter ?? 0.2;
23
26
  this.headers = options.headers ?? {};
27
+ this.floodGate = options.floodGate ?? true;
28
+ }
29
+ /** Waits out the remainder of a Telegram-ordered flood window, if any. */
30
+ async waitForFloodWindow() {
31
+ if (!this.floodGate)
32
+ return;
33
+ const waitMs = this.floodUntil - Date.now();
34
+ if (waitMs > 0)
35
+ await new Promise((resolve) => setTimeout(resolve, waitMs));
36
+ }
37
+ /** Extends the flood window when Telegram answers 429 or sends retry_after. */
38
+ recordFloodWindow(data) {
39
+ if (!this.floodGate)
40
+ return;
41
+ if (data.ok || (data.error_code !== 429 && data.parameters?.retry_after === undefined))
42
+ return;
43
+ const retryAfterMs = Math.max(0, (data.parameters?.retry_after ?? 0) * 1000);
44
+ this.floodUntil = Math.max(this.floodUntil, Date.now() + retryAfterMs);
24
45
  }
25
46
  async request({ method, payload = {}, signal, timeoutMs }) {
26
47
  const effectiveTimeoutMs = timeoutMs ?? this.timeoutMs;
@@ -39,6 +60,7 @@ export class FetchTransport {
39
60
  }
40
61
  let attempt = 0;
41
62
  while (true) {
63
+ await this.waitForFloodWindow();
42
64
  let responseStatus;
43
65
  const controller = new AbortController();
44
66
  const timeout = setTimeout(() => controller.abort(new Error(`Request timed out after ${effectiveTimeoutMs}ms`)), effectiveTimeoutMs);
@@ -65,6 +87,7 @@ export class FetchTransport {
65
87
  throw error;
66
88
  }
67
89
  const data = await response.json();
90
+ this.recordFloodWindow(data);
68
91
  if (!data.ok && isRetryableResponse(response.status, data) && attempt < this.retries) {
69
92
  const retryAfterMs = data.parameters?.retry_after === undefined ? undefined : Math.max(0, data.parameters.retry_after * 1000);
70
93
  await waitBeforeRetry(attempt, this.backoffMs, this.maxBackoffMs, this.jitter, retryAfterMs);
@@ -1 +1 @@
1
- {"version":3,"file":"transport.js","sourceRoot":"","sources":["../../../src/api/transport.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../../../src/api/transport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import type { ChatId } from "../api/types.js";
2
+ /** One chat the broadcast could not deliver to. */
3
+ export interface BroadcastFailure {
4
+ chatId: ChatId;
5
+ attempts: number;
6
+ error: string;
7
+ errorKind?: string | undefined;
8
+ }
9
+ /** Live counters emitted through `onProgress` after each chat settles. */
10
+ export interface BroadcastProgress {
11
+ total: number;
12
+ processed: number;
13
+ delivered: number;
14
+ failed: number;
15
+ }
16
+ /** Final result of a broadcast run. */
17
+ export interface BroadcastReport {
18
+ total: number;
19
+ delivered: number;
20
+ failed: number;
21
+ durationMs: number;
22
+ failures: BroadcastFailure[];
23
+ }
24
+ export interface BroadcastOptions {
25
+ /**
26
+ * How many chats are messaged at the same time. Default `Infinity` — every
27
+ * chat is attempted immediately, with no proactive cooldown. Telegram's own
28
+ * 429 answers are honored automatically per chat.
29
+ */
30
+ concurrency?: number;
31
+ /**
32
+ * Attempts per chat when Telegram answers 429 (rate limit). The wait between
33
+ * attempts is exactly what Telegram orders via `retry_after`. Default `10`.
34
+ */
35
+ maxAttempts?: number;
36
+ /** Called after each chat settles, regardless of outcome. */
37
+ onProgress?: (progress: BroadcastProgress) => void;
38
+ /** Aborts pending sends; chats already delivered stay delivered. */
39
+ signal?: AbortSignal;
40
+ }
41
+ /**
42
+ * Sends to many chats in parallel with automatic 429 retry.
43
+ *
44
+ * There is no proactive cooldown: all chats (up to `concurrency`) are attempted
45
+ * at once. The only waiting ever done is the `retry_after` delay Telegram itself
46
+ * returns with a 429 answer, so bursts of 1000+ chats still deliver completely
47
+ * instead of failing.
48
+ */
49
+ export declare function runBroadcast(chatIds: readonly ChatId[], send: (chatId: ChatId) => Promise<unknown>, options?: BroadcastOptions): Promise<BroadcastReport>;
50
+ //# sourceMappingURL=broadcast.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broadcast.d.ts","sourceRoot":"","sources":["../../../src/broadcast/broadcast.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAG9C,mDAAmD;AACnD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED,0EAA0E;AAC1E,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,uCAAuC;AACvC,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,gBAAgB,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACnD,oEAAoE;IACpE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AASD;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,EAC1C,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,eAAe,CAAC,CAuC1B"}
@@ -0,0 +1,56 @@
1
+ import { TelegramError } from "../api/errors.js";
2
+ import { mapWithConcurrency } from "../utils/concurrency.js";
3
+ function sleep(delayMs) { return new Promise((resolve) => setTimeout(resolve, delayMs)); }
4
+ function describeError(error) {
5
+ if (error instanceof TelegramError)
6
+ return { message: error.message, kind: error.kind };
7
+ return { message: error instanceof Error ? error.message : String(error), kind: undefined };
8
+ }
9
+ /**
10
+ * Sends to many chats in parallel with automatic 429 retry.
11
+ *
12
+ * There is no proactive cooldown: all chats (up to `concurrency`) are attempted
13
+ * at once. The only waiting ever done is the `retry_after` delay Telegram itself
14
+ * returns with a 429 answer, so bursts of 1000+ chats still deliver completely
15
+ * instead of failing.
16
+ */
17
+ export async function runBroadcast(chatIds, send, options = {}) {
18
+ const startedAt = Date.now();
19
+ const maxAttempts = options.maxAttempts ?? 10;
20
+ const failures = [];
21
+ let delivered = 0;
22
+ let processed = 0;
23
+ const total = chatIds.length;
24
+ await mapWithConcurrency(chatIds, options.concurrency ?? Infinity, async (chatId) => {
25
+ let attempts = 0;
26
+ while (true) {
27
+ if (options.signal?.aborted) {
28
+ failures.push({ chatId, attempts, error: "aborted", errorKind: "aborted" });
29
+ break;
30
+ }
31
+ attempts += 1;
32
+ try {
33
+ await send(chatId);
34
+ delivered += 1;
35
+ break;
36
+ }
37
+ catch (error) {
38
+ const telegram = error instanceof TelegramError ? error : undefined;
39
+ if (telegram?.kind === "rate-limit" && attempts < maxAttempts) {
40
+ // Telegram told us exactly how long to wait; honor it (plus a small
41
+ // jitter so retried chats do not fire as one synchronized wave).
42
+ const retryAfterMs = Math.max(0, (telegram.retryAfter ?? 1) * 1000);
43
+ await sleep(retryAfterMs + Math.random() * 250);
44
+ continue;
45
+ }
46
+ const { message, kind } = describeError(error);
47
+ failures.push({ chatId, attempts, error: message, errorKind: kind });
48
+ break;
49
+ }
50
+ }
51
+ processed += 1;
52
+ options.onProgress?.({ total, processed, delivered, failed: failures.length });
53
+ });
54
+ return { total, delivered, failed: failures.length, durationMs: Date.now() - startedAt, failures };
55
+ }
56
+ //# sourceMappingURL=broadcast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broadcast.js","sourceRoot":"","sources":["../../../src/broadcast/broadcast.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { ApiClient } from "../api/client.js";
2
2
  import { type FetchTransportOptions, type Transport } from "../api/transport.js";
3
- import type { BotCommand, BotCommandScope, Update, User } from "../api/types.js";
3
+ import type { BotCommand, BotCommandScope, ChatId, Update, User } from "../api/types.js";
4
4
  import { Context } from "../context/context.js";
5
5
  import { type Middleware } from "../middleware/compose.js";
6
6
  import { Router, type RouterOptions, type UpdateFilter } from "../router/router.js";
@@ -9,6 +9,7 @@ import { type Storage } from "../storage/storage.js";
9
9
  import { PluginManager, type Plugin } from "../plugins/plugin.js";
10
10
  import { Logger, type LoggerOptions } from "../observability/logger.js";
11
11
  import { type Wizard } from "../state/conversation.js";
12
+ import { type BroadcastOptions, type BroadcastReport } from "../broadcast/broadcast.js";
12
13
  export type BotStatus = "created" | "initialized" | "starting" | "running" | "stopping" | "stopped" | "error";
13
14
  export type BotContext<S extends object = Record<string, unknown>> = Context<S>;
14
15
  export interface BotOptions<S extends object = Record<string, unknown>> {
@@ -25,6 +26,15 @@ export interface BotOptions<S extends object = Record<string, unknown>> {
25
26
  retryDelayMs?: number;
26
27
  maxRetryDelayMs?: number;
27
28
  };
29
+ /**
30
+ * Update-processing tuning. Updates always run in parallel across chats
31
+ * while staying ordered within a single chat. `concurrency` caps how many
32
+ * updates may be processed at the same time (default `Infinity` — bursts of
33
+ * 1000+ messages are processed at once, with no artificial cooldown).
34
+ */
35
+ updates?: {
36
+ concurrency?: number;
37
+ };
28
38
  router?: RouterOptions;
29
39
  logger?: Logger | LoggerOptions;
30
40
  branding?: boolean;
@@ -51,6 +61,12 @@ export declare class Bot<S extends object = Record<string, unknown>> {
51
61
  private pollingAbort;
52
62
  private offset;
53
63
  private me?;
64
+ /** Caps how many updates run at once (default: unlimited). */
65
+ private readonly updateLimiter;
66
+ /** Per-chat processing chains: parallel across chats, ordered within a chat. */
67
+ private readonly chatChains;
68
+ /** Memoized init so a burst of updates triggers exactly one getMe call. */
69
+ private initOnce;
54
70
  private readonly brandingEnabled;
55
71
  /** Branding effects run only on an interactive TTY; structured logs stay untouched otherwise. */
56
72
  private readonly brandingActive;
@@ -97,7 +113,33 @@ export declare class Bot<S extends object = Record<string, unknown>> {
97
113
  getMe(): Promise<User>;
98
114
  setCommands(commands: BotCommand[], scope?: BotCommandScope, languageCode?: string): Promise<true>;
99
115
  deleteCommands(scope?: BotCommandScope, languageCode?: string): Promise<true>;
116
+ /**
117
+ * Handles a single update. Updates for different chats run in parallel;
118
+ * updates for the same chat are processed strictly in arrival order so
119
+ * sessions, wizards, and conversations never interleave. Rejects for this
120
+ * update's failure (as before) without affecting other updates.
121
+ */
100
122
  handleUpdate(update: Update): Promise<void>;
123
+ /**
124
+ * Handles a whole batch of updates at once: every chat in the batch is
125
+ * processed immediately (parallel across chats, ordered per chat), so a
126
+ * burst of 1000 messages is not stuck behind one slow handler. Individual
127
+ * handler failures are logged, emitted as `update:error`, and passed to the
128
+ * `catch()` error boundary; they never reject this promise.
129
+ */
130
+ handleUpdates(updates: readonly Update[]): Promise<void>;
131
+ /**
132
+ * Sends to many chats in parallel — built for broadcasts to 1000+ users.
133
+ * There is no proactive cooldown: every chat is attempted at once (up to
134
+ * `concurrency`). When Telegram answers 429, the send is retried
135
+ * automatically after exactly the `retry_after` delay Telegram ordered, so
136
+ * bursts deliver completely instead of failing.
137
+ */
138
+ broadcast(chatIds: readonly ChatId[], send: (chatId: ChatId) => Promise<unknown>, options?: BroadcastOptions): Promise<BroadcastReport>;
139
+ /** Runs init() once even when many updates arrive concurrently. */
140
+ private ensureInitialized;
141
+ private processUpdate;
142
+ private runUpdate;
101
143
  private conversationKey;
102
144
  private waitForRetry;
103
145
  private poll;
@@ -1 +1 @@
1
- {"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../../../src/core/bot.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../../../src/core/bot.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,8 @@ import { PluginManager } from "../plugins/plugin.js";
9
9
  import { createLogger, describeIncomingUpdate, Logger, summarizeUpdate } from "../observability/logger.js";
10
10
  import { printStatusLine, printTeleBibzBanner, runStartupSequence, startTeleBibzBanner, startTerminalAnimation } from "../branding/terminal.js";
11
11
  import { conversationKeyFromContext } from "../state/conversation.js";
12
+ import { runBroadcast } from "../broadcast/broadcast.js";
13
+ import { Limiter } from "../utils/concurrency.js";
12
14
  export class Bot {
13
15
  api;
14
16
  router;
@@ -24,6 +26,12 @@ export class Bot {
24
26
  pollingAbort;
25
27
  offset = 0;
26
28
  me;
29
+ /** Caps how many updates run at once (default: unlimited). */
30
+ updateLimiter;
31
+ /** Per-chat processing chains: parallel across chats, ordered within a chat. */
32
+ chatChains = new Map();
33
+ /** Memoized init so a burst of updates triggers exactly one getMe call. */
34
+ initOnce;
27
35
  brandingEnabled;
28
36
  /** Branding effects run only on an interactive TTY; structured logs stay untouched otherwise. */
29
37
  brandingActive;
@@ -50,6 +58,7 @@ export class Bot {
50
58
  transport,
51
59
  });
52
60
  this.plugins = new PluginManager(this);
61
+ this.updateLimiter = new Limiter(config.updates?.concurrency ?? Infinity);
53
62
  this.pollingOptions = {
54
63
  allowedUpdates: config.polling?.allowedUpdates ?? [],
55
64
  limit: config.polling?.limit ?? 100,
@@ -207,7 +216,68 @@ export class Bot {
207
216
  async getMe() { const me = await this.api.methods.getMe(); this.me = me; return me; }
208
217
  async setCommands(commands, scope, languageCode) { return this.api.call("setMyCommands", { commands, scope, language_code: languageCode }); }
209
218
  async deleteCommands(scope, languageCode) { return this.api.call("deleteMyCommands", { scope, language_code: languageCode }); }
219
+ /**
220
+ * Handles a single update. Updates for different chats run in parallel;
221
+ * updates for the same chat are processed strictly in arrival order so
222
+ * sessions, wizards, and conversations never interleave. Rejects for this
223
+ * update's failure (as before) without affecting other updates.
224
+ */
210
225
  async handleUpdate(update) {
226
+ const key = this.conversationKey(update);
227
+ const previous = this.chatChains.get(key);
228
+ const run = (previous ?? Promise.resolve()).catch(() => undefined).then(() => this.processUpdate(update));
229
+ const tail = run.then(() => undefined, () => undefined);
230
+ this.chatChains.set(key, tail);
231
+ void tail.then(() => {
232
+ if (this.chatChains.get(key) === tail)
233
+ this.chatChains.delete(key);
234
+ });
235
+ await run;
236
+ }
237
+ /**
238
+ * Handles a whole batch of updates at once: every chat in the batch is
239
+ * processed immediately (parallel across chats, ordered per chat), so a
240
+ * burst of 1000 messages is not stuck behind one slow handler. Individual
241
+ * handler failures are logged, emitted as `update:error`, and passed to the
242
+ * `catch()` error boundary; they never reject this promise.
243
+ */
244
+ async handleUpdates(updates) {
245
+ await Promise.all(updates.map(async (update) => {
246
+ try {
247
+ await this.handleUpdate(update);
248
+ }
249
+ catch {
250
+ // Already logged and emitted by processUpdate; the polling loop must
251
+ // keep flowing no matter how many handlers failed.
252
+ }
253
+ }));
254
+ }
255
+ /**
256
+ * Sends to many chats in parallel — built for broadcasts to 1000+ users.
257
+ * There is no proactive cooldown: every chat is attempted at once (up to
258
+ * `concurrency`). When Telegram answers 429, the send is retried
259
+ * automatically after exactly the `retry_after` delay Telegram ordered, so
260
+ * bursts deliver completely instead of failing.
261
+ */
262
+ async broadcast(chatIds, send, options) {
263
+ return runBroadcast(chatIds, send, options);
264
+ }
265
+ /** Runs init() once even when many updates arrive concurrently. */
266
+ ensureInitialized() {
267
+ if (this.me)
268
+ return Promise.resolve();
269
+ if (!this.initOnce) {
270
+ this.initOnce = this.init().then(() => { this.initOnce = undefined; }, (error) => {
271
+ this.initOnce = undefined;
272
+ throw error;
273
+ });
274
+ }
275
+ return this.initOnce;
276
+ }
277
+ async processUpdate(update) {
278
+ await this.updateLimiter.run(() => this.runUpdate(update));
279
+ }
280
+ async runUpdate(update) {
211
281
  this.logger.incoming(describeIncomingUpdate(update));
212
282
  const message = update.message
213
283
  ?? update.edited_message
@@ -220,7 +290,7 @@ export class Bot {
220
290
  const key = this.conversationKey(update);
221
291
  const session = await this.session.get(key) ?? {};
222
292
  if (!this.me)
223
- await this.init();
293
+ await this.ensureInitialized();
224
294
  if (!this.me)
225
295
  return;
226
296
  const ctx = new Context({ update, api: this.api, session, services: this.services, me: this.me });
@@ -309,16 +379,12 @@ export class Bot {
309
379
  try {
310
380
  const updates = await this.api.request("getUpdates", { offset: this.offset, limit: this.pollingOptions.limit, timeout, allowed_updates: allowedUpdates }, signal, { timeoutMs: requestTimeoutMs });
311
381
  delay = this.pollingOptions.retryDelayMs;
382
+ // Confirm the whole batch first, then process it: updates run in
383
+ // parallel across chats (ordered per chat) instead of one by one.
312
384
  for (const update of updates) {
313
385
  this.offset = Math.max(this.offset, update.update_id + 1);
314
- try {
315
- await this.handleUpdate(update);
316
- }
317
- catch {
318
- // The update has already advanced the offset. Continue with the rest of
319
- // the batch instead of reconnecting or replaying a failed handler.
320
- }
321
386
  }
387
+ await this.handleUpdates(updates);
322
388
  }
323
389
  catch (error) {
324
390
  if (signal.aborted)