cross-tab-worker-databus 0.10.0 → 0.11.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 +13 -0
- package/README.md +1 -0
- package/README.zh.md +1 -0
- package/dist/centrifuge.js +1 -1
- package/dist/{chunk-ZOPNTR4E.js → chunk-NX76TAV3.js} +28 -2
- package/dist/{chunk-ZOPNTR4E.js.map → chunk-NX76TAV3.js.map} +2 -2
- package/dist/cjs/centrifuge.cjs +27 -1
- package/dist/cjs/centrifuge.cjs.map +2 -2
- package/dist/cjs/index.cjs +27 -1
- package/dist/cjs/index.cjs.map +2 -2
- package/dist/core/data-bus.d.ts +3 -0
- package/dist/core/data-bus.d.ts.map +1 -1
- package/dist/core/trace.d.ts +7 -0
- package/dist/core/trace.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/docs/api.md +2 -2
- package/docs/architecture.md +4 -0
- package/docs/capabilities.md +2 -2
- package/docs/configuration.md +1 -1
- package/docs/roadmap.md +15 -1
- package/docs/zh/api.md +2 -2
- package/docs/zh/architecture.md +4 -0
- package/docs/zh/capabilities.md +2 -2
- package/docs/zh/configuration.md +1 -1
- package/package.json +1 -1
package/dist/cjs/centrifuge.cjs
CHANGED
|
@@ -1066,6 +1066,8 @@ var DataBusTraceReporter = class {
|
|
|
1066
1066
|
// Bucketed histogram: bucket index = floor(delayMs / 50), capped at 19.
|
|
1067
1067
|
latencyBuckets = new Array(LATENCY_BUCKET_COUNT).fill(0);
|
|
1068
1068
|
latencySumMs = 0;
|
|
1069
|
+
dedupAccepted = 0;
|
|
1070
|
+
dedupSuppressed = 0;
|
|
1069
1071
|
constructor(options, now = Date.now) {
|
|
1070
1072
|
this.enabled = options?.enabled ?? false;
|
|
1071
1073
|
this.mode = options?.mode ?? "all";
|
|
@@ -1141,6 +1143,13 @@ var DataBusTraceReporter = class {
|
|
|
1141
1143
|
this.latencyBuckets[bucketIndex] = (this.latencyBuckets[bucketIndex] ?? 0) + 1;
|
|
1142
1144
|
this.latencySumMs += delayMs;
|
|
1143
1145
|
}
|
|
1146
|
+
/** Record deduplication outcomes for the next metrics window. */
|
|
1147
|
+
recordDedupAccepted() {
|
|
1148
|
+
if (this.metricsActive) this.dedupAccepted += 1;
|
|
1149
|
+
}
|
|
1150
|
+
recordDedupSuppressed() {
|
|
1151
|
+
if (this.metricsActive) this.dedupSuppressed += 1;
|
|
1152
|
+
}
|
|
1144
1153
|
/** True when metrics recording is active: enabled and mode includes metrics.
|
|
1145
1154
|
* Extracted so the four record / flush methods share one guard expression
|
|
1146
1155
|
* instead of repeating `!this.enabled || this.mode === 'events'` at each. */
|
|
@@ -1154,7 +1163,7 @@ var DataBusTraceReporter = class {
|
|
|
1154
1163
|
}
|
|
1155
1164
|
flushNow() {
|
|
1156
1165
|
const timestamp = this.now();
|
|
1157
|
-
if (this.received > 0 || this.dispatched > 0) {
|
|
1166
|
+
if (this.received > 0 || this.dispatched > 0 || this.dedupAccepted > 0 || this.dedupSuppressed > 0) {
|
|
1158
1167
|
const samples = this.latencySamples;
|
|
1159
1168
|
this.emit({
|
|
1160
1169
|
type: "message_metrics",
|
|
@@ -1168,6 +1177,8 @@ var DataBusTraceReporter = class {
|
|
|
1168
1177
|
dispatchP50Ms: roundMs(percentileMs(this.latencyBuckets, samples, 0.5)),
|
|
1169
1178
|
dispatchP95Ms: roundMs(percentileMs(this.latencyBuckets, samples, 0.95)),
|
|
1170
1179
|
dispatchMaxMs: roundMs(percentileMs(this.latencyBuckets, samples, 1)),
|
|
1180
|
+
dedupAccepted: this.dedupAccepted,
|
|
1181
|
+
dedupSuppressed: this.dedupSuppressed,
|
|
1171
1182
|
timestamp
|
|
1172
1183
|
});
|
|
1173
1184
|
this.resetMetrics();
|
|
@@ -1182,6 +1193,8 @@ var DataBusTraceReporter = class {
|
|
|
1182
1193
|
this.receivedAt.clear();
|
|
1183
1194
|
this.latencyBuckets.fill(0);
|
|
1184
1195
|
this.latencySumMs = 0;
|
|
1196
|
+
this.dedupAccepted = 0;
|
|
1197
|
+
this.dedupSuppressed = 0;
|
|
1185
1198
|
}
|
|
1186
1199
|
emit(event) {
|
|
1187
1200
|
try {
|
|
@@ -1232,6 +1245,7 @@ var CrossTabDataBus = class _CrossTabDataBus {
|
|
|
1232
1245
|
replayBuffers;
|
|
1233
1246
|
replayMaxPerTopic;
|
|
1234
1247
|
replayPersistence;
|
|
1248
|
+
replayRetentionMs;
|
|
1235
1249
|
replayHydration;
|
|
1236
1250
|
initialConfig;
|
|
1237
1251
|
hasInitialConfig;
|
|
@@ -1279,6 +1293,10 @@ var CrossTabDataBus = class _CrossTabDataBus {
|
|
|
1279
1293
|
this.replayMaxPerTopic = replay?.maxPerTopic ?? DEFAULT_REPLAY_MAX_PER_TOPIC;
|
|
1280
1294
|
this.replayBuffers = replay ? /* @__PURE__ */ new Map() : null;
|
|
1281
1295
|
this.replayPersistence = replay?.persistence ?? null;
|
|
1296
|
+
this.replayRetentionMs = replay?.retentionMs;
|
|
1297
|
+
if (this.replayRetentionMs !== void 0 && (!Number.isFinite(this.replayRetentionMs) || this.replayRetentionMs <= 0)) {
|
|
1298
|
+
throw new TypeError("replay.retentionMs must be a positive finite number.");
|
|
1299
|
+
}
|
|
1282
1300
|
this.replayHydration = this.hydrateReplay();
|
|
1283
1301
|
const { autoStart, initialConfig, trace, transport, dedup, ...clusterOptions } = options;
|
|
1284
1302
|
this.transport = transport;
|
|
@@ -1638,10 +1656,12 @@ var CrossTabDataBus = class _CrossTabDataBus {
|
|
|
1638
1656
|
if (this.seenMessageIds.has(message.messageId)) {
|
|
1639
1657
|
this.trace.event({ type: "reliability", operation: "dedup_suppressed", topic: message.topic });
|
|
1640
1658
|
this.dedupSuppressed += 1;
|
|
1659
|
+
this.trace.recordDedupSuppressed();
|
|
1641
1660
|
return true;
|
|
1642
1661
|
}
|
|
1643
1662
|
this.seenMessageIds.set(message.messageId, now);
|
|
1644
1663
|
this.dedupAccepted += 1;
|
|
1664
|
+
this.trace.recordDedupAccepted();
|
|
1645
1665
|
while (this.seenMessageIds.size > this.dedupMaxEntries) {
|
|
1646
1666
|
const oldest = this.seenMessageIds.keys().next().value;
|
|
1647
1667
|
if (oldest === void 0) break;
|
|
@@ -1676,6 +1696,9 @@ var CrossTabDataBus = class _CrossTabDataBus {
|
|
|
1676
1696
|
if (buffer.length > this.replayMaxPerTopic) buffer.shift();
|
|
1677
1697
|
if (this.replayPersistence) {
|
|
1678
1698
|
void this.replayPersistence.append(storedMessage).catch((error) => this.reportError(error));
|
|
1699
|
+
if (this.replayRetentionMs !== void 0 && this.replayPersistence.clearBefore) {
|
|
1700
|
+
void this.replayPersistence.clearBefore(Date.now() - this.replayRetentionMs).catch((error) => this.reportError(error));
|
|
1701
|
+
}
|
|
1679
1702
|
}
|
|
1680
1703
|
}
|
|
1681
1704
|
async hydrateReplay() {
|
|
@@ -1683,6 +1706,9 @@ var CrossTabDataBus = class _CrossTabDataBus {
|
|
|
1683
1706
|
return;
|
|
1684
1707
|
}
|
|
1685
1708
|
try {
|
|
1709
|
+
if (this.replayRetentionMs !== void 0 && this.replayPersistence.clearBefore) {
|
|
1710
|
+
await this.replayPersistence.clearBefore(Date.now() - this.replayRetentionMs);
|
|
1711
|
+
}
|
|
1686
1712
|
for (const message of await this.replayPersistence.load()) {
|
|
1687
1713
|
let buffer = this.replayBuffers.get(message.topic);
|
|
1688
1714
|
if (!buffer) {
|