bun-ws-router
Version:
Lightweight client/server WebSocket router for Bun with type-safe Zod/Valibot validation.
88 lines • 2.87 kB
JavaScript
// SPDX-FileCopyrightText: 2025-present Kriasoft
// SPDX-License-Identifier: MIT
export class MessageQueue {
policy;
maxSize;
queue = [];
overflowCallbacks = new Set();
constructor(policy, maxSize) {
this.policy = policy;
this.maxSize = maxSize;
}
setOverflowCallback(cb) {
if (cb) {
this.overflowCallbacks.add(cb);
}
}
removeOverflowCallback(cb) {
this.overflowCallbacks.delete(cb);
}
/**
* Enqueue a pre-serialized message.
* Returns true if enqueued/sent, false if dropped.
*/
enqueue(message) {
if (this.policy === "off") {
return false; // Drop immediately
}
if (this.queue.length >= this.maxSize) {
if (this.policy === "drop-newest") {
console.warn(`[Client] Queue overflow (${this.maxSize}), dropping newest message`);
for (const cb of Array.from(this.overflowCallbacks)) {
try {
cb(new Error(`Queue overflow: dropping newest message`), {
type: "overflow",
details: { policy: "drop-newest", maxSize: this.maxSize },
});
}
catch (error) {
console.error("[Client] Overflow callback error:", error);
}
}
return false; // Drop new message
}
else if (this.policy === "drop-oldest") {
console.warn(`[Client] Queue overflow (${this.maxSize}), dropping oldest message`);
for (const cb of Array.from(this.overflowCallbacks)) {
try {
cb(new Error(`Queue overflow: dropping oldest message`), {
type: "overflow",
details: { policy: "drop-oldest", maxSize: this.maxSize },
});
}
catch (error) {
console.error("[Client] Overflow callback error:", error);
}
}
this.queue.shift(); // Evict oldest
}
}
this.queue.push(message);
return true;
}
/**
* Flush all queued messages to WebSocket.
* Returns number of messages sent.
*/
flush(ws) {
let sent = 0;
while (this.queue.length > 0) {
const message = this.queue.shift();
if (message !== undefined) {
ws.send(message);
sent++;
}
}
return sent;
}
/**
* Clear queue without sending.
*/
clear() {
this.queue = [];
}
get size() {
return this.queue.length;
}
}
//# sourceMappingURL=queue.js.map