cross-tab-worker-databus 0.21.24 → 0.21.26

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.
@@ -2125,7 +2125,9 @@ var ReplayManager = class {
2125
2125
  trace;
2126
2126
  onPersistenceError;
2127
2127
  onDispatchError;
2128
- /** Bumped on suspend/stop so in-flight persistence retries are cancelled. */
2128
+ /** Bumped by exactly one statement, in `suspend()` below — which is where the
2129
+ * `generation !== this.retryGeneration` tests throughout this file look for a
2130
+ * cancellation. This class's own `stop()` does not touch the field. */
2129
2131
  retryGeneration = 0;
2130
2132
  pendingReplayPersistence = [];
2131
2133
  persistenceFlushScheduled = false;
@@ -2284,13 +2286,19 @@ var ReplayManager = class {
2284
2286
  this.scheduleRetentionCleanup(this.now() - this.retentionMs);
2285
2287
  }, this.retentionSweepMs);
2286
2288
  }
2287
- /** Stop the periodic retention sweep. */
2289
+ /** Stop the periodic retention sweep. Its only caller in `src/` is `suspend()`,
2290
+ * which chains it at its end — the class is internal (`ReplayManager` appears
2291
+ * nowhere in the barrel), so no consumer reaches this method directly. It
2292
+ * cancels no in-flight work: that is the `retryGeneration` bump in `suspend()`. */
2288
2293
  stop() {
2289
2294
  if (this.retentionTimer) clearInterval(this.retentionTimer);
2290
2295
  this.retentionTimer = null;
2291
2296
  }
2292
- /** Suspend the manager: cancel in-flight persistence retries (so a hidden tab
2293
- * or stopped bus does not keep hammering the store) and stop the sweep. */
2297
+ /** Cancel in-flight persistence retries by superseding their generation, so a
2298
+ * hidden tab or a stopped bus does not keep hammering the store. This is the
2299
+ * field's only writer; the bus reaches it from its two `replayManager.suspend()`
2300
+ * call sites (the cluster's `onSuspend` handler, and `beginStop()`), and this
2301
+ * class's own `stop()` only clears the sweep timer. */
2294
2302
  suspend() {
2295
2303
  this.retryGeneration += 1;
2296
2304
  if (this.hydration) {
@@ -2464,7 +2472,7 @@ var ReplayManager = class {
2464
2472
  });
2465
2473
  }
2466
2474
  /** Run a persistence operation with exponential backoff on transient failure.
2467
- * Bumped `retryGeneration` (suspend/stop) cancels the loop early; a
2475
+ * The `suspend()` bump of `retryGeneration` cancels the loop early; a
2468
2476
  * structurally failing operation throws after `persistenceRetryMaxAttempts`,
2469
2477
  * leaving the ring buffer intact so the bus keeps working. */
2470
2478
  async withPersistenceRetry(persistenceOperation, operation) {
@@ -2620,7 +2628,7 @@ var SDK_VERSION = (
2620
2628
  // declaration's type is `string | undefined` and the export's is `string`
2621
2629
  // (dropping the conditional is TS2322, measured). Recorded here so the leg reads
2622
2630
  // as a shape the harness cannot reach rather than as a case nobody exercised.
2623
- true ? "0.21.24" : ""
2631
+ true ? "0.21.26" : ""
2624
2632
  );
2625
2633
 
2626
2634
  // src/core/data-bus.ts
@@ -3434,15 +3442,21 @@ var CrossTabDataBus = class {
3434
3442
  }
3435
3443
  /** Deliver a message to every local handler registered for its topic,
3436
3444
  * plus every handler registered with a wildcard subscription that matches
3437
- * (e.g. a handler subscribed to "chat.*" receives "chat.room.1"). */
3445
+ * (e.g. a handler subscribed to "chat.*" receives "chat.room.1"). Both sets are
3446
+ * collected before the first handler runs, so a publication is delivered to the
3447
+ * subscribers that existed when its delivery began — see the note in the body. */
3438
3448
  dispatch(message) {
3439
3449
  this.trace.recordDispatched(message.topic);
3440
- this.invokeHandlers(this.topicHandlers.get(message.topic) ?? [], (handler) => handler(message));
3450
+ const exactHandlers = this.topicHandlers.get(message.topic);
3451
+ const delivered = exactHandlers ? Array.from(exactHandlers) : [];
3452
+ const wildcards = [];
3441
3453
  for (const [pattern, handlers] of this.topicHandlers) {
3442
3454
  if (pattern !== message.topic && topicMatchesPattern(pattern, message.topic)) {
3443
- this.invokeHandlers(handlers, (handler) => handler(message));
3455
+ for (const handler of handlers) wildcards.push(handler);
3444
3456
  }
3445
3457
  }
3458
+ this.invokeHandlers(delivered, (handler) => handler(message));
3459
+ this.invokeHandlers(wildcards, (handler) => handler(message));
3446
3460
  this.replayManager.record(message);
3447
3461
  }
3448
3462
  /**