diff --git a/src/lib/enums/LiveTTSEvents.ts b/src/lib/enums/LiveTTSEvents.ts index b7e9a7e..6c39a47 100644 --- a/src/lib/enums/LiveTTSEvents.ts +++ b/src/lib/enums/LiveTTSEvents.ts @@ -24,6 +24,11 @@ export enum LiveTTSEvents { Flushed = "Flushed", Warning = "Warning", + /** + * Audio data event. + */ + Audio = "Audio", + /** * Catch all for any other message event */ diff --git a/src/packages/AbstractLiveClient.ts b/src/packages/AbstractLiveClient.ts index b0cf78c..088fffc 100644 --- a/src/packages/AbstractLiveClient.ts +++ b/src/packages/AbstractLiveClient.ts @@ -2,6 +2,7 @@ import { AbstractClient, noop } from "./AbstractClient"; import { CONNECTION_STATE, SOCKET_STATES } from "../lib/constants"; import type { DeepgramClientOptions, LiveSchema } from "../lib/types"; import type { WebSocket as WSWebSocket } from "ws"; +import { LiveTTSEvents } from "../lib/enums"; /** * Represents a constructor for a WebSocket-like object that can be used in the application. @@ -258,6 +259,48 @@ export abstract class AbstractLiveClient extends AbstractClient { * @abstract Requires subclasses to set up context aware event handlers. */ abstract setupConnection(): void; + + /** + * Handles incoming messages from the WebSocket connection. + * @param event - The MessageEvent object representing the received message. + */ + protected handleMessage(event: MessageEvent): void { + if (typeof event.data === "string") { + try { + const data = JSON.parse(event.data); + this.handleTextMessage(data); + } catch (error) { + this.emit(LiveTTSEvents.Error, { + event, + message: "Unable to parse `data` as JSON.", + error, + }); + } + } else if (event.data instanceof ArrayBuffer) { + this.handleBinaryMessage(event.data); + } else { + this.emit(LiveTTSEvents.Error, { + event, + message: "Received unknown data type.", + }); + } + } + + /** + * Handles text messages received from the WebSocket connection. + * @param data - The parsed JSON data. + */ + protected handleTextMessage(data: any): void { + // To be implemented by subclasses + } + + /** + * Handles binary messages received from the WebSocket connection. + * @param data - The binary data. + */ + protected handleBinaryMessage(data: ArrayBuffer): void { + // To be implemented by subclasses + } } class WSWebSocketDummy { diff --git a/src/packages/SpeakLiveClient.ts b/src/packages/SpeakLiveClient.ts index 0cc7051..a3c12ef 100644 --- a/src/packages/SpeakLiveClient.ts +++ b/src/packages/SpeakLiveClient.ts @@ -58,29 +58,35 @@ export class SpeakLiveClient extends AbstractLiveClient { }; this.conn.onmessage = (event: MessageEvent) => { - try { - const data: any = JSON.parse(event.data.toString()); - - if (data.type === LiveTTSEvents.Metadata) { - this.emit(LiveTTSEvents.Metadata, data); - } else if (data.type === LiveTTSEvents.Flushed) { - this.emit(LiveTTSEvents.Flushed, data); - } else if (data.type === "Warning") { - this.emit(LiveTTSEvents.Warning, data); - } else { - this.emit(LiveTTSEvents.Unhandled, data); - } - } catch (error) { - this.emit(LiveTTSEvents.Error, { - event, - message: "Unable to parse `data` as JSON.", - error, - }); - } + this.handleMessage(event); }; } } + /** + * Handles text messages received from the WebSocket connection. + * @param data - The parsed JSON data. + */ + protected handleTextMessage(data: any): void { + if (data.type === LiveTTSEvents.Metadata) { + this.emit(LiveTTSEvents.Metadata, data); + } else if (data.type === LiveTTSEvents.Flushed) { + this.emit(LiveTTSEvents.Flushed, data); + } else if (data.type === LiveTTSEvents.Warning) { + this.emit(LiveTTSEvents.Warning, data); + } else { + this.emit(LiveTTSEvents.Unhandled, data); + } + } + + /** + * Handles binary messages received from the WebSocket connection. + * @param data - The binary data. + */ + protected handleBinaryMessage(data: ArrayBuffer): void { + this.emit(LiveTTSEvents.Audio, data); + } + /** * Sends a text input message to the server. *