@deepgram/sdk 5.0.0-alpha.1 → 5.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -42,6 +42,9 @@ const core = __importStar(require("./core/index.js"));
42
42
  function normalizeClientOptions(options) {
43
43
  const headers = (0, headers_js_1.mergeHeaders)({
44
44
  "X-Fern-Language": "JavaScript",
45
+ "X-Fern-SDK-Name": "",
46
+ "X-Fern-SDK-Version": "0.0.219",
47
+ "User-Agent": "/0.0.219",
45
48
  "X-Fern-Runtime": core.RUNTIME.type,
46
49
  "X-Fern-Runtime-Version": core.RUNTIME.version,
47
50
  }, options === null || options === void 0 ? void 0 : options.headers);
@@ -60,6 +60,19 @@ const headers_js_1 = require("./core/headers.js");
60
60
  const json_js_1 = require("./core/json.js");
61
61
  const core = __importStar(require("./core/index.js"));
62
62
  const environments = __importStar(require("./environments.js"));
63
+ const index_js_1 = require("./core/runtime/index.js");
64
+ // Import ws library for Node.js (will be undefined in browser)
65
+ let NodeWebSocket;
66
+ try {
67
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
68
+ NodeWebSocket = require("ws");
69
+ // Handle both default export and named export
70
+ NodeWebSocket = NodeWebSocket.WebSocket || NodeWebSocket.default || NodeWebSocket;
71
+ }
72
+ catch (_a) {
73
+ // ws not available (e.g., in browser)
74
+ NodeWebSocket = undefined;
75
+ }
63
76
  /**
64
77
  * Custom wrapper around DeepgramClient that ensures the custom websocket implementation
65
78
  * from ws.ts is always used, even if the auto-generated code changes.
@@ -130,24 +143,78 @@ class WrappedSpeakClient extends Client_js_3.SpeakClient {
130
143
  return new WrappedSpeakV1Client(this._options);
131
144
  }
132
145
  }
146
+ /**
147
+ * Helper function to get WebSocket class and handle headers/protocols based on runtime.
148
+ * In Node.js, use the 'ws' library which supports headers.
149
+ * In browser, use Sec-WebSocket-Protocol for authentication since headers aren't supported.
150
+ */
151
+ function getWebSocketOptions(headers) {
152
+ const options = {};
153
+ // Check if we're in a browser environment (browser or web-worker)
154
+ const isBrowser = index_js_1.RUNTIME.type === "browser" || index_js_1.RUNTIME.type === "web-worker";
155
+ // In Node.js, ensure we use the 'ws' library which supports headers
156
+ if (index_js_1.RUNTIME.type === "node" && NodeWebSocket) {
157
+ options.WebSocket = NodeWebSocket;
158
+ options.headers = headers;
159
+ }
160
+ else if (isBrowser) {
161
+ // In browser, native WebSocket doesn't support custom headers
162
+ // Extract Authorization header and use Sec-WebSocket-Protocol instead
163
+ const authHeader = headers.Authorization || headers.authorization;
164
+ const browserHeaders = Object.assign({}, headers);
165
+ // Remove Authorization from headers since it won't work in browser
166
+ delete browserHeaders.Authorization;
167
+ delete browserHeaders.authorization;
168
+ options.headers = browserHeaders;
169
+ // If we have an Authorization header, extract the token and format as protocols
170
+ // Deepgram expects:
171
+ // - For API keys: Sec-WebSocket-Protocol: token,API_KEY_GOES_HERE
172
+ // - For Bearer tokens: Sec-WebSocket-Protocol: bearer,TOKEN_GOES_HERE
173
+ // The comma separates multiple protocols, so we pass them as an array
174
+ if (authHeader && typeof authHeader === "string") {
175
+ if (authHeader.startsWith("Token ")) {
176
+ // API key: "Token API_KEY" -> ["token", "API_KEY"]
177
+ const apiKey = authHeader.substring(6); // Remove "Token " prefix
178
+ options.protocols = ["token", apiKey];
179
+ }
180
+ else if (authHeader.startsWith("Bearer ")) {
181
+ // Access token: "Bearer TOKEN" -> ["bearer", "TOKEN"]
182
+ const token = authHeader.substring(7); // Remove "Bearer " prefix
183
+ options.protocols = ["bearer", token];
184
+ }
185
+ else {
186
+ // Fallback: use the entire header value if it doesn't match expected format
187
+ options.protocols = [authHeader];
188
+ }
189
+ }
190
+ }
191
+ else {
192
+ // Fallback for other environments
193
+ options.headers = headers;
194
+ }
195
+ return options;
196
+ }
133
197
  /**
134
198
  * Wrapper for Agent V1Client that overrides connect to use custom websocket.
135
199
  */
136
200
  class WrappedAgentV1Client extends Client_js_4.V1Client {
137
201
  connect() {
138
202
  return __awaiter(this, arguments, void 0, function* (args = {}) {
139
- var _a, _b, _c, _d;
203
+ var _a, _b, _c, _d, _e;
140
204
  const { headers, debug, reconnectAttempts } = args;
141
205
  // Get Authorization from authProvider (matching the working version)
142
206
  const authRequest = yield ((_a = this._options.authProvider) === null || _a === void 0 ? void 0 : _a.getAuthRequest());
143
207
  const _headers = (0, headers_js_1.mergeHeaders)((_b = authRequest === null || authRequest === void 0 ? void 0 : authRequest.headers) !== null && _b !== void 0 ? _b : {}, headers);
208
+ // Get WebSocket options with proper header handling
209
+ const wsOptions = getWebSocketOptions(_headers);
144
210
  // Explicitly use the custom ReconnectingWebSocket from ws.ts
145
211
  const socket = new ws_js_1.ReconnectingWebSocket({
146
212
  url: core.url.join((_c = (yield core.Supplier.get(this._options.baseUrl))) !== null && _c !== void 0 ? _c : ((_d = (yield core.Supplier.get(this._options.environment))) !== null && _d !== void 0 ? _d : environments.DeepgramEnvironment.Production).agent, "/v1/agent/converse"),
147
- protocols: [],
213
+ protocols: (_e = wsOptions.protocols) !== null && _e !== void 0 ? _e : [],
148
214
  queryParameters: {},
149
- headers: _headers,
215
+ headers: wsOptions.headers,
150
216
  options: {
217
+ WebSocket: wsOptions.WebSocket,
151
218
  debug: debug !== null && debug !== void 0 ? debug : false,
152
219
  maxRetries: reconnectAttempts !== null && reconnectAttempts !== void 0 ? reconnectAttempts : 30,
153
220
  startClosed: true,
@@ -203,6 +270,13 @@ class WrappedAgentV1Socket extends Socket_js_1.V1Socket {
203
270
  }
204
271
  }
205
272
  connect() {
273
+ // Ensure socket is ready to connect - if _connectLock is stuck, force reconnect
274
+ // by closing and reconnecting
275
+ if (this.socket.readyState === this.socket.CLOSED) {
276
+ // Force a fresh reconnect to ensure _connectLock is reset
277
+ this.socket._connectLock = false;
278
+ this.socket._shouldReconnect = true;
279
+ }
206
280
  // Call parent connect, but then ensure our binary handler is still active
207
281
  super.connect();
208
282
  // Re-setup binary handling in case connect() re-registered handlers
@@ -216,7 +290,7 @@ class WrappedAgentV1Socket extends Socket_js_1.V1Socket {
216
290
  class WrappedListenV1Client extends Client_js_5.V1Client {
217
291
  connect(args) {
218
292
  return __awaiter(this, void 0, void 0, function* () {
219
- var _a, _b;
293
+ var _a, _b, _c;
220
294
  // Extract all the args (same as the original implementation)
221
295
  const { callback, callback_method: callbackMethod, channels, diarize, dictation, encoding, endpointing, extra, interim_results: interimResults, keyterm, keywords, language, mip_opt_out: mipOptOut, model, multichannel, numerals, profanity_filter: profanityFilter, punctuate, redact, replace, sample_rate: sampleRate, search, smart_format: smartFormat, tag, utterance_end_ms: utteranceEndMs, vad_events: vadEvents, version, headers, debug, reconnectAttempts, } = args;
222
296
  // Build query params (same as original)
@@ -277,13 +351,16 @@ class WrappedListenV1Client extends Client_js_5.V1Client {
277
351
  // Get Authorization from authProvider (matching the working version)
278
352
  const authRequest = yield this._options.authProvider.getAuthRequest();
279
353
  const _headers = (0, headers_js_1.mergeHeaders)(authRequest.headers, headers);
354
+ // Get WebSocket options with proper header handling
355
+ const wsOptions = getWebSocketOptions(_headers);
280
356
  // Explicitly use the custom ReconnectingWebSocket from ws.ts
281
357
  const socket = new ws_js_1.ReconnectingWebSocket({
282
358
  url: core.url.join((_a = (yield core.Supplier.get(this._options.baseUrl))) !== null && _a !== void 0 ? _a : ((_b = (yield core.Supplier.get(this._options.environment))) !== null && _b !== void 0 ? _b : environments.DeepgramEnvironment.Production).production, "/v1/listen"),
283
- protocols: [],
359
+ protocols: (_c = wsOptions.protocols) !== null && _c !== void 0 ? _c : [],
284
360
  queryParameters: _queryParams,
285
- headers: _headers,
361
+ headers: wsOptions.headers,
286
362
  options: {
363
+ WebSocket: wsOptions.WebSocket,
287
364
  debug: debug !== null && debug !== void 0 ? debug : false,
288
365
  maxRetries: reconnectAttempts !== null && reconnectAttempts !== void 0 ? reconnectAttempts : 30,
289
366
  startClosed: true,
@@ -335,6 +412,12 @@ class WrappedListenV1Socket extends Socket_js_2.V1Socket {
335
412
  }
336
413
  }
337
414
  connect() {
415
+ // Ensure socket is ready to connect - if _connectLock is stuck, force reconnect
416
+ if (this.socket.readyState === this.socket.CLOSED) {
417
+ // Force a fresh reconnect to ensure _connectLock is reset
418
+ this.socket._connectLock = false;
419
+ this.socket._shouldReconnect = true;
420
+ }
338
421
  super.connect();
339
422
  this.setupBinaryHandling();
340
423
  return this;
@@ -346,7 +429,7 @@ class WrappedListenV1Socket extends Socket_js_2.V1Socket {
346
429
  class WrappedListenV2Client extends Client_js_6.V2Client {
347
430
  connect(args) {
348
431
  return __awaiter(this, void 0, void 0, function* () {
349
- var _a, _b, _c, _d;
432
+ var _a, _b, _c, _d, _e;
350
433
  const { model, encoding, sample_rate: sampleRate, eager_eot_threshold: eagerEotThreshold, eot_threshold: eotThreshold, eot_timeout_ms: eotTimeoutMs, keyterm, mip_opt_out: mipOptOut, tag, headers, debug, reconnectAttempts, } = args;
351
434
  const _queryParams = {};
352
435
  _queryParams.model = model;
@@ -369,13 +452,16 @@ class WrappedListenV2Client extends Client_js_6.V2Client {
369
452
  // Get Authorization from authProvider (matching the working version)
370
453
  const authRequest = yield ((_a = this._options.authProvider) === null || _a === void 0 ? void 0 : _a.getAuthRequest());
371
454
  const _headers = (0, headers_js_1.mergeHeaders)((_b = authRequest === null || authRequest === void 0 ? void 0 : authRequest.headers) !== null && _b !== void 0 ? _b : {}, headers);
455
+ // Get WebSocket options with proper header handling
456
+ const wsOptions = getWebSocketOptions(_headers);
372
457
  // Explicitly use the custom ReconnectingWebSocket from ws.ts
373
458
  const socket = new ws_js_1.ReconnectingWebSocket({
374
459
  url: core.url.join((_c = (yield core.Supplier.get(this._options.baseUrl))) !== null && _c !== void 0 ? _c : ((_d = (yield core.Supplier.get(this._options.environment))) !== null && _d !== void 0 ? _d : environments.DeepgramEnvironment.Production).production, "/v2/listen"),
375
- protocols: [],
460
+ protocols: (_e = wsOptions.protocols) !== null && _e !== void 0 ? _e : [],
376
461
  queryParameters: _queryParams,
377
- headers: _headers,
462
+ headers: wsOptions.headers,
378
463
  options: {
464
+ WebSocket: wsOptions.WebSocket,
379
465
  debug: debug !== null && debug !== void 0 ? debug : false,
380
466
  maxRetries: reconnectAttempts !== null && reconnectAttempts !== void 0 ? reconnectAttempts : 30,
381
467
  startClosed: true,
@@ -427,6 +513,12 @@ class WrappedListenV2Socket extends Socket_js_3.V2Socket {
427
513
  }
428
514
  }
429
515
  connect() {
516
+ // Ensure socket is ready to connect - if _connectLock is stuck, force reconnect
517
+ if (this.socket.readyState === this.socket.CLOSED) {
518
+ // Force a fresh reconnect to ensure _connectLock is reset
519
+ this.socket._connectLock = false;
520
+ this.socket._shouldReconnect = true;
521
+ }
430
522
  super.connect();
431
523
  this.setupBinaryHandling();
432
524
  return this;
@@ -438,7 +530,7 @@ class WrappedListenV2Socket extends Socket_js_3.V2Socket {
438
530
  class WrappedSpeakV1Client extends Client_js_7.V1Client {
439
531
  connect(args) {
440
532
  return __awaiter(this, void 0, void 0, function* () {
441
- var _a, _b;
533
+ var _a, _b, _c;
442
534
  const { encoding, mip_opt_out: mipOptOut, model, sample_rate: sampleRate, headers, debug, reconnectAttempts, } = args;
443
535
  const _queryParams = {};
444
536
  if (encoding != null)
@@ -452,13 +544,16 @@ class WrappedSpeakV1Client extends Client_js_7.V1Client {
452
544
  // Get Authorization from authProvider (matching the working version)
453
545
  const authRequest = yield this._options.authProvider.getAuthRequest();
454
546
  const _headers = (0, headers_js_1.mergeHeaders)(authRequest.headers, headers);
547
+ // Get WebSocket options with proper header handling
548
+ const wsOptions = getWebSocketOptions(_headers);
455
549
  // Explicitly use the custom ReconnectingWebSocket from ws.ts
456
550
  const socket = new ws_js_1.ReconnectingWebSocket({
457
551
  url: core.url.join((_a = (yield core.Supplier.get(this._options.baseUrl))) !== null && _a !== void 0 ? _a : ((_b = (yield core.Supplier.get(this._options.environment))) !== null && _b !== void 0 ? _b : environments.DeepgramEnvironment.Production).production, "/v1/speak"),
458
- protocols: [],
552
+ protocols: (_c = wsOptions.protocols) !== null && _c !== void 0 ? _c : [],
459
553
  queryParameters: _queryParams,
460
- headers: _headers,
554
+ headers: wsOptions.headers,
461
555
  options: {
556
+ WebSocket: wsOptions.WebSocket,
462
557
  debug: debug !== null && debug !== void 0 ? debug : false,
463
558
  maxRetries: reconnectAttempts !== null && reconnectAttempts !== void 0 ? reconnectAttempts : 30,
464
559
  startClosed: true,
@@ -510,6 +605,12 @@ class WrappedSpeakV1Socket extends Socket_js_4.V1Socket {
510
605
  }
511
606
  }
512
607
  connect() {
608
+ // Ensure socket is ready to connect - if _connectLock is stuck, force reconnect
609
+ if (this.socket.readyState === this.socket.CLOSED) {
610
+ // Force a fresh reconnect to ensure _connectLock is reset
611
+ this.socket._connectLock = false;
612
+ this.socket._shouldReconnect = true;
613
+ }
513
614
  super.connect();
514
615
  this.setupBinaryHandling();
515
616
  return this;
@@ -42,7 +42,6 @@ export declare class ReconnectingWebSocket {
42
42
  private _binaryType;
43
43
  private _closeCalled;
44
44
  private _messageQueue;
45
- private _nodeMessageHandler?;
46
45
  private readonly _url;
47
46
  private readonly _protocols?;
48
47
  private readonly _options;
@@ -39,14 +39,13 @@ const index_js_1 = require("../runtime/index.js");
39
39
  const qs_js_1 = require("../url/qs.js");
40
40
  const Events = __importStar(require("./events.js"));
41
41
  const getGlobalWebSocket = () => {
42
- // In Node.js, prefer the ws library over the built-in WebSocket for better header support
43
- if (index_js_1.RUNTIME.type === "node") {
44
- return ws_1.WebSocket;
45
- }
46
- else if (typeof WebSocket !== "undefined") {
42
+ if (typeof WebSocket !== "undefined") {
47
43
  // @ts-ignore
48
44
  return WebSocket;
49
45
  }
46
+ else if (index_js_1.RUNTIME.type === "node") {
47
+ return ws_1.WebSocket;
48
+ }
50
49
  return undefined;
51
50
  };
52
51
  /**
@@ -122,14 +121,12 @@ class ReconnectingWebSocket {
122
121
  };
123
122
  this._handleError = (event) => {
124
123
  this._debug("error event", event.message);
125
- // Use a non-1000 close code so _shouldReconnect remains true for retries
126
- this._disconnect(1006, event.message === "TIMEOUT" ? "timeout" : undefined);
124
+ this._disconnect(undefined, event.message === "TIMEOUT" ? "timeout" : undefined);
127
125
  if (this.onerror) {
128
126
  this.onerror(event);
129
127
  }
128
+ this._debug("exec error listeners");
130
129
  this._listeners.error.forEach((listener) => this._callEventListener(event, listener));
131
- // Ensure we can retry by setting _shouldReconnect to true
132
- this._shouldReconnect = true;
133
130
  this._connect();
134
131
  };
135
132
  this._handleClose = (event) => {
@@ -366,18 +363,7 @@ class ReconnectingWebSocket {
366
363
  }
367
364
  const options = {};
368
365
  if (this._headers) {
369
- // Ensure all header values are strings for ws library
370
- const stringHeaders = {};
371
- for (const [key, value] of Object.entries(this._headers)) {
372
- if (typeof value === "string") {
373
- stringHeaders[key] = value;
374
- }
375
- else if (value != null) {
376
- // Convert non-string values to strings
377
- stringHeaders[key] = String(value);
378
- }
379
- }
380
- options.headers = stringHeaders;
366
+ options.headers = this._headers;
381
367
  }
382
368
  if (this._queryParameters && Object.keys(this._queryParameters).length > 0) {
383
369
  const queryString = (0, qs_js_1.toQueryString)(this._queryParameters, { arrayFormat: "repeat" });
@@ -431,14 +417,7 @@ class ReconnectingWebSocket {
431
417
  this._debug("removeListeners");
432
418
  this._ws.removeEventListener("open", this._handleOpen);
433
419
  this._ws.removeEventListener("close", this._handleClose);
434
- if (index_js_1.RUNTIME.type === "node" && this._nodeMessageHandler) {
435
- // Remove the message listener we added with .on()
436
- this._ws.off("message", this._nodeMessageHandler);
437
- this._nodeMessageHandler = undefined;
438
- }
439
- else {
440
- this._ws.removeEventListener("message", this._handleMessage);
441
- }
420
+ this._ws.removeEventListener("message", this._handleMessage);
442
421
  // @ts-ignore
443
422
  this._ws.removeEventListener("error", this._handleError);
444
423
  }
@@ -449,24 +428,7 @@ class ReconnectingWebSocket {
449
428
  this._debug("addListeners");
450
429
  this._ws.addEventListener("open", this._handleOpen);
451
430
  this._ws.addEventListener("close", this._handleClose);
452
- // For ws library, we need to wrap the message data in a MessageEvent-like object
453
- if (index_js_1.RUNTIME.type === "node") {
454
- // ws library emits data directly via .on(), not as MessageEvent
455
- // Convert Buffer to string for text messages
456
- this._nodeMessageHandler = (data, isBinary) => {
457
- // Convert Buffer to string if it's a text message
458
- let messageData = data;
459
- if (!isBinary && Buffer.isBuffer(data)) {
460
- messageData = data.toString("utf8");
461
- }
462
- const event = { data: messageData, type: "message", target: this._ws };
463
- this._handleMessage(event);
464
- };
465
- this._ws.on("message", this._nodeMessageHandler);
466
- }
467
- else {
468
- this._ws.addEventListener("message", this._handleMessage);
469
- }
431
+ this._ws.addEventListener("message", this._handleMessage);
470
432
  // @ts-ignore
471
433
  this._ws.addEventListener("error", this._handleError);
472
434
  }
@@ -0,0 +1 @@
1
+ export declare const SDK_VERSION = "0.0.219";
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SDK_VERSION = void 0;
4
+ exports.SDK_VERSION = "0.0.219";
@@ -5,6 +5,9 @@ import * as core from "./core/index.mjs";
5
5
  export function normalizeClientOptions(options) {
6
6
  const headers = mergeHeaders({
7
7
  "X-Fern-Language": "JavaScript",
8
+ "X-Fern-SDK-Name": "",
9
+ "X-Fern-SDK-Version": "0.0.219",
10
+ "User-Agent": "/0.0.219",
8
11
  "X-Fern-Runtime": core.RUNTIME.type,
9
12
  "X-Fern-Runtime-Version": core.RUNTIME.version,
10
13
  }, options === null || options === void 0 ? void 0 : options.headers);
@@ -24,6 +24,19 @@ import { mergeHeaders, mergeOnlyDefinedHeaders } from "./core/headers.mjs";
24
24
  import { fromJson } from "./core/json.mjs";
25
25
  import * as core from "./core/index.mjs";
26
26
  import * as environments from "./environments.mjs";
27
+ import { RUNTIME } from "./core/runtime/index.mjs";
28
+ // Import ws library for Node.js (will be undefined in browser)
29
+ let NodeWebSocket;
30
+ try {
31
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
32
+ NodeWebSocket = require("ws");
33
+ // Handle both default export and named export
34
+ NodeWebSocket = NodeWebSocket.WebSocket || NodeWebSocket.default || NodeWebSocket;
35
+ }
36
+ catch (_a) {
37
+ // ws not available (e.g., in browser)
38
+ NodeWebSocket = undefined;
39
+ }
27
40
  /**
28
41
  * Custom wrapper around DeepgramClient that ensures the custom websocket implementation
29
42
  * from ws.ts is always used, even if the auto-generated code changes.
@@ -93,24 +106,78 @@ class WrappedSpeakClient extends SpeakClientImpl {
93
106
  return new WrappedSpeakV1Client(this._options);
94
107
  }
95
108
  }
109
+ /**
110
+ * Helper function to get WebSocket class and handle headers/protocols based on runtime.
111
+ * In Node.js, use the 'ws' library which supports headers.
112
+ * In browser, use Sec-WebSocket-Protocol for authentication since headers aren't supported.
113
+ */
114
+ function getWebSocketOptions(headers) {
115
+ const options = {};
116
+ // Check if we're in a browser environment (browser or web-worker)
117
+ const isBrowser = RUNTIME.type === "browser" || RUNTIME.type === "web-worker";
118
+ // In Node.js, ensure we use the 'ws' library which supports headers
119
+ if (RUNTIME.type === "node" && NodeWebSocket) {
120
+ options.WebSocket = NodeWebSocket;
121
+ options.headers = headers;
122
+ }
123
+ else if (isBrowser) {
124
+ // In browser, native WebSocket doesn't support custom headers
125
+ // Extract Authorization header and use Sec-WebSocket-Protocol instead
126
+ const authHeader = headers.Authorization || headers.authorization;
127
+ const browserHeaders = Object.assign({}, headers);
128
+ // Remove Authorization from headers since it won't work in browser
129
+ delete browserHeaders.Authorization;
130
+ delete browserHeaders.authorization;
131
+ options.headers = browserHeaders;
132
+ // If we have an Authorization header, extract the token and format as protocols
133
+ // Deepgram expects:
134
+ // - For API keys: Sec-WebSocket-Protocol: token,API_KEY_GOES_HERE
135
+ // - For Bearer tokens: Sec-WebSocket-Protocol: bearer,TOKEN_GOES_HERE
136
+ // The comma separates multiple protocols, so we pass them as an array
137
+ if (authHeader && typeof authHeader === "string") {
138
+ if (authHeader.startsWith("Token ")) {
139
+ // API key: "Token API_KEY" -> ["token", "API_KEY"]
140
+ const apiKey = authHeader.substring(6); // Remove "Token " prefix
141
+ options.protocols = ["token", apiKey];
142
+ }
143
+ else if (authHeader.startsWith("Bearer ")) {
144
+ // Access token: "Bearer TOKEN" -> ["bearer", "TOKEN"]
145
+ const token = authHeader.substring(7); // Remove "Bearer " prefix
146
+ options.protocols = ["bearer", token];
147
+ }
148
+ else {
149
+ // Fallback: use the entire header value if it doesn't match expected format
150
+ options.protocols = [authHeader];
151
+ }
152
+ }
153
+ }
154
+ else {
155
+ // Fallback for other environments
156
+ options.headers = headers;
157
+ }
158
+ return options;
159
+ }
96
160
  /**
97
161
  * Wrapper for Agent V1Client that overrides connect to use custom websocket.
98
162
  */
99
163
  class WrappedAgentV1Client extends AgentV1Client {
100
164
  connect() {
101
165
  return __awaiter(this, arguments, void 0, function* (args = {}) {
102
- var _a, _b, _c, _d;
166
+ var _a, _b, _c, _d, _e;
103
167
  const { headers, debug, reconnectAttempts } = args;
104
168
  // Get Authorization from authProvider (matching the working version)
105
169
  const authRequest = yield ((_a = this._options.authProvider) === null || _a === void 0 ? void 0 : _a.getAuthRequest());
106
170
  const _headers = mergeHeaders((_b = authRequest === null || authRequest === void 0 ? void 0 : authRequest.headers) !== null && _b !== void 0 ? _b : {}, headers);
171
+ // Get WebSocket options with proper header handling
172
+ const wsOptions = getWebSocketOptions(_headers);
107
173
  // Explicitly use the custom ReconnectingWebSocket from ws.ts
108
174
  const socket = new ReconnectingWebSocket({
109
175
  url: core.url.join((_c = (yield core.Supplier.get(this._options.baseUrl))) !== null && _c !== void 0 ? _c : ((_d = (yield core.Supplier.get(this._options.environment))) !== null && _d !== void 0 ? _d : environments.DeepgramEnvironment.Production).agent, "/v1/agent/converse"),
110
- protocols: [],
176
+ protocols: (_e = wsOptions.protocols) !== null && _e !== void 0 ? _e : [],
111
177
  queryParameters: {},
112
- headers: _headers,
178
+ headers: wsOptions.headers,
113
179
  options: {
180
+ WebSocket: wsOptions.WebSocket,
114
181
  debug: debug !== null && debug !== void 0 ? debug : false,
115
182
  maxRetries: reconnectAttempts !== null && reconnectAttempts !== void 0 ? reconnectAttempts : 30,
116
183
  startClosed: true,
@@ -166,6 +233,13 @@ class WrappedAgentV1Socket extends AgentV1Socket {
166
233
  }
167
234
  }
168
235
  connect() {
236
+ // Ensure socket is ready to connect - if _connectLock is stuck, force reconnect
237
+ // by closing and reconnecting
238
+ if (this.socket.readyState === this.socket.CLOSED) {
239
+ // Force a fresh reconnect to ensure _connectLock is reset
240
+ this.socket._connectLock = false;
241
+ this.socket._shouldReconnect = true;
242
+ }
169
243
  // Call parent connect, but then ensure our binary handler is still active
170
244
  super.connect();
171
245
  // Re-setup binary handling in case connect() re-registered handlers
@@ -179,7 +253,7 @@ class WrappedAgentV1Socket extends AgentV1Socket {
179
253
  class WrappedListenV1Client extends ListenV1Client {
180
254
  connect(args) {
181
255
  return __awaiter(this, void 0, void 0, function* () {
182
- var _a, _b;
256
+ var _a, _b, _c;
183
257
  // Extract all the args (same as the original implementation)
184
258
  const { callback, callback_method: callbackMethod, channels, diarize, dictation, encoding, endpointing, extra, interim_results: interimResults, keyterm, keywords, language, mip_opt_out: mipOptOut, model, multichannel, numerals, profanity_filter: profanityFilter, punctuate, redact, replace, sample_rate: sampleRate, search, smart_format: smartFormat, tag, utterance_end_ms: utteranceEndMs, vad_events: vadEvents, version, headers, debug, reconnectAttempts, } = args;
185
259
  // Build query params (same as original)
@@ -240,13 +314,16 @@ class WrappedListenV1Client extends ListenV1Client {
240
314
  // Get Authorization from authProvider (matching the working version)
241
315
  const authRequest = yield this._options.authProvider.getAuthRequest();
242
316
  const _headers = mergeHeaders(authRequest.headers, headers);
317
+ // Get WebSocket options with proper header handling
318
+ const wsOptions = getWebSocketOptions(_headers);
243
319
  // Explicitly use the custom ReconnectingWebSocket from ws.ts
244
320
  const socket = new ReconnectingWebSocket({
245
321
  url: core.url.join((_a = (yield core.Supplier.get(this._options.baseUrl))) !== null && _a !== void 0 ? _a : ((_b = (yield core.Supplier.get(this._options.environment))) !== null && _b !== void 0 ? _b : environments.DeepgramEnvironment.Production).production, "/v1/listen"),
246
- protocols: [],
322
+ protocols: (_c = wsOptions.protocols) !== null && _c !== void 0 ? _c : [],
247
323
  queryParameters: _queryParams,
248
- headers: _headers,
324
+ headers: wsOptions.headers,
249
325
  options: {
326
+ WebSocket: wsOptions.WebSocket,
250
327
  debug: debug !== null && debug !== void 0 ? debug : false,
251
328
  maxRetries: reconnectAttempts !== null && reconnectAttempts !== void 0 ? reconnectAttempts : 30,
252
329
  startClosed: true,
@@ -298,6 +375,12 @@ class WrappedListenV1Socket extends ListenV1Socket {
298
375
  }
299
376
  }
300
377
  connect() {
378
+ // Ensure socket is ready to connect - if _connectLock is stuck, force reconnect
379
+ if (this.socket.readyState === this.socket.CLOSED) {
380
+ // Force a fresh reconnect to ensure _connectLock is reset
381
+ this.socket._connectLock = false;
382
+ this.socket._shouldReconnect = true;
383
+ }
301
384
  super.connect();
302
385
  this.setupBinaryHandling();
303
386
  return this;
@@ -309,7 +392,7 @@ class WrappedListenV1Socket extends ListenV1Socket {
309
392
  class WrappedListenV2Client extends ListenV2Client {
310
393
  connect(args) {
311
394
  return __awaiter(this, void 0, void 0, function* () {
312
- var _a, _b, _c, _d;
395
+ var _a, _b, _c, _d, _e;
313
396
  const { model, encoding, sample_rate: sampleRate, eager_eot_threshold: eagerEotThreshold, eot_threshold: eotThreshold, eot_timeout_ms: eotTimeoutMs, keyterm, mip_opt_out: mipOptOut, tag, headers, debug, reconnectAttempts, } = args;
314
397
  const _queryParams = {};
315
398
  _queryParams.model = model;
@@ -332,13 +415,16 @@ class WrappedListenV2Client extends ListenV2Client {
332
415
  // Get Authorization from authProvider (matching the working version)
333
416
  const authRequest = yield ((_a = this._options.authProvider) === null || _a === void 0 ? void 0 : _a.getAuthRequest());
334
417
  const _headers = mergeHeaders((_b = authRequest === null || authRequest === void 0 ? void 0 : authRequest.headers) !== null && _b !== void 0 ? _b : {}, headers);
418
+ // Get WebSocket options with proper header handling
419
+ const wsOptions = getWebSocketOptions(_headers);
335
420
  // Explicitly use the custom ReconnectingWebSocket from ws.ts
336
421
  const socket = new ReconnectingWebSocket({
337
422
  url: core.url.join((_c = (yield core.Supplier.get(this._options.baseUrl))) !== null && _c !== void 0 ? _c : ((_d = (yield core.Supplier.get(this._options.environment))) !== null && _d !== void 0 ? _d : environments.DeepgramEnvironment.Production).production, "/v2/listen"),
338
- protocols: [],
423
+ protocols: (_e = wsOptions.protocols) !== null && _e !== void 0 ? _e : [],
339
424
  queryParameters: _queryParams,
340
- headers: _headers,
425
+ headers: wsOptions.headers,
341
426
  options: {
427
+ WebSocket: wsOptions.WebSocket,
342
428
  debug: debug !== null && debug !== void 0 ? debug : false,
343
429
  maxRetries: reconnectAttempts !== null && reconnectAttempts !== void 0 ? reconnectAttempts : 30,
344
430
  startClosed: true,
@@ -390,6 +476,12 @@ class WrappedListenV2Socket extends ListenV2Socket {
390
476
  }
391
477
  }
392
478
  connect() {
479
+ // Ensure socket is ready to connect - if _connectLock is stuck, force reconnect
480
+ if (this.socket.readyState === this.socket.CLOSED) {
481
+ // Force a fresh reconnect to ensure _connectLock is reset
482
+ this.socket._connectLock = false;
483
+ this.socket._shouldReconnect = true;
484
+ }
393
485
  super.connect();
394
486
  this.setupBinaryHandling();
395
487
  return this;
@@ -401,7 +493,7 @@ class WrappedListenV2Socket extends ListenV2Socket {
401
493
  class WrappedSpeakV1Client extends SpeakV1Client {
402
494
  connect(args) {
403
495
  return __awaiter(this, void 0, void 0, function* () {
404
- var _a, _b;
496
+ var _a, _b, _c;
405
497
  const { encoding, mip_opt_out: mipOptOut, model, sample_rate: sampleRate, headers, debug, reconnectAttempts, } = args;
406
498
  const _queryParams = {};
407
499
  if (encoding != null)
@@ -415,13 +507,16 @@ class WrappedSpeakV1Client extends SpeakV1Client {
415
507
  // Get Authorization from authProvider (matching the working version)
416
508
  const authRequest = yield this._options.authProvider.getAuthRequest();
417
509
  const _headers = mergeHeaders(authRequest.headers, headers);
510
+ // Get WebSocket options with proper header handling
511
+ const wsOptions = getWebSocketOptions(_headers);
418
512
  // Explicitly use the custom ReconnectingWebSocket from ws.ts
419
513
  const socket = new ReconnectingWebSocket({
420
514
  url: core.url.join((_a = (yield core.Supplier.get(this._options.baseUrl))) !== null && _a !== void 0 ? _a : ((_b = (yield core.Supplier.get(this._options.environment))) !== null && _b !== void 0 ? _b : environments.DeepgramEnvironment.Production).production, "/v1/speak"),
421
- protocols: [],
515
+ protocols: (_c = wsOptions.protocols) !== null && _c !== void 0 ? _c : [],
422
516
  queryParameters: _queryParams,
423
- headers: _headers,
517
+ headers: wsOptions.headers,
424
518
  options: {
519
+ WebSocket: wsOptions.WebSocket,
425
520
  debug: debug !== null && debug !== void 0 ? debug : false,
426
521
  maxRetries: reconnectAttempts !== null && reconnectAttempts !== void 0 ? reconnectAttempts : 30,
427
522
  startClosed: true,
@@ -473,6 +568,12 @@ class WrappedSpeakV1Socket extends SpeakV1Socket {
473
568
  }
474
569
  }
475
570
  connect() {
571
+ // Ensure socket is ready to connect - if _connectLock is stuck, force reconnect
572
+ if (this.socket.readyState === this.socket.CLOSED) {
573
+ // Force a fresh reconnect to ensure _connectLock is reset
574
+ this.socket._connectLock = false;
575
+ this.socket._shouldReconnect = true;
576
+ }
476
577
  super.connect();
477
578
  this.setupBinaryHandling();
478
579
  return this;
@@ -42,7 +42,6 @@ export declare class ReconnectingWebSocket {
42
42
  private _binaryType;
43
43
  private _closeCalled;
44
44
  private _messageQueue;
45
- private _nodeMessageHandler?;
46
45
  private readonly _url;
47
46
  private readonly _protocols?;
48
47
  private readonly _options;