Files
VoiceAgent/dist/core/WebSocketManager.js
Bijit Mondal 5e7eb469ae feat: Introduce new core components for conversation and speech management
- Added ConversationManager for managing conversation history with configurable limits.
- Implemented InputQueue for serial processing of input items.
- Created SpeechManager for handling text-to-speech generation and streaming.
- Developed StreamProcessor for processing LLM streams and forwarding events.
- Added TranscriptionManager for audio transcription using AI SDK.
- Introduced WebSocketManager for managing WebSocket connections and messaging.
- Updated VoiceAgent to support new architecture and improved socket handling.
- Refactored index files to export new core components.
2026-02-23 16:15:49 +05:30

126 lines
3.8 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebSocketManager = void 0;
const ws_1 = require("ws");
const events_1 = require("events");
/**
* Manages a single WebSocket connection lifecycle.
* Handles connecting, attaching existing sockets, sending messages,
* and clean disconnection.
*/
class WebSocketManager extends events_1.EventEmitter {
socket;
_isConnected = false;
get isConnected() {
return this._isConnected;
}
get currentSocket() {
return this.socket;
}
/**
* Connect to a WebSocket server by URL.
*/
connect(url) {
// Clean up any existing connection first
if (this.socket) {
this.disconnect();
}
return new Promise((resolve, reject) => {
try {
this.socket = new ws_1.WebSocket(url);
this.attachListeners();
this.socket.once("open", () => {
this._isConnected = true;
this.emit("connected");
resolve();
});
this.socket.once("error", (error) => {
reject(error);
});
}
catch (error) {
reject(error);
}
});
}
/**
* Attach an existing WebSocket (server-side usage).
*/
handleSocket(socket) {
// Clean up any existing connection first
if (this.socket) {
this.disconnect();
}
this.socket = socket;
this._isConnected = true;
this.attachListeners();
this.emit("connected");
}
/**
* Send a JSON message via WebSocket if connected.
* Gracefully handles send failures (e.g., socket closing mid-send).
*/
send(message) {
if (!this.socket || !this._isConnected)
return;
try {
if (this.socket.readyState === ws_1.WebSocket.OPEN) {
this.socket.send(JSON.stringify(message));
}
else {
console.warn(`Cannot send message, socket state: ${this.socket.readyState}`);
}
}
catch (error) {
// Socket may have closed between the readyState check and send()
console.error("Failed to send WebSocket message:", error);
this.emit("error", error);
}
}
/**
* Disconnect and clean up the current socket.
*/
disconnect() {
if (!this.socket)
return;
try {
this.socket.removeAllListeners();
if (this.socket.readyState === ws_1.WebSocket.OPEN ||
this.socket.readyState === ws_1.WebSocket.CONNECTING) {
this.socket.close();
}
}
catch {
// Ignore close errors — socket may already be dead
}
this.socket = undefined;
this._isConnected = false;
}
/**
* Attach internal event listeners on the current socket.
*/
attachListeners() {
if (!this.socket)
return;
this.socket.on("message", (data) => {
try {
const message = JSON.parse(data.toString());
this.emit("message", message);
}
catch (err) {
console.error("Failed to parse WebSocket message:", err);
this.emit("error", err);
}
});
this.socket.on("close", () => {
this._isConnected = false;
this.emit("disconnected");
});
this.socket.on("error", (error) => {
console.error("WebSocket error:", error);
this.emit("error", error);
});
}
}
exports.WebSocketManager = WebSocketManager;
//# sourceMappingURL=WebSocketManager.js.map