@corti/dictation-web 0.0.0-rc.359 → 0.0.0-test.571

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.
Files changed (223) hide show
  1. package/README.md +163 -102
  2. package/dist/CortiDictation.d.ts +6 -2
  3. package/dist/CortiDictation.js +36 -14
  4. package/dist/CortiDictation.js.map +1 -1
  5. package/dist/bundle.js +3888 -1787
  6. package/dist/components/audio-visualiser.d.ts +5 -3
  7. package/dist/components/audio-visualiser.js +38 -46
  8. package/dist/components/audio-visualiser.js.map +1 -1
  9. package/dist/components/corti-dictation.d.ts +136 -0
  10. package/dist/components/corti-dictation.js +273 -0
  11. package/dist/components/corti-dictation.js.map +1 -0
  12. package/dist/components/device-selector.d.ts +14 -0
  13. package/dist/components/device-selector.js +75 -0
  14. package/dist/components/device-selector.js.map +1 -0
  15. package/dist/components/keybinding-selector.d.ts +14 -0
  16. package/dist/components/keybinding-selector.js +81 -0
  17. package/dist/components/keybinding-selector.js.map +1 -0
  18. package/dist/components/language-selector.d.ts +15 -0
  19. package/dist/components/language-selector.js +74 -0
  20. package/dist/components/language-selector.js.map +1 -0
  21. package/dist/components/mode-selector.d.ts +14 -0
  22. package/dist/components/mode-selector.js +73 -0
  23. package/dist/components/mode-selector.js.map +1 -0
  24. package/dist/components/recording-button.d.ts +31 -0
  25. package/dist/components/recording-button.js +262 -0
  26. package/dist/components/recording-button.js.map +1 -0
  27. package/dist/components/settings-menu.d.ts +12 -14
  28. package/dist/components/settings-menu.js +68 -153
  29. package/dist/components/settings-menu.js.map +1 -1
  30. package/dist/constants.d.ts +8 -2
  31. package/dist/constants.js +38 -12
  32. package/dist/constants.js.map +1 -1
  33. package/dist/contexts/dictation-context.d.ts +107 -0
  34. package/dist/contexts/dictation-context.js +290 -0
  35. package/dist/contexts/dictation-context.js.map +1 -0
  36. package/dist/controllers/DictationController.d.ts +35 -0
  37. package/dist/controllers/DictationController.js +130 -0
  38. package/dist/controllers/DictationController.js.map +1 -0
  39. package/dist/controllers/MediaController.d.ts +31 -0
  40. package/dist/controllers/MediaController.js +99 -0
  41. package/dist/controllers/MediaController.js.map +1 -0
  42. package/dist/controllers/devices-controller.d.ts +26 -0
  43. package/dist/controllers/devices-controller.js +99 -0
  44. package/dist/controllers/devices-controller.js.map +1 -0
  45. package/dist/controllers/dictation-controller.d.ts +29 -0
  46. package/dist/controllers/dictation-controller.js +179 -0
  47. package/dist/controllers/dictation-controller.js.map +1 -0
  48. package/dist/controllers/keybinding-controller.d.ts +17 -0
  49. package/dist/controllers/keybinding-controller.js +80 -0
  50. package/dist/controllers/keybinding-controller.js.map +1 -0
  51. package/dist/controllers/languages-controller.d.ts +26 -0
  52. package/dist/controllers/languages-controller.js +83 -0
  53. package/dist/controllers/languages-controller.js.map +1 -0
  54. package/dist/controllers/media-controller.d.ts +24 -0
  55. package/dist/controllers/media-controller.js +115 -0
  56. package/dist/controllers/media-controller.js.map +1 -0
  57. package/dist/index.d.ts +11 -1
  58. package/dist/index.js +39 -3
  59. package/dist/index.js.map +1 -1
  60. package/dist/package.json +14 -0
  61. package/dist/src/components/audio-visualiser.d.ts +14 -0
  62. package/dist/src/components/audio-visualiser.js +57 -0
  63. package/dist/src/components/audio-visualiser.js.map +1 -0
  64. package/dist/src/components/corti-dictation.d.ts +123 -0
  65. package/dist/src/components/corti-dictation.js +224 -0
  66. package/dist/src/components/corti-dictation.js.map +1 -0
  67. package/dist/src/components/device-selector.d.ts +24 -0
  68. package/dist/src/components/device-selector.js +106 -0
  69. package/dist/src/components/device-selector.js.map +1 -0
  70. package/dist/src/components/language-selector.d.ts +24 -0
  71. package/dist/src/components/language-selector.js +100 -0
  72. package/dist/src/components/language-selector.js.map +1 -0
  73. package/dist/src/components/recording-button.d.ts +37 -0
  74. package/dist/src/components/recording-button.js +203 -0
  75. package/dist/src/components/recording-button.js.map +1 -0
  76. package/dist/src/components/settings-menu.d.ts +16 -0
  77. package/dist/src/components/settings-menu.js +80 -0
  78. package/dist/src/components/settings-menu.js.map +1 -0
  79. package/dist/src/constants.d.ts +4 -0
  80. package/dist/src/constants.js +37 -0
  81. package/dist/src/constants.js.map +1 -0
  82. package/dist/src/contexts/dictation-context.d.ts +97 -0
  83. package/dist/src/contexts/dictation-context.js +208 -0
  84. package/dist/src/contexts/dictation-context.js.map +1 -0
  85. package/dist/src/controllers/DictationController.d.ts +35 -0
  86. package/dist/src/controllers/DictationController.js +130 -0
  87. package/dist/src/controllers/DictationController.js.map +1 -0
  88. package/dist/src/controllers/MediaController.d.ts +31 -0
  89. package/dist/src/controllers/MediaController.js +99 -0
  90. package/dist/src/controllers/MediaController.js.map +1 -0
  91. package/dist/src/icons/icons.d.ts +17 -0
  92. package/dist/src/icons/icons.js +158 -0
  93. package/dist/src/icons/icons.js.map +1 -0
  94. package/dist/src/styles/ComponentStyles.d.ts +2 -0
  95. package/dist/src/styles/ComponentStyles.js +18 -0
  96. package/dist/src/styles/ComponentStyles.js.map +1 -0
  97. package/dist/src/styles/audio-visualiser.d.ts +2 -0
  98. package/dist/src/styles/audio-visualiser.js +33 -0
  99. package/dist/src/styles/audio-visualiser.js.map +1 -0
  100. package/dist/src/styles/buttons.d.ts +2 -0
  101. package/dist/src/styles/buttons.js +52 -0
  102. package/dist/src/styles/buttons.js.map +1 -0
  103. package/dist/src/styles/callout.d.ts +2 -0
  104. package/dist/src/styles/callout.js +23 -0
  105. package/dist/src/styles/callout.js.map +1 -0
  106. package/dist/src/styles/default-theme.d.ts +2 -0
  107. package/dist/src/styles/default-theme.js +50 -0
  108. package/dist/src/styles/default-theme.js.map +1 -0
  109. package/dist/src/styles/recording-button.d.ts +2 -0
  110. package/dist/src/styles/recording-button.js +8 -0
  111. package/dist/src/styles/recording-button.js.map +1 -0
  112. package/dist/src/styles/select.d.ts +2 -0
  113. package/dist/src/styles/select.js +36 -0
  114. package/dist/src/styles/select.js.map +1 -0
  115. package/dist/src/styles/settings-menu.d.ts +2 -0
  116. package/dist/src/styles/settings-menu.js +34 -0
  117. package/dist/src/styles/settings-menu.js.map +1 -0
  118. package/dist/src/types.d.ts +7 -0
  119. package/dist/src/types.js +2 -0
  120. package/dist/src/types.js.map +1 -0
  121. package/dist/src/utils/auth.d.ts +9 -0
  122. package/dist/src/utils/auth.js +21 -0
  123. package/dist/src/utils/auth.js.map +1 -0
  124. package/dist/src/utils/converters.d.ts +4 -0
  125. package/dist/src/utils/converters.js +8 -0
  126. package/dist/src/utils/converters.js.map +1 -0
  127. package/dist/src/utils/devices.d.ts +26 -0
  128. package/dist/src/utils/devices.js +53 -0
  129. package/dist/src/utils/devices.js.map +1 -0
  130. package/dist/src/utils/events.d.ts +44 -0
  131. package/dist/src/utils/events.js +88 -0
  132. package/dist/src/utils/events.js.map +1 -0
  133. package/dist/src/utils/languages.d.ts +7 -0
  134. package/dist/src/utils/languages.js +29 -0
  135. package/dist/src/utils/languages.js.map +1 -0
  136. package/dist/src/utils/media.d.ts +6 -0
  137. package/dist/src/utils/media.js +39 -0
  138. package/dist/src/utils/media.js.map +1 -0
  139. package/dist/src/utils/token.d.ts +13 -0
  140. package/dist/src/utils/token.js +60 -0
  141. package/dist/src/utils/token.js.map +1 -0
  142. package/dist/src/utils/validation.d.ts +1 -0
  143. package/dist/src/utils/validation.js +7 -0
  144. package/dist/src/utils/validation.js.map +1 -0
  145. package/dist/stories/audio-visualiser.stories.d.ts +39 -0
  146. package/dist/stories/audio-visualiser.stories.js +71 -0
  147. package/dist/stories/audio-visualiser.stories.js.map +1 -0
  148. package/dist/stories/corti-dictation.stories.d.ts +27 -0
  149. package/dist/stories/corti-dictation.stories.js +129 -0
  150. package/dist/stories/corti-dictation.stories.js.map +1 -0
  151. package/dist/stories/device-selector.stories.d.ts +18 -0
  152. package/dist/stories/device-selector.stories.js +84 -0
  153. package/dist/stories/device-selector.stories.js.map +1 -0
  154. package/dist/stories/language-selector.stories.d.ts +18 -0
  155. package/dist/stories/language-selector.stories.js +53 -0
  156. package/dist/stories/language-selector.stories.js.map +1 -0
  157. package/dist/stories/recording-button.stories.d.ts +27 -0
  158. package/dist/stories/recording-button.stories.js +90 -0
  159. package/dist/stories/recording-button.stories.js.map +1 -0
  160. package/dist/stories/settings-menu.stories.d.ts +23 -0
  161. package/dist/stories/settings-menu.stories.js +156 -0
  162. package/dist/stories/settings-menu.stories.js.map +1 -0
  163. package/dist/styles/ComponentStyles.js +6 -41
  164. package/dist/styles/ComponentStyles.js.map +1 -1
  165. package/dist/styles/audio-visualiser.d.ts +2 -0
  166. package/dist/styles/audio-visualiser.js +33 -0
  167. package/dist/styles/audio-visualiser.js.map +1 -0
  168. package/dist/styles/buttons.js +19 -26
  169. package/dist/styles/buttons.js.map +1 -1
  170. package/dist/styles/callout.js +7 -17
  171. package/dist/styles/callout.js.map +1 -1
  172. package/dist/styles/component-styles.d.ts +3 -0
  173. package/dist/styles/component-styles.js +32 -0
  174. package/dist/styles/component-styles.js.map +1 -0
  175. package/dist/styles/default-theme.d.ts +2 -0
  176. package/dist/styles/default-theme.js +14 -0
  177. package/dist/styles/default-theme.js.map +1 -0
  178. package/dist/styles/keybinding-selector.d.ts +2 -0
  179. package/dist/styles/keybinding-selector.js +72 -0
  180. package/dist/styles/keybinding-selector.js.map +1 -0
  181. package/dist/styles/mode-selector.d.ts +2 -0
  182. package/dist/styles/mode-selector.js +54 -0
  183. package/dist/styles/mode-selector.js.map +1 -0
  184. package/dist/styles/recording-button.d.ts +2 -0
  185. package/dist/styles/recording-button.js +8 -0
  186. package/dist/styles/recording-button.js.map +1 -0
  187. package/dist/styles/select.d.ts +1 -1
  188. package/dist/styles/select.js +14 -18
  189. package/dist/styles/select.js.map +1 -1
  190. package/dist/styles/settings-menu.d.ts +2 -0
  191. package/dist/styles/settings-menu.js +42 -0
  192. package/dist/styles/settings-menu.js.map +1 -0
  193. package/dist/tsconfig.stories.tsbuildinfo +1 -0
  194. package/dist/types.d.ts +9 -8
  195. package/dist/types.js.map +1 -1
  196. package/dist/utils/auth.d.ts +9 -0
  197. package/dist/utils/auth.js +21 -0
  198. package/dist/utils/auth.js.map +1 -0
  199. package/dist/utils/converters.d.ts +4 -0
  200. package/dist/utils/converters.js +8 -0
  201. package/dist/utils/converters.js.map +1 -0
  202. package/dist/utils/devices.d.ts +26 -0
  203. package/dist/utils/devices.js +53 -0
  204. package/dist/utils/devices.js.map +1 -0
  205. package/dist/utils/events.d.ts +53 -0
  206. package/dist/utils/events.js +102 -0
  207. package/dist/utils/events.js.map +1 -0
  208. package/dist/utils/keybinding.d.ts +49 -0
  209. package/dist/utils/keybinding.js +140 -0
  210. package/dist/utils/keybinding.js.map +1 -0
  211. package/dist/utils/languages.d.ts +8 -0
  212. package/dist/utils/languages.js +29 -0
  213. package/dist/utils/languages.js.map +1 -0
  214. package/dist/utils/media.d.ts +6 -0
  215. package/dist/utils/media.js +39 -0
  216. package/dist/utils/media.js.map +1 -0
  217. package/dist/utils/token.d.ts +13 -0
  218. package/dist/utils/token.js +60 -0
  219. package/dist/utils/token.js.map +1 -0
  220. package/dist/utils/validation.d.ts +1 -0
  221. package/dist/utils/validation.js +7 -0
  222. package/dist/utils/validation.js.map +1 -0
  223. package/package.json +29 -55
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Extracts the initial access token from auth config
3
+ * @throws Error if token is missing or invalid
4
+ */
5
+ export async function getInitialToken(config) {
6
+ const initialToken = "accessToken" in config
7
+ ? {
8
+ accessToken: config.accessToken,
9
+ refreshToken: config.refreshToken,
10
+ }
11
+ : await config.refreshAccessToken();
12
+ if (!initialToken?.accessToken ||
13
+ typeof initialToken.accessToken !== "string") {
14
+ throw new Error("Access token is required and must be a string");
15
+ }
16
+ return {
17
+ accessToken: initialToken.accessToken,
18
+ refreshToken: initialToken.refreshToken,
19
+ };
20
+ }
21
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/utils/auth.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAA2B;IAE3B,MAAM,YAAY,GAChB,aAAa,IAAI,MAAM;QACrB,CAAC,CAAC;YACE,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,YAAY,EAAE,MAAM,CAAC,YAAY;SAClC;QACH,CAAC,CAAC,MAAM,MAAM,CAAC,kBAAkB,EAAE,CAAC;IAExC,IACE,CAAC,YAAY,EAAE,WAAW;QAC1B,OAAO,YAAY,CAAC,WAAW,KAAK,QAAQ,EAC5C,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IAED,OAAO;QACL,WAAW,EAAE,YAAY,CAAC,WAAW;QACrC,YAAY,EAAE,YAAY,CAAC,YAAY;KACxC,CAAC;AACJ,CAAC","sourcesContent":["import type { Corti } from \"@corti/sdk\";\n\n/**\n * Extracts the initial access token from auth config\n * @throws Error if token is missing or invalid\n */\nexport async function getInitialToken(\n config: Corti.BearerOptions,\n): Promise<{ accessToken: string; refreshToken?: string }> {\n const initialToken =\n \"accessToken\" in config\n ? {\n accessToken: config.accessToken,\n refreshToken: config.refreshToken,\n }\n : await config.refreshAccessToken();\n\n if (\n !initialToken?.accessToken ||\n typeof initialToken.accessToken !== \"string\"\n ) {\n throw new Error(\"Access token is required and must be a string\");\n }\n\n return {\n accessToken: initialToken.accessToken,\n refreshToken: initialToken.refreshToken,\n };\n}\n"]}
@@ -0,0 +1,4 @@
1
+ export declare const commaSeparatedConverter: {
2
+ fromAttribute: (value: string | null) => string[] | undefined;
3
+ toAttribute: (value: string[] | undefined) => string | undefined;
4
+ };
@@ -0,0 +1,8 @@
1
+ export const commaSeparatedConverter = {
2
+ fromAttribute: (value) => value
3
+ ?.split(",")
4
+ .map((s) => s.trim())
5
+ .filter(Boolean),
6
+ toAttribute: (value) => value?.join(","),
7
+ };
8
+ //# sourceMappingURL=converters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"converters.js","sourceRoot":"","sources":["../../src/utils/converters.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,aAAa,EAAE,CAAC,KAAoB,EAAE,EAAE,CACtC,KAAK;QACH,EAAE,KAAK,CAAC,GAAG,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,OAAO,CAAC;IACpB,WAAW,EAAE,CAAC,KAA2B,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC;CAC/D,CAAC","sourcesContent":["export const commaSeparatedConverter = {\n fromAttribute: (value: string | null) =>\n value\n ?.split(\",\")\n .map((s) => s.trim())\n .filter(Boolean),\n toAttribute: (value: string[] | undefined) => value?.join(\",\"),\n};\n"]}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Requests access to the microphone.
3
+ *
4
+ * This function checks if the microphone permission is in "prompt" state, then requests
5
+ * access and stops any active tracks immediately.
6
+ *
7
+ * @returns A promise that resolves when the permission request is complete.
8
+ * @throws Error if microphone access is denied or unavailable.
9
+ */
10
+ export declare function requestMicAccess(): Promise<void>;
11
+ /**
12
+ * Retrieves available audio input devices.
13
+ *
14
+ * This function uses the mediaDevices API to enumerate devices and filters out those
15
+ * which are audio inputs. In some browsers, you may need to request user media before
16
+ * device labels are populated.
17
+ *
18
+ * @returns A promise that resolves with an object containing:
19
+ * - `devices`: an array of MediaDeviceInfo objects for audio inputs.
20
+ * - `defaultDevice`: the first audio input device, if available.
21
+ * @throws Error if mediaDevices API is unavailable or device enumeration fails.
22
+ */
23
+ export declare function getAudioDevices(): Promise<{
24
+ devices: MediaDeviceInfo[];
25
+ defaultDevice?: MediaDeviceInfo;
26
+ }>;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Requests access to the microphone.
3
+ *
4
+ * This function checks if the microphone permission is in "prompt" state, then requests
5
+ * access and stops any active tracks immediately.
6
+ *
7
+ * @returns A promise that resolves when the permission request is complete.
8
+ * @throws Error if microphone access is denied or unavailable.
9
+ */
10
+ export async function requestMicAccess() {
11
+ if (!navigator.permissions) {
12
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
13
+ stream.getTracks().forEach((track) => {
14
+ track.stop();
15
+ });
16
+ return;
17
+ }
18
+ const permissionStatus = await navigator.permissions.query({
19
+ name: "microphone",
20
+ });
21
+ if (permissionStatus.state === "denied") {
22
+ throw new Error("Microphone permission is denied");
23
+ }
24
+ if (permissionStatus.state === "prompt") {
25
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
26
+ stream.getTracks().forEach((track) => {
27
+ track.stop();
28
+ });
29
+ }
30
+ }
31
+ /**
32
+ * Retrieves available audio input devices.
33
+ *
34
+ * This function uses the mediaDevices API to enumerate devices and filters out those
35
+ * which are audio inputs. In some browsers, you may need to request user media before
36
+ * device labels are populated.
37
+ *
38
+ * @returns A promise that resolves with an object containing:
39
+ * - `devices`: an array of MediaDeviceInfo objects for audio inputs.
40
+ * - `defaultDevice`: the first audio input device, if available.
41
+ * @throws Error if mediaDevices API is unavailable or device enumeration fails.
42
+ */
43
+ export async function getAudioDevices() {
44
+ if (!navigator.mediaDevices?.enumerateDevices) {
45
+ throw new Error("MediaDevices API is not available");
46
+ }
47
+ await requestMicAccess();
48
+ const devices = await navigator.mediaDevices.enumerateDevices();
49
+ const audioDevices = devices.filter((device) => device.kind === "audioinput");
50
+ const defaultDevice = audioDevices.length > 0 ? audioDevices[0] : undefined;
51
+ return { defaultDevice, devices: audioDevices };
52
+ }
53
+ //# sourceMappingURL=devices.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devices.js","sourceRoot":"","sources":["../../src/utils/devices.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAE1E,MAAM,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACnC,KAAK,CAAC,IAAI,EAAE,CAAC;QACf,CAAC,CAAC,CAAC;QAEH,OAAO;IACT,CAAC;IAED,MAAM,gBAAgB,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC;QACzD,IAAI,EAAE,YAA8B;KACrC,CAAC,CAAC;IAEH,IAAI,gBAAgB,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IAED,IAAI,gBAAgB,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxC,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAE1E,MAAM,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACnC,KAAK,CAAC,IAAI,EAAE,CAAC;QACf,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IAInC,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,gBAAgB,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,gBAAgB,EAAE,CAAC;IAEzB,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,gBAAgB,EAAE,CAAC;IAChE,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;IAC9E,MAAM,aAAa,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAE5E,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;AAClD,CAAC","sourcesContent":["/**\n * Requests access to the microphone.\n *\n * This function checks if the microphone permission is in \"prompt\" state, then requests\n * access and stops any active tracks immediately.\n *\n * @returns A promise that resolves when the permission request is complete.\n * @throws Error if microphone access is denied or unavailable.\n */\nexport async function requestMicAccess(): Promise<void> {\n if (!navigator.permissions) {\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n\n stream.getTracks().forEach((track) => {\n track.stop();\n });\n\n return;\n }\n\n const permissionStatus = await navigator.permissions.query({\n name: \"microphone\" as PermissionName,\n });\n\n if (permissionStatus.state === \"denied\") {\n throw new Error(\"Microphone permission is denied\");\n }\n\n if (permissionStatus.state === \"prompt\") {\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n\n stream.getTracks().forEach((track) => {\n track.stop();\n });\n }\n}\n\n/**\n * Retrieves available audio input devices.\n *\n * This function uses the mediaDevices API to enumerate devices and filters out those\n * which are audio inputs. In some browsers, you may need to request user media before\n * device labels are populated.\n *\n * @returns A promise that resolves with an object containing:\n * - `devices`: an array of MediaDeviceInfo objects for audio inputs.\n * - `defaultDevice`: the first audio input device, if available.\n * @throws Error if mediaDevices API is unavailable or device enumeration fails.\n */\nexport async function getAudioDevices(): Promise<{\n devices: MediaDeviceInfo[];\n defaultDevice?: MediaDeviceInfo;\n}> {\n if (!navigator.mediaDevices?.enumerateDevices) {\n throw new Error(\"MediaDevices API is not available\");\n }\n\n await requestMicAccess();\n\n const devices = await navigator.mediaDevices.enumerateDevices();\n const audioDevices = devices.filter((device) => device.kind === \"audioinput\");\n const defaultDevice = audioDevices.length > 0 ? audioDevices[0] : undefined;\n\n return { defaultDevice, devices: audioDevices };\n}\n"]}
@@ -0,0 +1,53 @@
1
+ import type { Corti } from "@corti/sdk";
2
+ import type { DictationMode, RecordingState } from "../types.js";
3
+ export type LanguagesChangedEventDetail = {
4
+ languages: Corti.TranscribeSupportedLanguage[];
5
+ selectedLanguage: string | undefined;
6
+ };
7
+ export type LanguageChangedEventDetail = {
8
+ language: string;
9
+ };
10
+ export type RecordingDevicesChangedEventDetail = {
11
+ devices: MediaDeviceInfo[];
12
+ selectedDevice: MediaDeviceInfo | undefined;
13
+ };
14
+ export type RecordingStateChangedEventDetail = {
15
+ state: RecordingState;
16
+ };
17
+ export type AudioLevelChangedEventDetail = {
18
+ audioLevel: number;
19
+ };
20
+ export type TranscriptEventDetail = Corti.TranscribeTranscriptMessage;
21
+ export type CommandEventDetail = Corti.TranscribeCommandMessage;
22
+ export type UsageEventDetail = Corti.TranscribeUsageMessage;
23
+ export type ErrorEventDetail = {
24
+ message: string;
25
+ };
26
+ export declare function languagesChangedEvent(languages: Corti.TranscribeSupportedLanguage[], selectedLanguage: string | undefined): CustomEvent<LanguagesChangedEventDetail>;
27
+ /**
28
+ * @deprecated Use languagesChangedEvent instead. This event is kept for backward compatibility.
29
+ */
30
+ export declare function languageChangedEvent(language: string): CustomEvent<LanguageChangedEventDetail>;
31
+ export declare function recordingDevicesChangedEvent(devices: MediaDeviceInfo[], selectedDevice: MediaDeviceInfo | undefined): CustomEvent<RecordingDevicesChangedEventDetail>;
32
+ export declare function recordingStateChangedEvent(state: RecordingState): CustomEvent<RecordingStateChangedEventDetail>;
33
+ export declare function transcriptEvent(detail: TranscriptEventDetail): CustomEvent<TranscriptEventDetail>;
34
+ export declare function commandEvent(detail: CommandEventDetail): CustomEvent<CommandEventDetail>;
35
+ export declare function usageEvent(detail: UsageEventDetail): CustomEvent<UsageEventDetail>;
36
+ export declare function errorEvent(error: unknown): CustomEvent<ErrorEventDetail>;
37
+ export declare function streamClosedEvent(detail: unknown): CustomEvent;
38
+ export declare function readyEvent(): CustomEvent;
39
+ export declare function audioLevelChangedEvent(audioLevel: number): CustomEvent<AudioLevelChangedEventDetail>;
40
+ export type NetworkActivityEventDetail = {
41
+ direction: "sent" | "received";
42
+ data: unknown;
43
+ };
44
+ export declare function networkActivityEvent(direction: "sent" | "received", data: unknown): CustomEvent<NetworkActivityEventDetail>;
45
+ export type ModeChangedEventDetail = {
46
+ mode: DictationMode;
47
+ };
48
+ export type KeybindingChangedEventDetail = {
49
+ key: string | null | undefined;
50
+ code: string | null | undefined;
51
+ };
52
+ export declare function modeChangedEvent(mode: DictationMode): CustomEvent<ModeChangedEventDetail>;
53
+ export declare function keybindingChangedEvent(key: string | null | undefined, code: string | null | undefined): CustomEvent<KeybindingChangedEventDetail>;
@@ -0,0 +1,102 @@
1
+ export function languagesChangedEvent(languages, selectedLanguage) {
2
+ return new CustomEvent("languages-changed", {
3
+ bubbles: true,
4
+ composed: true,
5
+ detail: { languages, selectedLanguage },
6
+ });
7
+ }
8
+ /**
9
+ * @deprecated Use languagesChangedEvent instead. This event is kept for backward compatibility.
10
+ */
11
+ export function languageChangedEvent(language) {
12
+ return new CustomEvent("language-changed", {
13
+ bubbles: true,
14
+ composed: true,
15
+ detail: { language },
16
+ });
17
+ }
18
+ export function recordingDevicesChangedEvent(devices, selectedDevice) {
19
+ return new CustomEvent("recording-devices-changed", {
20
+ bubbles: true,
21
+ composed: true,
22
+ detail: { devices, selectedDevice },
23
+ });
24
+ }
25
+ export function recordingStateChangedEvent(state) {
26
+ return new CustomEvent("recording-state-changed", {
27
+ bubbles: true,
28
+ composed: true,
29
+ detail: { state },
30
+ });
31
+ }
32
+ export function transcriptEvent(detail) {
33
+ return new CustomEvent("transcript", {
34
+ bubbles: true,
35
+ composed: true,
36
+ detail,
37
+ });
38
+ }
39
+ export function commandEvent(detail) {
40
+ return new CustomEvent("command", {
41
+ bubbles: true,
42
+ composed: true,
43
+ detail,
44
+ });
45
+ }
46
+ export function usageEvent(detail) {
47
+ return new CustomEvent("usage", {
48
+ bubbles: true,
49
+ composed: true,
50
+ detail,
51
+ });
52
+ }
53
+ export function errorEvent(error) {
54
+ const message = error instanceof Error && error.message ? error.message : String(error);
55
+ return new CustomEvent("error", {
56
+ bubbles: false,
57
+ composed: true,
58
+ detail: { message },
59
+ });
60
+ }
61
+ export function streamClosedEvent(detail) {
62
+ return new CustomEvent("stream-closed", {
63
+ bubbles: true,
64
+ composed: true,
65
+ detail,
66
+ });
67
+ }
68
+ export function readyEvent() {
69
+ return new CustomEvent("ready", {
70
+ bubbles: true,
71
+ composed: true,
72
+ });
73
+ }
74
+ export function audioLevelChangedEvent(audioLevel) {
75
+ return new CustomEvent("audio-level-changed", {
76
+ bubbles: true,
77
+ composed: true,
78
+ detail: { audioLevel },
79
+ });
80
+ }
81
+ export function networkActivityEvent(direction, data) {
82
+ return new CustomEvent("network-activity", {
83
+ bubbles: true,
84
+ composed: true,
85
+ detail: { data, direction },
86
+ });
87
+ }
88
+ export function modeChangedEvent(mode) {
89
+ return new CustomEvent("mode-changed", {
90
+ bubbles: true,
91
+ composed: true,
92
+ detail: { mode },
93
+ });
94
+ }
95
+ export function keybindingChangedEvent(key, code) {
96
+ return new CustomEvent("keybinding-changed", {
97
+ bubbles: true,
98
+ composed: true,
99
+ detail: { code, key },
100
+ });
101
+ }
102
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/utils/events.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Corti } from \"@corti/sdk\";\nimport type { DictationMode, RecordingState } from \"../types.js\";\n\nexport type LanguagesChangedEventDetail = {\n languages: Corti.TranscribeSupportedLanguage[];\n selectedLanguage: string | undefined;\n};\n\nexport type LanguageChangedEventDetail = {\n language: string;\n};\n\nexport type RecordingDevicesChangedEventDetail = {\n devices: MediaDeviceInfo[];\n selectedDevice: MediaDeviceInfo | undefined;\n};\n\nexport type RecordingStateChangedEventDetail = {\n state: RecordingState;\n};\n\nexport type AudioLevelChangedEventDetail = {\n audioLevel: number;\n};\n\nexport type TranscriptEventDetail = Corti.TranscribeTranscriptMessage;\nexport type CommandEventDetail = Corti.TranscribeCommandMessage;\nexport type UsageEventDetail = Corti.TranscribeUsageMessage;\n\nexport type ErrorEventDetail = {\n message: string;\n};\n\nexport function languagesChangedEvent(\n languages: Corti.TranscribeSupportedLanguage[],\n selectedLanguage: string | undefined,\n): CustomEvent<LanguagesChangedEventDetail> {\n return new CustomEvent(\"languages-changed\", {\n bubbles: true,\n composed: true,\n detail: { languages, selectedLanguage },\n });\n}\n\n/**\n * @deprecated Use languagesChangedEvent instead. This event is kept for backward compatibility.\n */\nexport function languageChangedEvent(\n language: string,\n): CustomEvent<LanguageChangedEventDetail> {\n return new CustomEvent(\"language-changed\", {\n bubbles: true,\n composed: true,\n detail: { language },\n });\n}\n\nexport function recordingDevicesChangedEvent(\n devices: MediaDeviceInfo[],\n selectedDevice: MediaDeviceInfo | undefined,\n): CustomEvent<RecordingDevicesChangedEventDetail> {\n return new CustomEvent(\"recording-devices-changed\", {\n bubbles: true,\n composed: true,\n detail: { devices, selectedDevice },\n });\n}\n\nexport function recordingStateChangedEvent(\n state: RecordingState,\n): CustomEvent<RecordingStateChangedEventDetail> {\n return new CustomEvent(\"recording-state-changed\", {\n bubbles: true,\n composed: true,\n detail: { state },\n });\n}\n\nexport function transcriptEvent(\n detail: TranscriptEventDetail,\n): CustomEvent<TranscriptEventDetail> {\n return new CustomEvent(\"transcript\", {\n bubbles: true,\n composed: true,\n detail,\n });\n}\n\nexport function commandEvent(\n detail: CommandEventDetail,\n): CustomEvent<CommandEventDetail> {\n return new CustomEvent(\"command\", {\n bubbles: true,\n composed: true,\n detail,\n });\n}\n\nexport function usageEvent(\n detail: UsageEventDetail,\n): CustomEvent<UsageEventDetail> {\n return new CustomEvent(\"usage\", {\n bubbles: true,\n composed: true,\n detail,\n });\n}\n\nexport function errorEvent(error: unknown): CustomEvent<ErrorEventDetail> {\n const message =\n error instanceof Error && error.message ? error.message : String(error);\n\n return new CustomEvent(\"error\", {\n bubbles: false,\n composed: true,\n detail: { message },\n });\n}\n\nexport function streamClosedEvent(detail: unknown): CustomEvent {\n return new CustomEvent(\"stream-closed\", {\n bubbles: true,\n composed: true,\n detail,\n });\n}\n\nexport function readyEvent(): CustomEvent {\n return new CustomEvent(\"ready\", {\n bubbles: true,\n composed: true,\n });\n}\n\nexport function audioLevelChangedEvent(\n audioLevel: number,\n): CustomEvent<AudioLevelChangedEventDetail> {\n return new CustomEvent(\"audio-level-changed\", {\n bubbles: true,\n composed: true,\n detail: { audioLevel },\n });\n}\n\nexport type NetworkActivityEventDetail = {\n direction: \"sent\" | \"received\";\n data: unknown;\n};\n\nexport function networkActivityEvent(\n direction: \"sent\" | \"received\",\n data: unknown,\n): CustomEvent<NetworkActivityEventDetail> {\n return new CustomEvent(\"network-activity\", {\n bubbles: true,\n composed: true,\n detail: { data, direction },\n });\n}\n\nexport type ModeChangedEventDetail = {\n mode: DictationMode;\n};\n\nexport type KeybindingChangedEventDetail = {\n key: string | null | undefined;\n code: string | null | undefined;\n};\n\nexport function modeChangedEvent(\n mode: DictationMode,\n): CustomEvent<ModeChangedEventDetail> {\n return new CustomEvent(\"mode-changed\", {\n bubbles: true,\n composed: true,\n detail: { mode },\n });\n}\n\nexport function keybindingChangedEvent(\n key: string | null | undefined,\n code: string | null | undefined,\n): CustomEvent<KeybindingChangedEventDetail> {\n return new CustomEvent(\"keybinding-changed\", {\n bubbles: true,\n composed: true,\n detail: { code, key },\n });\n}\n"]}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Normalizes a keybinding string.
3
+ *
4
+ * @param keybinding - Keybinding string to normalize
5
+ * @returns Normalized keybinding string or null if empty
6
+ *
7
+ * @example
8
+ * normalizeKeybinding("k") // "k"
9
+ * normalizeKeybinding("meta") // "Cmd" on Mac
10
+ * normalizeKeybinding(" space ") // "Space"
11
+ */
12
+ export declare function normalizeKeybinding(keybinding: string | null | undefined): string | null;
13
+ /**
14
+ * Checks if a pressed key matches the keybinding.
15
+ * Checks both event.key and event.code for better reliability.
16
+ *
17
+ * @param event - KeyboardEvent to check
18
+ * @param keybinding - Keybinding string to match against
19
+ * @returns true if either the key or code matches the keybinding
20
+ *
21
+ * @example
22
+ * matchesKeybinding(event, "k") // true if event.key is "k" or event.code is "KeyK"
23
+ * matchesKeybinding(event, "`") // true if event.key is "`" or event.code is "Backquote"
24
+ */
25
+ export declare function matchesKeybinding(event: KeyboardEvent, keybinding: string | null | undefined): boolean;
26
+ /**
27
+ * Gets the pressed key from a KeyboardEvent.
28
+ * Treats modifier keys the same as any other key - they generate their own events.
29
+ * Keys longer than 1 character are capitalized (e.g., "Cmd", "Ctrl", "Space").
30
+ * Platform-specific: "Meta" -> "Cmd" on Mac, "Alt" -> "Opt" on Mac.
31
+ *
32
+ * @param event - KeyboardEvent to extract the pressed key from
33
+ * @returns Normalized key string in keybinding format (e.g., "Cmd", "Opt", "Ctrl", "k")
34
+ *
35
+ * @example
36
+ * getPressedKeyFromEvent(event) // "Cmd" when Meta key is pressed on Mac, "Opt" when Alt is pressed on Mac
37
+ */
38
+ export declare function getPressedKeyFromEvent(event: KeyboardEvent): string;
39
+ /**
40
+ * Checks if keybindings should be ignored for the current active element.
41
+ * Returns true if the user is typing in an input field.
42
+ *
43
+ * @param element - Element to check
44
+ * @returns true if keybindings should be ignored for this element
45
+ *
46
+ * @example
47
+ * shouldIgnoreKeybinding(document.activeElement) // true if input/textarea/contenteditable
48
+ */
49
+ export declare function shouldIgnoreKeybinding(element: Element | null): boolean;
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Checks if the current platform is macOS.
3
+ * Uses userAgent string for reliable cross-browser detection.
4
+ *
5
+ * @returns true if running on macOS
6
+ */
7
+ function isMac() {
8
+ if (typeof navigator === "undefined") {
9
+ return false;
10
+ }
11
+ // Check user agent for Mac patterns (most reliable method)
12
+ return /Mac|iPhone|iPad|iPod/.test(navigator.userAgent);
13
+ }
14
+ /**
15
+ * Capitalizes the first letter of a string.
16
+ *
17
+ * @param str - String to capitalize
18
+ * @returns String with first letter capitalized
19
+ */
20
+ function capitalize(str) {
21
+ if (str.length === 0) {
22
+ return str;
23
+ }
24
+ return str.charAt(0).toUpperCase() + str.slice(1);
25
+ }
26
+ /**
27
+ * Normalizes a key string to the keybinding format.
28
+ * Handles platform-specific mappings and capitalization.
29
+ *
30
+ * @param key - Key string to normalize (will be trimmed and lowercased)
31
+ * @returns Formatted key string for keybinding
32
+ *
33
+ * @example
34
+ * normalizeKeyForKeybinding("Control") // "Ctrl"
35
+ * normalizeKeyForKeybinding("META") // "Cmd" on Mac, "Meta" elsewhere
36
+ * normalizeKeyForKeybinding(" alt ") // "Opt" on Mac, "Alt" elsewhere
37
+ * normalizeKeyForKeybinding("shift") // "Shift"
38
+ * normalizeKeyForKeybinding("k") // "k"
39
+ */
40
+ function normalizeKeyForKeybinding(key) {
41
+ if (key === " ") {
42
+ return "Space";
43
+ }
44
+ const normalized = key.trim().toLowerCase();
45
+ if (normalized === "control") {
46
+ return "Ctrl";
47
+ }
48
+ if (normalized === "meta" || normalized === "cmd") {
49
+ return isMac() ? "Cmd" : "Meta";
50
+ }
51
+ if (normalized === "alt" || normalized === "opt") {
52
+ return isMac() ? "Opt" : "Alt";
53
+ }
54
+ if (normalized === "space") {
55
+ return "Space";
56
+ }
57
+ return normalized.length > 1 ? capitalize(normalized) : normalized;
58
+ }
59
+ /**
60
+ * Normalizes a keybinding string.
61
+ *
62
+ * @param keybinding - Keybinding string to normalize
63
+ * @returns Normalized keybinding string or null if empty
64
+ *
65
+ * @example
66
+ * normalizeKeybinding("k") // "k"
67
+ * normalizeKeybinding("meta") // "Cmd" on Mac
68
+ * normalizeKeybinding(" space ") // "Space"
69
+ */
70
+ export function normalizeKeybinding(keybinding) {
71
+ if (!keybinding) {
72
+ return null;
73
+ }
74
+ const trimmed = keybinding.trim();
75
+ if (trimmed === "") {
76
+ return null;
77
+ }
78
+ return normalizeKeyForKeybinding(trimmed);
79
+ }
80
+ /**
81
+ * Checks if a pressed key matches the keybinding.
82
+ * Checks both event.key and event.code for better reliability.
83
+ *
84
+ * @param event - KeyboardEvent to check
85
+ * @param keybinding - Keybinding string to match against
86
+ * @returns true if either the key or code matches the keybinding
87
+ *
88
+ * @example
89
+ * matchesKeybinding(event, "k") // true if event.key is "k" or event.code is "KeyK"
90
+ * matchesKeybinding(event, "`") // true if event.key is "`" or event.code is "Backquote"
91
+ */
92
+ export function matchesKeybinding(event, keybinding) {
93
+ const normalizedKeybinding = normalizeKeybinding(keybinding);
94
+ if (!normalizedKeybinding) {
95
+ return false;
96
+ }
97
+ const normalizedKey = normalizeKeyForKeybinding(event.key);
98
+ const normalizedCode = normalizeKeyForKeybinding(event.code);
99
+ return (normalizedKey === normalizedKeybinding ||
100
+ normalizedCode === normalizedKeybinding);
101
+ }
102
+ /**
103
+ * Gets the pressed key from a KeyboardEvent.
104
+ * Treats modifier keys the same as any other key - they generate their own events.
105
+ * Keys longer than 1 character are capitalized (e.g., "Cmd", "Ctrl", "Space").
106
+ * Platform-specific: "Meta" -> "Cmd" on Mac, "Alt" -> "Opt" on Mac.
107
+ *
108
+ * @param event - KeyboardEvent to extract the pressed key from
109
+ * @returns Normalized key string in keybinding format (e.g., "Cmd", "Opt", "Ctrl", "k")
110
+ *
111
+ * @example
112
+ * getPressedKeyFromEvent(event) // "Cmd" when Meta key is pressed on Mac, "Opt" when Alt is pressed on Mac
113
+ */
114
+ export function getPressedKeyFromEvent(event) {
115
+ return normalizeKeyForKeybinding(event.key);
116
+ }
117
+ /**
118
+ * Checks if keybindings should be ignored for the current active element.
119
+ * Returns true if the user is typing in an input field.
120
+ *
121
+ * @param element - Element to check
122
+ * @returns true if keybindings should be ignored for this element
123
+ *
124
+ * @example
125
+ * shouldIgnoreKeybinding(document.activeElement) // true if input/textarea/contenteditable
126
+ */
127
+ export function shouldIgnoreKeybinding(element) {
128
+ if (!element) {
129
+ return false;
130
+ }
131
+ const tagName = element.tagName.toLowerCase();
132
+ if (tagName === "input" || tagName === "textarea") {
133
+ return true;
134
+ }
135
+ if (element instanceof HTMLElement && element.contentEditable === "true") {
136
+ return true;
137
+ }
138
+ return false;
139
+ }
140
+ //# sourceMappingURL=keybinding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keybinding.js","sourceRoot":"","sources":["../../src/utils/keybinding.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Checks if the current platform is macOS.\n * Uses userAgent string for reliable cross-browser detection.\n *\n * @returns true if running on macOS\n */\nfunction isMac(): boolean {\n if (typeof navigator === \"undefined\") {\n return false;\n }\n\n // Check user agent for Mac patterns (most reliable method)\n return /Mac|iPhone|iPad|iPod/.test(navigator.userAgent);\n}\n\n/**\n * Capitalizes the first letter of a string.\n *\n * @param str - String to capitalize\n * @returns String with first letter capitalized\n */\nfunction capitalize(str: string): string {\n if (str.length === 0) {\n return str;\n }\n\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\n/**\n * Normalizes a key string to the keybinding format.\n * Handles platform-specific mappings and capitalization.\n *\n * @param key - Key string to normalize (will be trimmed and lowercased)\n * @returns Formatted key string for keybinding\n *\n * @example\n * normalizeKeyForKeybinding(\"Control\") // \"Ctrl\"\n * normalizeKeyForKeybinding(\"META\") // \"Cmd\" on Mac, \"Meta\" elsewhere\n * normalizeKeyForKeybinding(\" alt \") // \"Opt\" on Mac, \"Alt\" elsewhere\n * normalizeKeyForKeybinding(\"shift\") // \"Shift\"\n * normalizeKeyForKeybinding(\"k\") // \"k\"\n */\nfunction normalizeKeyForKeybinding(key: string): string {\n if (key === \" \") {\n return \"Space\";\n }\n\n const normalized = key.trim().toLowerCase();\n\n if (normalized === \"control\") {\n return \"Ctrl\";\n }\n if (normalized === \"meta\" || normalized === \"cmd\") {\n return isMac() ? \"Cmd\" : \"Meta\";\n }\n if (normalized === \"alt\" || normalized === \"opt\") {\n return isMac() ? \"Opt\" : \"Alt\";\n }\n if (normalized === \"space\") {\n return \"Space\";\n }\n\n return normalized.length > 1 ? capitalize(normalized) : normalized;\n}\n\n/**\n * Normalizes a keybinding string.\n *\n * @param keybinding - Keybinding string to normalize\n * @returns Normalized keybinding string or null if empty\n *\n * @example\n * normalizeKeybinding(\"k\") // \"k\"\n * normalizeKeybinding(\"meta\") // \"Cmd\" on Mac\n * normalizeKeybinding(\" space \") // \"Space\"\n */\nexport function normalizeKeybinding(\n keybinding: string | null | undefined,\n): string | null {\n if (!keybinding) {\n return null;\n }\n\n const trimmed = keybinding.trim();\n\n if (trimmed === \"\") {\n return null;\n }\n\n return normalizeKeyForKeybinding(trimmed);\n}\n\n/**\n * Checks if a pressed key matches the keybinding.\n * Checks both event.key and event.code for better reliability.\n *\n * @param event - KeyboardEvent to check\n * @param keybinding - Keybinding string to match against\n * @returns true if either the key or code matches the keybinding\n *\n * @example\n * matchesKeybinding(event, \"k\") // true if event.key is \"k\" or event.code is \"KeyK\"\n * matchesKeybinding(event, \"`\") // true if event.key is \"`\" or event.code is \"Backquote\"\n */\nexport function matchesKeybinding(\n event: KeyboardEvent,\n keybinding: string | null | undefined,\n): boolean {\n const normalizedKeybinding = normalizeKeybinding(keybinding);\n\n if (!normalizedKeybinding) {\n return false;\n }\n\n const normalizedKey = normalizeKeyForKeybinding(event.key);\n const normalizedCode = normalizeKeyForKeybinding(event.code);\n\n return (\n normalizedKey === normalizedKeybinding ||\n normalizedCode === normalizedKeybinding\n );\n}\n\n/**\n * Gets the pressed key from a KeyboardEvent.\n * Treats modifier keys the same as any other key - they generate their own events.\n * Keys longer than 1 character are capitalized (e.g., \"Cmd\", \"Ctrl\", \"Space\").\n * Platform-specific: \"Meta\" -> \"Cmd\" on Mac, \"Alt\" -> \"Opt\" on Mac.\n *\n * @param event - KeyboardEvent to extract the pressed key from\n * @returns Normalized key string in keybinding format (e.g., \"Cmd\", \"Opt\", \"Ctrl\", \"k\")\n *\n * @example\n * getPressedKeyFromEvent(event) // \"Cmd\" when Meta key is pressed on Mac, \"Opt\" when Alt is pressed on Mac\n */\nexport function getPressedKeyFromEvent(event: KeyboardEvent): string {\n return normalizeKeyForKeybinding(event.key);\n}\n\n/**\n * Checks if keybindings should be ignored for the current active element.\n * Returns true if the user is typing in an input field.\n *\n * @param element - Element to check\n * @returns true if keybindings should be ignored for this element\n *\n * @example\n * shouldIgnoreKeybinding(document.activeElement) // true if input/textarea/contenteditable\n */\nexport function shouldIgnoreKeybinding(element: Element | null): boolean {\n if (!element) {\n return false;\n }\n\n const tagName = element.tagName.toLowerCase();\n\n if (tagName === \"input\" || tagName === \"textarea\") {\n return true;\n }\n\n if (element instanceof HTMLElement && element.contentEditable === \"true\") {\n return true;\n }\n\n return false;\n}\n"]}
@@ -0,0 +1,8 @@
1
+ import type { Corti } from "@corti/sdk";
2
+ export declare const DEFAULT_LANGUAGES_BY_REGION: Record<string, Corti.TranscribeSupportedLanguage[]>;
3
+ export declare function getLanguageName(languageCode: string): string;
4
+ export declare function checkIfDefaultLanguagesList(languages?: Corti.TranscribeSupportedLanguage[]): boolean;
5
+ export declare function getLanguagesByRegion(region?: string): {
6
+ languages: Corti.TranscribeSupportedLanguage[];
7
+ defaultLanguage: string | undefined;
8
+ };
@@ -0,0 +1,29 @@
1
+ import { LANGUAGES_SUPPORTED_EU, LANGUAGES_SUPPORTED_US, } from "../constants.js";
2
+ export const DEFAULT_LANGUAGES_BY_REGION = {
3
+ default: LANGUAGES_SUPPORTED_EU,
4
+ eu: LANGUAGES_SUPPORTED_EU,
5
+ us: LANGUAGES_SUPPORTED_US,
6
+ };
7
+ export function getLanguageName(languageCode) {
8
+ try {
9
+ const userLocale = navigator.language || "en";
10
+ const displayNames = new Intl.DisplayNames([userLocale], {
11
+ type: "language",
12
+ });
13
+ const languageName = displayNames.of(languageCode);
14
+ return languageName || languageCode;
15
+ }
16
+ catch {
17
+ return languageCode;
18
+ }
19
+ }
20
+ export function checkIfDefaultLanguagesList(languages = []) {
21
+ return Object.values(DEFAULT_LANGUAGES_BY_REGION).some((languageList) => languageList === languages);
22
+ }
23
+ export function getLanguagesByRegion(region) {
24
+ const languages = DEFAULT_LANGUAGES_BY_REGION[region || "default"] ||
25
+ DEFAULT_LANGUAGES_BY_REGION["default"];
26
+ const defaultLanguage = languages?.[0];
27
+ return { defaultLanguage, languages };
28
+ }
29
+ //# sourceMappingURL=languages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"languages.js","sourceRoot":"","sources":["../../src/utils/languages.ts"],"names":[],"mappings":"AACA,OAAO,EACL,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,CAAC,MAAM,2BAA2B,GAGpC;IACF,OAAO,EAAE,sBAAsB;IAC/B,EAAE,EAAE,sBAAsB;IAC1B,EAAE,EAAE,sBAAsB;CAC3B,CAAC;AAEF,MAAM,UAAU,eAAe,CAAC,YAAoB;IAClD,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,SAAS,CAAC,QAAQ,IAAI,IAAI,CAAC;QAC9C,MAAM,YAAY,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,UAAU,CAAC,EAAE;YACvD,IAAI,EAAE,UAAU;SACjB,CAAC,CAAC;QACH,MAAM,YAAY,GAAG,YAAY,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;QAEnD,OAAO,YAAY,IAAI,YAAY,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,YAAY,CAAC;IACtB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,2BAA2B,CACzC,YAAiD,EAAE;IAEnD,OAAO,MAAM,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC,IAAI,CACpD,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,KAAK,SAAS,CAC7C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAe;IAIlD,MAAM,SAAS,GACb,2BAA2B,CAAC,MAAM,IAAI,SAAS,CAAC;QAChD,2BAA2B,CAAC,SAAS,CAAC,CAAC;IACzC,MAAM,eAAe,GAAG,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;IAEvC,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC;AACxC,CAAC","sourcesContent":["import type { Corti } from \"@corti/sdk\";\nimport {\n LANGUAGES_SUPPORTED_EU,\n LANGUAGES_SUPPORTED_US,\n} from \"../constants.js\";\n\nexport const DEFAULT_LANGUAGES_BY_REGION: Record<\n string,\n Corti.TranscribeSupportedLanguage[]\n> = {\n default: LANGUAGES_SUPPORTED_EU,\n eu: LANGUAGES_SUPPORTED_EU,\n us: LANGUAGES_SUPPORTED_US,\n};\n\nexport function getLanguageName(languageCode: string): string {\n try {\n const userLocale = navigator.language || \"en\";\n const displayNames = new Intl.DisplayNames([userLocale], {\n type: \"language\",\n });\n const languageName = displayNames.of(languageCode);\n\n return languageName || languageCode;\n } catch {\n return languageCode;\n }\n}\n\nexport function checkIfDefaultLanguagesList(\n languages: Corti.TranscribeSupportedLanguage[] = [],\n): boolean {\n return Object.values(DEFAULT_LANGUAGES_BY_REGION).some(\n (languageList) => languageList === languages,\n );\n}\n\nexport function getLanguagesByRegion(region?: string): {\n languages: Corti.TranscribeSupportedLanguage[];\n defaultLanguage: string | undefined;\n} {\n const languages =\n DEFAULT_LANGUAGES_BY_REGION[region || \"default\"] ||\n DEFAULT_LANGUAGES_BY_REGION[\"default\"];\n const defaultLanguage = languages?.[0];\n\n return { defaultLanguage, languages };\n}\n"]}
@@ -0,0 +1,6 @@
1
+ export declare function getMediaStream(deviceId?: string, debug_displayAudio?: boolean): Promise<MediaStream>;
2
+ export declare function createAudioAnalyzer(mediaStream: MediaStream): {
3
+ audioContext: AudioContext;
4
+ analyser: AnalyserNode;
5
+ };
6
+ export declare function calculateAudioLevel(analyser: AnalyserNode): number;
@@ -0,0 +1,39 @@
1
+ export async function getMediaStream(deviceId, debug_displayAudio) {
2
+ if (debug_displayAudio) {
3
+ const stream = await navigator.mediaDevices.getDisplayMedia({
4
+ audio: true,
5
+ video: true,
6
+ });
7
+ stream.getTracks().forEach((track) => {
8
+ if (track.kind === "video") {
9
+ stream.removeTrack(track);
10
+ }
11
+ });
12
+ return stream;
13
+ }
14
+ if (!deviceId) {
15
+ throw new Error("No device ID provided");
16
+ }
17
+ const constraints = deviceId !== "default"
18
+ ? { audio: { deviceId: { exact: deviceId } } }
19
+ : { audio: true };
20
+ return await navigator.mediaDevices.getUserMedia(constraints);
21
+ }
22
+ export function createAudioAnalyzer(mediaStream) {
23
+ const audioContext = new AudioContext();
24
+ const source = audioContext.createMediaStreamSource(mediaStream);
25
+ const analyser = audioContext.createAnalyser();
26
+ analyser.fftSize = 8192;
27
+ source.connect(analyser);
28
+ return { analyser, audioContext };
29
+ }
30
+ export function calculateAudioLevel(analyser) {
31
+ const dataArray = new Uint8Array(analyser.fftSize);
32
+ analyser.getByteTimeDomainData(dataArray);
33
+ const sumSquares = Array.from(dataArray).reduce((sum, value) => {
34
+ const normalized = (value - 128) / 128;
35
+ return sum + normalized * normalized;
36
+ }, 0);
37
+ return Math.sqrt(sumSquares / dataArray.length);
38
+ }
39
+ //# sourceMappingURL=media.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media.js","sourceRoot":"","sources":["../../src/utils/media.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,QAAiB,EACjB,kBAA4B;IAE5B,IAAI,kBAAkB,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,eAAe,CAAC;YAC1D,KAAK,EAAE,IAAI;YACX,KAAK,EAAE,IAAI;SACZ,CAAC,CAAC;QAEH,MAAM,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACnC,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBAC3B,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,WAAW,GACf,QAAQ,KAAK,SAAS;QACpB,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE;QAC9C,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAEtB,OAAO,MAAM,SAAS,CAAC,YAAY,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,WAAwB;IAI1D,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC;IACxC,MAAM,MAAM,GAAG,YAAY,CAAC,uBAAuB,CAAC,WAAW,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,YAAY,CAAC,cAAc,EAAE,CAAC;IAE/C,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC;IAExB,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEzB,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,QAAsB;IACxD,MAAM,SAAS,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACnD,QAAQ,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAE1C,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;QAC7D,MAAM,UAAU,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;QACvC,OAAO,GAAG,GAAG,UAAU,GAAG,UAAU,CAAC;IACvC,CAAC,EAAE,CAAC,CAAC,CAAC;IAEN,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AAClD,CAAC","sourcesContent":["export async function getMediaStream(\n deviceId?: string,\n debug_displayAudio?: boolean,\n): Promise<MediaStream> {\n if (debug_displayAudio) {\n const stream = await navigator.mediaDevices.getDisplayMedia({\n audio: true,\n video: true,\n });\n\n stream.getTracks().forEach((track) => {\n if (track.kind === \"video\") {\n stream.removeTrack(track);\n }\n });\n\n return stream;\n }\n\n if (!deviceId) {\n throw new Error(\"No device ID provided\");\n }\n\n const constraints: MediaStreamConstraints =\n deviceId !== \"default\"\n ? { audio: { deviceId: { exact: deviceId } } }\n : { audio: true };\n\n return await navigator.mediaDevices.getUserMedia(constraints);\n}\n\nexport function createAudioAnalyzer(mediaStream: MediaStream): {\n audioContext: AudioContext;\n analyser: AnalyserNode;\n} {\n const audioContext = new AudioContext();\n const source = audioContext.createMediaStreamSource(mediaStream);\n const analyser = audioContext.createAnalyser();\n\n analyser.fftSize = 8192;\n\n source.connect(analyser);\n\n return { analyser, audioContext };\n}\n\nexport function calculateAudioLevel(analyser: AnalyserNode): number {\n const dataArray = new Uint8Array(analyser.fftSize);\n analyser.getByteTimeDomainData(dataArray);\n\n const sumSquares = Array.from(dataArray).reduce((sum, value) => {\n const normalized = (value - 128) / 128;\n return sum + normalized * normalized;\n }, 0);\n\n return Math.sqrt(sumSquares / dataArray.length);\n}\n"]}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Decodes a JWT token and extracts environment and tenant information.
3
+ *
4
+ * @param token - The JWT token to decode
5
+ * @returns Object containing environment, tenant, accessToken, and expiresAt
6
+ * @throws Error if token format is invalid or cannot be decoded
7
+ */
8
+ export declare function decodeToken(token: string): {
9
+ accessToken: string;
10
+ environment: string;
11
+ expiresAt: number | undefined;
12
+ tenant: string;
13
+ };