cross-tab-worker-databus 0.20.94 → 0.20.96
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 +21 -0
- package/dist/centrifuge.d.ts +4 -4
- package/dist/centrifuge.d.ts.map +1 -1
- package/dist/centrifuge.js +13 -14
- package/dist/centrifuge.js.map +2 -2
- package/dist/{chunk-RTTTA6JS.js → chunk-SSSJNWCH.js} +28 -12
- package/dist/{chunk-RTTTA6JS.js.map → chunk-SSSJNWCH.js.map} +2 -2
- package/dist/cjs/centrifuge.cjs +39 -24
- package/dist/cjs/centrifuge.cjs.map +2 -2
- package/dist/cjs/hooks.cjs +1 -4
- package/dist/cjs/hooks.cjs.map +2 -2
- package/dist/cjs/index.cjs +27 -11
- package/dist/cjs/index.cjs.map +2 -2
- package/dist/core/cluster.d.ts.map +1 -1
- package/dist/core/data-bus.d.ts +6 -0
- package/dist/core/data-bus.d.ts.map +1 -1
- package/dist/core/storage-batch.d.ts.map +1 -1
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +1 -4
- package/dist/hooks.js.map +2 -2
- package/dist/index.js +1 -1
- package/docs/api.md +1 -0
- package/docs/architecture.md +2 -0
- package/docs/benchmarks.md +9 -9
- package/docs/configuration.md +1 -1
- package/docs/getting-started.md +2 -0
- package/docs/release-checklist.md +1 -1
- package/docs/roadmap.md +17 -1
- package/docs/zh/api.md +1 -0
- package/docs/zh/architecture.md +2 -0
- package/docs/zh/benchmarks.md +9 -9
- package/docs/zh/configuration.md +1 -1
- package/docs/zh/getting-started.md +2 -0
- package/docs/zh/release-checklist.md +1 -1
- package/docs/zh/roadmap.md +17 -1
- package/package.json +2 -2
package/dist/cjs/centrifuge.cjs
CHANGED
|
@@ -542,11 +542,11 @@ var BatchingStorageWriter = class {
|
|
|
542
542
|
if (typeof queueMicrotask === "function") queueMicrotask(flush);
|
|
543
543
|
else setTimeout(flush, 0);
|
|
544
544
|
}
|
|
545
|
-
//
|
|
546
|
-
//
|
|
547
|
-
//
|
|
545
|
+
// Arm the single backoff timer for the pass that just failed. Exactly one
|
|
546
|
+
// retry can be in flight because flush() — the only caller — cancels any
|
|
547
|
+
// armed retry on entry and stops at the first failing key, so this always
|
|
548
|
+
// runs with `retryHandle` cleared.
|
|
548
549
|
scheduleRetry() {
|
|
549
|
-
if (this.retryHandle !== null) return;
|
|
550
550
|
this.retryHandle = setTimeout(() => {
|
|
551
551
|
this.retryHandle = null;
|
|
552
552
|
this.flush();
|
|
@@ -747,9 +747,8 @@ var WorkerClusterRuntime = class {
|
|
|
747
747
|
touchRouteOwnerCache(topicKey, value) {
|
|
748
748
|
if (this.routeOwnerCache.has(topicKey)) this.routeOwnerCache.delete(topicKey);
|
|
749
749
|
this.routeOwnerCache.set(topicKey, value);
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
if (oldest === void 0) break;
|
|
750
|
+
for (const oldest of this.routeOwnerCache.keys()) {
|
|
751
|
+
if (this.routeOwnerCache.size <= this.routeOwnerCacheMax) break;
|
|
753
752
|
this.routeOwnerCache.delete(oldest);
|
|
754
753
|
}
|
|
755
754
|
}
|
|
@@ -2407,9 +2406,8 @@ var DedupManager = class {
|
|
|
2407
2406
|
this.accepted += 1;
|
|
2408
2407
|
this.windowAccepted += 1;
|
|
2409
2408
|
this.trace.recordDedupAccepted();
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
if (oldest === void 0) break;
|
|
2409
|
+
for (const oldest of this.seenMessageIds.keys()) {
|
|
2410
|
+
if (this.seenMessageIds.size <= this.maxEntries) break;
|
|
2413
2411
|
this.seenMessageIds.delete(oldest);
|
|
2414
2412
|
}
|
|
2415
2413
|
return false;
|
|
@@ -2470,7 +2468,7 @@ var DedupManager = class {
|
|
|
2470
2468
|
};
|
|
2471
2469
|
|
|
2472
2470
|
// src/core/version.ts
|
|
2473
|
-
var SDK_VERSION = true ? "0.20.
|
|
2471
|
+
var SDK_VERSION = true ? "0.20.96" : "";
|
|
2474
2472
|
|
|
2475
2473
|
// src/core/data-bus.ts
|
|
2476
2474
|
var DEFAULT_REPLAY_MAX_PER_TOPIC = 100;
|
|
@@ -2561,6 +2559,10 @@ var CrossTabDataBus = class {
|
|
|
2561
2559
|
// themselves demand: the failure path starts an on-demand reopen instead of
|
|
2562
2560
|
// stranding them until some unrelated future operation arrives.
|
|
2563
2561
|
recoveryWaiters = 0;
|
|
2562
|
+
// Latch for the empty-topic deprecation warning so a hot publish path cannot
|
|
2563
|
+
// fill the console. It is per-bus and never reset: the warning is about the
|
|
2564
|
+
// caller's code, not about a transient runtime condition.
|
|
2565
|
+
emptyTopicWarned = false;
|
|
2564
2566
|
/** Monotonic generation incremented on every successful transport open.
|
|
2565
2567
|
* Stays in lockstep with `lastSuccessAt` so callers can detect that the
|
|
2566
2568
|
* transport has been reopened even if the timestamp window is short. */
|
|
@@ -2965,6 +2967,7 @@ var CrossTabDataBus = class {
|
|
|
2965
2967
|
};
|
|
2966
2968
|
}
|
|
2967
2969
|
this.ensureStarted();
|
|
2970
|
+
if (topic === "") this.warnEmptyTopic("subscribe");
|
|
2968
2971
|
const handlers = this.topicHandlers.get(topic) ?? /* @__PURE__ */ new Set();
|
|
2969
2972
|
const wasUnused = handlers.size === 0;
|
|
2970
2973
|
handlers.add(handler);
|
|
@@ -3014,8 +3017,20 @@ var CrossTabDataBus = class {
|
|
|
3014
3017
|
resetDedup() {
|
|
3015
3018
|
this.dedupManager.reset();
|
|
3016
3019
|
}
|
|
3020
|
+
/** Warn (once per bus) that an empty topic is deprecated, without changing
|
|
3021
|
+
* behavior yet. `''` flows through routing as a literal channel, so the
|
|
3022
|
+
* subscription it creates can never be addressed by a transport: the message
|
|
3023
|
+
* silently goes nowhere. A future minor rejects it at this boundary. */
|
|
3024
|
+
warnEmptyTopic(operation) {
|
|
3025
|
+
if (this.emptyTopicWarned) return;
|
|
3026
|
+
this.emptyTopicWarned = true;
|
|
3027
|
+
console.warn(
|
|
3028
|
+
`cross-tab-worker-databus: ${operation}("") addresses a channel no transport can route. Use a non-empty topic; passing "" is planned to throw in a future minor.`
|
|
3029
|
+
);
|
|
3030
|
+
}
|
|
3017
3031
|
/** Publish a message to `topic`. The owning Worker delivers it to the transport. */
|
|
3018
3032
|
publish(topic, data, options) {
|
|
3033
|
+
if (topic === "") this.warnEmptyTopic("publish");
|
|
3019
3034
|
this.ensureStarted();
|
|
3020
3035
|
if (this.rejectPublishDuringStop("publish")) return;
|
|
3021
3036
|
if (!this.cluster.publish(topic, data, options)) {
|
|
@@ -3034,6 +3049,7 @@ var CrossTabDataBus = class {
|
|
|
3034
3049
|
publishBatch(topic, items) {
|
|
3035
3050
|
this.ensureStarted();
|
|
3036
3051
|
if (items.length === 0) return;
|
|
3052
|
+
if (topic === "") this.warnEmptyTopic("publishBatch");
|
|
3037
3053
|
if (this.rejectPublishDuringStop("publishBatch")) return;
|
|
3038
3054
|
if (items.length === 1) {
|
|
3039
3055
|
const first = items[0];
|
|
@@ -3926,12 +3942,13 @@ var CentrifugeWorkerTransport = class {
|
|
|
3926
3942
|
heartbeatHandle = null;
|
|
3927
3943
|
localSession = null;
|
|
3928
3944
|
handlers = null;
|
|
3929
|
-
// Monotonically increasing counter, bumped each time a backend is created
|
|
3930
|
-
//
|
|
3945
|
+
// Monotonically increasing counter, bumped each time a backend is created or
|
|
3946
|
+
// the transport stops. Only the asynchronous credential bridge compares it:
|
|
3947
|
+
// a provider may settle after the Worker it was answering is gone. Worker
|
|
3948
|
+
// error events need no such check — stop() and onWorkerFailed() remove those
|
|
3949
|
+
// listeners before the generation moves on, so a superseded backend can no
|
|
3950
|
+
// longer reach this object at all.
|
|
3931
3951
|
generation = 0;
|
|
3932
|
-
// Generation captured when the current backend was created. Error handlers
|
|
3933
|
-
// only act when the backend that registered them is still current.
|
|
3934
|
-
backendGeneration = 0;
|
|
3935
3952
|
get diagnosticsBackend() {
|
|
3936
3953
|
return this.backend ?? "uninitialized";
|
|
3937
3954
|
}
|
|
@@ -4024,7 +4041,7 @@ var CentrifugeWorkerTransport = class {
|
|
|
4024
4041
|
}
|
|
4025
4042
|
/** Create and initialise a dedicated Worker, then send the INIT message. */
|
|
4026
4043
|
startDedicatedWorker(input) {
|
|
4027
|
-
this.
|
|
4044
|
+
this.generation += 1;
|
|
4028
4045
|
const worker = (this.workerFactory ?? createDefaultWorker)();
|
|
4029
4046
|
this.worker = worker;
|
|
4030
4047
|
worker.addEventListener("message", this.handleMessage);
|
|
@@ -4033,7 +4050,7 @@ var CentrifugeWorkerTransport = class {
|
|
|
4033
4050
|
}
|
|
4034
4051
|
/** Create and initialise a SharedWorker, open the MessagePort, and send the INIT message. */
|
|
4035
4052
|
startSharedWorker(input) {
|
|
4036
|
-
this.
|
|
4053
|
+
this.generation += 1;
|
|
4037
4054
|
const shared = (this.sharedWorkerFactory ?? createDefaultSharedWorker)();
|
|
4038
4055
|
this.sharedWorker = shared;
|
|
4039
4056
|
const port = shared.port;
|
|
@@ -4103,9 +4120,10 @@ var CentrifugeWorkerTransport = class {
|
|
|
4103
4120
|
}
|
|
4104
4121
|
/** Handle a Worker-level failure (crash, message decode error). Discards the
|
|
4105
4122
|
* dead backend so a later start()/reopen can rebuild from scratch, and
|
|
4106
|
-
* signals an error status so the DataBus can trigger recovery.
|
|
4107
|
-
*
|
|
4108
|
-
*
|
|
4123
|
+
* signals an error status so the DataBus can trigger recovery. A superseded
|
|
4124
|
+
* backend cannot reach this: its listeners are removed before the transport
|
|
4125
|
+
* moves on, which is what keeps late Worker errors from tearing down a fresh
|
|
4126
|
+
* session (pinned by 'ignores error events from a superseded worker'). */
|
|
4109
4127
|
onWorkerFailed(message) {
|
|
4110
4128
|
this.worker?.removeEventListener("message", this.handleMessage);
|
|
4111
4129
|
this.worker?.removeEventListener("error", this.handleWorkerError);
|
|
@@ -4136,15 +4154,12 @@ var CentrifugeWorkerTransport = class {
|
|
|
4136
4154
|
this.heartbeatHandle = null;
|
|
4137
4155
|
}
|
|
4138
4156
|
handleWorkerError = () => {
|
|
4139
|
-
if (this.generation !== this.backendGeneration) return;
|
|
4140
4157
|
this.onWorkerFailed("Centrifuge worker failed.");
|
|
4141
4158
|
};
|
|
4142
4159
|
handlePortError = () => {
|
|
4143
|
-
if (this.generation !== this.backendGeneration) return;
|
|
4144
4160
|
this.onWorkerFailed("Centrifuge shared worker message decoding failed.");
|
|
4145
4161
|
};
|
|
4146
4162
|
handleSharedWorkerError = () => {
|
|
4147
|
-
if (this.generation !== this.backendGeneration) return;
|
|
4148
4163
|
this.onWorkerFailed("Centrifuge shared worker failed.");
|
|
4149
4164
|
};
|
|
4150
4165
|
/** Clear the Worker/port/backend references after a failure or stop. */
|