mirror of
https://github.com/Bijit-Mondal/VoiceAgent.git
synced 2026-03-02 18:36:39 +00:00
- 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.
126 lines
3.8 KiB
JavaScript
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
|