cross-tab-worker-databus 0.20.70 → 0.20.71

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.
@@ -1442,6 +1442,8 @@ var CrossTabDataBus = class {
1442
1442
  persistenceRetryMaxAttempts;
1443
1443
  persistenceRetryBackoffMs;
1444
1444
  persistenceRetryGeneration = 0;
1445
+ pendingReplayPersistence = [];
1446
+ replayPersistenceFlushScheduled = false;
1445
1447
  replayHydration;
1446
1448
  // Retention cleanup is coalesced so a burst of publications does not issue
1447
1449
  // one IndexedDB read/write transaction per message. The newest cutoff wins.
@@ -2076,12 +2078,28 @@ var CrossTabDataBus = class {
2076
2078
  }
2077
2079
  }
2078
2080
  if (this.replayPersistence) {
2079
- void this.withPersistenceRetry("append", () => this.replayPersistence.append(storedMessage)).catch((error) => this.reportPersistenceError(error));
2081
+ if (this.replayPersistence.appendBatch) {
2082
+ this.pendingReplayPersistence.push(storedMessage);
2083
+ this.scheduleReplayPersistenceFlush();
2084
+ } else {
2085
+ void this.withPersistenceRetry("append", () => this.replayPersistence.append(storedMessage)).catch((error) => this.reportPersistenceError(error));
2086
+ }
2080
2087
  if (this.replayRetentionMs !== void 0 && this.replayPersistence.clearBefore) {
2081
2088
  this.scheduleReplayRetentionCleanup(this.now() - this.replayRetentionMs);
2082
2089
  }
2083
2090
  }
2084
2091
  }
2092
+ scheduleReplayPersistenceFlush() {
2093
+ if (this.replayPersistenceFlushScheduled) return;
2094
+ this.replayPersistenceFlushScheduled = true;
2095
+ queueMicrotask(() => {
2096
+ this.replayPersistenceFlushScheduled = false;
2097
+ const batch = this.pendingReplayPersistence.splice(0);
2098
+ if (batch.length === 0 || !this.replayPersistence) return;
2099
+ const operation = this.replayPersistence.appendBatch ? () => this.replayPersistence.appendBatch(batch) : () => Promise.all(batch.map((message) => this.replayPersistence.append(message))).then(() => void 0);
2100
+ void this.withPersistenceRetry("append", operation).catch((error) => this.reportPersistenceError(error));
2101
+ });
2102
+ }
2085
2103
  async hydrateReplay() {
2086
2104
  if (!this.replayBuffers || !this.replayPersistence) {
2087
2105
  return;
@@ -2485,6 +2503,46 @@ function createIndexedDbReplayPersistence(options) {
2485
2503
  });
2486
2504
  });
2487
2505
  },
2506
+ appendBatch(messages) {
2507
+ if (messages.length === 0) return Promise.resolve();
2508
+ return serializeMutation(async () => {
2509
+ const db = await open();
2510
+ await new Promise((resolve, reject) => {
2511
+ let transaction;
2512
+ try {
2513
+ transaction = db.transaction(storeName, "readwrite");
2514
+ } catch (error) {
2515
+ invalidate(db);
2516
+ reject(error);
2517
+ return;
2518
+ }
2519
+ const store = transaction.objectStore(storeName);
2520
+ const grouped = /* @__PURE__ */ new Map();
2521
+ for (const message of messages) grouped.set(message.topic, [...grouped.get(message.topic) ?? [], message]);
2522
+ for (const [topic, topicMessages] of grouped) {
2523
+ const request = store.get(topic);
2524
+ request.onsuccess = () => {
2525
+ let history = (request.result?.messages ?? []).concat(topicMessages);
2526
+ if (pruneStrategy !== "count" && retentionMs !== void 0) {
2527
+ const cutoff = Date.now() - retentionMs;
2528
+ history = history.filter((item) => item.timestamp === void 0 || item.timestamp >= cutoff);
2529
+ }
2530
+ if (pruneStrategy !== "age") history = history.slice(-maxPerTopic);
2531
+ store.put({ topic, messages: history });
2532
+ };
2533
+ request.onerror = () => {
2534
+ invalidate(db);
2535
+ reject(request.error ?? new Error("Failed to read replay history."));
2536
+ };
2537
+ }
2538
+ transaction.oncomplete = () => resolve();
2539
+ transaction.onerror = () => {
2540
+ invalidate(db);
2541
+ reject(transaction.error ?? new Error("Failed to persist replay history batch."));
2542
+ };
2543
+ });
2544
+ });
2545
+ },
2488
2546
  clear() {
2489
2547
  return serializeMutation(async () => {
2490
2548
  const db = await open();