cross-tab-worker-databus 0.20.18 → 0.20.20

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
@@ -2,6 +2,19 @@
2
2
 
3
3
  本项目遵循 [Semantic Versioning](https://semver.org/);变更记录格式参考 [Keep a Changelog](https://keepachangelog.com/)。
4
4
 
5
+ ## [0.20.20] - 2026-09-03
6
+
7
+ ### Added
8
+
9
+ - Automatic recovery now emits an `exhausted` reliability event when `recovery.maxAttempts` is reached, instead of stopping silently.
10
+
11
+ ## [0.20.19] - 2026-09-03
12
+
13
+ ### Added
14
+
15
+ - Added optional `recovery.maxAttempts` to cap automatic transport reopen attempts while preserving explicit demand-driven recovery.
16
+ - Added validation and regression coverage for capped recovery sequences.
17
+
5
18
  ## [0.20.18] - 2026-09-03
6
19
 
7
20
  ### Added
@@ -2,7 +2,7 @@ import {
2
2
  CrossTabDataBus,
3
3
  parseDataBusPublication,
4
4
  selectWorkerBackend
5
- } from "./chunk-UN5Q6JUA.js";
5
+ } from "./chunk-2PUSQWOL.js";
6
6
 
7
7
  // src/centrifuge-session.ts
8
8
  import { Centrifuge } from "centrifuge";
@@ -1285,6 +1285,7 @@ var CrossTabDataBus = class {
1285
1285
  pendingStop = null;
1286
1286
  // Minimum interval in ms between automatic recovery attempts.
1287
1287
  recoveryCooldownMs;
1288
+ recoveryMaxAttempts;
1288
1289
  constructor(options) {
1289
1290
  const replay = options.replay;
1290
1291
  if (replay) {
@@ -1316,9 +1317,13 @@ var CrossTabDataBus = class {
1316
1317
  }
1317
1318
  const { autoStart, initialConfig, trace, transport, dedup, recovery, ...clusterOptions } = options;
1318
1319
  this.recoveryCooldownMs = recovery?.cooldownMs ?? 1e3;
1320
+ this.recoveryMaxAttempts = recovery?.maxAttempts ?? Number.POSITIVE_INFINITY;
1319
1321
  if (!Number.isFinite(this.recoveryCooldownMs) || this.recoveryCooldownMs <= 0) {
1320
1322
  throw new TypeError("recovery.cooldownMs must be a positive finite number.");
1321
1323
  }
1324
+ if (!(this.recoveryMaxAttempts === Number.POSITIVE_INFINITY || Number.isSafeInteger(this.recoveryMaxAttempts) && this.recoveryMaxAttempts > 0)) {
1325
+ throw new TypeError("recovery.maxAttempts must be a positive safe integer.");
1326
+ }
1322
1327
  this.now = dedup?.now ?? Date.now;
1323
1328
  this.replayHydration = this.hydrateReplay();
1324
1329
  this.transport = transport;
@@ -1877,6 +1882,10 @@ var CrossTabDataBus = class {
1877
1882
  if (now - this.lastRecoveryAt >= this.recoveryCooldownMs) {
1878
1883
  this.lastRecoveryAt = now;
1879
1884
  const attempt = ++this.recoveryAttempt;
1885
+ if (attempt > this.recoveryMaxAttempts) {
1886
+ this.trace.event({ type: "reliability", operation: "transport_recovery", attempt: this.recoveryMaxAttempts, outcome: "exhausted" });
1887
+ return;
1888
+ }
1880
1889
  this.trace.event({ type: "reliability", operation: "transport_recovery", attempt, outcome: "scheduled" });
1881
1890
  setTimeout(() => {
1882
1891
  if (this.stopping || !this.started || this.suspended) return;
@@ -2095,4 +2104,4 @@ export {
2095
2104
  parseDataBusPublication,
2096
2105
  selectWorkerBackend
2097
2106
  };
2098
- //# sourceMappingURL=chunk-UN5Q6JUA.js.map
2107
+ //# sourceMappingURL=chunk-2PUSQWOL.js.map