cross-tab-worker-databus 0.20.53 → 0.20.57
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 +20 -0
- package/dist/centrifuge.js +1 -1
- package/dist/{chunk-MHJNBVEK.js → chunk-WAQJT3EE.js} +25 -3
- package/dist/chunk-WAQJT3EE.js.map +7 -0
- package/dist/cjs/centrifuge.cjs +24 -2
- package/dist/cjs/centrifuge.cjs.map +2 -2
- package/dist/cjs/index.cjs +24 -2
- package/dist/cjs/index.cjs.map +2 -2
- package/dist/core/cluster.d.ts +2 -0
- package/dist/core/cluster.d.ts.map +1 -1
- package/dist/core/data-bus.d.ts +2 -0
- package/dist/core/data-bus.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/docs/roadmap.md +5 -1
- package/docs/zh/roadmap.md +5 -1
- package/package.json +1 -1
- package/dist/chunk-MHJNBVEK.js.map +0 -7
package/dist/cjs/centrifuge.cjs
CHANGED
|
@@ -352,6 +352,8 @@ var WorkerClusterRuntime = class {
|
|
|
352
352
|
// membership drives isAssigned() and load. Grows only via CONTROL/SUBSCRIBE
|
|
353
353
|
// (or local self-subscribe), never via the reverse cache.
|
|
354
354
|
assignedTopics = /* @__PURE__ */ new Map();
|
|
355
|
+
routeOwnerCache = /* @__PURE__ */ new Map();
|
|
356
|
+
wildcardPublishCache = /* @__PURE__ */ new Map();
|
|
355
357
|
// Reverse mapping: opaque topicKey → plaintext topic. A bounded cache with
|
|
356
358
|
// FIFO eviction — NOT authoritative. It can hold a topicKey that is also in
|
|
357
359
|
// assignedTopics (the owned guard prevents evicting those), because it is
|
|
@@ -413,6 +415,8 @@ var WorkerClusterRuntime = class {
|
|
|
413
415
|
this.removeLifecycleListeners();
|
|
414
416
|
this.subscribedTopics.clear();
|
|
415
417
|
this.assignedTopics.clear();
|
|
418
|
+
this.routeOwnerCache.clear();
|
|
419
|
+
this.wildcardPublishCache.clear();
|
|
416
420
|
this.knownTopics.clear();
|
|
417
421
|
this.suspended = false;
|
|
418
422
|
}
|
|
@@ -460,6 +464,8 @@ var WorkerClusterRuntime = class {
|
|
|
460
464
|
for (const topic of this.subscribedTopics) this.releaseSubscription(topic, false);
|
|
461
465
|
this.handoffAssignedTopics();
|
|
462
466
|
this.assignedTopics.clear();
|
|
467
|
+
this.routeOwnerCache.clear();
|
|
468
|
+
this.wildcardPublishCache.clear();
|
|
463
469
|
this.removeStorage(this.workerStorageKey(this.workerId));
|
|
464
470
|
this.flushStorage();
|
|
465
471
|
this.notifyRegistry();
|
|
@@ -556,14 +562,27 @@ var WorkerClusterRuntime = class {
|
|
|
556
562
|
if (this.assignedTopics.has(topicKey)) {
|
|
557
563
|
return this.sendControl(this.workerId, "PUBLISH", topic, topicKey, data, metadata);
|
|
558
564
|
}
|
|
565
|
+
const cachedPattern = this.wildcardPublishCache.get(topic);
|
|
566
|
+
if (cachedPattern !== void 0) {
|
|
567
|
+
if (cachedPattern === null || this.assignedTopics.has(cachedPattern)) {
|
|
568
|
+
return this.sendControl(this.workerId, "PUBLISH", topic, topicKey, data, metadata);
|
|
569
|
+
}
|
|
570
|
+
this.wildcardPublishCache.delete(topic);
|
|
571
|
+
}
|
|
559
572
|
for (const pattern of this.assignedTopics.values()) {
|
|
560
573
|
if (pattern !== topic && topicMatchesPattern(pattern, topic)) {
|
|
574
|
+
this.wildcardPublishCache.set(topic, pattern);
|
|
561
575
|
return this.sendControl(this.workerId, "PUBLISH", topic, topicKey, data, metadata);
|
|
562
576
|
}
|
|
563
577
|
}
|
|
578
|
+
this.wildcardPublishCache.set(topic, null);
|
|
564
579
|
const workers = this.readWorkers();
|
|
565
580
|
const route = this.readRoute(topicKey);
|
|
566
|
-
const
|
|
581
|
+
const cached = this.routeOwnerCache.get(topicKey);
|
|
582
|
+
const cachedLive = cached && route && route.generation === cached.generation && route.workerId === cached.workerId && workers.some((worker) => worker.workerId === cached.workerId);
|
|
583
|
+
const target = cachedLive ? cached.workerId : this.routeOwnerIsLive(route, workers) ? route?.workerId ?? this.workerId : this.workerId;
|
|
584
|
+
if (route && target === route.workerId) this.routeOwnerCache.set(topicKey, { workerId: route.workerId, generation: route.generation });
|
|
585
|
+
else this.routeOwnerCache.delete(topicKey);
|
|
567
586
|
return this.sendControl(target, "PUBLISH", topic, topicKey, data, metadata);
|
|
568
587
|
}
|
|
569
588
|
/** True when `route` exists and its owner worker is among `workers`.
|
|
@@ -1287,6 +1306,7 @@ var CrossTabDataBus = class {
|
|
|
1287
1306
|
// Last transport failure, retained so ready() can surface it to callers who
|
|
1288
1307
|
// never awaited start() directly. Cleared on the next successful start.
|
|
1289
1308
|
lastError = null;
|
|
1309
|
+
lastErrorAt = null;
|
|
1290
1310
|
// Gate that serialises start/stop/suspend/resume — only one lifecycle
|
|
1291
1311
|
// transition at a time. Resets to null once the operation settles.
|
|
1292
1312
|
startPromise = null;
|
|
@@ -1500,6 +1520,7 @@ var CrossTabDataBus = class {
|
|
|
1500
1520
|
this.updateStatus("error");
|
|
1501
1521
|
this.reportError(error);
|
|
1502
1522
|
this.lastError = error;
|
|
1523
|
+
this.lastErrorAt = this.now();
|
|
1503
1524
|
this.transportReady = false;
|
|
1504
1525
|
if (stopClusterOnFailure) {
|
|
1505
1526
|
this.stopping = true;
|
|
@@ -1661,7 +1682,7 @@ var CrossTabDataBus = class {
|
|
|
1661
1682
|
/** Return the current automatic transport recovery state. `hasError` means a transport error is currently retained. */
|
|
1662
1683
|
getRecoveryStats() {
|
|
1663
1684
|
const errorMessage = this.lastError instanceof Error ? this.lastError.message : this.lastError === null ? null : String(this.lastError);
|
|
1664
|
-
return { attempt: this.recoveryAttempt, exhausted: this.recoveryExhausted, maxAttempts: this.recoveryMaxAttempts, hasError: this.lastError !== null, errorMessage };
|
|
1685
|
+
return { attempt: this.recoveryAttempt, exhausted: this.recoveryExhausted, maxAttempts: this.recoveryMaxAttempts, hasError: this.lastError !== null, errorMessage, errorAt: this.lastErrorAt };
|
|
1665
1686
|
}
|
|
1666
1687
|
/** Snapshot of the cluster state (workers, routes, assignments).
|
|
1667
1688
|
* For diagnostics only — the returned object is a shallow copy but
|
|
@@ -1699,6 +1720,7 @@ var CrossTabDataBus = class {
|
|
|
1699
1720
|
this.startPromise = null;
|
|
1700
1721
|
this.pendingStop = null;
|
|
1701
1722
|
this.lastError = null;
|
|
1723
|
+
this.lastErrorAt = null;
|
|
1702
1724
|
this.activeConfig = void 0;
|
|
1703
1725
|
this.recoveryAttempt = 0;
|
|
1704
1726
|
this.recoveryExhausted = false;
|