@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/config.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Configuration management for SpeechOS Core SDK
3
3
  */
4
- import type { SpeechOSCoreConfig } from "./types.js";
4
+ import type { SpeechOSCoreConfig, WebSocketFactory } from "./types.js";
5
5
  /**
6
6
  * Default host - can be overridden by SPEECHOS_HOST env var at build time
7
7
  */
@@ -14,6 +14,8 @@ interface ResolvedConfig {
14
14
  userId: string;
15
15
  host: string;
16
16
  debug: boolean;
17
+ /** Custom WebSocket factory (undefined means use native WebSocket) */
18
+ webSocketFactory: WebSocketFactory | undefined;
17
19
  }
18
20
  /**
19
21
  * Validates and merges user config with defaults
package/dist/config.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Configuration management for SpeechOS Core SDK
3
3
  */
4
- import type { SpeechOSCoreConfig } from "./types.js";
4
+ import type { SpeechOSCoreConfig, WebSocketFactory } from "./types.js";
5
5
  /**
6
6
  * Default host - can be overridden by SPEECHOS_HOST env var at build time
7
7
  */
@@ -14,6 +14,8 @@ interface ResolvedConfig {
14
14
  userId: string;
15
15
  host: string;
16
16
  debug: boolean;
17
+ /** Custom WebSocket factory (undefined means use native WebSocket) */
18
+ webSocketFactory: WebSocketFactory | undefined;
17
19
  }
18
20
  /**
19
21
  * Validates and merges user config with defaults
package/dist/index.cjs CHANGED
@@ -35,7 +35,8 @@ const defaultConfig = {
35
35
  apiKey: "",
36
36
  userId: "",
37
37
  host: DEFAULT_HOST,
38
- debug: false
38
+ debug: false,
39
+ webSocketFactory: void 0
39
40
  };
40
41
  /**
41
42
  * Validates and merges user config with defaults
@@ -48,7 +49,8 @@ function validateConfig(userConfig) {
48
49
  apiKey: userConfig.apiKey,
49
50
  userId: userConfig.userId ?? defaultConfig.userId,
50
51
  host: userConfig.host ?? defaultConfig.host,
51
- debug: userConfig.debug ?? defaultConfig.debug
52
+ debug: userConfig.debug ?? defaultConfig.debug,
53
+ webSocketFactory: userConfig.webSocketFactory ?? defaultConfig.webSocketFactory
52
54
  };
53
55
  }
54
56
  /**
@@ -1418,6 +1420,8 @@ const MESSAGE_TYPE_EDITED_TEXT = "edited_text";
1418
1420
  const MESSAGE_TYPE_EXECUTE_COMMAND = "execute_command";
1419
1421
  const MESSAGE_TYPE_COMMAND_RESULT = "command_result";
1420
1422
  const MESSAGE_TYPE_ERROR = "error";
1423
+ const WS_OPEN = 1;
1424
+ const WS_CLOSED = 3;
1421
1425
  /**
1422
1426
  * Response timeout in milliseconds.
1423
1427
  */
@@ -1536,7 +1540,10 @@ var WebSocketManager = class {
1536
1540
  state.setMicEnabled(true);
1537
1541
  const wsUrl = this.getWebSocketUrl();
1538
1542
  if (config.debug) console.log("[SpeechOS] Connecting to WebSocket:", wsUrl);
1539
- this.ws = new WebSocket(wsUrl);
1543
+ this.pendingAuth = new Deferred$1();
1544
+ this.pendingAuth.setTimeout(RESPONSE_TIMEOUT_MS, "Connection timed out", "connection_timeout", "connection");
1545
+ const factory = config.webSocketFactory ?? ((url) => new WebSocket(url));
1546
+ this.ws = factory(wsUrl);
1540
1547
  this.ws.onopen = () => {
1541
1548
  if (config.debug) console.log("[SpeechOS] WebSocket connected, authenticating...");
1542
1549
  this.authenticate();
@@ -1545,19 +1552,21 @@ var WebSocketManager = class {
1545
1552
  this.handleMessage(event.data);
1546
1553
  };
1547
1554
  this.ws.onerror = (event) => {
1548
- console.error("[SpeechOS] WebSocket error:", event);
1555
+ const isConnectionBlocked = this.ws?.readyState === WS_CLOSED;
1556
+ const errorCode = isConnectionBlocked ? "connection_blocked" : "websocket_error";
1557
+ const errorMessage = isConnectionBlocked ? "This site's CSP blocks the extension. Try embedded mode instead." : "WebSocket connection error";
1558
+ console.error("[SpeechOS] WebSocket error:", event, { isConnectionBlocked });
1549
1559
  events.emit("error", {
1550
- code: "websocket_error",
1551
- message: "WebSocket connection error",
1560
+ code: errorCode,
1561
+ message: errorMessage,
1552
1562
  source: "connection"
1553
1563
  });
1564
+ if (this.pendingAuth) this.pendingAuth.reject(new Error(errorMessage));
1554
1565
  };
1555
1566
  this.ws.onclose = (event) => {
1556
1567
  if (config.debug) console.log("[SpeechOS] WebSocket closed:", event.code, event.reason);
1557
1568
  state.setConnected(false);
1558
1569
  };
1559
- this.pendingAuth = new Deferred$1();
1560
- this.pendingAuth.setTimeout(RESPONSE_TIMEOUT_MS, "Connection timed out", "connection_timeout", "connection");
1561
1570
  await this.pendingAuth.promise;
1562
1571
  this.pendingAuth = null;
1563
1572
  if (this.audioCapture) this.audioCapture.setReady();
@@ -1606,7 +1615,7 @@ var WebSocketManager = class {
1606
1615
  * Actually send the audio chunk (async operation).
1607
1616
  */
1608
1617
  async doSendAudioChunk(chunk) {
1609
- if (this.ws && this.ws.readyState === WebSocket.OPEN) {
1618
+ if (this.ws && this.ws.readyState === WS_OPEN) {
1610
1619
  const arrayBuffer = await chunk.arrayBuffer();
1611
1620
  this.ws.send(arrayBuffer);
1612
1621
  }
@@ -1792,7 +1801,7 @@ var WebSocketManager = class {
1792
1801
  * the transcript. Uses the same pattern as LiveKit's ReadableStream approach.
1793
1802
  */
1794
1803
  async waitForBufferDrain() {
1795
- if (!this.ws || this.ws.readyState !== WebSocket.OPEN) return;
1804
+ if (!this.ws || this.ws.readyState !== WS_OPEN) return;
1796
1805
  const config = getConfig();
1797
1806
  const startTime = Date.now();
1798
1807
  while (this.ws.bufferedAmount > 0) {
@@ -1808,7 +1817,7 @@ var WebSocketManager = class {
1808
1817
  * Send a JSON message over the WebSocket.
1809
1818
  */
1810
1819
  sendMessage(message) {
1811
- if (this.ws && this.ws.readyState === WebSocket.OPEN) this.ws.send(JSON.stringify(message));
1820
+ if (this.ws && this.ws.readyState === WS_OPEN) this.ws.send(JSON.stringify(message));
1812
1821
  }
1813
1822
  /**
1814
1823
  * Disconnect from the WebSocket.
@@ -1850,7 +1859,7 @@ var WebSocketManager = class {
1850
1859
  * Check if connected to WebSocket.
1851
1860
  */
1852
1861
  isConnected() {
1853
- return this.ws !== null && this.ws.readyState === WebSocket.OPEN;
1862
+ return this.ws !== null && this.ws.readyState === WS_OPEN;
1854
1863
  }
1855
1864
  /**
1856
1865
  * Get the last input text from a command result.