@corti/dictation-web 0.5.0-rc.5 → 0.5.0
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/README.md +2 -2
- package/dist/bundle.js +106 -28
- package/dist/components/recording-button.js +19 -5
- package/dist/components/recording-button.js.map +1 -1
- package/dist/controllers/dictation-controller.js +81 -5
- package/dist/controllers/dictation-controller.js.map +1 -1
- package/dist/controllers/media-controller.d.ts +2 -3
- package/dist/controllers/media-controller.js +4 -17
- package/dist/controllers/media-controller.js.map +1 -1
- package/dist/icons/icons.d.ts +1 -1
- package/dist/icons/icons.js +7 -7
- package/dist/icons/icons.js.map +1 -1
- package/dist/styles/audio-visualiser.js.map +1 -1
- package/dist/styles/callout.js +1 -1
- package/dist/styles/callout.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/languages.js +1 -1
- package/dist/utils/languages.js.map +1 -1
- package/dist/utils/token.js +3 -3
- package/dist/utils/token.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -163,7 +163,7 @@ For more control, use individual components to build a custom UI:
|
|
|
163
163
|
|
|
164
164
|
The component supports both push-to-talk and toggle-to-talk keybindings simultaneously. You can configure separate keybindings for each behavior:
|
|
165
165
|
|
|
166
|
-
**Toggle-to-Talk Keybinding (default:
|
|
166
|
+
**Toggle-to-Talk Keybinding (default: `Enter`):**
|
|
167
167
|
- Pressing the key toggles recording on/off
|
|
168
168
|
- Works like clicking the button
|
|
169
169
|
|
|
@@ -175,7 +175,7 @@ The component supports both push-to-talk and toggle-to-talk keybindings simultan
|
|
|
175
175
|
You can use either key names (from `event.key`) or key codes (from `event.code`):
|
|
176
176
|
|
|
177
177
|
```html
|
|
178
|
-
<!-- Configure toggle-to-talk keybinding (default:
|
|
178
|
+
<!-- Configure toggle-to-talk keybinding (default: Enter) -->
|
|
179
179
|
<corti-dictation toggleToTalkKeybinding="`"></corti-dictation>
|
|
180
180
|
|
|
181
181
|
<!-- Configure push-to-talk keybinding (default: Space) -->
|
package/dist/bundle.js
CHANGED
|
@@ -1211,7 +1211,7 @@ function getLanguageName(languageCode) {
|
|
|
1211
1211
|
}
|
|
1212
1212
|
}
|
|
1213
1213
|
function getLanguagesByRegion(region) {
|
|
1214
|
-
const languages = DEFAULT_LANGUAGES_BY_REGION[region || "default"] || DEFAULT_LANGUAGES_BY_REGION
|
|
1214
|
+
const languages = DEFAULT_LANGUAGES_BY_REGION[region || "default"] || DEFAULT_LANGUAGES_BY_REGION.default;
|
|
1215
1215
|
const defaultLanguage = languages?.[0];
|
|
1216
1216
|
return { defaultLanguage, languages };
|
|
1217
1217
|
}
|
|
@@ -1347,14 +1347,14 @@ function decodeToken(token) {
|
|
|
1347
1347
|
const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
|
|
1348
1348
|
let jsonPayload;
|
|
1349
1349
|
try {
|
|
1350
|
-
jsonPayload = decodeURIComponent(atob(base64).split("").map((c6) =>
|
|
1351
|
-
} catch (
|
|
1350
|
+
jsonPayload = decodeURIComponent(atob(base64).split("").map((c6) => `%${`00${c6.charCodeAt(0).toString(16)}`.slice(-2)}`).join(""));
|
|
1351
|
+
} catch (_error) {
|
|
1352
1352
|
throw new Error("Failed to decode token payload");
|
|
1353
1353
|
}
|
|
1354
1354
|
let tokenDetails;
|
|
1355
1355
|
try {
|
|
1356
1356
|
tokenDetails = JSON.parse(jsonPayload);
|
|
1357
|
-
} catch (
|
|
1357
|
+
} catch (_error) {
|
|
1358
1358
|
throw new Error("Invalid JSON payload in token");
|
|
1359
1359
|
}
|
|
1360
1360
|
const issuerUrl = tokenDetails.iss;
|
|
@@ -11282,7 +11282,11 @@ var _DictationController_callbacks;
|
|
|
11282
11282
|
var _DictationController_lastDictationConfig;
|
|
11283
11283
|
var _DictationController_lastSocketUrl;
|
|
11284
11284
|
var _DictationController_lastSocketProxy;
|
|
11285
|
+
var _DictationController_messageBuffer;
|
|
11286
|
+
var _DictationController_connectionPromise;
|
|
11285
11287
|
var _DictationController_configHasChanged;
|
|
11288
|
+
var _DictationController_establishConnection;
|
|
11289
|
+
var _DictationController_flushMessageBuffer;
|
|
11286
11290
|
var _DictationController_connectProxy;
|
|
11287
11291
|
var _DictationController_connectAuth;
|
|
11288
11292
|
var _DictationController_setupWebSocketHandlers;
|
|
@@ -11296,7 +11300,18 @@ var DictationController = class {
|
|
|
11296
11300
|
_DictationController_lastDictationConfig.set(this, null);
|
|
11297
11301
|
_DictationController_lastSocketUrl.set(this, void 0);
|
|
11298
11302
|
_DictationController_lastSocketProxy.set(this, void 0);
|
|
11303
|
+
_DictationController_messageBuffer.set(this, []);
|
|
11304
|
+
_DictationController_connectionPromise.set(this, null);
|
|
11299
11305
|
this.mediaRecorderHandler = (data) => {
|
|
11306
|
+
if (__classPrivateFieldGet4(this, _DictationController_connectionPromise, "f")) {
|
|
11307
|
+
console.log("[DictationController] Buffering audio chunk (connection pending):", data.size);
|
|
11308
|
+
__classPrivateFieldGet4(this, _DictationController_messageBuffer, "f").push({ data, type: "audio" });
|
|
11309
|
+
return;
|
|
11310
|
+
}
|
|
11311
|
+
console.log("[DictationController] Sending audio chunk directly:", {
|
|
11312
|
+
size: data.size,
|
|
11313
|
+
socketState: __classPrivateFieldGet4(this, _DictationController_webSocket, "f")?.readyState
|
|
11314
|
+
});
|
|
11300
11315
|
__classPrivateFieldGet4(this, _DictationController_webSocket, "f")?.sendAudio(data);
|
|
11301
11316
|
__classPrivateFieldGet4(this, _DictationController_callbacks, "f")?.onNetworkActivity?.("sent", {
|
|
11302
11317
|
size: data.size,
|
|
@@ -11316,7 +11331,8 @@ var DictationController = class {
|
|
|
11316
11331
|
if (__classPrivateFieldGet4(this, _DictationController_webSocket, "f")?.readyState === WebSocket.OPEN) {
|
|
11317
11332
|
throw new Error("Already connected. Disconnect before reconnecting.");
|
|
11318
11333
|
}
|
|
11319
|
-
__classPrivateFieldSet3(this,
|
|
11334
|
+
__classPrivateFieldSet3(this, _DictationController_connectionPromise, __classPrivateFieldGet4(this, _DictationController_instances, "m", _DictationController_establishConnection).call(this, dictationConfig), "f");
|
|
11335
|
+
await __classPrivateFieldGet4(this, _DictationController_connectionPromise, "f");
|
|
11320
11336
|
__classPrivateFieldGet4(this, _DictationController_callbacks, "f")?.onNetworkActivity?.("sent", {
|
|
11321
11337
|
configuration: dictationConfig,
|
|
11322
11338
|
type: "config"
|
|
@@ -11330,6 +11346,18 @@ var DictationController = class {
|
|
|
11330
11346
|
return newConnection;
|
|
11331
11347
|
}
|
|
11332
11348
|
async pause() {
|
|
11349
|
+
console.log("[DictationController] pause() called", {
|
|
11350
|
+
connectionPending: !!__classPrivateFieldGet4(this, _DictationController_connectionPromise, "f"),
|
|
11351
|
+
socketState: __classPrivateFieldGet4(this, _DictationController_webSocket, "f")?.readyState
|
|
11352
|
+
});
|
|
11353
|
+
if (__classPrivateFieldGet4(this, _DictationController_connectionPromise, "f")) {
|
|
11354
|
+
console.log("[DictationController] Buffering flush (connection pending)");
|
|
11355
|
+
__classPrivateFieldGet4(this, _DictationController_messageBuffer, "f").push({ data: { type: "flush" }, type: "flush" });
|
|
11356
|
+
return;
|
|
11357
|
+
}
|
|
11358
|
+
console.log("[DictationController] Sending flush", {
|
|
11359
|
+
socketState: __classPrivateFieldGet4(this, _DictationController_webSocket, "f")?.readyState
|
|
11360
|
+
});
|
|
11333
11361
|
__classPrivateFieldGet4(this, _DictationController_webSocket, "f")?.sendFlush({ type: "flush" });
|
|
11334
11362
|
__classPrivateFieldGet4(this, _DictationController_callbacks, "f")?.onNetworkActivity?.("sent", { type: "flush" });
|
|
11335
11363
|
}
|
|
@@ -11391,10 +11419,60 @@ var DictationController = class {
|
|
|
11391
11419
|
__classPrivateFieldSet3(this, _DictationController_lastDictationConfig, null, "f");
|
|
11392
11420
|
__classPrivateFieldSet3(this, _DictationController_lastSocketUrl, void 0, "f");
|
|
11393
11421
|
__classPrivateFieldSet3(this, _DictationController_lastSocketProxy, void 0, "f");
|
|
11422
|
+
__classPrivateFieldSet3(this, _DictationController_messageBuffer, [], "f");
|
|
11423
|
+
__classPrivateFieldSet3(this, _DictationController_connectionPromise, null, "f");
|
|
11394
11424
|
}
|
|
11395
11425
|
};
|
|
11396
|
-
_DictationController_cortiClient = /* @__PURE__ */ new WeakMap(), _DictationController_webSocket = /* @__PURE__ */ new WeakMap(), _DictationController_closeTimeout = /* @__PURE__ */ new WeakMap(), _DictationController_callbacks = /* @__PURE__ */ new WeakMap(), _DictationController_lastDictationConfig = /* @__PURE__ */ new WeakMap(), _DictationController_lastSocketUrl = /* @__PURE__ */ new WeakMap(), _DictationController_lastSocketProxy = /* @__PURE__ */ new WeakMap(), _DictationController_instances = /* @__PURE__ */ new WeakSet(), _DictationController_configHasChanged = function _DictationController_configHasChanged2() {
|
|
11426
|
+
_DictationController_cortiClient = /* @__PURE__ */ new WeakMap(), _DictationController_webSocket = /* @__PURE__ */ new WeakMap(), _DictationController_closeTimeout = /* @__PURE__ */ new WeakMap(), _DictationController_callbacks = /* @__PURE__ */ new WeakMap(), _DictationController_lastDictationConfig = /* @__PURE__ */ new WeakMap(), _DictationController_lastSocketUrl = /* @__PURE__ */ new WeakMap(), _DictationController_lastSocketProxy = /* @__PURE__ */ new WeakMap(), _DictationController_messageBuffer = /* @__PURE__ */ new WeakMap(), _DictationController_connectionPromise = /* @__PURE__ */ new WeakMap(), _DictationController_instances = /* @__PURE__ */ new WeakSet(), _DictationController_configHasChanged = function _DictationController_configHasChanged2() {
|
|
11397
11427
|
return JSON.stringify(this.host._dictationConfig) !== JSON.stringify(__classPrivateFieldGet4(this, _DictationController_lastDictationConfig, "f")) || this.host._socketUrl !== __classPrivateFieldGet4(this, _DictationController_lastSocketUrl, "f") || JSON.stringify(this.host._socketProxy) !== JSON.stringify(__classPrivateFieldGet4(this, _DictationController_lastSocketProxy, "f"));
|
|
11428
|
+
}, _DictationController_establishConnection = async function _DictationController_establishConnection2(dictationConfig) {
|
|
11429
|
+
try {
|
|
11430
|
+
console.log("[DictationController] Delay complete, connecting to WebSocket...");
|
|
11431
|
+
__classPrivateFieldSet3(this, _DictationController_webSocket, this.host._socketUrl || this.host._socketProxy ? await __classPrivateFieldGet4(this, _DictationController_instances, "m", _DictationController_connectProxy).call(this, dictationConfig) : await __classPrivateFieldGet4(this, _DictationController_instances, "m", _DictationController_connectAuth).call(this, dictationConfig), "f");
|
|
11432
|
+
console.log("[DictationController] Starting connection establishment (10s delay)...");
|
|
11433
|
+
await new Promise((resolve) => setTimeout(resolve, 1e4));
|
|
11434
|
+
console.log("[DictationController] WebSocket connected, flushing message buffer...", {
|
|
11435
|
+
bufferedMessages: __classPrivateFieldGet4(this, _DictationController_messageBuffer, "f").length,
|
|
11436
|
+
socketState: __classPrivateFieldGet4(this, _DictationController_webSocket, "f")?.readyState
|
|
11437
|
+
});
|
|
11438
|
+
__classPrivateFieldGet4(this, _DictationController_instances, "m", _DictationController_flushMessageBuffer).call(this);
|
|
11439
|
+
} catch (error) {
|
|
11440
|
+
console.error("[DictationController] Connection establishment failed:", error);
|
|
11441
|
+
__classPrivateFieldSet3(this, _DictationController_messageBuffer, [], "f");
|
|
11442
|
+
throw error;
|
|
11443
|
+
} finally {
|
|
11444
|
+
console.log("[DictationController] Connection promise cleared");
|
|
11445
|
+
__classPrivateFieldSet3(this, _DictationController_connectionPromise, null, "f");
|
|
11446
|
+
}
|
|
11447
|
+
}, _DictationController_flushMessageBuffer = function _DictationController_flushMessageBuffer2() {
|
|
11448
|
+
console.log("[DictationController] Flushing buffer:", {
|
|
11449
|
+
messages: __classPrivateFieldGet4(this, _DictationController_messageBuffer, "f").length,
|
|
11450
|
+
socketState: __classPrivateFieldGet4(this, _DictationController_webSocket, "f")?.readyState
|
|
11451
|
+
});
|
|
11452
|
+
for (const message of __classPrivateFieldGet4(this, _DictationController_messageBuffer, "f")) {
|
|
11453
|
+
switch (message.type) {
|
|
11454
|
+
case "audio":
|
|
11455
|
+
console.log("[DictationController] Sending buffered audio chunk:", message.data.size);
|
|
11456
|
+
__classPrivateFieldGet4(this, _DictationController_webSocket, "f")?.sendAudio(message.data);
|
|
11457
|
+
__classPrivateFieldGet4(this, _DictationController_callbacks, "f")?.onNetworkActivity?.("sent", {
|
|
11458
|
+
size: message.data.size,
|
|
11459
|
+
type: "audio"
|
|
11460
|
+
});
|
|
11461
|
+
break;
|
|
11462
|
+
case "flush":
|
|
11463
|
+
console.log("[DictationController] Sending buffered flush");
|
|
11464
|
+
__classPrivateFieldGet4(this, _DictationController_webSocket, "f")?.sendFlush(message.data);
|
|
11465
|
+
__classPrivateFieldGet4(this, _DictationController_callbacks, "f")?.onNetworkActivity?.("sent", message.data);
|
|
11466
|
+
break;
|
|
11467
|
+
case "end":
|
|
11468
|
+
console.log("[DictationController] Sending buffered end");
|
|
11469
|
+
__classPrivateFieldGet4(this, _DictationController_webSocket, "f")?.sendEnd(message.data);
|
|
11470
|
+
__classPrivateFieldGet4(this, _DictationController_callbacks, "f")?.onNetworkActivity?.("sent", message.data);
|
|
11471
|
+
break;
|
|
11472
|
+
}
|
|
11473
|
+
}
|
|
11474
|
+
console.log("[DictationController] Buffer cleared");
|
|
11475
|
+
__classPrivateFieldSet3(this, _DictationController_messageBuffer, [], "f");
|
|
11398
11476
|
}, _DictationController_connectProxy = async function _DictationController_connectProxy2(dictationConfig) {
|
|
11399
11477
|
const proxyOptions = this.host._socketProxy || {
|
|
11400
11478
|
url: this.host._socketUrl || ""
|
|
@@ -11660,7 +11738,6 @@ var _MediaController_audioLevel;
|
|
|
11660
11738
|
var _MediaController_onTrackEnded;
|
|
11661
11739
|
var _MediaController_onAudioLevelChange;
|
|
11662
11740
|
var _MediaController_dataHandler;
|
|
11663
|
-
var _MediaController_bufferedChunks;
|
|
11664
11741
|
var MediaController = class {
|
|
11665
11742
|
constructor(host) {
|
|
11666
11743
|
_MediaController_mediaStream.set(this, null);
|
|
@@ -11672,15 +11749,15 @@ var MediaController = class {
|
|
|
11672
11749
|
_MediaController_onTrackEnded.set(this, void 0);
|
|
11673
11750
|
_MediaController_onAudioLevelChange.set(this, void 0);
|
|
11674
11751
|
_MediaController_dataHandler.set(this, void 0);
|
|
11675
|
-
_MediaController_bufferedChunks.set(this, []);
|
|
11676
11752
|
this.host = host;
|
|
11677
11753
|
host.addController(this);
|
|
11678
11754
|
}
|
|
11679
11755
|
hostDisconnected() {
|
|
11680
11756
|
this.cleanup();
|
|
11681
11757
|
}
|
|
11682
|
-
async initialize(onTrackEnded) {
|
|
11758
|
+
async initialize(dataHandler, onTrackEnded) {
|
|
11683
11759
|
await this.cleanup();
|
|
11760
|
+
__classPrivateFieldSet5(this, _MediaController_dataHandler, dataHandler, "f");
|
|
11684
11761
|
__classPrivateFieldSet5(this, _MediaController_onTrackEnded, onTrackEnded, "f");
|
|
11685
11762
|
__classPrivateFieldSet5(this, _MediaController_mediaStream, await getMediaStream(this.host._selectedDevice?.deviceId, this.host._debug_displayAudio), "f");
|
|
11686
11763
|
__classPrivateFieldGet6(this, _MediaController_mediaStream, "f").getTracks().forEach((track) => {
|
|
@@ -11697,9 +11774,7 @@ var MediaController = class {
|
|
|
11697
11774
|
__classPrivateFieldGet6(this, _MediaController_mediaRecorder, "f").ondataavailable = (event) => {
|
|
11698
11775
|
if (__classPrivateFieldGet6(this, _MediaController_dataHandler, "f")) {
|
|
11699
11776
|
__classPrivateFieldGet6(this, _MediaController_dataHandler, "f").call(this, event.data);
|
|
11700
|
-
return;
|
|
11701
11777
|
}
|
|
11702
|
-
__classPrivateFieldGet6(this, _MediaController_bufferedChunks, "f").push(event.data);
|
|
11703
11778
|
};
|
|
11704
11779
|
}
|
|
11705
11780
|
getAudioLevel() {
|
|
@@ -11750,7 +11825,6 @@ var MediaController = class {
|
|
|
11750
11825
|
__classPrivateFieldSet5(this, _MediaController_onTrackEnded, void 0, "f");
|
|
11751
11826
|
__classPrivateFieldSet5(this, _MediaController_onAudioLevelChange, void 0, "f");
|
|
11752
11827
|
__classPrivateFieldSet5(this, _MediaController_dataHandler, void 0, "f");
|
|
11753
|
-
__classPrivateFieldSet5(this, _MediaController_bufferedChunks, [], "f");
|
|
11754
11828
|
}
|
|
11755
11829
|
/**
|
|
11756
11830
|
* Stops the media recorder and waits for all buffered data to be flushed.
|
|
@@ -11768,16 +11842,6 @@ var MediaController = class {
|
|
|
11768
11842
|
__classPrivateFieldGet6(this, _MediaController_mediaRecorder, "f").stop();
|
|
11769
11843
|
});
|
|
11770
11844
|
}
|
|
11771
|
-
addDataHandler(handler) {
|
|
11772
|
-
for (const chunk of __classPrivateFieldGet6(this, _MediaController_bufferedChunks, "f")) {
|
|
11773
|
-
handler(chunk);
|
|
11774
|
-
}
|
|
11775
|
-
__classPrivateFieldSet5(this, _MediaController_bufferedChunks, [], "f");
|
|
11776
|
-
__classPrivateFieldSet5(this, _MediaController_dataHandler, handler, "f");
|
|
11777
|
-
}
|
|
11778
|
-
removeDataHandler() {
|
|
11779
|
-
__classPrivateFieldSet5(this, _MediaController_dataHandler, void 0, "f");
|
|
11780
|
-
}
|
|
11781
11845
|
get mediaRecorder() {
|
|
11782
11846
|
return __classPrivateFieldGet6(this, _MediaController_mediaRecorder, "f");
|
|
11783
11847
|
}
|
|
@@ -11785,7 +11849,7 @@ var MediaController = class {
|
|
|
11785
11849
|
return __classPrivateFieldGet6(this, _MediaController_audioLevel, "f");
|
|
11786
11850
|
}
|
|
11787
11851
|
};
|
|
11788
|
-
_MediaController_mediaStream = /* @__PURE__ */ new WeakMap(), _MediaController_audioContext = /* @__PURE__ */ new WeakMap(), _MediaController_analyser = /* @__PURE__ */ new WeakMap(), _MediaController_mediaRecorder = /* @__PURE__ */ new WeakMap(), _MediaController_visualiserInterval = /* @__PURE__ */ new WeakMap(), _MediaController_audioLevel = /* @__PURE__ */ new WeakMap(), _MediaController_onTrackEnded = /* @__PURE__ */ new WeakMap(), _MediaController_onAudioLevelChange = /* @__PURE__ */ new WeakMap(), _MediaController_dataHandler = /* @__PURE__ */ new WeakMap()
|
|
11852
|
+
_MediaController_mediaStream = /* @__PURE__ */ new WeakMap(), _MediaController_audioContext = /* @__PURE__ */ new WeakMap(), _MediaController_analyser = /* @__PURE__ */ new WeakMap(), _MediaController_mediaRecorder = /* @__PURE__ */ new WeakMap(), _MediaController_visualiserInterval = /* @__PURE__ */ new WeakMap(), _MediaController_audioLevel = /* @__PURE__ */ new WeakMap(), _MediaController_onTrackEnded = /* @__PURE__ */ new WeakMap(), _MediaController_onAudioLevelChange = /* @__PURE__ */ new WeakMap(), _MediaController_dataHandler = /* @__PURE__ */ new WeakMap();
|
|
11789
11853
|
|
|
11790
11854
|
// dist/styles/buttons.js
|
|
11791
11855
|
var ButtonStyles = i`
|
|
@@ -12149,7 +12213,10 @@ var DictationRecordingButton = class DictationRecordingButton2 extends i4 {
|
|
|
12149
12213
|
_DictationRecordingButton_handleWebSocketMessage.set(this, (message) => {
|
|
12150
12214
|
switch (message.type) {
|
|
12151
12215
|
case "CONFIG_ACCEPTED":
|
|
12152
|
-
|
|
12216
|
+
console.log("[RecordingButton] CONFIG_ACCEPTED received", {
|
|
12217
|
+
recordingState: this._recordingState,
|
|
12218
|
+
willSetProcessing: this._recordingState === "initializing"
|
|
12219
|
+
});
|
|
12153
12220
|
if (this._recordingState === "initializing") {
|
|
12154
12221
|
__classPrivateFieldSet6(this, _DictationRecordingButton_processing, true, "f");
|
|
12155
12222
|
__classPrivateFieldGet7(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_dispatchRecordingStateChanged).call(this, "recording");
|
|
@@ -12185,7 +12252,7 @@ var DictationRecordingButton = class DictationRecordingButton2 extends i4 {
|
|
|
12185
12252
|
}
|
|
12186
12253
|
});
|
|
12187
12254
|
_DictationRecordingButton_handleWebSocketError.set(this, (error) => {
|
|
12188
|
-
this.dispatchEvent(errorEvent(
|
|
12255
|
+
this.dispatchEvent(errorEvent(`Socket error: ${error.message}`));
|
|
12189
12256
|
__classPrivateFieldSet6(this, _DictationRecordingButton_processing, false, "f");
|
|
12190
12257
|
__classPrivateFieldSet6(this, _DictationRecordingButton_connection, "CLOSED", "f");
|
|
12191
12258
|
__classPrivateFieldGet7(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_handleStop).call(this);
|
|
@@ -12315,14 +12382,17 @@ _DictationRecordingButton_dispatchRecordingStateChanged = function _DictationRec
|
|
|
12315
12382
|
}));
|
|
12316
12383
|
};
|
|
12317
12384
|
_DictationRecordingButton_handleStart = async function _DictationRecordingButton_handleStart2() {
|
|
12385
|
+
console.log("[RecordingButton] handleStart() called");
|
|
12318
12386
|
__classPrivateFieldGet7(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_dispatchRecordingStateChanged).call(this, "initializing");
|
|
12319
12387
|
try {
|
|
12320
|
-
|
|
12388
|
+
console.log("[RecordingButton] Initializing media controller...");
|
|
12389
|
+
await __classPrivateFieldGet7(this, _DictationRecordingButton_mediaController, "f").initialize(__classPrivateFieldGet7(this, _DictationRecordingButton_dictationController, "f").mediaRecorderHandler, () => {
|
|
12321
12390
|
if (this._recordingState === "recording") {
|
|
12322
12391
|
this.dispatchEvent(errorEvent("Recording device access was lost."));
|
|
12323
12392
|
__classPrivateFieldGet7(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_handleStop).call(this);
|
|
12324
12393
|
}
|
|
12325
12394
|
});
|
|
12395
|
+
console.log("[RecordingButton] Starting MediaRecorder...");
|
|
12326
12396
|
__classPrivateFieldGet7(this, _DictationRecordingButton_mediaController, "f").mediaRecorder?.start(AUDIO_CHUNK_INTERVAL_MS);
|
|
12327
12397
|
__classPrivateFieldGet7(this, _DictationRecordingButton_mediaController, "f").startAudioLevelMonitoring((level) => {
|
|
12328
12398
|
this.dispatchEvent(audioLevelChangedEvent(level));
|
|
@@ -12331,6 +12401,7 @@ _DictationRecordingButton_handleStart = async function _DictationRecordingButton
|
|
|
12331
12401
|
__classPrivateFieldSet6(this, _DictationRecordingButton_connection, "CONNECTING", "f");
|
|
12332
12402
|
}
|
|
12333
12403
|
__classPrivateFieldGet7(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_dispatchRecordingStateChanged).call(this, "recording");
|
|
12404
|
+
console.log("[RecordingButton] Connecting to WebSocket...");
|
|
12334
12405
|
const isNewConnection = await __classPrivateFieldGet7(this, _DictationRecordingButton_dictationController, "f").connect(this._dictationConfig, {
|
|
12335
12406
|
onClose: __classPrivateFieldGet7(this, _DictationRecordingButton_handleWebSocketClose, "f"),
|
|
12336
12407
|
onError: __classPrivateFieldGet7(this, _DictationRecordingButton_handleWebSocketError, "f"),
|
|
@@ -12339,27 +12410,34 @@ _DictationRecordingButton_handleStart = async function _DictationRecordingButton
|
|
|
12339
12410
|
this.dispatchEvent(networkActivityEvent(direction, data));
|
|
12340
12411
|
}
|
|
12341
12412
|
});
|
|
12413
|
+
console.log("[RecordingButton] Connection established", { isNewConnection });
|
|
12342
12414
|
if (!isNewConnection) {
|
|
12343
|
-
__classPrivateFieldGet7(this, _DictationRecordingButton_mediaController, "f").addDataHandler(__classPrivateFieldGet7(this, _DictationRecordingButton_dictationController, "f").mediaRecorderHandler);
|
|
12344
12415
|
__classPrivateFieldSet6(this, _DictationRecordingButton_processing, true, "f");
|
|
12345
12416
|
}
|
|
12346
12417
|
__classPrivateFieldSet6(this, _DictationRecordingButton_connection, "OPEN", "f");
|
|
12347
12418
|
__classPrivateFieldGet7(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_dispatchRecordingStateChanged).call(this, "recording");
|
|
12348
12419
|
} catch (error) {
|
|
12420
|
+
console.error("[RecordingButton] Error in handleStart:", error);
|
|
12349
12421
|
this.dispatchEvent(errorEvent(error));
|
|
12350
12422
|
await __classPrivateFieldGet7(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_handleStop).call(this);
|
|
12351
12423
|
}
|
|
12352
12424
|
};
|
|
12353
12425
|
_DictationRecordingButton_handleStop = async function _DictationRecordingButton_handleStop2() {
|
|
12426
|
+
console.log("[RecordingButton] handleStop() called");
|
|
12354
12427
|
__classPrivateFieldGet7(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_dispatchRecordingStateChanged).call(this, "stopping");
|
|
12355
12428
|
try {
|
|
12429
|
+
console.log("[RecordingButton] Stopping audio level monitoring...");
|
|
12356
12430
|
__classPrivateFieldGet7(this, _DictationRecordingButton_mediaController, "f").stopAudioLevelMonitoring();
|
|
12431
|
+
console.log("[RecordingButton] Stopping media recorder...");
|
|
12357
12432
|
await __classPrivateFieldGet7(this, _DictationRecordingButton_mediaController, "f").stopRecording();
|
|
12358
|
-
__classPrivateFieldGet7(this, _DictationRecordingButton_mediaController, "f").removeDataHandler();
|
|
12359
12433
|
__classPrivateFieldGet7(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_dispatchRecordingStateChanged).call(this, "stopped");
|
|
12434
|
+
console.log("[RecordingButton] Calling dictationController.pause()...");
|
|
12360
12435
|
await __classPrivateFieldGet7(this, _DictationRecordingButton_dictationController, "f").pause();
|
|
12436
|
+
console.log("[RecordingButton] Cleaning up media controller...");
|
|
12361
12437
|
await __classPrivateFieldGet7(this, _DictationRecordingButton_mediaController, "f").cleanup();
|
|
12438
|
+
console.log("[RecordingButton] Stop complete");
|
|
12362
12439
|
} catch (error) {
|
|
12440
|
+
console.error("[RecordingButton] Error in handleStop:", error);
|
|
12363
12441
|
this.dispatchEvent(errorEvent(error));
|
|
12364
12442
|
}
|
|
12365
12443
|
};
|
|
@@ -44,7 +44,10 @@ let DictationRecordingButton = class DictationRecordingButton extends LitElement
|
|
|
44
44
|
_DictationRecordingButton_handleWebSocketMessage.set(this, (message) => {
|
|
45
45
|
switch (message.type) {
|
|
46
46
|
case "CONFIG_ACCEPTED":
|
|
47
|
-
|
|
47
|
+
console.log("[RecordingButton] CONFIG_ACCEPTED received", {
|
|
48
|
+
recordingState: this._recordingState,
|
|
49
|
+
willSetProcessing: this._recordingState === "initializing",
|
|
50
|
+
});
|
|
48
51
|
if (this._recordingState === "initializing") {
|
|
49
52
|
__classPrivateFieldSet(this, _DictationRecordingButton_processing, true, "f");
|
|
50
53
|
__classPrivateFieldGet(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_dispatchRecordingStateChanged).call(this, "recording");
|
|
@@ -81,7 +84,7 @@ let DictationRecordingButton = class DictationRecordingButton extends LitElement
|
|
|
81
84
|
}
|
|
82
85
|
});
|
|
83
86
|
_DictationRecordingButton_handleWebSocketError.set(this, (error) => {
|
|
84
|
-
this.dispatchEvent(errorEvent(
|
|
87
|
+
this.dispatchEvent(errorEvent(`Socket error: ${error.message}`));
|
|
85
88
|
__classPrivateFieldSet(this, _DictationRecordingButton_processing, false, "f");
|
|
86
89
|
__classPrivateFieldSet(this, _DictationRecordingButton_connection, "CLOSED", "f");
|
|
87
90
|
__classPrivateFieldGet(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_handleStop).call(this);
|
|
@@ -223,14 +226,17 @@ _DictationRecordingButton_dispatchRecordingStateChanged = function _DictationRec
|
|
|
223
226
|
}));
|
|
224
227
|
};
|
|
225
228
|
_DictationRecordingButton_handleStart = async function _DictationRecordingButton_handleStart() {
|
|
229
|
+
console.log("[RecordingButton] handleStart() called");
|
|
226
230
|
__classPrivateFieldGet(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_dispatchRecordingStateChanged).call(this, "initializing");
|
|
227
231
|
try {
|
|
228
|
-
|
|
232
|
+
console.log("[RecordingButton] Initializing media controller...");
|
|
233
|
+
await __classPrivateFieldGet(this, _DictationRecordingButton_mediaController, "f").initialize(__classPrivateFieldGet(this, _DictationRecordingButton_dictationController, "f").mediaRecorderHandler, () => {
|
|
229
234
|
if (this._recordingState === "recording") {
|
|
230
235
|
this.dispatchEvent(errorEvent("Recording device access was lost."));
|
|
231
236
|
__classPrivateFieldGet(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_handleStop).call(this);
|
|
232
237
|
}
|
|
233
238
|
});
|
|
239
|
+
console.log("[RecordingButton] Starting MediaRecorder...");
|
|
234
240
|
__classPrivateFieldGet(this, _DictationRecordingButton_mediaController, "f").mediaRecorder?.start(AUDIO_CHUNK_INTERVAL_MS);
|
|
235
241
|
__classPrivateFieldGet(this, _DictationRecordingButton_mediaController, "f").startAudioLevelMonitoring((level) => {
|
|
236
242
|
this.dispatchEvent(audioLevelChangedEvent(level));
|
|
@@ -239,6 +245,7 @@ _DictationRecordingButton_handleStart = async function _DictationRecordingButton
|
|
|
239
245
|
__classPrivateFieldSet(this, _DictationRecordingButton_connection, "CONNECTING", "f");
|
|
240
246
|
}
|
|
241
247
|
__classPrivateFieldGet(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_dispatchRecordingStateChanged).call(this, "recording");
|
|
248
|
+
console.log("[RecordingButton] Connecting to WebSocket...");
|
|
242
249
|
const isNewConnection = await __classPrivateFieldGet(this, _DictationRecordingButton_dictationController, "f").connect(this._dictationConfig, {
|
|
243
250
|
onClose: __classPrivateFieldGet(this, _DictationRecordingButton_handleWebSocketClose, "f"),
|
|
244
251
|
onError: __classPrivateFieldGet(this, _DictationRecordingButton_handleWebSocketError, "f"),
|
|
@@ -247,29 +254,36 @@ _DictationRecordingButton_handleStart = async function _DictationRecordingButton
|
|
|
247
254
|
this.dispatchEvent(networkActivityEvent(direction, data));
|
|
248
255
|
},
|
|
249
256
|
});
|
|
257
|
+
console.log("[RecordingButton] Connection established", { isNewConnection });
|
|
250
258
|
if (!isNewConnection) {
|
|
251
|
-
__classPrivateFieldGet(this, _DictationRecordingButton_mediaController, "f").addDataHandler(__classPrivateFieldGet(this, _DictationRecordingButton_dictationController, "f").mediaRecorderHandler);
|
|
252
259
|
__classPrivateFieldSet(this, _DictationRecordingButton_processing, true, "f");
|
|
253
260
|
}
|
|
254
261
|
__classPrivateFieldSet(this, _DictationRecordingButton_connection, "OPEN", "f");
|
|
255
262
|
__classPrivateFieldGet(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_dispatchRecordingStateChanged).call(this, "recording");
|
|
256
263
|
}
|
|
257
264
|
catch (error) {
|
|
265
|
+
console.error("[RecordingButton] Error in handleStart:", error);
|
|
258
266
|
this.dispatchEvent(errorEvent(error));
|
|
259
267
|
await __classPrivateFieldGet(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_handleStop).call(this);
|
|
260
268
|
}
|
|
261
269
|
};
|
|
262
270
|
_DictationRecordingButton_handleStop = async function _DictationRecordingButton_handleStop() {
|
|
271
|
+
console.log("[RecordingButton] handleStop() called");
|
|
263
272
|
__classPrivateFieldGet(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_dispatchRecordingStateChanged).call(this, "stopping");
|
|
264
273
|
try {
|
|
274
|
+
console.log("[RecordingButton] Stopping audio level monitoring...");
|
|
265
275
|
__classPrivateFieldGet(this, _DictationRecordingButton_mediaController, "f").stopAudioLevelMonitoring();
|
|
276
|
+
console.log("[RecordingButton] Stopping media recorder...");
|
|
266
277
|
await __classPrivateFieldGet(this, _DictationRecordingButton_mediaController, "f").stopRecording();
|
|
267
|
-
__classPrivateFieldGet(this, _DictationRecordingButton_mediaController, "f").removeDataHandler();
|
|
268
278
|
__classPrivateFieldGet(this, _DictationRecordingButton_instances, "m", _DictationRecordingButton_dispatchRecordingStateChanged).call(this, "stopped");
|
|
279
|
+
console.log("[RecordingButton] Calling dictationController.pause()...");
|
|
269
280
|
await __classPrivateFieldGet(this, _DictationRecordingButton_dictationController, "f").pause();
|
|
281
|
+
console.log("[RecordingButton] Cleaning up media controller...");
|
|
270
282
|
await __classPrivateFieldGet(this, _DictationRecordingButton_mediaController, "f").cleanup();
|
|
283
|
+
console.log("[RecordingButton] Stop complete");
|
|
271
284
|
}
|
|
272
285
|
catch (error) {
|
|
286
|
+
console.error("[RecordingButton] Error in handleStop:", error);
|
|
273
287
|
this.dispatchEvent(errorEvent(error));
|
|
274
288
|
}
|
|
275
289
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recording-button.js","sourceRoot":"","sources":["../../src/components/recording-button.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Corti } from \"@corti/sdk\";\nimport { consume } from \"@lit/context\";\nimport {\n type CSSResultGroup,\n html,\n LitElement,\n type PropertyValues,\n} from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { AUDIO_CHUNK_INTERVAL_MS } from \"../constants.js\";\nimport {\n accessTokenContext,\n authConfigContext,\n debugDisplayAudioContext,\n dictationConfigContext,\n pushToTalkKeybindingContext,\n recordingStateContext,\n regionContext,\n selectedDeviceContext,\n socketProxyContext,\n socketUrlContext,\n tenantNameContext,\n toggleToTalkKeybindingContext,\n} from \"../contexts/dictation-context.js\";\nimport {\n DictationController,\n type TranscribeMessage,\n} from \"../controllers/dictation-controller.js\";\nimport { KeybindingController } from \"../controllers/keybinding-controller.js\";\nimport { MediaController } from \"../controllers/media-controller.js\";\nimport ButtonStyles from \"../styles/buttons.js\";\nimport RecordingButtonStyles from \"../styles/recording-button.js\";\nimport type { ProxyOptions, RecordingState } from \"../types.js\";\nimport {\n audioLevelChangedEvent,\n commandEvent,\n errorEvent,\n networkActivityEvent,\n type RecordingStateChangedEventDetail,\n recordingStateChangedEvent,\n streamClosedEvent,\n transcriptEvent,\n usageEvent,\n} from \"../utils/events.js\";\n\nimport \"./audio-visualiser.js\";\nimport \"../icons/icons.js\";\n\n@customElement(\"dictation-recording-button\")\nexport class DictationRecordingButton extends LitElement {\n @consume({ context: recordingStateContext, subscribe: true })\n @state()\n _recordingState: RecordingState = \"stopped\";\n\n @consume({ context: selectedDeviceContext, subscribe: true })\n @state()\n _selectedDevice?: MediaDeviceInfo;\n\n @consume({ context: accessTokenContext, subscribe: true })\n @state()\n _accessToken?: string;\n\n @consume({ context: authConfigContext, subscribe: true })\n @state()\n _authConfig?: Corti.BearerOptions;\n\n @consume({ context: regionContext, subscribe: true })\n @state()\n _region?: string;\n\n @consume({ context: tenantNameContext, subscribe: true })\n @state()\n _tenantName?: string;\n\n @consume({ context: dictationConfigContext, subscribe: true })\n @state()\n _dictationConfig?: Corti.TranscribeConfig;\n\n @consume({ context: socketUrlContext, subscribe: true })\n @state()\n _socketUrl?: string;\n\n @consume({ context: socketProxyContext, subscribe: true })\n @state()\n _socketProxy?: ProxyOptions;\n\n @consume({ context: debugDisplayAudioContext, subscribe: true })\n @state()\n _debug_displayAudio?: boolean;\n\n @consume({ context: pushToTalkKeybindingContext, subscribe: true })\n @state()\n _pushToTalkKeybinding?: string | null;\n\n @consume({ context: toggleToTalkKeybindingContext, subscribe: true })\n @state()\n _toggleToTalkKeybinding?: string | null;\n\n @property({ type: Boolean })\n allowButtonFocus: boolean = false;\n\n #mediaController = new MediaController(this);\n #dictationController = new DictationController(this);\n #keybindingController = new KeybindingController(this);\n #closeConnectionOnInit = false;\n #processing = false;\n #connection: RecordingStateChangedEventDetail[\"connection\"] = \"CLOSED\";\n\n static styles: CSSResultGroup = [RecordingButtonStyles, ButtonStyles];\n\n protected update(changedProperties: PropertyValues) {\n if (\n changedProperties.has(\"_recordingState\") &&\n this._recordingState === \"recording\" &&\n this.#closeConnectionOnInit\n ) {\n this.#closeConnectionOnInit = false;\n this.#handleStop();\n }\n\n super.update(changedProperties);\n }\n\n #handleClick(event: MouseEvent): void {\n if (!this.allowButtonFocus) {\n event.preventDefault();\n }\n\n this.toggleRecording();\n }\n\n #handleWebSocketMessage = (message: TranscribeMessage): void => {\n switch (message.type) {\n case \"CONFIG_ACCEPTED\":\n this.#mediaController.addDataHandler(\n this.#dictationController.mediaRecorderHandler,\n );\n\n if (this._recordingState === \"initializing\") {\n this.#processing = true;\n this.#dispatchRecordingStateChanged(\"recording\");\n }\n break;\n case \"CONFIG_DENIED\":\n this.dispatchEvent(\n errorEvent(`Config denied: ${message.reason ?? \"Unknown reason\"}`),\n );\n this.#handleStop();\n break;\n case \"CONFIG_TIMEOUT\":\n this.dispatchEvent(errorEvent(\"Config timeout\"));\n this.#handleStop();\n break;\n case \"transcript\":\n this.dispatchEvent(transcriptEvent(message));\n break;\n case \"command\":\n this.dispatchEvent(commandEvent(message));\n break;\n case \"usage\":\n this.dispatchEvent(usageEvent(message));\n break;\n case \"error\":\n this.dispatchEvent(errorEvent(message.error));\n this.#handleStop();\n break;\n case \"flushed\":\n if (\n this._recordingState === \"stopped\" ||\n this._recordingState === \"stopping\"\n ) {\n this.#processing = false;\n this.#dispatchRecordingStateChanged(this._recordingState);\n }\n break;\n }\n };\n\n #handleWebSocketError = (error: Error): void => {\n this.dispatchEvent(errorEvent(\"Socket error: \" + error.message));\n this.#processing = false;\n this.#connection = \"CLOSED\";\n this.#handleStop();\n };\n\n #handleWebSocketClose = (event: unknown): void => {\n // When we already have new socket opened\n if (this.#dictationController.isConnectionOpen()) {\n return;\n }\n\n this.#processing = false;\n this.#connection = \"CLOSED\";\n this.dispatchEvent(streamClosedEvent(event));\n this.#dispatchRecordingStateChanged(this._recordingState);\n };\n\n #dispatchRecordingStateChanged(state: RecordingState): void {\n this.dispatchEvent(\n recordingStateChangedEvent(state, {\n connection: this.#connection,\n processing: this.#processing,\n }),\n );\n }\n\n async #handleStart(): Promise<void> {\n this.#dispatchRecordingStateChanged(\"initializing\");\n\n try {\n await this.#mediaController.initialize(() => {\n if (this._recordingState === \"recording\") {\n this.dispatchEvent(errorEvent(\"Recording device access was lost.\"));\n this.#handleStop();\n }\n });\n this.#mediaController.mediaRecorder?.start(AUDIO_CHUNK_INTERVAL_MS);\n this.#mediaController.startAudioLevelMonitoring((level) => {\n this.dispatchEvent(audioLevelChangedEvent(level));\n });\n\n if (this.#connection !== \"OPEN\") {\n this.#connection = \"CONNECTING\";\n }\n\n this.#dispatchRecordingStateChanged(\"recording\");\n\n const isNewConnection = await this.#dictationController.connect(\n this._dictationConfig,\n {\n onClose: this.#handleWebSocketClose,\n onError: this.#handleWebSocketError,\n onMessage: this.#handleWebSocketMessage,\n onNetworkActivity: (direction, data) => {\n this.dispatchEvent(networkActivityEvent(direction, data));\n },\n },\n );\n\n if (!isNewConnection) {\n this.#mediaController.addDataHandler(\n this.#dictationController.mediaRecorderHandler,\n );\n this.#processing = true;\n }\n\n this.#connection = \"OPEN\";\n\n this.#dispatchRecordingStateChanged(\"recording\");\n } catch (error) {\n this.dispatchEvent(errorEvent(error));\n await this.#handleStop();\n }\n }\n\n async #handleStop(): Promise<void> {\n this.#dispatchRecordingStateChanged(\"stopping\");\n\n try {\n this.#mediaController.stopAudioLevelMonitoring();\n await this.#mediaController.stopRecording();\n this.#mediaController.removeDataHandler();\n\n this.#dispatchRecordingStateChanged(\"stopped\");\n\n await this.#dictationController.pause();\n await this.#mediaController.cleanup();\n } catch (error) {\n this.dispatchEvent(errorEvent(error));\n }\n }\n\n public startRecording(): void {\n if (this._recordingState !== \"stopped\") {\n return;\n }\n\n this.#handleStart();\n }\n\n public stopRecording(): void {\n if (\n this._recordingState === \"stopped\" ||\n this._recordingState === \"stopping\"\n ) {\n return;\n }\n\n if (this._recordingState === \"initializing\") {\n this.#closeConnectionOnInit = true;\n return;\n }\n\n this.#handleStop();\n }\n\n public toggleRecording(): void {\n if (this._recordingState === \"stopped\") {\n this.startRecording();\n } else if (this._recordingState === \"recording\") {\n this.stopRecording();\n }\n }\n\n public async openConnection(): Promise<void> {\n if (this._recordingState !== \"stopped\" || this.#processing) {\n return;\n }\n\n if (this.#dictationController.isConnectionOpen()) {\n return;\n }\n\n try {\n this.#connection = \"CONNECTING\";\n this.#dispatchRecordingStateChanged(\"stopped\");\n\n await this.#dictationController.connect(this._dictationConfig, {\n onClose: this.#handleWebSocketClose,\n onError: this.#handleWebSocketError,\n onMessage: this.#handleWebSocketMessage,\n onNetworkActivity: (direction, data) => {\n this.dispatchEvent(networkActivityEvent(direction, data));\n },\n });\n\n this.#connection = \"OPEN\";\n this.#dispatchRecordingStateChanged(\"stopped\");\n } catch (error) {\n this.#connection = \"CLOSED\";\n this.dispatchEvent(errorEvent(error));\n }\n }\n\n public async closeConnection(): Promise<void> {\n if (this._recordingState !== \"stopped\" || this.#processing) {\n return;\n }\n\n if (!this.#dictationController.isConnectionOpen()) {\n this.#connection = \"CLOSED\";\n this.#dispatchRecordingStateChanged(\"stopped\");\n return;\n }\n\n try {\n this.#connection = \"CLOSING\";\n this.#dispatchRecordingStateChanged(\"stopped\");\n await this.#dictationController.closeConnection(\n this.#handleWebSocketClose,\n );\n } catch (error) {\n this.dispatchEvent(errorEvent(error));\n }\n }\n\n render() {\n const isLoading =\n this._recordingState === \"initializing\" ||\n this._recordingState === \"stopping\";\n const isRecording = this._recordingState === \"recording\";\n\n return html`\n <button\n @click=${this.#handleClick}\n ?disabled=${isLoading}\n class=${isRecording ? \"red\" : \"accent\"}\n aria-label=${isRecording ? \"Stop recording\" : \"Start recording\"}\n aria-pressed=${isRecording}\n >\n ${\n isLoading\n ? html`<icon-loading-spinner />`\n : isRecording\n ? html`<icon-recording />`\n : html`<icon-mic-on />`\n }\n <dictation-audio-visualiser\n .level=${this.#mediaController.audioLevel}\n ?active=${isRecording}\n />\n </button>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"dictation-recording-button\": DictationRecordingButton;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"recording-button.js","sourceRoot":"","sources":["../../src/components/recording-button.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Corti } from \"@corti/sdk\";\nimport { consume } from \"@lit/context\";\nimport {\n type CSSResultGroup,\n html,\n LitElement,\n type PropertyValues,\n} from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { AUDIO_CHUNK_INTERVAL_MS } from \"../constants.js\";\nimport {\n accessTokenContext,\n authConfigContext,\n debugDisplayAudioContext,\n dictationConfigContext,\n pushToTalkKeybindingContext,\n recordingStateContext,\n regionContext,\n selectedDeviceContext,\n socketProxyContext,\n socketUrlContext,\n tenantNameContext,\n toggleToTalkKeybindingContext,\n} from \"../contexts/dictation-context.js\";\nimport {\n DictationController,\n type TranscribeMessage,\n} from \"../controllers/dictation-controller.js\";\nimport { KeybindingController } from \"../controllers/keybinding-controller.js\";\nimport { MediaController } from \"../controllers/media-controller.js\";\nimport ButtonStyles from \"../styles/buttons.js\";\nimport RecordingButtonStyles from \"../styles/recording-button.js\";\nimport type { ProxyOptions, RecordingState } from \"../types.js\";\nimport {\n audioLevelChangedEvent,\n commandEvent,\n errorEvent,\n networkActivityEvent,\n type RecordingStateChangedEventDetail,\n recordingStateChangedEvent,\n streamClosedEvent,\n transcriptEvent,\n usageEvent,\n} from \"../utils/events.js\";\n\nimport \"./audio-visualiser.js\";\nimport \"../icons/icons.js\";\n\n@customElement(\"dictation-recording-button\")\nexport class DictationRecordingButton extends LitElement {\n @consume({ context: recordingStateContext, subscribe: true })\n @state()\n _recordingState: RecordingState = \"stopped\";\n\n @consume({ context: selectedDeviceContext, subscribe: true })\n @state()\n _selectedDevice?: MediaDeviceInfo;\n\n @consume({ context: accessTokenContext, subscribe: true })\n @state()\n _accessToken?: string;\n\n @consume({ context: authConfigContext, subscribe: true })\n @state()\n _authConfig?: Corti.BearerOptions;\n\n @consume({ context: regionContext, subscribe: true })\n @state()\n _region?: string;\n\n @consume({ context: tenantNameContext, subscribe: true })\n @state()\n _tenantName?: string;\n\n @consume({ context: dictationConfigContext, subscribe: true })\n @state()\n _dictationConfig?: Corti.TranscribeConfig;\n\n @consume({ context: socketUrlContext, subscribe: true })\n @state()\n _socketUrl?: string;\n\n @consume({ context: socketProxyContext, subscribe: true })\n @state()\n _socketProxy?: ProxyOptions;\n\n @consume({ context: debugDisplayAudioContext, subscribe: true })\n @state()\n _debug_displayAudio?: boolean;\n\n @consume({ context: pushToTalkKeybindingContext, subscribe: true })\n @state()\n _pushToTalkKeybinding?: string | null;\n\n @consume({ context: toggleToTalkKeybindingContext, subscribe: true })\n @state()\n _toggleToTalkKeybinding?: string | null;\n\n @property({ type: Boolean })\n allowButtonFocus: boolean = false;\n\n #mediaController = new MediaController(this);\n #dictationController = new DictationController(this);\n #keybindingController = new KeybindingController(this);\n #closeConnectionOnInit = false;\n #processing = false;\n #connection: RecordingStateChangedEventDetail[\"connection\"] = \"CLOSED\";\n\n static styles: CSSResultGroup = [RecordingButtonStyles, ButtonStyles];\n\n protected update(changedProperties: PropertyValues) {\n if (\n changedProperties.has(\"_recordingState\") &&\n this._recordingState === \"recording\" &&\n this.#closeConnectionOnInit\n ) {\n this.#closeConnectionOnInit = false;\n this.#handleStop();\n }\n\n super.update(changedProperties);\n }\n\n #handleClick(event: MouseEvent): void {\n if (!this.allowButtonFocus) {\n event.preventDefault();\n }\n\n this.toggleRecording();\n }\n\n #handleWebSocketMessage = (message: TranscribeMessage): void => {\n switch (message.type) {\n case \"CONFIG_ACCEPTED\":\n console.log(\"[RecordingButton] CONFIG_ACCEPTED received\", {\n recordingState: this._recordingState,\n willSetProcessing: this._recordingState === \"initializing\",\n });\n if (this._recordingState === \"initializing\") {\n this.#processing = true;\n this.#dispatchRecordingStateChanged(\"recording\");\n }\n break;\n case \"CONFIG_DENIED\":\n this.dispatchEvent(\n errorEvent(`Config denied: ${message.reason ?? \"Unknown reason\"}`),\n );\n this.#handleStop();\n break;\n case \"CONFIG_TIMEOUT\":\n this.dispatchEvent(errorEvent(\"Config timeout\"));\n this.#handleStop();\n break;\n case \"transcript\":\n this.dispatchEvent(transcriptEvent(message));\n break;\n case \"command\":\n this.dispatchEvent(commandEvent(message));\n break;\n case \"usage\":\n this.dispatchEvent(usageEvent(message));\n break;\n case \"error\":\n this.dispatchEvent(errorEvent(message.error));\n this.#handleStop();\n break;\n case \"flushed\":\n if (\n this._recordingState === \"stopped\" ||\n this._recordingState === \"stopping\"\n ) {\n this.#processing = false;\n this.#dispatchRecordingStateChanged(this._recordingState);\n }\n break;\n }\n };\n\n #handleWebSocketError = (error: Error): void => {\n this.dispatchEvent(errorEvent(`Socket error: ${error.message}`));\n this.#processing = false;\n this.#connection = \"CLOSED\";\n this.#handleStop();\n };\n\n #handleWebSocketClose = (event: unknown): void => {\n // When we already have new socket opened\n if (this.#dictationController.isConnectionOpen()) {\n return;\n }\n\n this.#processing = false;\n this.#connection = \"CLOSED\";\n this.dispatchEvent(streamClosedEvent(event));\n this.#dispatchRecordingStateChanged(this._recordingState);\n };\n\n #dispatchRecordingStateChanged(state: RecordingState): void {\n this.dispatchEvent(\n recordingStateChangedEvent(state, {\n connection: this.#connection,\n processing: this.#processing,\n }),\n );\n }\n\n async #handleStart(): Promise<void> {\n console.log(\"[RecordingButton] handleStart() called\");\n this.#dispatchRecordingStateChanged(\"initializing\");\n\n try {\n console.log(\"[RecordingButton] Initializing media controller...\");\n await this.#mediaController.initialize(\n this.#dictationController.mediaRecorderHandler,\n () => {\n if (this._recordingState === \"recording\") {\n this.dispatchEvent(errorEvent(\"Recording device access was lost.\"));\n this.#handleStop();\n }\n },\n );\n console.log(\"[RecordingButton] Starting MediaRecorder...\");\n this.#mediaController.mediaRecorder?.start(AUDIO_CHUNK_INTERVAL_MS);\n this.#mediaController.startAudioLevelMonitoring((level) => {\n this.dispatchEvent(audioLevelChangedEvent(level));\n });\n\n if (this.#connection !== \"OPEN\") {\n this.#connection = \"CONNECTING\";\n }\n\n this.#dispatchRecordingStateChanged(\"recording\");\n\n console.log(\"[RecordingButton] Connecting to WebSocket...\");\n const isNewConnection = await this.#dictationController.connect(\n this._dictationConfig,\n {\n onClose: this.#handleWebSocketClose,\n onError: this.#handleWebSocketError,\n onMessage: this.#handleWebSocketMessage,\n onNetworkActivity: (direction, data) => {\n this.dispatchEvent(networkActivityEvent(direction, data));\n },\n },\n );\n\n console.log(\"[RecordingButton] Connection established\", { isNewConnection });\n\n if (!isNewConnection) {\n this.#processing = true;\n }\n\n this.#connection = \"OPEN\";\n\n this.#dispatchRecordingStateChanged(\"recording\");\n } catch (error) {\n console.error(\"[RecordingButton] Error in handleStart:\", error);\n this.dispatchEvent(errorEvent(error));\n await this.#handleStop();\n }\n }\n\n async #handleStop(): Promise<void> {\n console.log(\"[RecordingButton] handleStop() called\");\n this.#dispatchRecordingStateChanged(\"stopping\");\n\n try {\n console.log(\"[RecordingButton] Stopping audio level monitoring...\");\n this.#mediaController.stopAudioLevelMonitoring();\n console.log(\"[RecordingButton] Stopping media recorder...\");\n await this.#mediaController.stopRecording();\n\n this.#dispatchRecordingStateChanged(\"stopped\");\n\n console.log(\"[RecordingButton] Calling dictationController.pause()...\");\n await this.#dictationController.pause();\n console.log(\"[RecordingButton] Cleaning up media controller...\");\n await this.#mediaController.cleanup();\n console.log(\"[RecordingButton] Stop complete\");\n } catch (error) {\n console.error(\"[RecordingButton] Error in handleStop:\", error);\n this.dispatchEvent(errorEvent(error));\n }\n }\n\n public startRecording(): void {\n if (this._recordingState !== \"stopped\") {\n return;\n }\n\n this.#handleStart();\n }\n\n public stopRecording(): void {\n if (\n this._recordingState === \"stopped\" ||\n this._recordingState === \"stopping\"\n ) {\n return;\n }\n\n if (this._recordingState === \"initializing\") {\n this.#closeConnectionOnInit = true;\n return;\n }\n\n this.#handleStop();\n }\n\n public toggleRecording(): void {\n if (this._recordingState === \"stopped\") {\n this.startRecording();\n } else if (this._recordingState === \"recording\") {\n this.stopRecording();\n }\n }\n\n public async openConnection(): Promise<void> {\n if (this._recordingState !== \"stopped\" || this.#processing) {\n return;\n }\n\n if (this.#dictationController.isConnectionOpen()) {\n return;\n }\n\n try {\n this.#connection = \"CONNECTING\";\n this.#dispatchRecordingStateChanged(\"stopped\");\n\n await this.#dictationController.connect(this._dictationConfig, {\n onClose: this.#handleWebSocketClose,\n onError: this.#handleWebSocketError,\n onMessage: this.#handleWebSocketMessage,\n onNetworkActivity: (direction, data) => {\n this.dispatchEvent(networkActivityEvent(direction, data));\n },\n });\n\n this.#connection = \"OPEN\";\n this.#dispatchRecordingStateChanged(\"stopped\");\n } catch (error) {\n this.#connection = \"CLOSED\";\n this.dispatchEvent(errorEvent(error));\n }\n }\n\n public async closeConnection(): Promise<void> {\n if (this._recordingState !== \"stopped\" || this.#processing) {\n return;\n }\n\n if (!this.#dictationController.isConnectionOpen()) {\n this.#connection = \"CLOSED\";\n this.#dispatchRecordingStateChanged(\"stopped\");\n return;\n }\n\n try {\n this.#connection = \"CLOSING\";\n this.#dispatchRecordingStateChanged(\"stopped\");\n await this.#dictationController.closeConnection(\n this.#handleWebSocketClose,\n );\n } catch (error) {\n this.dispatchEvent(errorEvent(error));\n }\n }\n\n render() {\n const isLoading =\n this._recordingState === \"initializing\" ||\n this._recordingState === \"stopping\";\n const isRecording = this._recordingState === \"recording\";\n\n return html`\n <button\n @click=${this.#handleClick}\n ?disabled=${isLoading}\n class=${isRecording ? \"red\" : \"accent\"}\n aria-label=${isRecording ? \"Stop recording\" : \"Start recording\"}\n aria-pressed=${isRecording}\n >\n ${\n isLoading\n ? html`<icon-loading-spinner />`\n : isRecording\n ? html`<icon-recording />`\n : html`<icon-mic-on />`\n }\n <dictation-audio-visualiser\n .level=${this.#mediaController.audioLevel}\n ?active=${isRecording}\n />\n </button>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"dictation-recording-button\": DictationRecordingButton;\n }\n}\n"]}
|