cross-tab-worker-databus 0.20.92 → 0.20.94
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 -1
- package/dist/centrifuge.js +1 -1
- package/dist/centrifuge.shared.worker.js +44 -21
- package/dist/centrifuge.shared.worker.js.map +3 -3
- package/dist/centrifuge.worker.js +44 -21
- package/dist/centrifuge.worker.js.map +3 -3
- package/dist/{chunk-QB74C4EH.js → chunk-RTTTA6JS.js} +41 -7
- package/dist/chunk-RTTTA6JS.js.map +7 -0
- package/dist/cjs/centrifuge.cjs +40 -6
- package/dist/cjs/centrifuge.cjs.map +2 -2
- package/dist/cjs/index.cjs +40 -6
- package/dist/cjs/index.cjs.map +2 -2
- package/dist/cjs/vue.cjs +1 -5
- package/dist/cjs/vue.cjs.map +2 -2
- package/dist/core/cluster.d.ts.map +1 -1
- package/dist/core/environment.d.ts.map +1 -1
- package/dist/core/storage-batch.d.ts +4 -0
- package/dist/core/storage-batch.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/vue.d.ts.map +1 -1
- package/dist/vue.js +1 -5
- package/dist/vue.js.map +2 -2
- package/docs/benchmarks.md +10 -10
- package/docs/configuration.md +2 -0
- package/docs/release-checklist.md +1 -1
- package/docs/roadmap.md +19 -5
- package/docs/zh/benchmarks.md +10 -10
- package/docs/zh/configuration.md +2 -0
- package/docs/zh/release-checklist.md +1 -1
- package/docs/zh/roadmap.md +19 -5
- package/package.json +6 -5
- package/dist/chunk-QB74C4EH.js.map +0 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## [0.20.94] - 2026-09-22
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- `useCrossTabSubscription` in the Vue adapter no longer registers a watcher on its own `handler` parameter. That binding cannot change, so the effect was permanently inert while implying handlers could be swapped in place; the subscription now binds the handler directly with identical delivery behavior.
|
|
7
|
+
- The CI `verify` gate no longer fails on runner load. The package/compat gates spawn five subprocesses per case against vitest's 5000ms default and the seeded lifecycle fuzzer ran at 98% of its own 30s budget under coverage instrumentation; the unit-suite ceiling is now 15s and the fuzzer holds an explicit 120s.
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
- Coverage thresholds moved from advisory to enforced: the floors were 85/80/90/85 while the suite measured 98.13/94.59/98.17/99.19, so a change could lose ten points of branch coverage and still pass the release gate. They are now 96/92/96/97.
|
|
11
|
+
- Nine previously unasserted behaviors now have mutation-verified regressions: route-owner-cache eviction and its LRU ordering (the old test passed with the eviction loop deleted outright), the failed-hydration retry on the next `start()`, the metadata-less item of an unpacked remote batch, the `replay.maxPerTopic` / `pruneStrategy` option guards, `serializeError`'s no-`structuredClone` branch, superseded-client `state` / `disconnected` isolation, the async credential-provider rejection reply, the WebSocket shared handshake gate, and the single-item batch frame shapes.
|
|
12
|
+
|
|
13
|
+
## [0.20.93] - 2026-09-19
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- The compatibility gate now rejects disabled public exports, removed worker default conditions, conditional exports replaced with untyped strings or null type targets, incompatible package-level `types`/`typesVersions` metadata, unavailable unconditional targets, destructive fallback-array changes, and removed nested or custom export conditions.
|
|
17
|
+
- Storage capability detection now requires a complete write-read-delete round trip, so write-only or unreadable adapters enter the existing local-mode fallback instead of starting coordination against an unusable registry.
|
|
18
|
+
- Cluster startup now degrades safely when channel construction throws, and tab identity remains stable within the document when session storage is unavailable or unreadable.
|
|
19
|
+
- Storage writer cleanup now cancels pending retries and resets backoff before a failing clear and after final cluster teardown flushes, preventing background writes from surviving page hide or stop.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
- Refreshed patch-level development dependencies used by the test and lint toolchain.
|
|
4
23
|
|
|
5
24
|
## [0.20.92] - 2026-09-18
|
|
6
25
|
|
package/dist/centrifuge.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// node_modules/.pnpm/centrifuge@5.7.
|
|
1
|
+
// node_modules/.pnpm/centrifuge@5.7.4/node_modules/centrifuge/build/index.mjs
|
|
2
2
|
function __awaiter(thisArg, _arguments, P, generator) {
|
|
3
3
|
function adopt(value) {
|
|
4
4
|
return value instanceof P ? value : new P(function(resolve) {
|
|
@@ -494,6 +494,16 @@ function errorExists(data) {
|
|
|
494
494
|
function ttlMilliseconds(ttl) {
|
|
495
495
|
return Math.min(ttl * 1e3, 2147483647);
|
|
496
496
|
}
|
|
497
|
+
function localStorageItem(key) {
|
|
498
|
+
try {
|
|
499
|
+
if (typeof localStorage === "undefined" || localStorage === null || !isFunction(localStorage.getItem)) {
|
|
500
|
+
return null;
|
|
501
|
+
}
|
|
502
|
+
return localStorage.getItem(key);
|
|
503
|
+
} catch (e) {
|
|
504
|
+
return null;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
497
507
|
var MapPhase;
|
|
498
508
|
(function(MapPhase2) {
|
|
499
509
|
MapPhase2[MapPhase2["Live"] = 0] = "Live";
|
|
@@ -796,6 +806,7 @@ var BaseSubscription = class extends EventEmitter {
|
|
|
796
806
|
}
|
|
797
807
|
_clearSubscribedState() {
|
|
798
808
|
this._clearRefreshTimeout();
|
|
809
|
+
this._cancelAllDebounce();
|
|
799
810
|
this._clearSharedPollSignatureRefresh();
|
|
800
811
|
this._clearSharedPollTrackRetry();
|
|
801
812
|
this._clearSharedPollReplayRetry();
|
|
@@ -1237,12 +1248,13 @@ var BaseSubscription = class extends EventEmitter {
|
|
|
1237
1248
|
return;
|
|
1238
1249
|
if (typeof pub.data === "string") {
|
|
1239
1250
|
const rawBytes = pub.data;
|
|
1251
|
+
const encoded = new TextEncoder().encode(rawBytes);
|
|
1240
1252
|
if (!pub.removed) {
|
|
1241
|
-
this._prevValueMap.set(pub.key,
|
|
1253
|
+
this._prevValueMap.set(pub.key, encoded);
|
|
1242
1254
|
} else {
|
|
1243
1255
|
this._prevValueMap.delete(pub.key);
|
|
1244
1256
|
}
|
|
1245
|
-
const byteLen =
|
|
1257
|
+
const byteLen = encoded.length;
|
|
1246
1258
|
this._deltaNumPubs++;
|
|
1247
1259
|
this._deltaNumFull++;
|
|
1248
1260
|
this._deltaBytesReceived += byteLen;
|
|
@@ -2531,7 +2543,7 @@ var HttpStreamTransport = class {
|
|
|
2531
2543
|
}
|
|
2532
2544
|
try {
|
|
2533
2545
|
if (self2._protocol === "json") {
|
|
2534
|
-
jsonStreamBuf += self2._utf8decoder.decode(value);
|
|
2546
|
+
jsonStreamBuf += self2._utf8decoder.decode(value, { stream: true });
|
|
2535
2547
|
while (jsonStreamPos < jsonStreamBuf.length) {
|
|
2536
2548
|
if (jsonStreamBuf[jsonStreamPos] === "\n") {
|
|
2537
2549
|
const line = jsonStreamBuf.substring(0, jsonStreamPos);
|
|
@@ -2826,9 +2838,9 @@ var WebtransportTransport = class {
|
|
|
2826
2838
|
try {
|
|
2827
2839
|
while (true) {
|
|
2828
2840
|
const { done, value } = yield reader.read();
|
|
2829
|
-
if (value.length > 0) {
|
|
2841
|
+
if (value && value.length > 0) {
|
|
2830
2842
|
if (this._protocol === "json") {
|
|
2831
|
-
jsonStreamBuf += this._utf8decoder.decode(value);
|
|
2843
|
+
jsonStreamBuf += this._utf8decoder.decode(value, { stream: true });
|
|
2832
2844
|
while (jsonStreamPos < jsonStreamBuf.length) {
|
|
2833
2845
|
if (jsonStreamBuf[jsonStreamPos] === "\n") {
|
|
2834
2846
|
const line = jsonStreamBuf.substring(0, jsonStreamPos);
|
|
@@ -3170,7 +3182,7 @@ var JsonCodec = class {
|
|
|
3170
3182
|
return data.trim().split("\n").map((r) => JSON.parse(r));
|
|
3171
3183
|
}
|
|
3172
3184
|
applyDeltaIfNeeded(pub, prevValue) {
|
|
3173
|
-
let newData, newPrevValue;
|
|
3185
|
+
let newData, newPrevValue, wireBytes;
|
|
3174
3186
|
let isDelta;
|
|
3175
3187
|
if (pub.delta) {
|
|
3176
3188
|
isDelta = true;
|
|
@@ -3178,12 +3190,14 @@ var JsonCodec = class {
|
|
|
3178
3190
|
const valueArray = applyDelta(prevValue, deltaBytes);
|
|
3179
3191
|
newData = JSON.parse(new TextDecoder().decode(valueArray));
|
|
3180
3192
|
newPrevValue = valueArray;
|
|
3193
|
+
wireBytes = deltaBytes.length;
|
|
3181
3194
|
} else {
|
|
3182
3195
|
isDelta = false;
|
|
3183
3196
|
newData = JSON.parse(pub.data);
|
|
3184
3197
|
newPrevValue = new TextEncoder().encode(pub.data);
|
|
3198
|
+
wireBytes = newPrevValue.length;
|
|
3185
3199
|
}
|
|
3186
|
-
return { newData, newPrevValue, isDelta, wireBytes
|
|
3200
|
+
return { newData, newPrevValue, isDelta, wireBytes, fullBytes: newPrevValue.length };
|
|
3187
3201
|
}
|
|
3188
3202
|
};
|
|
3189
3203
|
var defaults = {
|
|
@@ -3683,7 +3697,7 @@ var Centrifuge = class extends EventEmitter {
|
|
|
3683
3697
|
}
|
|
3684
3698
|
this._codec = new JsonCodec();
|
|
3685
3699
|
this._formatOverride();
|
|
3686
|
-
if (this._config.debug === true ||
|
|
3700
|
+
if (this._config.debug === true || localStorageItem("centrifuge.debug")) {
|
|
3687
3701
|
this._debugEnabled = true;
|
|
3688
3702
|
}
|
|
3689
3703
|
this._debug("config", this._config);
|
|
@@ -3829,6 +3843,13 @@ var Centrifuge = class extends EventEmitter {
|
|
|
3829
3843
|
}
|
|
3830
3844
|
return true;
|
|
3831
3845
|
}
|
|
3846
|
+
_advanceTransportIndex() {
|
|
3847
|
+
this._currentTransportIndex++;
|
|
3848
|
+
if (this._currentTransportIndex >= this._transports.length) {
|
|
3849
|
+
this._triedAllTransports = true;
|
|
3850
|
+
this._currentTransportIndex = 0;
|
|
3851
|
+
}
|
|
3852
|
+
}
|
|
3832
3853
|
_initializeTransport() {
|
|
3833
3854
|
let websocket;
|
|
3834
3855
|
if (this._config.websocket !== null) {
|
|
@@ -3902,7 +3923,7 @@ var Centrifuge = class extends EventEmitter {
|
|
|
3902
3923
|
});
|
|
3903
3924
|
if (!this._transport.supported()) {
|
|
3904
3925
|
this._debug("websocket transport not available");
|
|
3905
|
-
this.
|
|
3926
|
+
this._advanceTransportIndex();
|
|
3906
3927
|
count++;
|
|
3907
3928
|
continue;
|
|
3908
3929
|
}
|
|
@@ -3915,7 +3936,7 @@ var Centrifuge = class extends EventEmitter {
|
|
|
3915
3936
|
});
|
|
3916
3937
|
if (!this._transport.supported()) {
|
|
3917
3938
|
this._debug("webtransport transport not available");
|
|
3918
|
-
this.
|
|
3939
|
+
this._advanceTransportIndex();
|
|
3919
3940
|
count++;
|
|
3920
3941
|
continue;
|
|
3921
3942
|
}
|
|
@@ -3930,7 +3951,7 @@ var Centrifuge = class extends EventEmitter {
|
|
|
3930
3951
|
});
|
|
3931
3952
|
if (!this._transport.supported()) {
|
|
3932
3953
|
this._debug("http_stream transport not available");
|
|
3933
|
-
this.
|
|
3954
|
+
this._advanceTransportIndex();
|
|
3934
3955
|
count++;
|
|
3935
3956
|
continue;
|
|
3936
3957
|
}
|
|
@@ -3943,7 +3964,7 @@ var Centrifuge = class extends EventEmitter {
|
|
|
3943
3964
|
});
|
|
3944
3965
|
if (!this._transport.supported()) {
|
|
3945
3966
|
this._debug("sse transport not available");
|
|
3946
|
-
this.
|
|
3967
|
+
this._advanceTransportIndex();
|
|
3947
3968
|
count++;
|
|
3948
3969
|
continue;
|
|
3949
3970
|
}
|
|
@@ -3955,7 +3976,7 @@ var Centrifuge = class extends EventEmitter {
|
|
|
3955
3976
|
});
|
|
3956
3977
|
if (!this._transport.supported()) {
|
|
3957
3978
|
this._debug("sockjs transport not available");
|
|
3958
|
-
this.
|
|
3979
|
+
this._advanceTransportIndex();
|
|
3959
3980
|
count++;
|
|
3960
3981
|
continue;
|
|
3961
3982
|
}
|
|
@@ -4053,11 +4074,7 @@ var Centrifuge = class extends EventEmitter {
|
|
|
4053
4074
|
reason = "transport closed";
|
|
4054
4075
|
}
|
|
4055
4076
|
if (self2._emulation && !self2._transportWasOpen) {
|
|
4056
|
-
self2.
|
|
4057
|
-
if (self2._currentTransportIndex >= self2._transports.length) {
|
|
4058
|
-
self2._triedAllTransports = true;
|
|
4059
|
-
self2._currentTransportIndex = 0;
|
|
4060
|
-
}
|
|
4077
|
+
self2._advanceTransportIndex();
|
|
4061
4078
|
}
|
|
4062
4079
|
} else {
|
|
4063
4080
|
self2._transportWasOpen = true;
|
|
@@ -4343,7 +4360,7 @@ var Centrifuge = class extends EventEmitter {
|
|
|
4343
4360
|
});
|
|
4344
4361
|
}
|
|
4345
4362
|
}
|
|
4346
|
-
p
|
|
4363
|
+
p.then(() => {
|
|
4347
4364
|
finishDispatch();
|
|
4348
4365
|
});
|
|
4349
4366
|
}
|
|
@@ -4395,6 +4412,12 @@ var Centrifuge = class extends EventEmitter {
|
|
|
4395
4412
|
this._subs[channel]._invalidateState();
|
|
4396
4413
|
}
|
|
4397
4414
|
}
|
|
4415
|
+
for (const channel in this._serverSubs) {
|
|
4416
|
+
if (this._serverSubs.hasOwnProperty(channel)) {
|
|
4417
|
+
this._serverSubs[channel].offset = 0;
|
|
4418
|
+
this._serverSubs[channel].epoch = "_";
|
|
4419
|
+
}
|
|
4420
|
+
}
|
|
4398
4421
|
}
|
|
4399
4422
|
if (this._isDisconnected()) {
|
|
4400
4423
|
return;
|
|
@@ -4406,7 +4429,7 @@ var Centrifuge = class extends EventEmitter {
|
|
|
4406
4429
|
code,
|
|
4407
4430
|
reason
|
|
4408
4431
|
};
|
|
4409
|
-
let needEvent
|
|
4432
|
+
let needEvent;
|
|
4410
4433
|
if (reconnect) {
|
|
4411
4434
|
needEvent = this._setState(State.Connecting);
|
|
4412
4435
|
} else {
|