@speechos/core 0.2.5 → 0.2.6

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.
package/dist/index.d.cts CHANGED
@@ -12,5 +12,5 @@ export { livekit, Deferred } from "./livekit.js";
12
12
  export { websocket } from "./websocket.js";
13
13
  export { getBackend } from "./backend.js";
14
14
  export type { VoiceBackend } from "./backend.js";
15
- export type { SpeechOSCoreConfig, SpeechOSState, SpeechOSAction, SpeechOSEventMap, StateChangeCallback, UnsubscribeFn, RecordingState, LiveKitTokenResponse, ServerErrorMessage, ErrorSource, UserVocabularyData, CommandArgument, CommandDefinition, CommandResult, SessionSettings, VoiceSessionOptions, } from "./types.js";
15
+ export type { SpeechOSCoreConfig, SpeechOSState, SpeechOSAction, SpeechOSEventMap, StateChangeCallback, UnsubscribeFn, RecordingState, LiveKitTokenResponse, ServerErrorMessage, ErrorSource, UserVocabularyData, CommandArgument, CommandDefinition, CommandResult, SessionSettings, VoiceSessionOptions, WebSocketLike, WebSocketFactory, } from "./types.js";
16
16
  export declare const VERSION = "0.1.0";
package/dist/index.d.ts CHANGED
@@ -12,5 +12,5 @@ export { livekit, Deferred } from "./livekit.js";
12
12
  export { websocket } from "./websocket.js";
13
13
  export { getBackend } from "./backend.js";
14
14
  export type { VoiceBackend } from "./backend.js";
15
- export type { SpeechOSCoreConfig, SpeechOSState, SpeechOSAction, SpeechOSEventMap, StateChangeCallback, UnsubscribeFn, RecordingState, LiveKitTokenResponse, ServerErrorMessage, ErrorSource, UserVocabularyData, CommandArgument, CommandDefinition, CommandResult, SessionSettings, VoiceSessionOptions, } from "./types.js";
15
+ export type { SpeechOSCoreConfig, SpeechOSState, SpeechOSAction, SpeechOSEventMap, StateChangeCallback, UnsubscribeFn, RecordingState, LiveKitTokenResponse, ServerErrorMessage, ErrorSource, UserVocabularyData, CommandArgument, CommandDefinition, CommandResult, SessionSettings, VoiceSessionOptions, WebSocketLike, WebSocketFactory, } from "./types.js";
16
16
  export declare const VERSION = "0.1.0";
package/dist/index.js CHANGED
@@ -12,7 +12,8 @@ const defaultConfig = {
12
12
  apiKey: "",
13
13
  userId: "",
14
14
  host: DEFAULT_HOST,
15
- debug: false
15
+ debug: false,
16
+ webSocketFactory: void 0
16
17
  };
17
18
  /**
18
19
  * Validates and merges user config with defaults
@@ -25,7 +26,8 @@ function validateConfig(userConfig) {
25
26
  apiKey: userConfig.apiKey,
26
27
  userId: userConfig.userId ?? defaultConfig.userId,
27
28
  host: userConfig.host ?? defaultConfig.host,
28
- debug: userConfig.debug ?? defaultConfig.debug
29
+ debug: userConfig.debug ?? defaultConfig.debug,
30
+ webSocketFactory: userConfig.webSocketFactory ?? defaultConfig.webSocketFactory
29
31
  };
30
32
  }
31
33
  /**
@@ -1395,6 +1397,8 @@ const MESSAGE_TYPE_EDITED_TEXT = "edited_text";
1395
1397
  const MESSAGE_TYPE_EXECUTE_COMMAND = "execute_command";
1396
1398
  const MESSAGE_TYPE_COMMAND_RESULT = "command_result";
1397
1399
  const MESSAGE_TYPE_ERROR = "error";
1400
+ const WS_OPEN = 1;
1401
+ const WS_CLOSED = 3;
1398
1402
  /**
1399
1403
  * Response timeout in milliseconds.
1400
1404
  */
