@corti/dictation-web 0.6.0 → 0.7.0-ambient
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/bundle.js +1838 -1455
- package/dist/components/ambient-recording-button.d.ts +16 -0
- package/dist/components/ambient-recording-button.js +68 -0
- package/dist/components/ambient-recording-button.js.map +1 -0
- package/dist/components/corti-ambient.d.ts +27 -0
- package/dist/components/corti-ambient.js +97 -0
- package/dist/components/corti-ambient.js.map +1 -0
- package/dist/components/corti-dictation.d.ts +9 -109
- package/dist/components/corti-dictation.js +12 -187
- package/dist/components/corti-dictation.js.map +1 -1
- package/dist/components/corti-root.d.ts +121 -0
- package/dist/components/corti-root.js +196 -0
- package/dist/components/corti-root.js.map +1 -0
- package/dist/components/device-selector.js +1 -1
- package/dist/components/device-selector.js.map +1 -1
- package/dist/components/dictation-recording-button.d.ts +13 -0
- package/dist/components/dictation-recording-button.js +30 -0
- package/dist/components/dictation-recording-button.js.map +1 -0
- package/dist/components/keybinding-input.js +1 -1
- package/dist/components/keybinding-input.js.map +1 -1
- package/dist/components/keybinding-selector.js +1 -1
- package/dist/components/keybinding-selector.js.map +1 -1
- package/dist/components/language-selector.js +2 -1
- package/dist/components/language-selector.js.map +1 -1
- package/dist/components/{recording-button.d.ts → recording-button-base.d.ts} +7 -9
- package/dist/components/recording-button-base.js +321 -0
- package/dist/components/recording-button-base.js.map +1 -0
- package/dist/components/settings-menu.js +1 -1
- package/dist/components/settings-menu.js.map +1 -1
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +9 -0
- package/dist/constants.js.map +1 -1
- package/dist/contexts/ambient-context.d.ts +18 -0
- package/dist/contexts/ambient-context.js +48 -0
- package/dist/contexts/ambient-context.js.map +1 -0
- package/dist/contexts/dictation-context.d.ts +3 -92
- package/dist/contexts/dictation-context.js +5 -257
- package/dist/contexts/dictation-context.js.map +1 -1
- package/dist/contexts/mixins/auth-context.d.ts +32 -0
- package/dist/contexts/mixins/auth-context.js +116 -0
- package/dist/contexts/mixins/auth-context.js.map +1 -0
- package/dist/contexts/mixins/devices-context.d.ts +14 -0
- package/dist/contexts/mixins/devices-context.js +58 -0
- package/dist/contexts/mixins/devices-context.js.map +1 -0
- package/dist/contexts/mixins/keybindings-context.d.ts +13 -0
- package/dist/contexts/mixins/keybindings-context.js +62 -0
- package/dist/contexts/mixins/keybindings-context.js.map +1 -0
- package/dist/contexts/mixins/languages-context.d.ts +11 -0
- package/dist/contexts/mixins/languages-context.js +54 -0
- package/dist/contexts/mixins/languages-context.js.map +1 -0
- package/dist/contexts/mixins/proxy-context.d.ts +14 -0
- package/dist/contexts/mixins/proxy-context.js +24 -0
- package/dist/contexts/mixins/proxy-context.js.map +1 -0
- package/dist/contexts/mixins/recording-state-context.d.ts +13 -0
- package/dist/contexts/mixins/recording-state-context.js +30 -0
- package/dist/contexts/mixins/recording-state-context.js.map +1 -0
- package/dist/contexts/mixins/types.d.ts +5 -0
- package/dist/contexts/mixins/types.js +2 -0
- package/dist/contexts/mixins/types.js.map +1 -0
- package/dist/contexts/root-context.d.ts +8 -0
- package/dist/contexts/root-context.js +34 -0
- package/dist/contexts/root-context.js.map +1 -0
- package/dist/controllers/ambient-controller.d.ts +16 -0
- package/dist/controllers/ambient-controller.js +24 -0
- package/dist/controllers/ambient-controller.js.map +1 -0
- package/dist/controllers/dictation-controller.d.ts +8 -31
- package/dist/controllers/dictation-controller.js +17 -283
- package/dist/controllers/dictation-controller.js.map +1 -1
- package/dist/controllers/languages-controller.js +0 -4
- package/dist/controllers/languages-controller.js.map +1 -1
- package/dist/controllers/socket-controller.d.ts +51 -0
- package/dist/controllers/socket-controller.js +281 -0
- package/dist/controllers/socket-controller.js.map +1 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types.d.ts +3 -0
- package/dist/types.js.map +1 -1
- package/dist/utils/devices.d.ts +12 -8
- package/dist/utils/devices.js +39 -28
- package/dist/utils/devices.js.map +1 -1
- package/dist/utils/events.d.ts +5 -3
- package/dist/utils/events.js +7 -0
- package/dist/utils/events.js.map +1 -1
- package/dist/utils/keybinding.d.ts +2 -1
- package/dist/utils/keybinding.js +12 -6
- package/dist/utils/keybinding.js.map +1 -1
- package/package.json +1 -1
- package/dist/components/recording-button.js +0 -331
- package/dist/components/recording-button.js.map +0 -1
|
@@ -1,289 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
};
|
|
12
|
-
var _DictationController_instances, _DictationController_cortiClient, _DictationController_webSocket, _DictationController_closeTimeout, _DictationController_callbacks, _DictationController_lastDictationConfig, _DictationController_lastSocketUrl, _DictationController_lastSocketProxy, _DictationController_outboundQueue, _DictationController_socketReady, _DictationController_connectingPromise, _DictationController_connectionGeneration, _DictationController_isConnecting, _DictationController_configHasChanged, _DictationController_doConnect, _DictationController_connectProxy, _DictationController_connectAuth, _DictationController_setupWebSocketHandlers, _DictationController_isSocketOpen, _DictationController_drain;
|
|
13
|
-
import { CortiClient, CortiWebSocketProxyClient, } from "@corti/sdk";
|
|
14
|
-
import { DEFAULT_DICTATION_CONFIG } from "../constants.js";
|
|
15
|
-
import { errorEvent } from "../utils/events.js";
|
|
16
|
-
export class DictationController {
|
|
17
|
-
constructor(host) {
|
|
18
|
-
_DictationController_instances.add(this);
|
|
19
|
-
_DictationController_cortiClient.set(this, null);
|
|
20
|
-
_DictationController_webSocket.set(this, null);
|
|
21
|
-
_DictationController_closeTimeout.set(this, void 0);
|
|
22
|
-
_DictationController_callbacks.set(this, void 0);
|
|
23
|
-
_DictationController_lastDictationConfig.set(this, null);
|
|
24
|
-
_DictationController_lastSocketUrl.set(this, void 0);
|
|
25
|
-
_DictationController_lastSocketProxy.set(this, void 0);
|
|
26
|
-
_DictationController_outboundQueue.set(this, []);
|
|
27
|
-
_DictationController_socketReady.set(this, false);
|
|
28
|
-
_DictationController_connectingPromise.set(this, null);
|
|
29
|
-
_DictationController_connectionGeneration.set(this, 0);
|
|
30
|
-
_DictationController_isConnecting.set(this, false);
|
|
31
|
-
this.mediaRecorderHandler = (data) => {
|
|
32
|
-
if (__classPrivateFieldGet(this, _DictationController_socketReady, "f") && __classPrivateFieldGet(this, _DictationController_instances, "m", _DictationController_isSocketOpen).call(this)) {
|
|
33
|
-
__classPrivateFieldGet(this, _DictationController_webSocket, "f")?.send(data);
|
|
34
|
-
__classPrivateFieldGet(this, _DictationController_callbacks, "f")?.onNetworkActivity?.("sent", {
|
|
35
|
-
size: data.size,
|
|
36
|
-
type: "audio",
|
|
37
|
-
});
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
__classPrivateFieldGet(this, _DictationController_outboundQueue, "f").push(data);
|
|
41
|
-
};
|
|
42
|
-
this.host = host;
|
|
43
|
-
host.addController(this);
|
|
44
|
-
}
|
|
45
|
-
hostDisconnected() {
|
|
46
|
-
this.cleanup();
|
|
47
|
-
}
|
|
48
|
-
async connect(dictationConfig = DEFAULT_DICTATION_CONFIG, callbacks = {}) {
|
|
49
|
-
// If a connection attempt is already in progress with the same config, reuse it
|
|
50
|
-
// to avoid opening multiple sockets when connect() is called concurrently.
|
|
51
|
-
if (__classPrivateFieldGet(this, _DictationController_connectingPromise, "f") && !__classPrivateFieldGet(this, _DictationController_instances, "m", _DictationController_configHasChanged).call(this)) {
|
|
52
|
-
return __classPrivateFieldGet(this, _DictationController_connectingPromise, "f");
|
|
53
|
-
}
|
|
54
|
-
// #isConnecting must be set synchronously before #doConnect runs, because
|
|
55
|
-
// #doConnect calls cleanup() which closes the old socket, firing its "close"
|
|
56
|
-
// event synchronously. Handlers that check isConnecting() need to see true
|
|
57
|
-
// at that point — before #connectingPromise is even assigned.
|
|
58
|
-
__classPrivateFieldSet(this, _DictationController_isConnecting, true, "f");
|
|
59
|
-
__classPrivateFieldSet(this, _DictationController_connectingPromise, __classPrivateFieldGet(this, _DictationController_instances, "m", _DictationController_doConnect).call(this, dictationConfig, callbacks).finally(() => {
|
|
60
|
-
__classPrivateFieldSet(this, _DictationController_isConnecting, false, "f");
|
|
61
|
-
__classPrivateFieldSet(this, _DictationController_connectingPromise, null, "f");
|
|
62
|
-
}), "f");
|
|
63
|
-
return __classPrivateFieldGet(this, _DictationController_connectingPromise, "f");
|
|
64
|
-
}
|
|
65
|
-
async pause() {
|
|
66
|
-
if (__classPrivateFieldGet(this, _DictationController_socketReady, "f") && __classPrivateFieldGet(this, _DictationController_instances, "m", _DictationController_isSocketOpen).call(this)) {
|
|
67
|
-
__classPrivateFieldGet(this, _DictationController_webSocket, "f")?.send(JSON.stringify({ type: "flush" }));
|
|
68
|
-
__classPrivateFieldGet(this, _DictationController_callbacks, "f")?.onNetworkActivity?.("sent", { type: "flush" });
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
__classPrivateFieldGet(this, _DictationController_outboundQueue, "f").push({ type: "flush" });
|
|
72
|
-
}
|
|
73
|
-
isConnectionOpen() {
|
|
74
|
-
return (__classPrivateFieldGet(this, _DictationController_webSocket, "f") !== null &&
|
|
75
|
-
(__classPrivateFieldGet(this, _DictationController_webSocket, "f").readyState === WebSocket.OPEN ||
|
|
76
|
-
__classPrivateFieldGet(this, _DictationController_webSocket, "f").readyState === WebSocket.CONNECTING));
|
|
77
|
-
}
|
|
78
|
-
isConnecting() {
|
|
79
|
-
return __classPrivateFieldGet(this, _DictationController_isConnecting, "f");
|
|
80
|
-
}
|
|
81
|
-
async waitForConnection() {
|
|
82
|
-
await __classPrivateFieldGet(this, _DictationController_connectingPromise, "f");
|
|
83
|
-
}
|
|
84
|
-
async closeConnection(onClose) {
|
|
85
|
-
await new Promise((resolve, reject) => {
|
|
86
|
-
const oldSocket = __classPrivateFieldGet(this, _DictationController_webSocket, "f");
|
|
87
|
-
__classPrivateFieldSet(this, _DictationController_webSocket, null, "f");
|
|
88
|
-
if (!oldSocket ||
|
|
89
|
-
(oldSocket.readyState !== WebSocket.OPEN &&
|
|
90
|
-
oldSocket.readyState !== WebSocket.CONNECTING)) {
|
|
91
|
-
__classPrivateFieldSet(this, _DictationController_socketReady, false, "f");
|
|
92
|
-
resolve();
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
oldSocket.on("close", (event) => {
|
|
96
|
-
if (__classPrivateFieldGet(this, _DictationController_closeTimeout, "f")) {
|
|
97
|
-
clearTimeout(__classPrivateFieldGet(this, _DictationController_closeTimeout, "f"));
|
|
98
|
-
__classPrivateFieldSet(this, _DictationController_closeTimeout, undefined, "f");
|
|
99
|
-
}
|
|
100
|
-
if (onClose) {
|
|
101
|
-
onClose(event);
|
|
102
|
-
}
|
|
103
|
-
resolve();
|
|
104
|
-
});
|
|
105
|
-
const wasReady = __classPrivateFieldGet(this, _DictationController_socketReady, "f");
|
|
106
|
-
__classPrivateFieldSet(this, _DictationController_socketReady, false, "f");
|
|
107
|
-
oldSocket.on("message", (message) => {
|
|
108
|
-
__classPrivateFieldGet(this, _DictationController_callbacks, "f")?.onNetworkActivity?.("received", message);
|
|
109
|
-
if (__classPrivateFieldGet(this, _DictationController_callbacks, "f")?.onMessage) {
|
|
110
|
-
__classPrivateFieldGet(this, _DictationController_callbacks, "f")?.onMessage(message);
|
|
111
|
-
}
|
|
112
|
-
// closeConnection() may be called before CONFIG_ACCEPTED arrives (e.g.
|
|
113
|
-
// openConnection() followed immediately by closeConnection()). We can't
|
|
114
|
-
// use the outbound queue here because #webSocket is already null, so we
|
|
115
|
-
// send "end" directly on oldSocket as soon as config is accepted.
|
|
116
|
-
if (!wasReady && message.type === "CONFIG_ACCEPTED") {
|
|
117
|
-
oldSocket.sendEnd({ type: "end" });
|
|
118
|
-
__classPrivateFieldGet(this, _DictationController_callbacks, "f")?.onNetworkActivity?.("sent", { type: "end" });
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
if (message.type === "ended") {
|
|
122
|
-
if (__classPrivateFieldGet(this, _DictationController_closeTimeout, "f")) {
|
|
123
|
-
clearTimeout(__classPrivateFieldGet(this, _DictationController_closeTimeout, "f"));
|
|
124
|
-
__classPrivateFieldSet(this, _DictationController_closeTimeout, undefined, "f");
|
|
125
|
-
}
|
|
126
|
-
resolve();
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
if (wasReady) {
|
|
131
|
-
oldSocket.sendEnd({ type: "end" });
|
|
132
|
-
__classPrivateFieldGet(this, _DictationController_callbacks, "f")?.onNetworkActivity?.("sent", { type: "end" });
|
|
133
|
-
}
|
|
134
|
-
__classPrivateFieldSet(this, _DictationController_closeTimeout, window.setTimeout(() => {
|
|
135
|
-
reject(new Error("Connection close timeout"));
|
|
136
|
-
if (oldSocket?.readyState === WebSocket.OPEN) {
|
|
137
|
-
oldSocket.close();
|
|
138
|
-
}
|
|
139
|
-
}, 10000), "f");
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
cleanup() {
|
|
143
|
-
var _a;
|
|
144
|
-
// Incrementing generation invalidates any in-flight #doConnect awaits,
|
|
145
|
-
// causing them to discard their socket and return "superseded".
|
|
146
|
-
__classPrivateFieldSet(this, _DictationController_connectionGeneration, (_a = __classPrivateFieldGet(this, _DictationController_connectionGeneration, "f"), _a++, _a), "f");
|
|
147
|
-
__classPrivateFieldSet(this, _DictationController_socketReady, false, "f");
|
|
148
|
-
if (__classPrivateFieldGet(this, _DictationController_closeTimeout, "f")) {
|
|
149
|
-
clearTimeout(__classPrivateFieldGet(this, _DictationController_closeTimeout, "f"));
|
|
150
|
-
__classPrivateFieldSet(this, _DictationController_closeTimeout, undefined, "f");
|
|
151
|
-
}
|
|
152
|
-
if (this.isConnectionOpen()) {
|
|
153
|
-
__classPrivateFieldGet(this, _DictationController_webSocket, "f")?.close();
|
|
154
|
-
}
|
|
155
|
-
__classPrivateFieldSet(this, _DictationController_webSocket, null, "f");
|
|
156
|
-
__classPrivateFieldSet(this, _DictationController_cortiClient, null, "f");
|
|
157
|
-
__classPrivateFieldSet(this, _DictationController_lastDictationConfig, null, "f");
|
|
158
|
-
__classPrivateFieldSet(this, _DictationController_lastSocketUrl, undefined, "f");
|
|
159
|
-
__classPrivateFieldSet(this, _DictationController_lastSocketProxy, undefined, "f");
|
|
160
|
-
if (__classPrivateFieldGet(this, _DictationController_outboundQueue, "f").length > 0) {
|
|
161
|
-
this.host.dispatchEvent(errorEvent(`${__classPrivateFieldGet(this, _DictationController_outboundQueue, "f").length} unsent message(s) were discarded because the configuration changed before the connection was closed`));
|
|
162
|
-
}
|
|
163
|
-
__classPrivateFieldSet(this, _DictationController_outboundQueue, [], "f");
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
_DictationController_cortiClient = new WeakMap(), _DictationController_webSocket = new WeakMap(), _DictationController_closeTimeout = new WeakMap(), _DictationController_callbacks = new WeakMap(), _DictationController_lastDictationConfig = new WeakMap(), _DictationController_lastSocketUrl = new WeakMap(), _DictationController_lastSocketProxy = new WeakMap(), _DictationController_outboundQueue = new WeakMap(), _DictationController_socketReady = new WeakMap(), _DictationController_connectingPromise = new WeakMap(), _DictationController_connectionGeneration = new WeakMap(), _DictationController_isConnecting = new WeakMap(), _DictationController_instances = new WeakSet(), _DictationController_configHasChanged = function _DictationController_configHasChanged() {
|
|
167
|
-
return (JSON.stringify(this.host._dictationConfig) !==
|
|
168
|
-
JSON.stringify(__classPrivateFieldGet(this, _DictationController_lastDictationConfig, "f")) ||
|
|
169
|
-
this.host._socketUrl !== __classPrivateFieldGet(this, _DictationController_lastSocketUrl, "f") ||
|
|
170
|
-
JSON.stringify(this.host._socketProxy) !==
|
|
171
|
-
JSON.stringify(__classPrivateFieldGet(this, _DictationController_lastSocketProxy, "f")));
|
|
172
|
-
}, _DictationController_doConnect = async function _DictationController_doConnect(dictationConfig, callbacks) {
|
|
173
|
-
const newConnection = __classPrivateFieldGet(this, _DictationController_instances, "m", _DictationController_configHasChanged).call(this) || !this.isConnectionOpen();
|
|
174
|
-
if (newConnection) {
|
|
175
|
-
this.cleanup();
|
|
176
|
-
__classPrivateFieldSet(this, _DictationController_lastDictationConfig, this.host._dictationConfig || null, "f");
|
|
177
|
-
__classPrivateFieldSet(this, _DictationController_lastSocketUrl, this.host._socketUrl, "f");
|
|
178
|
-
__classPrivateFieldSet(this, _DictationController_lastSocketProxy, this.host._socketProxy, "f");
|
|
179
|
-
const generation = __classPrivateFieldGet(this, _DictationController_connectionGeneration, "f");
|
|
180
|
-
const socket = this.host._socketUrl || this.host._socketProxy
|
|
181
|
-
? await __classPrivateFieldGet(this, _DictationController_instances, "m", _DictationController_connectProxy).call(this, dictationConfig)
|
|
182
|
-
: await __classPrivateFieldGet(this, _DictationController_instances, "m", _DictationController_connectAuth).call(this, dictationConfig);
|
|
183
|
-
// If cleanup() was called while we were awaiting (e.g. config changed),
|
|
184
|
-
// the generation counter will have advanced — discard this stale socket.
|
|
185
|
-
if (__classPrivateFieldGet(this, _DictationController_connectionGeneration, "f") !== generation) {
|
|
186
|
-
socket.close();
|
|
187
|
-
return "superseded";
|
|
188
|
-
}
|
|
189
|
-
__classPrivateFieldSet(this, _DictationController_webSocket, socket, "f");
|
|
190
|
-
__classPrivateFieldGet(this, _DictationController_callbacks, "f")?.onNetworkActivity?.("sent", {
|
|
1
|
+
import { CortiWebSocketProxyClient, } from "@corti/sdk";
|
|
2
|
+
import { SocketController } from "./socket-controller.js";
|
|
3
|
+
export class DictationController extends SocketController {
|
|
4
|
+
async stopRecording() {
|
|
5
|
+
await this.pause();
|
|
6
|
+
}
|
|
7
|
+
async _connectThroughProxy(dictationConfig, proxy) {
|
|
8
|
+
return await CortiWebSocketProxyClient.transcribe.connect({
|
|
9
|
+
// awaitConfiguration: false — CONFIG_* appears in network activity before the socket is configured server-side
|
|
10
|
+
awaitConfiguration: false,
|
|
191
11
|
configuration: dictationConfig,
|
|
192
|
-
|
|
12
|
+
proxy,
|
|
193
13
|
});
|
|
194
14
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}
|
|
201
|
-
return newConnection;
|
|
202
|
-
}, _DictationController_connectProxy = async function _DictationController_connectProxy(dictationConfig) {
|
|
203
|
-
const proxyOptions = this.host._socketProxy || {
|
|
204
|
-
url: this.host._socketUrl || "",
|
|
205
|
-
};
|
|
206
|
-
if (!proxyOptions.url) {
|
|
207
|
-
throw new Error("Proxy URL is required when using proxy client");
|
|
208
|
-
}
|
|
209
|
-
return await CortiWebSocketProxyClient.transcribe.connect({
|
|
210
|
-
// setting to "false" to have CONFIG_* message in network activity events
|
|
211
|
-
awaitConfiguration: false,
|
|
212
|
-
configuration: dictationConfig,
|
|
213
|
-
proxy: proxyOptions,
|
|
214
|
-
});
|
|
215
|
-
}, _DictationController_connectAuth = async function _DictationController_connectAuth(dictationConfig) {
|
|
216
|
-
if (!this.host._authConfig && !this.host._accessToken) {
|
|
217
|
-
throw new Error("Auth configuration or access token is required to connect");
|
|
218
|
-
}
|
|
219
|
-
// Use authConfig if available, otherwise create one from accessToken
|
|
220
|
-
const auth = this.host._authConfig || {
|
|
221
|
-
accessToken: this.host._accessToken || "",
|
|
222
|
-
refreshAccessToken: () => ({
|
|
223
|
-
accessToken: this.host._accessToken || "",
|
|
224
|
-
}),
|
|
225
|
-
};
|
|
226
|
-
__classPrivateFieldSet(this, _DictationController_cortiClient, new CortiClient({
|
|
227
|
-
auth,
|
|
228
|
-
environment: this.host._region,
|
|
229
|
-
tenantName: this.host._tenantName,
|
|
230
|
-
}), "f");
|
|
231
|
-
return await __classPrivateFieldGet(this, _DictationController_cortiClient, "f").transcribe.connect({
|
|
232
|
-
// setting to "false" to have CONFIG_* message in network activity events
|
|
233
|
-
awaitConfiguration: false,
|
|
234
|
-
configuration: dictationConfig,
|
|
235
|
-
});
|
|
236
|
-
}, _DictationController_setupWebSocketHandlers = function _DictationController_setupWebSocketHandlers(callbacks) {
|
|
237
|
-
if (!__classPrivateFieldGet(this, _DictationController_webSocket, "f")) {
|
|
238
|
-
throw new Error("WebSocket not initialized");
|
|
239
|
-
}
|
|
240
|
-
__classPrivateFieldGet(this, _DictationController_webSocket, "f").on("message", (message) => {
|
|
241
|
-
if (message.type === "CONFIG_ACCEPTED") {
|
|
242
|
-
__classPrivateFieldSet(this, _DictationController_socketReady, true, "f");
|
|
243
|
-
__classPrivateFieldGet(this, _DictationController_instances, "m", _DictationController_drain).call(this);
|
|
244
|
-
}
|
|
245
|
-
callbacks.onNetworkActivity?.("received", message);
|
|
246
|
-
if (callbacks.onMessage) {
|
|
247
|
-
callbacks.onMessage(message);
|
|
248
|
-
}
|
|
249
|
-
});
|
|
250
|
-
__classPrivateFieldGet(this, _DictationController_webSocket, "f").on("error", (event) => {
|
|
251
|
-
__classPrivateFieldSet(this, _DictationController_socketReady, false, "f");
|
|
252
|
-
if (callbacks.onError) {
|
|
253
|
-
callbacks.onError(event);
|
|
254
|
-
}
|
|
255
|
-
});
|
|
256
|
-
__classPrivateFieldGet(this, _DictationController_webSocket, "f").on("close", (event) => {
|
|
257
|
-
__classPrivateFieldSet(this, _DictationController_socketReady, false, "f");
|
|
258
|
-
if (callbacks.onClose) {
|
|
259
|
-
callbacks.onClose(event);
|
|
260
|
-
}
|
|
261
|
-
});
|
|
262
|
-
}, _DictationController_isSocketOpen = function _DictationController_isSocketOpen() {
|
|
263
|
-
return (__classPrivateFieldGet(this, _DictationController_webSocket, "f") !== null && __classPrivateFieldGet(this, _DictationController_webSocket, "f").readyState === WebSocket.OPEN);
|
|
264
|
-
}, _DictationController_drain = function _DictationController_drain() {
|
|
265
|
-
if (!__classPrivateFieldGet(this, _DictationController_socketReady, "f") ||
|
|
266
|
-
!__classPrivateFieldGet(this, _DictationController_instances, "m", _DictationController_isSocketOpen).call(this) ||
|
|
267
|
-
__classPrivateFieldGet(this, _DictationController_outboundQueue, "f").length === 0) {
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
270
|
-
while (__classPrivateFieldGet(this, _DictationController_outboundQueue, "f").length > 0 && __classPrivateFieldGet(this, _DictationController_instances, "m", _DictationController_isSocketOpen).call(this)) {
|
|
271
|
-
const item = __classPrivateFieldGet(this, _DictationController_outboundQueue, "f").shift();
|
|
272
|
-
if (item === undefined) {
|
|
273
|
-
break;
|
|
274
|
-
}
|
|
275
|
-
if (item instanceof Blob) {
|
|
276
|
-
__classPrivateFieldGet(this, _DictationController_webSocket, "f").send(item);
|
|
277
|
-
__classPrivateFieldGet(this, _DictationController_callbacks, "f")?.onNetworkActivity?.("sent", {
|
|
278
|
-
size: item.size,
|
|
279
|
-
type: "audio",
|
|
280
|
-
});
|
|
281
|
-
continue;
|
|
282
|
-
}
|
|
283
|
-
__classPrivateFieldGet(this, _DictationController_webSocket, "f").send(JSON.stringify(item));
|
|
284
|
-
__classPrivateFieldGet(this, _DictationController_callbacks, "f")?.onNetworkActivity?.("sent", {
|
|
285
|
-
type: item.type,
|
|
15
|
+
async _connectThroughAuth(client, dictationConfig) {
|
|
16
|
+
return await client.transcribe.connect({
|
|
17
|
+
// awaitConfiguration: false — CONFIG_* appears in network activity before the socket is configured server-side
|
|
18
|
+
awaitConfiguration: false,
|
|
19
|
+
configuration: dictationConfig,
|
|
286
20
|
});
|
|
287
21
|
}
|
|
288
|
-
}
|
|
22
|
+
}
|
|
289
23
|
//# sourceMappingURL=dictation-controller.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dictation-controller.js","sourceRoot":"","sources":["../../src/controllers/dictation-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type Corti,\n type CortiAuth,\n CortiClient,\n CortiWebSocketProxyClient,\n} from \"@corti/sdk\";\nimport type { ReactiveController, ReactiveControllerHost } from \"lit\";\nimport { DEFAULT_DICTATION_CONFIG } from \"../constants.js\";\nimport type { ProxyOptions } from \"../types.js\";\nimport { errorEvent } from \"../utils/events.js\";\n\ntype TranscribeSocket = Awaited<\n ReturnType<CortiClient[\"transcribe\"][\"connect\"]>\n>;\n\ninterface DictationControllerHost extends ReactiveControllerHost {\n dispatchEvent: (event: Event) => void;\n _accessToken?: string;\n _authConfig?: CortiAuth.AuthTokenDerivable;\n _region?: string;\n _tenantName?: string;\n _socketUrl?: string;\n _socketProxy?: ProxyOptions;\n _dictationConfig?: Corti.TranscribeConfig;\n}\n\nexport type TranscribeMessage =\n | Corti.TranscribeConfigStatusMessage\n | Corti.TranscribeUsageMessage\n | Corti.TranscribeDeltaUsageMessage\n | Corti.TranscribeEndedMessage\n | Corti.TranscribeErrorMessage\n | Corti.TranscribeTranscriptMessage\n | Corti.TranscribeCommandMessage\n | Corti.TranscribeFlushedMessage;\n\ntype OutboundItem =\n | Blob\n | Corti.TranscribeFlushMessage\n | Corti.TranscribeEndMessage;\n\ninterface WebSocketCallbacks {\n onMessage?: (message: TranscribeMessage) => void;\n onError?: (error: Error) => void;\n onClose?: (event: unknown) => void;\n onNetworkActivity?: (direction: \"sent\" | \"received\", data: unknown) => void;\n}\n\nexport class DictationController implements ReactiveController {\n host: DictationControllerHost;\n\n #cortiClient: CortiClient | null = null;\n #webSocket: TranscribeSocket | null = null;\n #closeTimeout?: number;\n #callbacks?: WebSocketCallbacks;\n #lastDictationConfig: Corti.TranscribeConfig | null = null;\n #lastSocketUrl?: string;\n #lastSocketProxy?: ProxyOptions;\n #outboundQueue: OutboundItem[] = [];\n #socketReady = false;\n #connectingPromise: Promise<boolean | \"superseded\"> | null = null;\n #connectionGeneration = 0;\n #isConnecting = false;\n\n constructor(host: DictationControllerHost) {\n this.host = host;\n host.addController(this);\n }\n\n hostDisconnected(): void {\n this.cleanup();\n }\n\n #configHasChanged(): boolean {\n return (\n JSON.stringify(this.host._dictationConfig) !==\n JSON.stringify(this.#lastDictationConfig) ||\n this.host._socketUrl !== this.#lastSocketUrl ||\n JSON.stringify(this.host._socketProxy) !==\n JSON.stringify(this.#lastSocketProxy)\n );\n }\n\n async connect(\n dictationConfig: Corti.TranscribeConfig = DEFAULT_DICTATION_CONFIG,\n callbacks: WebSocketCallbacks = {},\n ): Promise<boolean | \"superseded\"> {\n // If a connection attempt is already in progress with the same config, reuse it\n // to avoid opening multiple sockets when connect() is called concurrently.\n if (this.#connectingPromise && !this.#configHasChanged()) {\n return this.#connectingPromise;\n }\n\n // #isConnecting must be set synchronously before #doConnect runs, because\n // #doConnect calls cleanup() which closes the old socket, firing its \"close\"\n // event synchronously. Handlers that check isConnecting() need to see true\n // at that point — before #connectingPromise is even assigned.\n this.#isConnecting = true;\n this.#connectingPromise = this.#doConnect(\n dictationConfig,\n callbacks,\n ).finally(() => {\n this.#isConnecting = false;\n this.#connectingPromise = null;\n });\n\n return this.#connectingPromise;\n }\n\n async #doConnect(\n dictationConfig: Corti.TranscribeConfig,\n callbacks: WebSocketCallbacks,\n ): Promise<boolean | \"superseded\"> {\n const newConnection = this.#configHasChanged() || !this.isConnectionOpen();\n\n if (newConnection) {\n this.cleanup();\n\n this.#lastDictationConfig = this.host._dictationConfig || null;\n this.#lastSocketUrl = this.host._socketUrl;\n this.#lastSocketProxy = this.host._socketProxy;\n\n const generation = this.#connectionGeneration;\n\n const socket =\n this.host._socketUrl || this.host._socketProxy\n ? await this.#connectProxy(dictationConfig)\n : await this.#connectAuth(dictationConfig);\n\n // If cleanup() was called while we were awaiting (e.g. config changed),\n // the generation counter will have advanced — discard this stale socket.\n if (this.#connectionGeneration !== generation) {\n socket.close();\n return \"superseded\";\n }\n\n this.#webSocket = socket;\n\n this.#callbacks?.onNetworkActivity?.(\"sent\", {\n configuration: dictationConfig,\n type: \"config\",\n });\n }\n\n this.#callbacks = callbacks;\n this.#setupWebSocketHandlers(callbacks);\n\n if (!newConnection && this.isConnectionOpen()) {\n this.#socketReady = true;\n this.#drain();\n }\n\n return newConnection;\n }\n\n async #connectProxy(\n dictationConfig: Corti.TranscribeConfig,\n ): Promise<TranscribeSocket> {\n const proxyOptions = this.host._socketProxy || {\n url: this.host._socketUrl || \"\",\n };\n\n if (!proxyOptions.url) {\n throw new Error(\"Proxy URL is required when using proxy client\");\n }\n\n return await CortiWebSocketProxyClient.transcribe.connect({\n // setting to \"false\" to have CONFIG_* message in network activity events\n awaitConfiguration: false,\n configuration: dictationConfig,\n proxy: proxyOptions,\n });\n }\n\n async #connectAuth(\n dictationConfig: Corti.TranscribeConfig,\n ): Promise<TranscribeSocket> {\n if (!this.host._authConfig && !this.host._accessToken) {\n throw new Error(\n \"Auth configuration or access token is required to connect\",\n );\n }\n\n // Use authConfig if available, otherwise create one from accessToken\n const auth: CortiAuth.AuthTokenDerivable = this.host._authConfig || {\n accessToken: this.host._accessToken || \"\",\n refreshAccessToken: () => ({\n accessToken: this.host._accessToken || \"\",\n }),\n };\n\n this.#cortiClient = new CortiClient({\n auth,\n environment: this.host._region,\n tenantName: this.host._tenantName,\n });\n\n return await this.#cortiClient.transcribe.connect({\n // setting to \"false\" to have CONFIG_* message in network activity events\n awaitConfiguration: false,\n configuration: dictationConfig,\n });\n }\n\n #setupWebSocketHandlers(callbacks: WebSocketCallbacks): void {\n if (!this.#webSocket) {\n throw new Error(\"WebSocket not initialized\");\n }\n\n this.#webSocket.on(\"message\", (message: TranscribeMessage) => {\n if (message.type === \"CONFIG_ACCEPTED\") {\n this.#socketReady = true;\n this.#drain();\n }\n\n callbacks.onNetworkActivity?.(\"received\", message);\n\n if (callbacks.onMessage) {\n callbacks.onMessage(message);\n }\n });\n\n this.#webSocket.on(\"error\", (event: Error) => {\n this.#socketReady = false;\n if (callbacks.onError) {\n callbacks.onError(event);\n }\n });\n\n this.#webSocket.on(\"close\", (event: unknown) => {\n this.#socketReady = false;\n if (callbacks.onClose) {\n callbacks.onClose(event);\n }\n });\n }\n\n #isSocketOpen(): boolean {\n return (\n this.#webSocket !== null && this.#webSocket.readyState === WebSocket.OPEN\n );\n }\n\n #drain(): void {\n if (\n !this.#socketReady ||\n !this.#isSocketOpen() ||\n this.#outboundQueue.length === 0\n ) {\n return;\n }\n\n while (this.#outboundQueue.length > 0 && this.#isSocketOpen()) {\n const item = this.#outboundQueue.shift();\n\n if (item === undefined) {\n break;\n }\n\n if (item instanceof Blob) {\n this.#webSocket!.send(item);\n this.#callbacks?.onNetworkActivity?.(\"sent\", {\n size: item.size,\n type: \"audio\",\n });\n continue;\n }\n\n this.#webSocket!.send(JSON.stringify(item));\n this.#callbacks?.onNetworkActivity?.(\"sent\", {\n type: item.type,\n });\n }\n }\n\n mediaRecorderHandler = (data: Blob): void => {\n if (this.#socketReady && this.#isSocketOpen()) {\n this.#webSocket?.send(data);\n this.#callbacks?.onNetworkActivity?.(\"sent\", {\n size: data.size,\n type: \"audio\",\n });\n return;\n }\n\n this.#outboundQueue.push(data);\n };\n\n async pause(): Promise<void> {\n if (this.#socketReady && this.#isSocketOpen()) {\n this.#webSocket?.send(JSON.stringify({ type: \"flush\" }));\n this.#callbacks?.onNetworkActivity?.(\"sent\", { type: \"flush\" });\n return;\n }\n\n this.#outboundQueue.push({ type: \"flush\" });\n }\n\n isConnectionOpen(): boolean {\n return (\n this.#webSocket !== null &&\n (this.#webSocket.readyState === WebSocket.OPEN ||\n this.#webSocket.readyState === WebSocket.CONNECTING)\n );\n }\n\n isConnecting(): boolean {\n return this.#isConnecting;\n }\n\n async waitForConnection(): Promise<void> {\n await this.#connectingPromise;\n }\n\n async closeConnection(onClose?: (event: unknown) => void): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const oldSocket = this.#webSocket;\n this.#webSocket = null;\n\n if (\n !oldSocket ||\n (oldSocket.readyState !== WebSocket.OPEN &&\n oldSocket.readyState !== WebSocket.CONNECTING)\n ) {\n this.#socketReady = false;\n resolve();\n return;\n }\n\n oldSocket.on(\"close\", (event) => {\n if (this.#closeTimeout) {\n clearTimeout(this.#closeTimeout);\n this.#closeTimeout = undefined;\n }\n\n if (onClose) {\n onClose(event);\n }\n\n resolve();\n });\n\n const wasReady = this.#socketReady;\n this.#socketReady = false;\n\n oldSocket.on(\"message\", (message) => {\n this.#callbacks?.onNetworkActivity?.(\"received\", message);\n\n if (this.#callbacks?.onMessage) {\n this.#callbacks?.onMessage(message);\n }\n\n // closeConnection() may be called before CONFIG_ACCEPTED arrives (e.g.\n // openConnection() followed immediately by closeConnection()). We can't\n // use the outbound queue here because #webSocket is already null, so we\n // send \"end\" directly on oldSocket as soon as config is accepted.\n if (!wasReady && message.type === \"CONFIG_ACCEPTED\") {\n oldSocket.sendEnd({ type: \"end\" });\n this.#callbacks?.onNetworkActivity?.(\"sent\", { type: \"end\" });\n return;\n }\n\n if (message.type === \"ended\") {\n if (this.#closeTimeout) {\n clearTimeout(this.#closeTimeout);\n this.#closeTimeout = undefined;\n }\n\n resolve();\n return;\n }\n });\n\n if (wasReady) {\n oldSocket.sendEnd({ type: \"end\" });\n this.#callbacks?.onNetworkActivity?.(\"sent\", { type: \"end\" });\n }\n\n this.#closeTimeout = window.setTimeout(() => {\n reject(new Error(\"Connection close timeout\"));\n\n if (oldSocket?.readyState === WebSocket.OPEN) {\n oldSocket.close();\n }\n }, 10000);\n });\n }\n\n cleanup(): void {\n // Incrementing generation invalidates any in-flight #doConnect awaits,\n // causing them to discard their socket and return \"superseded\".\n this.#connectionGeneration++;\n this.#socketReady = false;\n\n if (this.#closeTimeout) {\n clearTimeout(this.#closeTimeout);\n this.#closeTimeout = undefined;\n }\n\n if (this.isConnectionOpen()) {\n this.#webSocket?.close();\n }\n\n this.#webSocket = null;\n this.#cortiClient = null;\n this.#lastDictationConfig = null;\n this.#lastSocketUrl = undefined;\n this.#lastSocketProxy = undefined;\n\n if (this.#outboundQueue.length > 0) {\n this.host.dispatchEvent(\n errorEvent(\n `${this.#outboundQueue.length} unsent message(s) were discarded because the configuration changed before the connection was closed`,\n ),\n );\n }\n\n this.#outboundQueue = [];\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"dictation-controller.js","sourceRoot":"","sources":["../../src/controllers/dictation-controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,yBAAyB,GAC1B,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAqB1D,MAAM,OAAO,mBAAoB,SAAQ,gBAKxC;IACC,KAAK,CAAC,aAAa;QACjB,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAES,KAAK,CAAC,oBAAoB,CAClC,eAAuC,EACvC,KAAmB;QAEnB,OAAO,MAAM,yBAAyB,CAAC,UAAU,CAAC,OAAO,CAAC;YACxD,+GAA+G;YAC/G,kBAAkB,EAAE,KAAK;YACzB,aAAa,EAAE,eAAe;YAC9B,KAAK;SACN,CAAC,CAAC;IACL,CAAC;IAES,KAAK,CAAC,mBAAmB,CACjC,MAAmB,EACnB,eAAuC;QAEvC,OAAO,MAAM,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC;YACrC,+GAA+G;YAC/G,kBAAkB,EAAE,KAAK;YACzB,aAAa,EAAE,eAAe;SAC/B,CAAC,CAAC;IACL,CAAC;CACF","sourcesContent":["import {\n type Corti,\n type CortiClient,\n CortiWebSocketProxyClient,\n} from \"@corti/sdk\";\nimport type { ProxyOptions } from \"../types.js\";\nimport { SocketController } from \"./socket-controller.js\";\n\ntype TranscribeSocket = Awaited<\n ReturnType<CortiClient[\"transcribe\"][\"connect\"]>\n>;\n\nexport type TranscribeMessage =\n | Corti.TranscribeConfigStatusMessage\n | Corti.TranscribeUsageMessage\n | Corti.TranscribeDeltaUsageMessage\n | Corti.TranscribeEndedMessage\n | Corti.TranscribeErrorMessage\n | Corti.TranscribeTranscriptMessage\n | Corti.TranscribeCommandMessage\n | Corti.TranscribeFlushedMessage;\n\ntype OutboundItem =\n | Blob\n | Corti.TranscribeFlushMessage\n | Corti.TranscribeEndMessage;\n\nexport class DictationController extends SocketController<\n OutboundItem,\n TranscribeMessage,\n Corti.TranscribeConfig,\n TranscribeSocket\n> {\n async stopRecording(): Promise<void> {\n await this.pause();\n }\n\n protected async _connectThroughProxy(\n dictationConfig: Corti.TranscribeConfig,\n proxy: ProxyOptions,\n ): Promise<TranscribeSocket> {\n return await CortiWebSocketProxyClient.transcribe.connect({\n // awaitConfiguration: false — CONFIG_* appears in network activity before the socket is configured server-side\n awaitConfiguration: false,\n configuration: dictationConfig,\n proxy,\n });\n }\n\n protected async _connectThroughAuth(\n client: CortiClient,\n dictationConfig: Corti.TranscribeConfig,\n ): Promise<TranscribeSocket> {\n return await client.transcribe.connect({\n // awaitConfiguration: false — CONFIG_* appears in network activity before the socket is configured server-side\n awaitConfiguration: false,\n configuration: dictationConfig,\n });\n }\n}\n"]}
|
|
@@ -66,10 +66,6 @@ _LanguagesController_autoLoadedLanguages = new WeakMap(), _LanguagesController_l
|
|
|
66
66
|
const selectedLanguage = previousLanguage && languages.includes(previousLanguage)
|
|
67
67
|
? previousLanguage
|
|
68
68
|
: defaultLanguage;
|
|
69
|
-
this.host.dictationConfig = {
|
|
70
|
-
...this.host.dictationConfig,
|
|
71
|
-
primaryLanguage: selectedLanguage || "en",
|
|
72
|
-
};
|
|
73
69
|
this.host.requestUpdate();
|
|
74
70
|
this.host.dispatchEvent(languagesChangedEvent(languages, selectedLanguage));
|
|
75
71
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"languages-controller.js","sourceRoot":"","sources":["../../src/controllers/languages-controller.ts"],"names":[],"mappings":";;;;;;;;;;;;AAEA,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAU7D;;;;GAIG;AACH,MAAM,OAAO,mBAAmB;IAO9B,YAAY,IAA6B;;QALzC,mDAAgC,KAAK,EAAC;QACtC,gDAA6B,KAAK,EAAC;QACnC,sDAAyB;QACzB,2CAAwB,KAAK,EAAC;QAG5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IAED,UAAU;QACR,uBAAA,IAAI,oCAAgB,IAAI,MAAA,CAAC;QAEzB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACvC,uBAAA,IAAI,0EAAe,MAAnB,IAAI,CAAiB,CAAC;QACxB,CAAC;IACH,CAAC;IAED,UAAU;QACR,6CAA6C;QAC7C,IAAI,CAAC,uBAAA,IAAI,wCAAa,EAAE,CAAC;YACvB,OAAO;QACT,CAAC;QAED,iEAAiE;QACjE,IACE,CAAC,uBAAA,IAAI,2CAAgB,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM;YACxC,uBAAA,IAAI,gDAAqB,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,UAAU,KAAK,SAAS,EAClC,CAAC;YACD,uBAAA,IAAI,0EAAe,MAAnB,IAAI,CAAiB,CAAC;QACxB,CAAC;QAED,uBAAA,IAAI,uCAAmB,IAAI,CAAC,IAAI,CAAC,MAAM,MAAA,CAAC;IAC1C,CAAC;
|
|
1
|
+
{"version":3,"file":"languages-controller.js","sourceRoot":"","sources":["../../src/controllers/languages-controller.ts"],"names":[],"mappings":";;;;;;;;;;;;AAEA,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAU7D;;;;GAIG;AACH,MAAM,OAAO,mBAAmB;IAO9B,YAAY,IAA6B;;QALzC,mDAAgC,KAAK,EAAC;QACtC,gDAA6B,KAAK,EAAC;QACnC,sDAAyB;QACzB,2CAAwB,KAAK,EAAC;QAG5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IAED,UAAU;QACR,uBAAA,IAAI,oCAAgB,IAAI,MAAA,CAAC;QAEzB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACvC,uBAAA,IAAI,0EAAe,MAAnB,IAAI,CAAiB,CAAC;QACxB,CAAC;IACH,CAAC;IAED,UAAU;QACR,6CAA6C;QAC7C,IAAI,CAAC,uBAAA,IAAI,wCAAa,EAAE,CAAC;YACvB,OAAO;QACT,CAAC;QAED,iEAAiE;QACjE,IACE,CAAC,uBAAA,IAAI,2CAAgB,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM;YACxC,uBAAA,IAAI,gDAAqB,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,UAAU,KAAK,SAAS,EAClC,CAAC;YACD,uBAAA,IAAI,0EAAe,MAAnB,IAAI,CAAiB,CAAC;QACxB,CAAC;QAED,uBAAA,IAAI,uCAAmB,IAAI,CAAC,IAAI,CAAC,MAAM,MAAA,CAAC;IAC1C,CAAC;IAkCD;;OAEG;IACH,mBAAmB;QACjB,uBAAA,IAAI,4CAAwB,KAAK,MAAA,CAAC;IACpC,CAAC;CACF;6SAtCC,KAAK;IACH,IAAI,uBAAA,IAAI,6CAAkB,EAAE,CAAC;QAC3B,OAAO;IACT,CAAC;IAED,uBAAA,IAAI,yCAAqB,IAAI,MAAA,CAAC;IAE9B,IAAI,CAAC;QACH,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,GAAG,oBAAoB,CACzD,IAAI,CAAC,IAAI,CAAC,MAAM,CACjB,CAAC;QAEF,uBAAA,IAAI,4CAAwB,IAAI,MAAA,CAAC;QACjC,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAEjC,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,eAAe,CAAC;QACpE,MAAM,gBAAgB,GACpB,gBAAgB,IAAI,SAAS,CAAC,QAAQ,CAAC,gBAAgB,CAAC;YACtD,CAAC,CAAC,gBAAgB;YAClB,CAAC,CAAC,eAAe,CAAC;QAEtB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QAC1B,IAAI,CAAC,IAAI,CAAC,aAAa,CACrB,qBAAqB,CAAC,SAAS,EAAE,gBAAgB,CAAC,CACnD,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7C,CAAC;YAAS,CAAC;QACT,uBAAA,IAAI,yCAAqB,KAAK,MAAA,CAAC;IACjC,CAAC;AACH,CAAC","sourcesContent":["import type { Corti } from \"@corti/sdk\";\nimport type { ReactiveController, ReactiveControllerHost } from \"lit\";\nimport { errorEvent, languagesChangedEvent } from \"../utils/events.js\";\nimport { getLanguagesByRegion } from \"../utils/languages.js\";\n\ninterface LanguagesControllerHost extends ReactiveControllerHost {\n region?: string;\n dictationConfig?: Corti.TranscribeConfig;\n dispatchEvent(event: CustomEvent): boolean;\n requestUpdate(): void;\n _languages?: Corti.TranscribeSupportedLanguage[];\n}\n\n/**\n * Controller that manages automatic language loading based on region.\n * Loads languages when they're not present and handles region changes.\n * Reacts to updates and automatically loads languages when needed.\n */\nexport class LanguagesController implements ReactiveController {\n host: LanguagesControllerHost;\n #autoLoadedLanguages: boolean = false;\n #loadingLanguages: boolean = false;\n #previousRegion?: string;\n #initialized: boolean = false;\n\n constructor(host: LanguagesControllerHost) {\n this.host = host;\n host.addController(this);\n }\n\n initialize(): void {\n this.#initialized = true;\n\n if (this.host._languages === undefined) {\n this.#loadLanguages();\n }\n }\n\n hostUpdate(): void {\n // Only react to updates after initialization\n if (!this.#initialized) {\n return;\n }\n\n // When region changes, reload languages if they were auto-loaded\n if (\n (this.#previousRegion !== this.host.region &&\n this.#autoLoadedLanguages) ||\n this.host._languages === undefined\n ) {\n this.#loadLanguages();\n }\n\n this.#previousRegion = this.host.region;\n }\n\n async #loadLanguages(): Promise<void> {\n if (this.#loadingLanguages) {\n return;\n }\n\n this.#loadingLanguages = true;\n\n try {\n const { languages, defaultLanguage } = getLanguagesByRegion(\n this.host.region,\n );\n\n this.#autoLoadedLanguages = true;\n this.host._languages = languages;\n\n const previousLanguage = this.host.dictationConfig?.primaryLanguage;\n const selectedLanguage =\n previousLanguage && languages.includes(previousLanguage)\n ? previousLanguage\n : defaultLanguage;\n\n this.host.requestUpdate();\n this.host.dispatchEvent(\n languagesChangedEvent(languages, selectedLanguage),\n );\n } catch (error) {\n this.host.dispatchEvent(errorEvent(error));\n } finally {\n this.#loadingLanguages = false;\n }\n }\n\n /**\n * Clear the auto-loaded flag (when languages are set externally)\n */\n clearAutoLoadedFlag(): void {\n this.#autoLoadedLanguages = false;\n }\n}\n"]}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { type CortiAuth, CortiClient } from "@corti/sdk";
|
|
2
|
+
import type { ReactiveController, ReactiveControllerHost } from "lit";
|
|
3
|
+
import type { ProxyOptions } from "../types.js";
|
|
4
|
+
export interface SocketControllerHost extends ReactiveControllerHost {
|
|
5
|
+
dispatchEvent: (event: Event) => void;
|
|
6
|
+
_accessToken?: string;
|
|
7
|
+
_authConfig?: CortiAuth.AuthTokenDerivable;
|
|
8
|
+
_region?: string;
|
|
9
|
+
_tenantName?: string;
|
|
10
|
+
_socketUrl?: string;
|
|
11
|
+
_socketProxy?: ProxyOptions;
|
|
12
|
+
}
|
|
13
|
+
export type SocketControllerWebSocket = {
|
|
14
|
+
readyState: number;
|
|
15
|
+
close(): void;
|
|
16
|
+
on(event: "message", handler: (message: {
|
|
17
|
+
type: string;
|
|
18
|
+
}) => void): void;
|
|
19
|
+
on(event: "error", handler: (error: Error) => void): void;
|
|
20
|
+
on(event: "close", handler: (event: unknown) => void): void;
|
|
21
|
+
send(data: Blob | ArrayBufferLike | string): void;
|
|
22
|
+
sendEnd(message: {
|
|
23
|
+
type: "end";
|
|
24
|
+
}): void;
|
|
25
|
+
};
|
|
26
|
+
export type SocketControllerCallbacks<TMessage = unknown> = {
|
|
27
|
+
onMessage?: (message: TMessage) => void;
|
|
28
|
+
onError?: (error: Error) => void;
|
|
29
|
+
onClose?: (event: unknown) => void;
|
|
30
|
+
onNetworkActivity?: (direction: "sent" | "received", data: unknown) => void;
|
|
31
|
+
};
|
|
32
|
+
export type SocketControllerOutboundItem = Blob | {
|
|
33
|
+
type: string;
|
|
34
|
+
};
|
|
35
|
+
export declare abstract class SocketController<TOutbound extends SocketControllerOutboundItem, TMessage = unknown, TConfig = unknown, TSocket extends SocketControllerWebSocket = SocketControllerWebSocket> implements ReactiveController {
|
|
36
|
+
#private;
|
|
37
|
+
readonly host: SocketControllerHost;
|
|
38
|
+
protected abstract _connectThroughProxy(config: TConfig, proxy: ProxyOptions): Promise<TSocket>;
|
|
39
|
+
protected abstract _connectThroughAuth(client: CortiClient, config: TConfig): Promise<TSocket>;
|
|
40
|
+
constructor(host: SocketControllerHost);
|
|
41
|
+
connect(config: TConfig, callbacks: SocketControllerCallbacks<TMessage>): Promise<boolean | "superseded">;
|
|
42
|
+
hostDisconnected(): void;
|
|
43
|
+
isConnectionOpen(): boolean;
|
|
44
|
+
isConnecting(): boolean;
|
|
45
|
+
waitForConnection(): Promise<void>;
|
|
46
|
+
mediaRecorderHandler: (data: Blob) => void;
|
|
47
|
+
pause(): Promise<void>;
|
|
48
|
+
stopRecording(): Promise<void>;
|
|
49
|
+
closeConnection(onClose?: (event: unknown) => void): Promise<void>;
|
|
50
|
+
cleanup(): void;
|
|
51
|
+
}
|