cross-tab-worker-databus 0.20.16 → 0.20.18

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,20 @@
2
2
 
3
3
  本项目遵循 [Semantic Versioning](https://semver.org/);变更记录格式参考 [Keep a Changelog](https://keepachangelog.com/)。
4
4
 
5
+ ## [0.20.18] - 2026-09-03
6
+
7
+ ### Added
8
+
9
+ - Added optional `recovery.cooldownMs` to tune automatic transport reopen pacing for different runtime environments.
10
+ - Added validation and fake-timer coverage for custom recovery cooldowns.
11
+
12
+ ## [0.20.17] - 2026-09-03
13
+
14
+ ### Added
15
+
16
+ - Consecutive transport recovery traces now carry monotonic attempt numbers and reset after a successful reopen.
17
+ - Added regression coverage for multi-failure recovery sequences.
18
+
5
19
  ## [0.20.16] - 2026-09-03
6
20
 
7
21
  ### Added
@@ -2,7 +2,7 @@ import {
2
2
  CrossTabDataBus,
3
3
  parseDataBusPublication,
4
4
  selectWorkerBackend
5
- } from "./chunk-WSJN2RG7.js";
5
+ } from "./chunk-UN5Q6JUA.js";
6
6
 
7
7
  // src/centrifuge-session.ts
8
8
  import { Centrifuge } from "centrifuge";
@@ -1220,7 +1220,7 @@ var PersistenceRetryCancelledError = class extends Error {
1220
1220
  this.name = "PersistenceRetryCancelledError";
1221
1221
  }
1222
1222
  };