@@ -1513,7 +1517,10 @@ var WebSocketManager = class {
1513
1517
  state.setMicEnabled(true);
1514
1518
  const wsUrl = this.getWebSocketUrl();
1515
1519
  if (config.debug) console.log("[SpeechOS] Connecting to WebSocket:", wsUrl);
1516
- this.ws = new WebSocket(wsUrl);
1520
+ this.pendingAuth = new Deferred$1();
1521
+ this.pendingAuth.setTimeout(RESPONSE_TIMEOUT_MS, "Connection timed out", "connection_timeout", "connection");
1522
+ const factory = config.webSocketFactory ?? ((url) => new WebSocket(url));
1523
+ this.ws = factory(wsUrl);
1517
1524
  this.ws.onopen = () => {
1518
1525
  if (config.debug) console.log("[SpeechOS] WebSocket connected, authenticating...");
1519
1526
  this.authenticate();
@@ -1522,19 +1529,21 @@ var WebSocketManager = class {
1522
1529
  this.handleMessage(event.data);
1523
1530
  };
1524
1531
  this.ws.onerror = (event) => {
1525
- console.error("[SpeechOS] WebSocket error:", event);
1532
+ const isConnectionBlocked = this.ws?.readyState === WS_CLOSED;
1533
+ const errorCode = isConnectionBlocked ? "connection_blocked" : "websocket_error";
1534
+ const errorMessage = isConnectionBlocked ? "This site's CSP blocks the extension. Try embedded mode instead." : "WebSocket connection error";
1535
+ console.error("[SpeechOS] WebSocket error:", event, { isConnectionBlocked });
1526
1536
  events.emit("error", {
1527
- code: "websocket_error",
1528
- message: "WebSocket connection error",
1537
+ code: errorCode,
1538
+ message: errorMessage,
1529
1539
  source: "connection"
1530
1540
  });
1541
+ if (this.pendingAuth) this.pendingAuth.reject(new Error(errorMessage));
1531
1542
  };
1532
1543
  this.ws.onclose = (event) => {
1533
1544
  if (config.debug) console.log("[SpeechOS] WebSocket closed:", event.code, event.reason);
1534
1545
  state.setConnected(false);
1535
1546
  };
1536
- this.pendingAuth = new Deferred$1();
1537
- this.pendingAuth.setTimeout(RESPONSE_TIMEOUT_MS, "Connection timed out", "connection_timeout", "connection");
1538
1547
  await this.pendingAuth.promise;
1539
1548
  this.pendingAuth = null;
1540
1549
  if (this.audioCapture) this.audioCapture.setReady();
@@ -1583,7 +1592,7 @@ var WebSocketManager = class {
1583
1592
  * Actually send the audio chunk (async operation).
1584
1593
  */
1585
1594
  async doSendAudioChunk(chunk) {
1586
- if (this.ws && this.ws.readyState === WebSocket.OPEN) {
1595
+ if (this.ws && this.ws.readyState === WS_OPEN) {
1587
1596
  const arrayBuffer = await chunk.arrayBuffer();
1588
1597
  this.ws.send(arrayBuffer);
1589
1598
  }
@@ -1769,7 +1778,7 @@ var WebSocketManager = class {
1769
1778
  * the transcript. Uses the same pattern as LiveKit's ReadableStream approach.
1770
1779
  */
1771
1780
  async waitForBufferDrain() {
1772
- if (!this.ws || this.ws.readyState !== WebSocket.OPEN) return;
1781
+ if (!this.ws || this.ws.readyState !== WS_OPEN) return;
1773
1782
  const config = getConfig();
1774
1783
  const startTime = Date.now();
1775
1784
  while (this.ws.bufferedAmount > 0) {
@@ -1785,7 +1794,7 @@ var WebSocketManager = class {
1785
1794
  * Send a JSON message over the WebSocket.
1786
1795
  */
1787
1796
  sendMessage(message) {
1788
- if (this.ws && this.ws.readyState === WebSocket.OPEN) this.ws.send(JSON.stringify(message));
1797
+ if (this.ws && this.ws.readyState === WS_OPEN) this.ws.send(JSON.stringify(message));
1789
1798
  }
1790
1799
  /**
1791
1800
  * Disconnect from the WebSocket.
@@ -1827,7 +1836,7 @@ var WebSocketManager = class {
1827
1836
  * Check if connected to WebSocket.
1828
1837
  */
1829
1838
  isConnected() {
1830
- return this.ws !== null && this.ws.readyState === WebSocket.OPEN;
1839
+ return this.ws !== null && this.ws.readyState === WS_OPEN;
1831
1840
  }
1832
1841
  /**
1833
1842
  * Get the last input text from a command result.