cross-tab-worker-databus 0.7.0 → 0.8.0
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 +7 -1
- package/dist/centrifuge-protocol.d.ts +4 -0
- package/dist/centrifuge-protocol.d.ts.map +1 -1
- package/dist/centrifuge-session.d.ts.map +1 -1
- package/dist/centrifuge.d.ts +2 -1
- package/dist/centrifuge.d.ts.map +1 -1
- package/dist/centrifuge.js +13 -10
- package/dist/centrifuge.js.map +2 -2
- package/dist/centrifuge.shared.worker.js +7 -4
- package/dist/centrifuge.shared.worker.js.map +2 -2
- package/dist/centrifuge.worker.js +7 -4
- package/dist/centrifuge.worker.js.map +2 -2
- package/dist/{chunk-SI7N5KNJ.js → chunk-WWUY2FV2.js} +35 -14
- package/dist/chunk-WWUY2FV2.js.map +7 -0
- package/dist/cjs/centrifuge.cjs +46 -22
- package/dist/cjs/centrifuge.cjs.map +2 -2
- package/dist/cjs/index.cjs +48 -18
- package/dist/cjs/index.cjs.map +2 -2
- package/dist/core/cluster.d.ts +2 -2
- package/dist/core/cluster.d.ts.map +1 -1
- package/dist/core/data-bus.d.ts +4 -2
- package/dist/core/data-bus.d.ts.map +1 -1
- package/dist/core/trace.d.ts +2 -11
- package/dist/core/trace.d.ts.map +1 -1
- package/dist/core/types.d.ts +8 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -6
- package/dist/index.js.map +2 -2
- package/dist/websocket.d.ts +2 -2
- package/dist/websocket.d.ts.map +1 -1
- package/docs/api.md +12 -2
- package/docs/zh/api.md +12 -2
- package/package.json +1 -1
- package/dist/chunk-SI7N5KNJ.js.map +0 -7
package/dist/cjs/centrifuge.cjs
CHANGED
|
@@ -549,20 +549,20 @@ var WorkerClusterRuntime = class {
|
|
|
549
549
|
* posted to a remote owner, so the caller can surface the failure instead of
|
|
550
550
|
* silently dropping the publication.
|
|
551
551
|
*/
|
|
552
|
-
publish(topic, data) {
|
|
552
|
+
publish(topic, data, messageId) {
|
|
553
553
|
const topicKey = this.rememberTopic(topic);
|
|
554
554
|
if (this.assignedTopics.has(topicKey)) {
|
|
555
|
-
return this.sendControl(this.workerId, "PUBLISH", topic, topicKey, data);
|
|
555
|
+
return this.sendControl(this.workerId, "PUBLISH", topic, topicKey, data, messageId);
|
|
556
556
|
}
|
|
557
557
|
for (const pattern of this.assignedTopics.values()) {
|
|
558
558
|
if (pattern !== topic && topicMatchesPattern(pattern, topic)) {
|
|
559
|
-
return this.sendControl(this.workerId, "PUBLISH", topic, topicKey, data);
|
|
559
|
+
return this.sendControl(this.workerId, "PUBLISH", topic, topicKey, data, messageId);
|
|
560
560
|
}
|
|
561
561
|
}
|
|
562
562
|
const workers = this.readWorkers();
|
|
563
563
|
const route = this.readRoute(topicKey);
|
|
564
564
|
const target = this.routeOwnerIsLive(route, workers) ? route?.workerId ?? this.workerId : this.workerId;
|
|
565
|
-
return this.sendControl(target, "PUBLISH", topic, topicKey, data);
|
|
565
|
+
return this.sendControl(target, "PUBLISH", topic, topicKey, data, messageId);
|
|
566
566
|
}
|
|
567
567
|
/** True when `route` exists and its owner worker is among `workers`.
|
|
568
568
|
* Shared by subscribe (skip re-assignment) and publish (route to owner).
|
|
@@ -684,7 +684,11 @@ var WorkerClusterRuntime = class {
|
|
|
684
684
|
default:
|
|
685
685
|
break;
|
|
686
686
|
}
|
|
687
|
-
|
|
687
|
+
if (message.messageId === void 0) {
|
|
688
|
+
this.handlers.onControl(message.action, message.topic, message.data);
|
|
689
|
+
} else {
|
|
690
|
+
this.handlers.onControl(message.action, message.topic, message.data, message.messageId);
|
|
691
|
+
}
|
|
688
692
|
if (message.action !== "PUBLISH") this.updateLoad();
|
|
689
693
|
}
|
|
690
694
|
/**
|
|
@@ -801,7 +805,7 @@ var WorkerClusterRuntime = class {
|
|
|
801
805
|
* Local execution updates the assignment map and route synchronously, bypassing
|
|
802
806
|
* the BroadcastChannel latency.
|
|
803
807
|
*/
|
|
804
|
-
sendControl(targetWorkerId, action, topic, topicKey, data) {
|
|
808
|
+
sendControl(targetWorkerId, action, topic, topicKey, data, messageId) {
|
|
805
809
|
if (targetWorkerId === this.workerId) {
|
|
806
810
|
switch (action) {
|
|
807
811
|
case "SUBSCRIBE":
|
|
@@ -815,7 +819,8 @@ var WorkerClusterRuntime = class {
|
|
|
815
819
|
default:
|
|
816
820
|
break;
|
|
817
821
|
}
|
|
818
|
-
this.handlers.onControl(action, topic, data);
|
|
822
|
+
if (messageId === void 0) this.handlers.onControl(action, topic, data);
|
|
823
|
+
else this.handlers.onControl(action, topic, data, messageId);
|
|
819
824
|
if (action !== "PUBLISH") this.updateLoad();
|
|
820
825
|
return true;
|
|
821
826
|
}
|
|
@@ -826,7 +831,8 @@ var WorkerClusterRuntime = class {
|
|
|
826
831
|
action,
|
|
827
832
|
topic,
|
|
828
833
|
topicKey,
|
|
829
|
-
...data === void 0 ? {} : { data }
|
|
834
|
+
...data === void 0 ? {} : { data },
|
|
835
|
+
...messageId === void 0 ? {} : { messageId }
|
|
830
836
|
});
|
|
831
837
|
}
|
|
832
838
|
/** Post a message on the BroadcastChannel. Returns false on postMessage failure. */
|
|
@@ -1278,7 +1284,7 @@ var CrossTabDataBus = class _CrossTabDataBus {
|
|
|
1278
1284
|
handlers: {
|
|
1279
1285
|
// The cluster calls `onControl` when it receives a SUBSCRIBE/UNSUBSCRIBE/PUBLISH
|
|
1280
1286
|
// control message — meaning the owning Worker has delegated the action to us.
|
|
1281
|
-
onControl: (action, topic, data) => {
|
|
1287
|
+
onControl: (action, topic, data, messageId) => {
|
|
1282
1288
|
switch (action) {
|
|
1283
1289
|
case "SUBSCRIBE":
|
|
1284
1290
|
if (this.subscribeTransport(topic)) this.traceSubscription("subscribe", topic);
|
|
@@ -1287,7 +1293,7 @@ var CrossTabDataBus = class _CrossTabDataBus {
|
|
|
1287
1293
|
if (this.unsubscribeTransport(topic)) this.traceSubscription("unsubscribe", topic);
|
|
1288
1294
|
break;
|
|
1289
1295
|
case "PUBLISH":
|
|
1290
|
-
this.runTransport(() => this.transport.publish(topic, data));
|
|
1296
|
+
this.runTransport(() => this.transport.publish(topic, data, messageId ? { messageId } : void 0));
|
|
1291
1297
|
break;
|
|
1292
1298
|
default:
|
|
1293
1299
|
break;
|
|
@@ -1466,10 +1472,22 @@ var CrossTabDataBus = class _CrossTabDataBus {
|
|
|
1466
1472
|
}
|
|
1467
1473
|
this.cluster.unsubscribe(topic);
|
|
1468
1474
|
}
|
|
1475
|
+
/** Clear all in-memory replay buffers and, when supported, durable history. */
|
|
1476
|
+
async clearReplay() {
|
|
1477
|
+
this.replayBuffers?.clear();
|
|
1478
|
+
if (this.replayPersistence?.clear) {
|
|
1479
|
+
try {
|
|
1480
|
+
await this.replayPersistence.clear();
|
|
1481
|
+
} catch (error) {
|
|
1482
|
+
this.reportError(error);
|
|
1483
|
+
throw error;
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1469
1487
|
/** Publish a message to `topic`. The owning Worker delivers it to the transport. */
|
|
1470
|
-
publish(topic, data) {
|
|
1488
|
+
publish(topic, data, options) {
|
|
1471
1489
|
this.ensureStarted();
|
|
1472
|
-
if (!this.cluster.publish(topic, data)) {
|
|
1490
|
+
if (!this.cluster.publish(topic, data, options?.messageId)) {
|
|
1473
1491
|
this.reportError(
|
|
1474
1492
|
new Error("Failed to send the publish control message to the owning worker.")
|
|
1475
1493
|
);
|
|
@@ -1556,7 +1574,10 @@ var CrossTabDataBus = class _CrossTabDataBus {
|
|
|
1556
1574
|
for (const [id, timestamp] of this.seenMessageIds) {
|
|
1557
1575
|
if (now - timestamp > this.dedupTtlMs) this.seenMessageIds.delete(id);
|
|
1558
1576
|
}
|
|
1559
|
-
if (this.seenMessageIds.has(message.messageId))
|
|
1577
|
+
if (this.seenMessageIds.has(message.messageId)) {
|
|
1578
|
+
this.trace.event({ type: "reliability", operation: "dedup_suppressed", topic: message.topic });
|
|
1579
|
+
return true;
|
|
1580
|
+
}
|
|
1560
1581
|
this.seenMessageIds.set(message.messageId, now);
|
|
1561
1582
|
while (this.seenMessageIds.size > this.dedupMaxEntries) {
|
|
1562
1583
|
const oldest = this.seenMessageIds.keys().next().value;
|
|
@@ -1830,7 +1851,7 @@ var CentrifugeSession = class {
|
|
|
1830
1851
|
return;
|
|
1831
1852
|
case "PUBLISH":
|
|
1832
1853
|
case "PUBLISH_BIN":
|
|
1833
|
-
this.publish(message.topic, message.data);
|
|
1854
|
+
this.publish(message.topic, message.data, message.messageId);
|
|
1834
1855
|
return;
|
|
1835
1856
|
case "STOP":
|
|
1836
1857
|
this.stop();
|
|
@@ -1895,9 +1916,10 @@ var CentrifugeSession = class {
|
|
|
1895
1916
|
subscription.unsubscribe();
|
|
1896
1917
|
}
|
|
1897
1918
|
/** Publish a message to the Centrifuge channel. */
|
|
1898
|
-
publish(topic, data) {
|
|
1919
|
+
publish(topic, data, messageId) {
|
|
1899
1920
|
if (!this.client) return this.postError(new Error("Centrifuge client is not initialized."));
|
|
1900
|
-
|
|
1921
|
+
const payload = messageId ? { data, messageId } : data;
|
|
1922
|
+
void this.client.publish(topic, payload).catch((error) => this.postError(error));
|
|
1901
1923
|
}
|
|
1902
1924
|
/** Forward a publication to the transport. Binary payloads take the
|
|
1903
1925
|
* zero-copy `MESSAGE_BIN` path when `transferable` is enabled; everything
|
|
@@ -1909,7 +1931,9 @@ var CentrifugeSession = class {
|
|
|
1909
1931
|
this.post({ type: "MESSAGE_BIN", topic, data }, [data]);
|
|
1910
1932
|
return;
|
|
1911
1933
|
}
|
|
1912
|
-
|
|
1934
|
+
const messageId = data && typeof data === "object" && typeof data.messageId === "string" ? data.messageId : void 0;
|
|
1935
|
+
const payload = messageId && Object.prototype.hasOwnProperty.call(data, "data") ? data.data : data;
|
|
1936
|
+
this.post({ type: "MESSAGE", topic, data: payload, ...messageId ? { messageId } : {} });
|
|
1913
1937
|
}
|
|
1914
1938
|
/** Disconnect the client and clear all subscriptions. */
|
|
1915
1939
|
stop() {
|
|
@@ -2039,12 +2063,12 @@ var CentrifugeWorkerTransport = class {
|
|
|
2039
2063
|
* Publish data to `topic`. Binary data (ArrayBuffer) is sent via Transferable
|
|
2040
2064
|
* when `transferable` is enabled, avoiding a structured-clone cycle.
|
|
2041
2065
|
*/
|
|
2042
|
-
publish(topic, data) {
|
|
2066
|
+
publish(topic, data, options) {
|
|
2043
2067
|
if (this.transferable && data instanceof ArrayBuffer) {
|
|
2044
|
-
this.post({ type: "PUBLISH_BIN", topic, data }, [data]);
|
|
2068
|
+
this.post({ type: "PUBLISH_BIN", topic, data, ...options?.messageId ? { messageId: options.messageId } : {} }, [data]);
|
|
2045
2069
|
return;
|
|
2046
2070
|
}
|
|
2047
|
-
this.post({ type: "PUBLISH", topic, data });
|
|
2071
|
+
this.post({ type: "PUBLISH", topic, data, ...options?.messageId ? { messageId: options.messageId } : {} });
|
|
2048
2072
|
}
|
|
2049
2073
|
/**
|
|
2050
2074
|
* Gracefully stop the transport: send STOP, clean up event listeners, and
|
|
@@ -2115,8 +2139,8 @@ var CentrifugeWorkerTransport = class {
|
|
|
2115
2139
|
* and the local-session sink — all three feed into this single dispatcher. */
|
|
2116
2140
|
handleOutput(message) {
|
|
2117
2141
|
if (message.type === "STATUS") this.handlers?.onStatus(message.status);
|
|
2118
|
-
if (message.type === "MESSAGE") this.handlers?.onMessage({ topic: message.topic, data: message.data });
|
|
2119
|
-
if (message.type === "MESSAGE_BIN") this.handlers?.onMessage({ topic: message.topic, data: message.data });
|
|
2142
|
+
if (message.type === "MESSAGE") this.handlers?.onMessage({ topic: message.topic, data: message.data, ...message.messageId ? { messageId: message.messageId } : {} });
|
|
2143
|
+
if (message.type === "MESSAGE_BIN") this.handlers?.onMessage({ topic: message.topic, data: message.data, ...message.messageId ? { messageId: message.messageId } : {} });
|
|
2120
2144
|
if (message.type === "ERROR") this.handlers?.onError(deserializeWorkerError(message.error));
|
|
2121
2145
|
}
|
|
2122
2146
|
/** Handle a Worker-level failure (crash, message decode error). Discards the
|