1223
- var CrossTabDataBus = class _CrossTabDataBus {
1223
+ var CrossTabDataBus = class {
1224
1224
  transport;
1225
1225
  cluster;
1226
1226
  // Map of topic → set of local subscribers.
@@ -1272,6 +1272,9 @@ var CrossTabDataBus = class _CrossTabDataBus {
1272
1272
  // Timestamp of the last automatic transport recovery attempt.
1273
1273
  // Used to avoid a tight retry loop when the transport fails repeatedly.
1274
1274
  lastRecoveryAt = 0;
1275
+ // Monotonic attempt number within one runtime recovery sequence; reset once
1276
+ // a transport reopen succeeds so traces can correlate repeated failures.
1277
+ recoveryAttempt = 0;
1275
1278
  // True while the tab is hidden so an in-flight transport start does not mark
1276
1279
  // the transport ready after suspendTransport() has stopped it.
1277
1280
  suspended = false;
@@ -1281,7 +1284,7 @@ var CrossTabDataBus = class _CrossTabDataBus {
1281
1284
  // stop to settle.
1282
1285
  pendingStop = null;
1283
1286
  // Minimum interval in ms between automatic recovery attempts.
1284
- static RECOVERY_COOLDOWN_MS = 1e3;
1287
+ recoveryCooldownMs;
1285
1288
  constructor(options) {
1286
1289
  const replay = options.replay;
1287
1290
  if (replay) {
@@ -1311,7 +1314,11 @@ var CrossTabDataBus = class _CrossTabDataBus {
1311
1314
  if (!Number.isFinite(this.persistenceRetryBackoffMs) || this.persistenceRetryBackoffMs < 0) {
1312
1315
  throw new TypeError("replay.persistenceRetry.backoffMs must be a non-negative finite number.");
1313
1316
  }
1314
- const { autoStart, initialConfig, trace, transport, dedup, ...clusterOptions } = options;
1317
+ const { autoStart, initialConfig, trace, transport, dedup, recovery, ...clusterOptions } = options;
1318
+ this.recoveryCooldownMs = recovery?.cooldownMs ?? 1e3;
1319
+ if (!Number.isFinite(this.recoveryCooldownMs) || this.recoveryCooldownMs <= 0) {
1320
+ throw new TypeError("recovery.cooldownMs must be a positive finite number.");
1321
+ }
1315
1322
  this.now = dedup?.now ?? Date.now;
1316
1323
  this.replayHydration = this.hydrateReplay();
1317
1324
  this.transport = transport;
@@ -1867,14 +1874,15 @@ var CrossTabDataBus = class _CrossTabDataBus {
1867
1874
  }
1868
1875
  if (status === "error" && this.started && !this.stopping) {
1869
1876
  const now = this.now();
1870
- if (now - this.lastRecoveryAt >= _CrossTabDataBus.RECOVERY_COOLDOWN_MS) {
1877
+ if (now - this.lastRecoveryAt >= this.recoveryCooldownMs) {
1871
1878
  this.lastRecoveryAt = now;
1872
- this.trace.event({ type: "reliability", operation: "transport_recovery", attempt: 1, outcome: "scheduled" });
1879
+ const attempt = ++this.recoveryAttempt;
1880
+ this.trace.event({ type: "reliability", operation: "transport_recovery", attempt, outcome: "scheduled" });
1873
1881
  setTimeout(() => {
1874
1882
  if (this.stopping || !this.started || this.suspended) return;
1875
1883
  if (this.status !== "error") return;
1876
- void this.reopenTransport();
1877
- }, _CrossTabDataBus.RECOVERY_COOLDOWN_MS);
1884
+ void this.reopenTransport(attempt);
1885
+ }, this.recoveryCooldownMs);
1878
1886
  }
1879
1887
  }
1880
1888
  this.invokeHandlers(this.statusHandlers, (handler) => handler(status));
@@ -1964,10 +1972,11 @@ var CrossTabDataBus = class _CrossTabDataBus {
1964
1972
  * its rejection so the reopen is not blocked. Returns the opening promise so
1965
1973
  * callers can queue operations behind it.
1966
1974
  */
1967
- reopenTransport() {
1975
+ reopenTransport(recoveryAttempt) {
1968
1976
  if (this.stopping || this.activeConfig === void 0) return Promise.resolve();
1969
1977
  if (this.startPromise && this.startPromise !== this.pendingStop) return this.startPromise;
1970
1978
  const config = this.activeConfig;
1979
+ const traceAttempt = recoveryAttempt ?? (this.recoveryAttempt > 0 ? this.recoveryAttempt : void 0);
1971
1980
  this.started = true;
1972
1981
  this.suspended = false;
1973
1982
  this.updateStatus("connecting");
@@ -1976,11 +1985,16 @@ var CrossTabDataBus = class _CrossTabDataBus {
1976
1985
  this.startPromise = opening;
1977
1986
  void opening.then(
1978
1987
  () => {
1979
- this.trace.event({ type: "reliability", operation: "transport_recovery", attempt: 1, outcome: "succeeded" });
1988
+ if (traceAttempt !== void 0) {
1989
+ this.trace.event({ type: "reliability", operation: "transport_recovery", attempt: traceAttempt, outcome: "succeeded" });
1990
+ this.recoveryAttempt = 0;
1991
+ }
1980
1992
  if (this.startPromise === opening) this.startPromise = null;
1981
1993
  },
1982
1994
  () => {
1983
- this.trace.event({ type: "reliability", operation: "transport_recovery", attempt: 1, outcome: "failed" });
1995
+ if (traceAttempt !== void 0) {
1996
+ this.trace.event({ type: "reliability", operation: "transport_recovery", attempt: traceAttempt, outcome: "failed" });
1997
+ }
1984
1998
  }
1985
1999
  );
1986
2000
  void opening.catch(() => void 0);
@@ -2081,4 +2095,4 @@ export {
2081
2095
  parseDataBusPublication,
2082
2096
  selectWorkerBackend
2083
2097
  };
2084
- //# sourceMappingURL=chunk-WSJN2RG7.js.map
2098
+ //# sourceMappingURL=chunk-UN5Q6JUA.js.map