@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 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: backtick) -->
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["default"];
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) => "%" + ("00" + c6.charCodeAt(0).toString(16)).slice(-2)).join(""));
1351
- } catch (error) {
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 (error) {
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, _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");
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(), _MediaController_bufferedChunks = /* @__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
- __classPrivateFieldGet7(this, _DictationRecordingButton_mediaController, "f").addDataHandler(__classPrivateFieldGet7(this, _DictationRecordingButton_dictationController, "f").mediaRecorderHandler);
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("Socket error: " + error.message));
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
- await __classPrivateFieldGet7(this, _DictationRecordingButton_mediaController, "f").initialize(() => {
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
- __classPrivateFieldGet(this, _DictationRecordingButton_mediaController, "f").addDataHandler(__classPrivateFieldGet(this, _DictationRecordingButton_dictationController, "f").mediaRecorderHandler);
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("Socket error: " + error.message));
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
- await __classPrivateFieldGet(this, _DictationRecordingButton_mediaController, "f").initialize(() => {
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":";;;;;;;;;;;;;;;;;;AACA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAEL,IAAI,EACJ,UAAU,GAEX,MAAM,KAAK,CAAC;AACb,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,wBAAwB,EACxB,sBAAsB,EACtB,2BAA2B,EAC3B,qBAAqB,EACrB,aAAa,EACb,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,6BAA6B,GAC9B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,mBAAmB,GAEpB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,YAAY,MAAM,sBAAsB,CAAC;AAChD,OAAO,qBAAqB,MAAM,+BAA+B,CAAC;AAElE,OAAO,EACL,sBAAsB,EACtB,YAAY,EACZ,UAAU,EACV,oBAAoB,EAEpB,0BAA0B,EAC1B,iBAAiB,EACjB,eAAe,EACf,UAAU,GACX,MAAM,oBAAoB,CAAC;AAE5B,OAAO,uBAAuB,CAAC;AAC/B,OAAO,mBAAmB,CAAC;AAGpB,IAAM,wBAAwB,GAA9B,MAAM,wBAAyB,SAAQ,UAAU;IAAjD;;;QAGL,oBAAe,GAAmB,SAAS,CAAC;QA+C5C,qBAAgB,GAAY,KAAK,CAAC;QAElC,oDAAmB,IAAI,eAAe,CAAC,IAAI,CAAC,EAAC;QAC7C,wDAAuB,IAAI,mBAAmB,CAAC,IAAI,CAAC,EAAC;QACrD,yDAAwB,IAAI,oBAAoB,CAAC,IAAI,CAAC,EAAC;QACvD,0DAAyB,KAAK,EAAC;QAC/B,+CAAc,KAAK,EAAC;QACpB,+CAA8D,QAAQ,EAAC;QAyBvE,2DAA0B,CAAC,OAA0B,EAAQ,EAAE;YAC7D,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;gBACrB,KAAK,iBAAiB;oBACpB,OAAO,CAAC,GAAG,CAAC,4CAA4C,EAAE;wBACxD,cAAc,EAAE,IAAI,CAAC,eAAe;wBACpC,iBAAiB,EAAE,IAAI,CAAC,eAAe,KAAK,cAAc;qBAC3D,CAAC,CAAC;oBACH,IAAI,IAAI,CAAC,eAAe,KAAK,cAAc,EAAE,CAAC;wBAC5C,uBAAA,IAAI,wCAAe,IAAI,MAAA,CAAC;wBACxB,uBAAA,IAAI,oGAA+B,MAAnC,IAAI,EAAgC,WAAW,CAAC,CAAC;oBACnD,CAAC;oBACD,MAAM;gBACR,KAAK,eAAe;oBAClB,IAAI,CAAC,aAAa,CAChB,UAAU,CAAC,kBAAkB,OAAO,CAAC,MAAM,IAAI,gBAAgB,EAAE,CAAC,CACnE,CAAC;oBACF,uBAAA,IAAI,iFAAY,MAAhB,IAAI,CAAc,CAAC;oBACnB,MAAM;gBACR,KAAK,gBAAgB;oBACnB,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC,CAAC;oBACjD,uBAAA,IAAI,iFAAY,MAAhB,IAAI,CAAc,CAAC;oBACnB,MAAM;gBACR,KAAK,YAAY;oBACf,IAAI,CAAC,aAAa,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;oBAC7C,MAAM;gBACR,KAAK,SAAS;oBACZ,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;oBAC1C,MAAM;gBACR,KAAK,OAAO;oBACV,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;oBACxC,MAAM;gBACR,KAAK,OAAO;oBACV,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;oBAC9C,uBAAA,IAAI,iFAAY,MAAhB,IAAI,CAAc,CAAC;oBACnB,MAAM;gBACR,KAAK,SAAS;oBACZ,IACE,IAAI,CAAC,eAAe,KAAK,SAAS;wBAClC,IAAI,CAAC,eAAe,KAAK,UAAU,EACnC,CAAC;wBACD,uBAAA,IAAI,wCAAe,KAAK,MAAA,CAAC;wBACzB,uBAAA,IAAI,oGAA+B,MAAnC,IAAI,EAAgC,IAAI,CAAC,eAAe,CAAC,CAAC;oBAC5D,CAAC;oBACD,MAAM;YACV,CAAC;QACH,CAAC,EAAC;QAEF,yDAAwB,CAAC,KAAY,EAAQ,EAAE;YAC7C,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,iBAAiB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACjE,uBAAA,IAAI,wCAAe,KAAK,MAAA,CAAC;YACzB,uBAAA,IAAI,wCAAe,QAAQ,MAAA,CAAC;YAC5B,uBAAA,IAAI,iFAAY,MAAhB,IAAI,CAAc,CAAC;QACrB,CAAC,EAAC;QAEF,yDAAwB,CAAC,KAAc,EAAQ,EAAE;YAC/C,yCAAyC;YACzC,IAAI,uBAAA,IAAI,qDAAqB,CAAC,gBAAgB,EAAE,EAAE,CAAC;gBACjD,OAAO;YACT,CAAC;YAED,uBAAA,IAAI,wCAAe,KAAK,MAAA,CAAC;YACzB,uBAAA,IAAI,wCAAe,QAAQ,MAAA,CAAC;YAC5B,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC;YAC7C,uBAAA,IAAI,oGAA+B,MAAnC,IAAI,EAAgC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC5D,CAAC,EAAC;IA0MJ,CAAC;IA/RW,MAAM,CAAC,iBAAiC;QAChD,IACE,iBAAiB,CAAC,GAAG,CAAC,iBAAiB,CAAC;YACxC,IAAI,CAAC,eAAe,KAAK,WAAW;YACpC,uBAAA,IAAI,uDAAuB,EAC3B,CAAC;YACD,uBAAA,IAAI,mDAA0B,KAAK,MAAA,CAAC;YACpC,uBAAA,IAAI,iFAAY,MAAhB,IAAI,CAAc,CAAC;QACrB,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAClC,CAAC;IAoKM,cAAc;QACnB,IAAI,IAAI,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;YACvC,OAAO;QACT,CAAC;QAED,uBAAA,IAAI,kFAAa,MAAjB,IAAI,CAAe,CAAC;IACtB,CAAC;IAEM,aAAa;QAClB,IACE,IAAI,CAAC,eAAe,KAAK,SAAS;YAClC,IAAI,CAAC,eAAe,KAAK,UAAU,EACnC,CAAC;YACD,OAAO;QACT,CAAC;QAED,IAAI,IAAI,CAAC,eAAe,KAAK,cAAc,EAAE,CAAC;YAC5C,uBAAA,IAAI,mDAA0B,IAAI,MAAA,CAAC;YACnC,OAAO;QACT,CAAC;QAED,uBAAA,IAAI,iFAAY,MAAhB,IAAI,CAAc,CAAC;IACrB,CAAC;IAEM,eAAe;QACpB,IAAI,IAAI,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;YACvC,IAAI,CAAC,cAAc,EAAE,CAAC;QACxB,CAAC;aAAM,IAAI,IAAI,CAAC,eAAe,KAAK,WAAW,EAAE,CAAC;YAChD,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,cAAc;QACzB,IAAI,IAAI,CAAC,eAAe,KAAK,SAAS,IAAI,uBAAA,IAAI,4CAAY,EAAE,CAAC;YAC3D,OAAO;QACT,CAAC;QAED,IAAI,uBAAA,IAAI,qDAAqB,CAAC,gBAAgB,EAAE,EAAE,CAAC;YACjD,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,uBAAA,IAAI,wCAAe,YAAY,MAAA,CAAC;YAChC,uBAAA,IAAI,oGAA+B,MAAnC,IAAI,EAAgC,SAAS,CAAC,CAAC;YAE/C,MAAM,uBAAA,IAAI,qDAAqB,CAAC,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE;gBAC7D,OAAO,EAAE,uBAAA,IAAI,sDAAsB;gBACnC,OAAO,EAAE,uBAAA,IAAI,sDAAsB;gBACnC,SAAS,EAAE,uBAAA,IAAI,wDAAwB;gBACvC,iBAAiB,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE;oBACrC,IAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;gBAC5D,CAAC;aACF,CAAC,CAAC;YAEH,uBAAA,IAAI,wCAAe,MAAM,MAAA,CAAC;YAC1B,uBAAA,IAAI,oGAA+B,MAAnC,IAAI,EAAgC,SAAS,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,uBAAA,IAAI,wCAAe,QAAQ,MAAA,CAAC;YAC5B,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,eAAe;QAC1B,IAAI,IAAI,CAAC,eAAe,KAAK,SAAS,IAAI,uBAAA,IAAI,4CAAY,EAAE,CAAC;YAC3D,OAAO;QACT,CAAC;QAED,IAAI,CAAC,uBAAA,IAAI,qDAAqB,CAAC,gBAAgB,EAAE,EAAE,CAAC;YAClD,uBAAA,IAAI,wCAAe,QAAQ,MAAA,CAAC;YAC5B,uBAAA,IAAI,oGAA+B,MAAnC,IAAI,EAAgC,SAAS,CAAC,CAAC;YAC/C,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,uBAAA,IAAI,wCAAe,SAAS,MAAA,CAAC;YAC7B,uBAAA,IAAI,oGAA+B,MAAnC,IAAI,EAAgC,SAAS,CAAC,CAAC;YAC/C,MAAM,uBAAA,IAAI,qDAAqB,CAAC,eAAe,CAC7C,uBAAA,IAAI,sDAAsB,CAC3B,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED,MAAM;QACJ,MAAM,SAAS,GACb,IAAI,CAAC,eAAe,KAAK,cAAc;YACvC,IAAI,CAAC,eAAe,KAAK,UAAU,CAAC;QACtC,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,KAAK,WAAW,CAAC;QAEzD,OAAO,IAAI,CAAA;;iBAEE,uBAAA,IAAI,kFAAa;oBACd,SAAS;gBACb,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ;qBACzB,WAAW,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,iBAAiB;uBAChD,WAAW;;UAGxB,SAAS;YACP,CAAC,CAAC,IAAI,CAAA,0BAA0B;YAChC,CAAC,CAAC,WAAW;gBACX,CAAC,CAAC,IAAI,CAAA,oBAAoB;gBAC1B,CAAC,CAAC,IAAI,CAAA,iBACZ;;mBAEW,uBAAA,IAAI,iDAAiB,CAAC,UAAU;oBAC/B,WAAW;;;KAG1B,CAAC;IACJ,CAAC;;;;;;;;;;;;uFAjRY,KAAiB;IAC5B,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC3B,KAAK,CAAC,cAAc,EAAE,CAAC;IACzB,CAAC;IAED,IAAI,CAAC,eAAe,EAAE,CAAC;AACzB,CAAC;2HAoE8B,KAAqB;IAClD,IAAI,CAAC,aAAa,CAChB,0BAA0B,CAAC,KAAK,EAAE;QAChC,UAAU,EAAE,uBAAA,IAAI,4CAAY;QAC5B,UAAU,EAAE,uBAAA,IAAI,4CAAY;KAC7B,CAAC,CACH,CAAC;AACJ,CAAC;wCAED,KAAK;IACH,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;IACtD,uBAAA,IAAI,oGAA+B,MAAnC,IAAI,EAAgC,cAAc,CAAC,CAAC;IAEpD,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;QAClE,MAAM,uBAAA,IAAI,iDAAiB,CAAC,UAAU,CACpC,uBAAA,IAAI,qDAAqB,CAAC,oBAAoB,EAC9C,GAAG,EAAE;YACH,IAAI,IAAI,CAAC,eAAe,KAAK,WAAW,EAAE,CAAC;gBACzC,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,mCAAmC,CAAC,CAAC,CAAC;gBACpE,uBAAA,IAAI,iFAAY,MAAhB,IAAI,CAAc,CAAC;YACrB,CAAC;QACH,CAAC,CACF,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;QAC3D,uBAAA,IAAI,iDAAiB,CAAC,aAAa,EAAE,KAAK,CAAC,uBAAuB,CAAC,CAAC;QACpE,uBAAA,IAAI,iDAAiB,CAAC,yBAAyB,CAAC,CAAC,KAAK,EAAE,EAAE;YACxD,IAAI,CAAC,aAAa,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QAEH,IAAI,uBAAA,IAAI,4CAAY,KAAK,MAAM,EAAE,CAAC;YAChC,uBAAA,IAAI,wCAAe,YAAY,MAAA,CAAC;QAClC,CAAC;QAED,uBAAA,IAAI,oGAA+B,MAAnC,IAAI,EAAgC,WAAW,CAAC,CAAC;QAEjD,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;QAC5D,MAAM,eAAe,GAAG,MAAM,uBAAA,IAAI,qDAAqB,CAAC,OAAO,CAC7D,IAAI,CAAC,gBAAgB,EACrB;YACE,OAAO,EAAE,uBAAA,IAAI,sDAAsB;YACnC,OAAO,EAAE,uBAAA,IAAI,sDAAsB;YACnC,SAAS,EAAE,uBAAA,IAAI,wDAAwB;YACvC,iBAAiB,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE;gBACrC,IAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;YAC5D,CAAC;SACF,CACF,CAAC;QAEF,OAAO,CAAC,GAAG,CAAC,0CAA0C,EAAE,EAAE,eAAe,EAAE,CAAC,CAAC;QAE7E,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,uBAAA,IAAI,wCAAe,IAAI,MAAA,CAAC;QAC1B,CAAC;QAED,uBAAA,IAAI,wCAAe,MAAM,MAAA,CAAC;QAE1B,uBAAA,IAAI,oGAA+B,MAAnC,IAAI,EAAgC,WAAW,CAAC,CAAC;IACnD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,yCAAyC,EAAE,KAAK,CAAC,CAAC;QAChE,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;QACtC,MAAM,uBAAA,IAAI,iFAAY,MAAhB,IAAI,CAAc,CAAC;IAC3B,CAAC;AACH,CAAC;uCAED,KAAK;IACH,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;IACrD,uBAAA,IAAI,oGAA+B,MAAnC,IAAI,EAAgC,UAAU,CAAC,CAAC;IAEhD,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;QACpE,uBAAA,IAAI,iDAAiB,CAAC,wBAAwB,EAAE,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;QAC5D,MAAM,uBAAA,IAAI,iDAAiB,CAAC,aAAa,EAAE,CAAC;QAE5C,uBAAA,IAAI,oGAA+B,MAAnC,IAAI,EAAgC,SAAS,CAAC,CAAC;QAE/C,OAAO,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAC;QACxE,MAAM,uBAAA,IAAI,qDAAqB,CAAC,KAAK,EAAE,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;QACjE,MAAM,uBAAA,IAAI,iDAAiB,CAAC,OAAO,EAAE,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,wCAAwC,EAAE,KAAK,CAAC,CAAC;QAC/D,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;IACxC,CAAC;AACH,CAAC;AA/KM,+BAAM,GAAmB,CAAC,qBAAqB,EAAE,YAAY,CAAC,AAAxD,CAAyD;AAxDtE;IAFC,OAAO,CAAC,EAAE,OAAO,EAAE,qBAAqB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAC5D,KAAK,EAAE;iEACoC;AAI5C;IAFC,OAAO,CAAC,EAAE,OAAO,EAAE,qBAAqB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAC5D,KAAK,EAAE;iEAC0B;AAIlC;IAFC,OAAO,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IACzD,KAAK,EAAE;8DACc;AAItB;IAFC,OAAO,CAAC,EAAE,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IACxD,KAAK,EAAE;6DAC0B;AAIlC;IAFC,OAAO,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IACpD,KAAK,EAAE;yDACS;AAIjB;IAFC,OAAO,CAAC,EAAE,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IACxD,KAAK,EAAE;6DACa;AAIrB;IAFC,OAAO,CAAC,EAAE,OAAO,EAAE,sBAAsB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAC7D,KAAK,EAAE;kEACkC;AAI1C;IAFC,OAAO,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IACvD,KAAK,EAAE;4DACY;AAIpB;IAFC,OAAO,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IACzD,KAAK,EAAE;8DACoB;AAI5B;IAFC,OAAO,CAAC,EAAE,OAAO,EAAE,wBAAwB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAC/D,KAAK,EAAE;qEACsB;AAI9B;IAFC,OAAO,CAAC,EAAE,OAAO,EAAE,2BAA2B,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAClE,KAAK,EAAE;uEAC8B;AAItC;IAFC,OAAO,CAAC,EAAE,OAAO,EAAE,6BAA6B,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IACpE,KAAK,EAAE;yEACgC;AAGxC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;kEACM;AAlDvB,wBAAwB;IADpC,aAAa,CAAC,4BAA4B,CAAC;GAC/B,wBAAwB,CA4VpC","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"]}