cross-tab-worker-databus 0.21.41 → 0.21.43

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.
@@ -1253,7 +1253,7 @@ var WorkerClusterRuntime = class {
1253
1253
  /** Handle a point-to-point CONTROL message (SUBSCRIBE / UNSUBSCRIBE / PUBLISH). */
1254
1254
  handleControlMessage(message) {
1255
1255
  if (message.targetWorkerId !== this.workerId) return;
1256
- if (message.topicKey !== void 0 && createOpaqueKey(message.topic) !== message.topicKey) return;
1256
+ if (createOpaqueKey(message.topic) !== message.topicKey) return;
1257
1257
  this.rememberTopic(message.topic);
1258
1258
  switch (message.action) {
1259
1259
  case CONTROL_ACTION.SUBSCRIBE: {
@@ -2461,6 +2461,8 @@ var DedupManager = class {
2461
2461
  seenMessageIds = /* @__PURE__ */ new Map();
2462
2462
  sweepTimer = null;
2463
2463
  windowStartedAt = 0;
2464
+ /** The most recent finite reading of `now`, and the fallback for a broken one. */
2465
+ lastFiniteNow = 0;
2464
2466
  windowAccepted = 0;
2465
2467
  suppressed = 0;
2466
2468
  accepted = 0;
@@ -2472,14 +2474,46 @@ var DedupManager = class {
2472
2474
  this.sweepMs = options.sweepMs;
2473
2475
  this.now = options.now;
2474
2476
  this.trace = options.trace;
2475
- this.windowStartedAt = this.now();
2477
+ this.lastFiniteNow = Number.isFinite(this.now()) ? this.now() : 0;
2478
+ this.windowStartedAt = this.lastFiniteNow;
2479
+ }
2480
+ /**
2481
+ * The injected clock, normalized.
2482
+ *
2483
+ * `dedup.now` is a public option and a non-wall-clock host is exactly the case it
2484
+ * exists for — one whose reading can be *missing* rather than merely unusual. Every
2485
+ * comparison this class makes is arithmetic on a timestamp, so a single non-finite
2486
+ * reading does not degrade one field: `now - timestamp > ttlMs` becomes
2487
+ * `NaN > ttlMs` (false, so nothing expires), the adaptive window's
2488
+ * `elapsed >= ADAPTIVE_WINDOW_MS` never fires, and `getStats().ttlMs` reports
2489
+ * `NaN` — which `JSON.stringify` turns into `null`, so a health summary or a
2490
+ * diagnostics log would carry a null where a duration belongs. Measured on the
2491
+ * pre-fix class: `getStats().ttlMs` → `NaN`, serialized → `null`, and an id
2492
+ * stayed suppressed for as long as it stayed in the map.
2493
+ *
2494
+ * Holding the last finite reading is the degradation that changes least: time
2495
+ * stands still, expiry pauses, and the adaptive window keeps the value it last
2496
+ * computed. Substituting `Date.now()` would be worse — it silently mixes two
2497
+ * clocks — and zeroing would expire the whole map on the next call. This is the
2498
+ * same class of guard `trace.ts` carries on its own public clock, and that
2499
+ * `websocket.ts` and `replay-manager.ts` apply to their numeric options; it is one
2500
+ * helper rather than a condition per site because the broken input is the *clock*,
2501
+ * not any particular comparison.
2502
+ */
2503
+ nowMs() {
2504
+ const reading = this.now();
2505
+ if (Number.isFinite(reading)) {
2506
+ this.lastFiniteNow = reading;
2507
+ return reading;
2508
+ }
2509
+ return this.lastFiniteNow;
2476
2510
  }
2477
2511
  /** True when a publication carrying `messageId` was already seen. Records the
2478
2512
  * ID and updates counters/trace on acceptance. Disabled or ID-less messages
2479
2513
  * always pass through. */
2480
2514
  isDuplicate(messageId, topic) {
2481
2515
  if (!this.enabled || !messageId) return false;
2482
- const now = this.now();
2516
+ const now = this.nowMs();
2483
2517
  const ttlMs = this.currentTtl();
2484
2518
  for (const [id, timestamp] of this.seenMessageIds) {
2485
2519
  if (now - timestamp > ttlMs) this.seenMessageIds.delete(id);
@@ -2530,12 +2564,12 @@ var DedupManager = class {
2530
2564
  this.seenMessageIds.clear();
2531
2565
  this.suppressed = 0;
2532
2566
  this.accepted = 0;
2533
- this.windowStartedAt = this.now();
2567
+ this.windowStartedAt = this.nowMs();
2534
2568
  this.windowAccepted = 0;
2535
2569
  }
2536
2570
  /** Remove IDs whose timestamp predates the effective TTL cutoff. */
2537
2571
  pruneExpired() {
2538
- const cutoff = this.now() - this.currentTtl();
2572
+ const cutoff = this.nowMs() - this.currentTtl();
2539
2573
  for (const [id, timestamp] of this.seenMessageIds) {
2540
2574
  if (timestamp < cutoff) this.seenMessageIds.delete(id);
2541
2575
  }
@@ -2546,7 +2580,7 @@ var DedupManager = class {
2546
2580
  * every ADAPTIVE_WINDOW_MS. */
2547
2581
  currentTtl() {
2548
2582
  if (!this.adaptiveBounds) return this.ttlMs;
2549
- const now = this.now();
2583
+ const now = this.nowMs();
2550
2584
  const elapsed = now - this.windowStartedAt;
2551
2585
  if (elapsed >= ADAPTIVE_WINDOW_MS) {
2552
2586
  this.windowStartedAt = now;
@@ -2570,7 +2604,7 @@ var SDK_VERSION = (
2570
2604
  // declaration's type is `string | undefined` and the export's is `string`
2571
2605
  // (dropping the conditional is TS2322, measured). Recorded here so the leg reads
2572
2606
  // as a shape the harness cannot reach rather than as a case nobody exercised.
2573
- true ? "0.21.41" : ""
2607
+ true ? "0.21.43" : ""
2574
2608
  );
2575
2609
 
2576
2610
  // src/core/data-bus.ts