@speechos/core 0.2.5 → 0.2.7
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 +3 -1
- package/dist/config.d.ts +3 -1
- package/dist/index.cjs +25 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +25 -14
- package/dist/index.js.map +1 -1
- package/dist/state.d.cts +2 -1
- package/dist/state.d.ts +2 -1
- package/dist/types.d.cts +35 -0
- package/dist/types.d.ts +35 -0
- package/package.json +1 -1
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
|
/**
|
|
@@ -337,14 +339,16 @@ var StateManager = class {
|
|
|
337
339
|
});
|
|
338
340
|
}
|
|
339
341
|
/**
|
|
340
|
-
* Complete the recording flow and return to idle
|
|
342
|
+
* Complete the recording flow and return to idle.
|
|
343
|
+
* Keeps widget visible but collapsed (just mic button, no action bubbles).
|
|
341
344
|
*/
|
|
342
345
|
completeRecording() {
|
|
343
346
|
this.setState({
|
|
344
347
|
recordingState: "idle",
|
|
345
348
|
activeAction: null,
|
|
346
349
|
isConnected: false,
|
|
347
|
-
isMicEnabled: false
|
|
350
|
+
isMicEnabled: false,
|
|
351
|
+
isExpanded: false
|
|
348
352
|
});
|
|
349
353
|
}
|
|
350
354
|
/**
|
|
@@ -1418,6 +1422,8 @@ const MESSAGE_TYPE_EDITED_TEXT = "edited_text";
|
|
|
1418
1422
|
const MESSAGE_TYPE_EXECUTE_COMMAND = "execute_command";
|
|
1419
1423
|
const MESSAGE_TYPE_COMMAND_RESULT = "command_result";
|
|
1420
1424
|
const MESSAGE_TYPE_ERROR = "error";
|
|
1425
|
+
const WS_OPEN = 1;
|
|
1426
|
+
const WS_CLOSED = 3;
|
|
1421
1427
|
/**
|
|
1422
1428
|
* Response timeout in milliseconds.
|
|
1423
1429
|
*/
|
|
@@ -1536,7 +1542,10 @@ var WebSocketManager = class {
|
|
|
1536
1542
|
state.setMicEnabled(true);
|
|
1537
1543
|
const wsUrl = this.getWebSocketUrl();
|
|
1538
1544
|
if (config.debug) console.log("[SpeechOS] Connecting to WebSocket:", wsUrl);
|
|
1539
|
-
this.
|
|
1545
|
+
this.pendingAuth = new Deferred$1();
|
|
1546
|
+
this.pendingAuth.setTimeout(RESPONSE_TIMEOUT_MS, "Connection timed out", "connection_timeout", "connection");
|
|
1547
|
+
const factory = config.webSocketFactory ?? ((url) => new WebSocket(url));
|
|
1548
|
+
this.ws = factory(wsUrl);
|
|
1540
1549
|
this.ws.onopen = () => {
|
|
1541
1550
|
if (config.debug) console.log("[SpeechOS] WebSocket connected, authenticating...");
|
|
1542
1551
|
this.authenticate();
|
|
@@ -1545,19 +1554,21 @@ var WebSocketManager = class {
|
|
|
1545
1554
|
this.handleMessage(event.data);
|
|
1546
1555
|
};
|
|
1547
1556
|
this.ws.onerror = (event) => {
|
|
1548
|
-
|
|
1557
|
+
const isConnectionBlocked = this.ws?.readyState === WS_CLOSED;
|
|
1558
|
+
const errorCode = isConnectionBlocked ? "connection_blocked" : "websocket_error";
|
|
1559
|
+
const errorMessage = isConnectionBlocked ? "This site's CSP blocks the extension. Try embedded mode instead." : "WebSocket connection error";
|
|
1560
|
+
console.error("[SpeechOS] WebSocket error:", event, { isConnectionBlocked });
|
|
1549
1561
|
events.emit("error", {
|
|
1550
|
-
code:
|
|
1551
|
-
message:
|
|
1562
|
+
code: errorCode,
|
|
1563
|
+
message: errorMessage,
|
|
1552
1564
|
source: "connection"
|
|
1553
1565
|
});
|
|
1566
|
+
if (this.pendingAuth) this.pendingAuth.reject(new Error(errorMessage));
|
|
1554
1567
|
};
|
|
1555
1568
|
this.ws.onclose = (event) => {
|
|
1556
1569
|
if (config.debug) console.log("[SpeechOS] WebSocket closed:", event.code, event.reason);
|
|
1557
1570
|
state.setConnected(false);
|
|
1558
1571
|
};
|
|
1559
|
-
this.pendingAuth = new Deferred$1();
|
|
1560
|
-
this.pendingAuth.setTimeout(RESPONSE_TIMEOUT_MS, "Connection timed out", "connection_timeout", "connection");
|
|
1561
1572
|
await this.pendingAuth.promise;
|
|
1562
1573
|
this.pendingAuth = null;
|
|
1563
1574
|
if (this.audioCapture) this.audioCapture.setReady();
|
|
@@ -1606,7 +1617,7 @@ var WebSocketManager = class {
|
|
|
1606
1617
|
* Actually send the audio chunk (async operation).
|
|
1607
1618
|
*/
|
|
1608
1619
|
async doSendAudioChunk(chunk) {
|
|
1609
|
-
if (this.ws && this.ws.readyState ===
|
|
1620
|
+
if (this.ws && this.ws.readyState === WS_OPEN) {
|
|
1610
1621
|
const arrayBuffer = await chunk.arrayBuffer();
|
|
1611
1622
|
this.ws.send(arrayBuffer);
|
|
1612
1623
|
}
|
|
@@ -1792,7 +1803,7 @@ var WebSocketManager = class {
|
|
|
1792
1803
|
* the transcript. Uses the same pattern as LiveKit's ReadableStream approach.
|
|
1793
1804
|
*/
|
|
1794
1805
|
async waitForBufferDrain() {
|
|
1795
|
-
if (!this.ws || this.ws.readyState !==
|
|
1806
|
+
if (!this.ws || this.ws.readyState !== WS_OPEN) return;
|
|
1796
1807
|
const config = getConfig();
|
|
1797
1808
|
const startTime = Date.now();
|
|
1798
1809
|
while (this.ws.bufferedAmount > 0) {
|
|
@@ -1808,7 +1819,7 @@ var WebSocketManager = class {
|
|
|
1808
1819
|
* Send a JSON message over the WebSocket.
|
|
1809
1820
|
*/
|
|
1810
1821
|
sendMessage(message) {
|
|
1811
|
-
if (this.ws && this.ws.readyState ===
|
|
1822
|
+
if (this.ws && this.ws.readyState === WS_OPEN) this.ws.send(JSON.stringify(message));
|
|
1812
1823
|
}
|
|
1813
1824
|
/**
|
|
1814
1825
|
* Disconnect from the WebSocket.
|
|
@@ -1850,7 +1861,7 @@ var WebSocketManager = class {
|
|
|
1850
1861
|
* Check if connected to WebSocket.
|
|
1851
1862
|
*/
|
|
1852
1863
|
isConnected() {
|
|
1853
|
-
return this.ws !== null && this.ws.readyState ===
|
|
1864
|
+
return this.ws !== null && this.ws.readyState === WS_OPEN;
|
|
1854
1865
|
}
|
|
1855
1866
|
/**
|
|
1856
1867
|
* Get the last input text from a command result.
|