Skip to content

Expose removeAllListeners() on ListenLiveClient and highlight AbortSignal docs #507

@psipher

Description

@psipher

Proposed changes

  1. Expose a removeAllListeners() (or clearListeners()) method on the ListenLiveClient (the underlying WebSocket wrapper) to allow developers to instantly detach all registered event callbacks before calling .close().
  2. Ensure AbortSignal support is prominently documented in the official README and getting-started guides for listen.v1.connect(), as it's the only safe way to cancel a mid-flight WebSocket handshake.

Context

In real-time streaming architectures (like an Electron app or Node.js backend) where users start and stop transcription sessions rapidly, there is no natively exposed, safe way to bulk-remove all event handlers before teardown.
This leads to:

  • Stray open / close / error handlers firing after .close() is requested.
  • Unwanted reconnect loops triggered by dangling listeners.
  • Memory leaks in long-running applications.
  • Currently, calling connection.removeAllListeners() throws: TypeError: connection.removeAllListeners is not a function
    This behavior is highly unexpected for developers who assume the client implements a standard Node.js EventEmitter pattern. Providing an explicit cleanup method drastically improves developer experience and application stability.

Possible Implementation

Implement a removeAllListeners() method that internally clears the accumulated listeners array or object map. Since the SDK mimics a DOM EventTarget, something like this on the internal ReconnectingWebSocket wrapper:

public removeAllListeners(): void {
    // If listeners are stored in an array/map internally:
    this._listeners = { error: [], message: [], open: [], close: [] };
}

Alternatively, expose clearListeners() as an alias for the same behavior.

Other information

SDK Version: @deepgram/sdk v5.4.0
Language: TypeScript / Node.js v24.x
OS: Windows 10 / Windows 11
Scope: This issue is not isolated to ListenV1Socket. The same V1Socket base pattern is shared across:

  • AgentV1Socket [Agent Socket]
  • SpeakV1Socket [Speak Socket]
    All three share the identical eventHandlers pattern and lack removeAllListeners(). A fix at the shared base class level would resolve the issue across all three WebSocket clients in one change.

Note: I checked that AbortSignal is supported internally via the abortSignal option on connect(), but because it's not prominently documented for the V5 SDK, it's easy for developers to miss it and face uncancelable Promises during teardown.

Current Workaround in use: Since .on() overwrites previous handlers, I am currently forcing a cleanup by overriding the handlers with no-ops before closing:

connection.on('open', () => {});
connection.on('close', () => {});
connection.on('message', () => {});
connection.on('error', () => {});
connection.close();

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions