@dxos/plugin-transcription 0.8.4-main.fd6878d → 0.9.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.
Files changed (367) hide show
  1. package/LICENSE +102 -5
  2. package/PLUGIN.mdl +401 -0
  3. package/README.md +1 -1
  4. package/dist/lib/neutral/TranscriptionArticle-L6XANBH5.mjs +54 -0
  5. package/dist/lib/neutral/TranscriptionArticle-L6XANBH5.mjs.map +7 -0
  6. package/dist/lib/neutral/TranscriptionPlugin.mjs +46 -0
  7. package/dist/lib/neutral/TranscriptionPlugin.mjs.map +7 -0
  8. package/dist/lib/neutral/TranscriptionPlugin.node.mjs +25 -0
  9. package/dist/lib/neutral/TranscriptionPlugin.node.mjs.map +7 -0
  10. package/dist/lib/neutral/TranscriptionPlugin.workerd.mjs +21 -0
  11. package/dist/lib/neutral/TranscriptionPlugin.workerd.mjs.map +7 -0
  12. package/dist/lib/neutral/blueprint-definition-DA4QFRYJ.mjs +15 -0
  13. package/dist/lib/neutral/blueprint-definition-DA4QFRYJ.mjs.map +7 -0
  14. package/dist/lib/neutral/blueprints/index.mjs +8 -0
  15. package/dist/lib/neutral/capabilities/index.mjs +17 -0
  16. package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
  17. package/dist/lib/neutral/chunk-FHNI26QW.mjs +45 -0
  18. package/dist/lib/neutral/chunk-FHNI26QW.mjs.map +7 -0
  19. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
  20. package/dist/lib/neutral/chunk-KAEXRX3Y.mjs +35 -0
  21. package/dist/lib/neutral/chunk-KAEXRX3Y.mjs.map +7 -0
  22. package/dist/lib/neutral/chunk-KMT3BMMQ.mjs +124 -0
  23. package/dist/lib/neutral/chunk-KMT3BMMQ.mjs.map +7 -0
  24. package/dist/lib/neutral/chunk-KXJZEYS7.mjs +8 -0
  25. package/dist/lib/neutral/chunk-KXJZEYS7.mjs.map +7 -0
  26. package/dist/lib/neutral/chunk-MLRJWAQH.mjs +179 -0
  27. package/dist/lib/neutral/chunk-MLRJWAQH.mjs.map +7 -0
  28. package/dist/lib/neutral/chunk-TO77KAQK.mjs +298 -0
  29. package/dist/lib/neutral/chunk-TO77KAQK.mjs.map +7 -0
  30. package/dist/lib/{browser/chunk-KJIQQHJB.mjs → neutral/chunk-TX3NQISZ.mjs} +115 -186
  31. package/dist/lib/neutral/chunk-TX3NQISZ.mjs.map +7 -0
  32. package/dist/lib/neutral/chunk-ZR4BH4QQ.mjs +30 -0
  33. package/dist/lib/neutral/chunk-ZR4BH4QQ.mjs.map +7 -0
  34. package/dist/lib/neutral/components/index.mjs +269 -0
  35. package/dist/lib/neutral/components/index.mjs.map +7 -0
  36. package/dist/lib/neutral/containers/index.mjs +9 -0
  37. package/dist/lib/neutral/containers/index.mjs.map +7 -0
  38. package/dist/lib/neutral/create-RVR7VC33.mjs +21 -0
  39. package/dist/lib/neutral/create-RVR7VC33.mjs.map +7 -0
  40. package/dist/lib/neutral/hooks/index.mjs +19 -0
  41. package/dist/lib/neutral/index.mjs +44 -0
  42. package/dist/lib/neutral/meta.json +1 -0
  43. package/dist/lib/neutral/meta.mjs +8 -0
  44. package/dist/lib/neutral/meta.mjs.map +7 -0
  45. package/dist/lib/neutral/open-A5KXKRH4.mjs +27 -0
  46. package/dist/lib/neutral/open-A5KXKRH4.mjs.map +7 -0
  47. package/dist/lib/neutral/operation-handler-NXMOAXFP.mjs +13 -0
  48. package/dist/lib/neutral/operation-handler-NXMOAXFP.mjs.map +7 -0
  49. package/dist/lib/neutral/operations/index.mjs +8 -0
  50. package/dist/lib/neutral/operations/index.mjs.map +7 -0
  51. package/dist/lib/neutral/plugin.mjs +16 -0
  52. package/dist/lib/neutral/plugin.mjs.map +7 -0
  53. package/dist/lib/neutral/react-surface-YMZRO242.mjs +26 -0
  54. package/dist/lib/neutral/react-surface-YMZRO242.mjs.map +7 -0
  55. package/dist/lib/neutral/summarize-5XPPMVTE.mjs +77 -0
  56. package/dist/lib/neutral/summarize-5XPPMVTE.mjs.map +7 -0
  57. package/dist/lib/neutral/text-content-KBB37HSM.mjs +30 -0
  58. package/dist/lib/neutral/text-content-KBB37HSM.mjs.map +7 -0
  59. package/dist/lib/neutral/transcriber-OGSF3XO5.mjs +59 -0
  60. package/dist/lib/neutral/transcriber-OGSF3XO5.mjs.map +7 -0
  61. package/dist/lib/neutral/translations.mjs +24 -0
  62. package/dist/lib/neutral/translations.mjs.map +7 -0
  63. package/dist/lib/neutral/types/index.mjs +10 -0
  64. package/dist/lib/neutral/types/index.mjs.map +7 -0
  65. package/dist/types/src/TranscriptionPlugin.d.ts +3 -1
  66. package/dist/types/src/TranscriptionPlugin.d.ts.map +1 -1
  67. package/dist/types/src/TranscriptionPlugin.node.d.ts +4 -0
  68. package/dist/types/src/TranscriptionPlugin.node.d.ts.map +1 -0
  69. package/dist/types/src/TranscriptionPlugin.test.d.ts +2 -0
  70. package/dist/types/src/TranscriptionPlugin.test.d.ts.map +1 -0
  71. package/dist/types/src/TranscriptionPlugin.workerd.d.ts +4 -0
  72. package/dist/types/src/TranscriptionPlugin.workerd.d.ts.map +1 -0
  73. package/dist/types/src/blueprints/index.d.ts +2 -0
  74. package/dist/types/src/blueprints/index.d.ts.map +1 -0
  75. package/dist/types/src/blueprints/transcription-blueprint.d.ts +4 -0
  76. package/dist/types/src/blueprints/transcription-blueprint.d.ts.map +1 -0
  77. package/dist/types/src/capabilities/blueprint-definition.d.ts +6 -0
  78. package/dist/types/src/capabilities/blueprint-definition.d.ts.map +1 -0
  79. package/dist/types/src/capabilities/index.d.ts +11 -4
  80. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  81. package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
  82. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
  83. package/dist/types/src/capabilities/react-surface.d.ts +3 -2
  84. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  85. package/dist/types/src/capabilities/text-content.d.ts +8 -0
  86. package/dist/types/src/capabilities/text-content.d.ts.map +1 -0
  87. package/dist/types/src/capabilities/transcriber.d.ts +4 -3
  88. package/dist/types/src/capabilities/transcriber.d.ts.map +1 -1
  89. package/dist/types/src/components/Oracle/Oracle.d.ts +24 -0
  90. package/dist/types/src/components/Oracle/Oracle.d.ts.map +1 -0
  91. package/dist/types/src/components/Oracle/Oracle.stories.d.ts +32 -0
  92. package/dist/types/src/components/Oracle/Oracle.stories.d.ts.map +1 -0
  93. package/dist/types/src/components/Oracle/index.d.ts +2 -0
  94. package/dist/types/src/components/Oracle/index.d.ts.map +1 -0
  95. package/dist/types/src/components/Transcription/Transcription.d.ts +11 -0
  96. package/dist/types/src/components/Transcription/Transcription.d.ts.map +1 -0
  97. package/dist/types/src/components/Transcription/Transcription.stories.d.ts +37 -0
  98. package/dist/types/src/components/Transcription/Transcription.stories.d.ts.map +1 -0
  99. package/dist/types/src/components/Transcription/index.d.ts +2 -0
  100. package/dist/types/src/components/Transcription/index.d.ts.map +1 -0
  101. package/dist/types/src/components/Transcription/transcription-extension.d.ts +15 -0
  102. package/dist/types/src/components/Transcription/transcription-extension.d.ts.map +1 -0
  103. package/dist/types/src/components/index.d.ts +2 -3
  104. package/dist/types/src/components/index.d.ts.map +1 -1
  105. package/dist/types/src/containers/TranscriptionArticle/TranscriptionArticle.d.ts +6 -0
  106. package/dist/types/src/containers/TranscriptionArticle/TranscriptionArticle.d.ts.map +1 -0
  107. package/dist/types/src/containers/TranscriptionArticle/TranscriptionArticle.stories.d.ts +28 -0
  108. package/dist/types/src/containers/TranscriptionArticle/TranscriptionArticle.stories.d.ts.map +1 -0
  109. package/dist/types/src/containers/TranscriptionArticle/index.d.ts +2 -0
  110. package/dist/types/src/containers/TranscriptionArticle/index.d.ts.map +1 -0
  111. package/dist/types/src/containers/index.d.ts +3 -0
  112. package/dist/types/src/containers/index.d.ts.map +1 -0
  113. package/dist/types/src/enrichment/conversation.test.d.ts +2 -0
  114. package/dist/types/src/enrichment/conversation.test.d.ts.map +1 -0
  115. package/dist/types/src/enrichment/operations.d.ts +200 -0
  116. package/dist/types/src/enrichment/operations.d.ts.map +1 -0
  117. package/dist/types/src/enrichment/parser.d.ts +26 -0
  118. package/dist/types/src/enrichment/parser.d.ts.map +1 -0
  119. package/dist/types/src/enrichment/stream-simulator.d.ts +38 -0
  120. package/dist/types/src/enrichment/stream-simulator.d.ts.map +1 -0
  121. package/dist/types/src/hooks/index.d.ts +2 -1
  122. package/dist/types/src/hooks/index.d.ts.map +1 -1
  123. package/dist/types/src/hooks/useAudioFile.d.ts.map +1 -1
  124. package/dist/types/src/hooks/useAudioTrack.d.ts.map +1 -1
  125. package/dist/types/src/hooks/useFeedModelAdapter.d.ts +12 -0
  126. package/dist/types/src/hooks/useFeedModelAdapter.d.ts.map +1 -0
  127. package/dist/types/src/hooks/useTranscriber.d.ts +2 -2
  128. package/dist/types/src/hooks/useTranscriber.d.ts.map +1 -1
  129. package/dist/types/src/hooks/useTranscriptionRecording.d.ts +12 -0
  130. package/dist/types/src/hooks/useTranscriptionRecording.d.ts.map +1 -0
  131. package/dist/types/src/hooks/useVoiceInput.d.ts.map +1 -1
  132. package/dist/types/src/index.d.ts +2 -3
  133. package/dist/types/src/index.d.ts.map +1 -1
  134. package/dist/types/src/meta.d.ts +2 -3
  135. package/dist/types/src/meta.d.ts.map +1 -1
  136. package/dist/types/src/model/model.d.ts +2 -2
  137. package/dist/types/src/model/model.d.ts.map +1 -1
  138. package/dist/types/src/{segments-normalization → normalization}/index.d.ts +1 -1
  139. package/dist/types/src/normalization/index.d.ts.map +1 -0
  140. package/dist/types/src/{segments-normalization → normalization}/message-normalizer.d.ts +9 -7
  141. package/dist/types/src/normalization/message-normalizer.d.ts.map +1 -0
  142. package/dist/types/src/normalization/normalization.d.ts +834 -0
  143. package/dist/types/src/normalization/normalization.d.ts.map +1 -0
  144. package/dist/types/src/normalization/normalization.test.d.ts.map +1 -0
  145. package/dist/types/src/normalization/utils.d.ts +3 -0
  146. package/dist/types/src/normalization/utils.d.ts.map +1 -0
  147. package/dist/types/src/operations/create.d.ts +5 -0
  148. package/dist/types/src/operations/create.d.ts.map +1 -0
  149. package/dist/types/src/operations/index.d.ts +3 -0
  150. package/dist/types/src/operations/index.d.ts.map +1 -0
  151. package/dist/types/src/operations/open.d.ts +5 -0
  152. package/dist/types/src/operations/open.d.ts.map +1 -0
  153. package/dist/types/src/operations/summarize.d.ts +8 -0
  154. package/dist/types/src/operations/summarize.d.ts.map +1 -0
  155. package/dist/types/src/plugin.d.ts +4 -0
  156. package/dist/types/src/plugin.d.ts.map +1 -0
  157. package/dist/types/src/stories/FileTranscription.stories.d.ts +20 -0
  158. package/dist/types/src/stories/FileTranscription.stories.d.ts.map +1 -0
  159. package/dist/types/src/stories/KeyWordRecognition.stories.d.ts +14 -0
  160. package/dist/types/src/stories/KeyWordRecognition.stories.d.ts.map +1 -0
  161. package/dist/types/src/stories/LiveTranscription.stories.d.ts +20 -0
  162. package/dist/types/src/stories/LiveTranscription.stories.d.ts.map +1 -0
  163. package/dist/types/src/stories/TranscriptionStory.d.ts +21 -0
  164. package/dist/types/src/stories/TranscriptionStory.d.ts.map +1 -0
  165. package/dist/types/src/stories/common.d.ts +248 -0
  166. package/dist/types/src/stories/common.d.ts.map +1 -0
  167. package/dist/types/src/testing/testing.d.ts +14 -15
  168. package/dist/types/src/testing/testing.d.ts.map +1 -1
  169. package/dist/types/src/transcriber/index.d.ts +1 -1
  170. package/dist/types/src/transcriber/index.d.ts.map +1 -1
  171. package/dist/types/src/transcriber/media-stream-recorder.d.ts +2 -2
  172. package/dist/types/src/transcriber/media-stream-recorder.d.ts.map +1 -1
  173. package/dist/types/src/transcriber/transcriber.d.ts +61 -6
  174. package/dist/types/src/transcriber/transcriber.d.ts.map +1 -1
  175. package/dist/types/src/transcriber/transcriber.test.d.ts +2 -0
  176. package/dist/types/src/transcriber/transcriber.test.d.ts.map +1 -0
  177. package/dist/types/src/transcriber/transcription-manager.d.ts +17 -16
  178. package/dist/types/src/transcriber/transcription-manager.d.ts.map +1 -1
  179. package/dist/types/src/translations.d.ts +9 -8
  180. package/dist/types/src/translations.d.ts.map +1 -1
  181. package/dist/types/src/types/TranscriptOperation.d.ts +1670 -0
  182. package/dist/types/src/types/TranscriptOperation.d.ts.map +1 -0
  183. package/dist/types/src/types/TranscriptionCapabilities.d.ts +17 -0
  184. package/dist/types/src/types/TranscriptionCapabilities.d.ts.map +1 -0
  185. package/dist/types/src/types/index.d.ts +2 -2
  186. package/dist/types/src/types/index.d.ts.map +1 -1
  187. package/dist/types/src/util/array.d.ts.map +1 -1
  188. package/dist/types/src/util/get-time-str.d.ts.map +1 -1
  189. package/dist/types/src/util/index.d.ts +1 -0
  190. package/dist/types/src/util/index.d.ts.map +1 -1
  191. package/dist/types/src/util/monitor-audio-level.d.ts.map +1 -1
  192. package/dist/types/src/util/render-byline.d.ts +4 -0
  193. package/dist/types/src/util/render-byline.d.ts.map +1 -0
  194. package/dist/types/tsconfig.tsbuildinfo +1 -1
  195. package/package.json +153 -85
  196. package/src/TranscriptionPlugin.node.ts +20 -0
  197. package/src/TranscriptionPlugin.test.ts +31 -0
  198. package/src/TranscriptionPlugin.tsx +28 -61
  199. package/src/TranscriptionPlugin.workerd.ts +18 -0
  200. package/src/blueprints/index.ts +5 -0
  201. package/src/blueprints/transcription-blueprint.ts +29 -0
  202. package/src/capabilities/blueprint-definition.ts +19 -0
  203. package/src/capabilities/index.ts +16 -6
  204. package/src/capabilities/operation-handler.ts +16 -0
  205. package/src/capabilities/react-surface.tsx +23 -14
  206. package/src/capabilities/text-content.ts +33 -0
  207. package/src/capabilities/transcriber.ts +54 -41
  208. package/src/components/Oracle/Oracle.stories.tsx +147 -0
  209. package/src/components/Oracle/Oracle.tsx +142 -0
  210. package/src/components/Oracle/index.ts +5 -0
  211. package/src/components/Transcription/Transcription.stories.tsx +213 -0
  212. package/src/components/Transcription/Transcription.tsx +55 -0
  213. package/src/components/{Transcript → Transcription}/index.ts +1 -1
  214. package/src/components/{Transcript/transcript-extension.ts → Transcription/transcription-extension.ts} +13 -46
  215. package/src/components/index.ts +2 -6
  216. package/src/containers/TranscriptionArticle/TranscriptionArticle.stories.tsx +61 -0
  217. package/src/containers/TranscriptionArticle/TranscriptionArticle.tsx +62 -0
  218. package/src/containers/TranscriptionArticle/index.ts +5 -0
  219. package/src/containers/index.ts +7 -0
  220. package/src/enrichment/conversation.test.ts +162 -0
  221. package/src/enrichment/conversation.txt +23 -0
  222. package/src/enrichment/operations.ts +271 -0
  223. package/src/enrichment/parser.ts +101 -0
  224. package/src/enrichment/stream-simulator.ts +125 -0
  225. package/src/hooks/index.ts +2 -1
  226. package/src/hooks/useAudioFile.ts +49 -53
  227. package/src/hooks/useAudioTrack.ts +1 -1
  228. package/src/hooks/useFeedModelAdapter.ts +46 -0
  229. package/src/hooks/useTranscriber.ts +15 -7
  230. package/src/hooks/useTranscriptionRecording.ts +87 -0
  231. package/src/hooks/useVoiceInput.ts +3 -4
  232. package/src/index.ts +4 -5
  233. package/src/meta.ts +32 -7
  234. package/src/model/model.test.ts +22 -16
  235. package/src/model/model.ts +3 -3
  236. package/src/{segments-normalization → normalization}/message-normalizer.ts +37 -24
  237. package/src/{segments-normalization → normalization}/normalization.test.ts +9 -48
  238. package/src/normalization/normalization.ts +76 -0
  239. package/src/{segments-normalization → normalization}/utils.ts +2 -2
  240. package/src/operations/create.ts +24 -0
  241. package/src/operations/index.ts +11 -0
  242. package/src/operations/open.ts +28 -0
  243. package/src/operations/summarize.ts +102 -0
  244. package/src/plugin.ts +11 -0
  245. package/src/stories/FileTranscription.stories.tsx +143 -0
  246. package/src/{components/stories → stories}/KeyWordRecognition.stories.tsx +50 -46
  247. package/src/stories/LiveTranscription.stories.tsx +153 -0
  248. package/src/stories/TranscriptionStory.tsx +101 -0
  249. package/src/stories/common.ts +233 -0
  250. package/src/testing/testing.ts +53 -65
  251. package/src/transcriber/index.ts +1 -1
  252. package/src/transcriber/media-stream-recorder.ts +3 -3
  253. package/src/transcriber/transcriber.browser.test.ts +4 -5
  254. package/src/transcriber/transcriber.test.ts +104 -0
  255. package/src/transcriber/transcriber.ts +105 -60
  256. package/src/transcriber/transcription-manager.ts +49 -59
  257. package/src/translations.ts +10 -7
  258. package/src/types/TranscriptOperation.ts +106 -0
  259. package/src/types/TranscriptionCapabilities.ts +39 -0
  260. package/src/types/index.ts +2 -2
  261. package/src/util/index.ts +1 -0
  262. package/src/util/render-byline.ts +33 -0
  263. package/src/vite-env.d.ts +10 -0
  264. package/dist/lib/browser/TranscriptContainer-FH7VAWYA.mjs +0 -11
  265. package/dist/lib/browser/chunk-5WH45KBY.mjs +0 -19
  266. package/dist/lib/browser/chunk-5WH45KBY.mjs.map +0 -7
  267. package/dist/lib/browser/chunk-BJWYA2BU.mjs +0 -782
  268. package/dist/lib/browser/chunk-BJWYA2BU.mjs.map +0 -7
  269. package/dist/lib/browser/chunk-KJIQQHJB.mjs.map +0 -7
  270. package/dist/lib/browser/chunk-KWOOVS5G.mjs +0 -55
  271. package/dist/lib/browser/chunk-KWOOVS5G.mjs.map +0 -7
  272. package/dist/lib/browser/chunk-SREIAQSP.mjs +0 -16
  273. package/dist/lib/browser/chunk-SREIAQSP.mjs.map +0 -7
  274. package/dist/lib/browser/chunk-UKUSJTQW.mjs +0 -8
  275. package/dist/lib/browser/chunk-UKUSJTQW.mjs.map +0 -7
  276. package/dist/lib/browser/index.mjs +0 -125
  277. package/dist/lib/browser/index.mjs.map +0 -7
  278. package/dist/lib/browser/intent-resolver-AOVQ7JI4.mjs +0 -30
  279. package/dist/lib/browser/intent-resolver-AOVQ7JI4.mjs.map +0 -7
  280. package/dist/lib/browser/meta.json +0 -1
  281. package/dist/lib/browser/react-surface-4MEJMKYQ.mjs +0 -34
  282. package/dist/lib/browser/react-surface-4MEJMKYQ.mjs.map +0 -7
  283. package/dist/lib/browser/transcriber-V77CN7XX.mjs +0 -56
  284. package/dist/lib/browser/transcriber-V77CN7XX.mjs.map +0 -7
  285. package/dist/lib/browser/types/index.mjs +0 -14
  286. package/dist/lib/node-esm/TranscriptContainer-GEUOOYHX.mjs +0 -12
  287. package/dist/lib/node-esm/chunk-A33GNR44.mjs +0 -507
  288. package/dist/lib/node-esm/chunk-A33GNR44.mjs.map +0 -7
  289. package/dist/lib/node-esm/chunk-IKQMDRY6.mjs +0 -56
  290. package/dist/lib/node-esm/chunk-IKQMDRY6.mjs.map +0 -7
  291. package/dist/lib/node-esm/chunk-PHP7MCAY.mjs +0 -10
  292. package/dist/lib/node-esm/chunk-PHP7MCAY.mjs.map +0 -7
  293. package/dist/lib/node-esm/chunk-TM2ASOZA.mjs +0 -17
  294. package/dist/lib/node-esm/chunk-TM2ASOZA.mjs.map +0 -7
  295. package/dist/lib/node-esm/chunk-XMUCZBP3.mjs +0 -21
  296. package/dist/lib/node-esm/chunk-XMUCZBP3.mjs.map +0 -7
  297. package/dist/lib/node-esm/chunk-Y7PCJ34K.mjs +0 -783
  298. package/dist/lib/node-esm/chunk-Y7PCJ34K.mjs.map +0 -7
  299. package/dist/lib/node-esm/index.mjs +0 -126
  300. package/dist/lib/node-esm/index.mjs.map +0 -7
  301. package/dist/lib/node-esm/intent-resolver-P4XPIKQF.mjs +0 -31
  302. package/dist/lib/node-esm/intent-resolver-P4XPIKQF.mjs.map +0 -7
  303. package/dist/lib/node-esm/meta.json +0 -1
  304. package/dist/lib/node-esm/react-surface-EZUPNHUC.mjs +0 -35
  305. package/dist/lib/node-esm/react-surface-EZUPNHUC.mjs.map +0 -7
  306. package/dist/lib/node-esm/transcriber-3SX3DNLV.mjs +0 -57
  307. package/dist/lib/node-esm/transcriber-3SX3DNLV.mjs.map +0 -7
  308. package/dist/lib/node-esm/types/index.mjs +0 -15
  309. package/dist/types/src/capabilities/capabilities.d.ts +0 -17
  310. package/dist/types/src/capabilities/capabilities.d.ts.map +0 -1
  311. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  312. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  313. package/dist/types/src/components/Transcript/Transcript.d.ts +0 -20
  314. package/dist/types/src/components/Transcript/Transcript.d.ts.map +0 -1
  315. package/dist/types/src/components/Transcript/Transcript.stories.d.ts +0 -24
  316. package/dist/types/src/components/Transcript/Transcript.stories.d.ts.map +0 -1
  317. package/dist/types/src/components/Transcript/deprecated/OldTranscript.d.ts +0 -28
  318. package/dist/types/src/components/Transcript/deprecated/OldTranscript.d.ts.map +0 -1
  319. package/dist/types/src/components/Transcript/index.d.ts +0 -2
  320. package/dist/types/src/components/Transcript/index.d.ts.map +0 -1
  321. package/dist/types/src/components/Transcript/transcript-extension.d.ts +0 -19
  322. package/dist/types/src/components/Transcript/transcript-extension.d.ts.map +0 -1
  323. package/dist/types/src/components/TranscriptContainer.d.ts +0 -9
  324. package/dist/types/src/components/TranscriptContainer.d.ts.map +0 -1
  325. package/dist/types/src/components/stories/FileTranscription.stories.d.ts +0 -17
  326. package/dist/types/src/components/stories/FileTranscription.stories.d.ts.map +0 -1
  327. package/dist/types/src/components/stories/KeyWordRecognition.stories.d.ts +0 -10
  328. package/dist/types/src/components/stories/KeyWordRecognition.stories.d.ts.map +0 -1
  329. package/dist/types/src/components/stories/MicrophoneTranscription.stories.d.ts +0 -19
  330. package/dist/types/src/components/stories/MicrophoneTranscription.stories.d.ts.map +0 -1
  331. package/dist/types/src/components/stories/TranscriptionStory.d.ts +0 -11
  332. package/dist/types/src/components/stories/TranscriptionStory.d.ts.map +0 -1
  333. package/dist/types/src/components/stories/useIsSpeaking.d.ts +0 -3
  334. package/dist/types/src/components/stories/useIsSpeaking.d.ts.map +0 -1
  335. package/dist/types/src/hooks/useQueueModelAdapter.d.ts +0 -8
  336. package/dist/types/src/hooks/useQueueModelAdapter.d.ts.map +0 -1
  337. package/dist/types/src/segments-normalization/index.d.ts.map +0 -1
  338. package/dist/types/src/segments-normalization/message-normalizer.d.ts.map +0 -1
  339. package/dist/types/src/segments-normalization/normalization.d.ts +0 -422
  340. package/dist/types/src/segments-normalization/normalization.d.ts.map +0 -1
  341. package/dist/types/src/segments-normalization/normalization.test.d.ts.map +0 -1
  342. package/dist/types/src/segments-normalization/utils.d.ts +0 -3
  343. package/dist/types/src/segments-normalization/utils.d.ts.map +0 -1
  344. package/dist/types/src/types/schema.d.ts +0 -41
  345. package/dist/types/src/types/schema.d.ts.map +0 -1
  346. package/dist/types/src/types/types.d.ts +0 -31
  347. package/dist/types/src/types/types.d.ts.map +0 -1
  348. package/src/capabilities/capabilities.ts +0 -33
  349. package/src/capabilities/intent-resolver.ts +0 -24
  350. package/src/components/Transcript/Transcript.stories.tsx +0 -243
  351. package/src/components/Transcript/Transcript.tsx +0 -101
  352. package/src/components/Transcript/deprecated/OldTranscript.tsx +0 -260
  353. package/src/components/TranscriptContainer.tsx +0 -36
  354. package/src/components/stories/FileTranscription.stories.tsx +0 -246
  355. package/src/components/stories/MicrophoneTranscription.stories.tsx +0 -283
  356. package/src/components/stories/TranscriptionStory.tsx +0 -41
  357. package/src/components/stories/useIsSpeaking.tsx +0 -40
  358. package/src/hooks/useQueueModelAdapter.ts +0 -66
  359. package/src/segments-normalization/normalization.ts +0 -115
  360. package/src/types/schema.ts +0 -41
  361. package/src/types/types.ts +0 -33
  362. package/dist/lib/{browser/types → neutral/blueprints}/index.mjs.map +0 -0
  363. package/dist/lib/{browser/TranscriptContainer-FH7VAWYA.mjs.map → neutral/chunk-J5LGTIGS.mjs.map} +0 -0
  364. package/dist/lib/{node-esm/types → neutral/hooks}/index.mjs.map +0 -0
  365. package/dist/lib/{node-esm/TranscriptContainer-GEUOOYHX.mjs.map → neutral/index.mjs.map} +0 -0
  366. package/dist/types/src/{segments-normalization → normalization}/normalization.test.d.ts +0 -0
  367. package/src/{segments-normalization → normalization}/index.ts +1 -1
@@ -2,12 +2,14 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { type PluginContext, contributes } from '@dxos/app-framework';
5
+ import * as Effect from 'effect/Effect';
6
+
7
+ import { Capabilities, Capability } from '@dxos/app-framework';
6
8
  import { ClientCapabilities } from '@dxos/plugin-client';
7
9
 
8
- import { MediaStreamRecorder, Transcriber, TranscriptionManager } from '../transcriber';
10
+ import { TranscriptionCapabilities } from '#types';
9
11
 
10
- import { TranscriptionCapabilities } from './capabilities';
12
+ import { MediaStreamRecorder, Transcriber, TranscriptionManager } from '../transcriber';
11
13
 
12
14
  // TODO(burdon): Move to config?
13
15
 
@@ -30,48 +32,59 @@ const TRANSCRIBE_AFTER_CHUNKS_AMOUNT = 50;
30
32
  /**
31
33
  * Records audio while user is speaking and transcribes it after user is done speaking.
32
34
  */
33
- export default (context: PluginContext) => {
34
- const getTranscriber: TranscriptionCapabilities.GetTranscriber = ({
35
- audioStreamTrack,
36
- onSegments,
37
- transcriberConfig,
38
- recorderConfig,
39
- }) => {
40
- // Initialize audio transcription.
41
- return new Transcriber({
42
- config: {
43
- transcribeAfterChunksAmount: TRANSCRIBE_AFTER_CHUNKS_AMOUNT,
44
- prefixBufferChunksAmount: PREFIXED_CHUNKS_AMOUNT,
45
- ...transcriberConfig,
46
- },
47
- recorder: new MediaStreamRecorder({
48
- mediaStreamTrack: audioStreamTrack,
35
+ export default Capability.makeModule(
36
+ Effect.fnUntraced(function* () {
37
+ // Get context for lazy capability access in callbacks.
38
+ const capabilities = yield* Capability.Service;
39
+ const registry = yield* Capability.get(Capabilities.AtomRegistry);
40
+
41
+ const transcriberProvider: TranscriptionCapabilities.TranscriberProvider = ({
42
+ audioStreamTrack,
43
+ onSegments,
44
+ transcriberConfig,
45
+ recorderConfig,
46
+ transcribe,
47
+ }) => {
48
+ // Initialize audio transcription.
49
+ return new Transcriber({
49
50
  config: {
50
- interval: RECORD_INTERVAL,
51
- ...recorderConfig,
51
+ transcribeAfterChunksAmount: TRANSCRIBE_AFTER_CHUNKS_AMOUNT,
52
+ prefixBufferChunksAmount: PREFIXED_CHUNKS_AMOUNT,
53
+ ...transcriberConfig,
52
54
  },
53
- }),
54
- onSegments,
55
- });
56
- };
55
+ recorder: new MediaStreamRecorder({
56
+ mediaStreamTrack: audioStreamTrack,
57
+ config: {
58
+ interval: RECORD_INTERVAL,
59
+ ...recorderConfig,
60
+ },
61
+ }),
62
+ onSegments,
63
+ transcribe,
64
+ });
65
+ };
57
66
 
58
- const getTranscriptionManager: TranscriptionCapabilities.GetTranscriptionManager = ({ messageEnricher }) => {
59
- const client = context.getCapability(ClientCapabilities.Client);
60
- const transcriptionManager = new TranscriptionManager({
61
- edgeClient: client.edge,
67
+ const transcriptionManagerProvider: TranscriptionCapabilities.TranscriptionManagerProvider = ({
62
68
  messageEnricher,
63
- });
69
+ }) => {
70
+ const client = capabilities.get(ClientCapabilities.Client);
71
+ const transcriptionManager = new TranscriptionManager({
72
+ edgeClient: client.edge.http,
73
+ messageEnricher,
74
+ registry,
75
+ });
64
76
 
65
- const identity = client.halo.identity.get();
66
- if (identity) {
67
- transcriptionManager.setIdentityDid(identity.did);
68
- }
77
+ const identity = client.halo.identity.get();
78
+ if (identity) {
79
+ transcriptionManager.setIdentityDid(identity.did);
80
+ }
69
81
 
70
- return transcriptionManager;
71
- };
82
+ return transcriptionManager;
83
+ };
72
84
 
73
- return [
74
- contributes(TranscriptionCapabilities.Transcriber, getTranscriber),
75
- contributes(TranscriptionCapabilities.TranscriptionManager, getTranscriptionManager),
76
- ];
77
- };
85
+ return [
86
+ Capability.contributes(TranscriptionCapabilities.TranscriberProvider, transcriberProvider),
87
+ Capability.contributes(TranscriptionCapabilities.TranscriptionManagerProvider, transcriptionManagerProvider),
88
+ ];
89
+ }),
90
+ );
@@ -0,0 +1,147 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import * as Effect from 'effect/Effect';
7
+ import React, { useCallback, useEffect, useState } from 'react';
8
+
9
+ import { withPluginManager } from '@dxos/app-framework/testing';
10
+ import { ClientPlugin, initializeIdentity } from '@dxos/plugin-client/testing';
11
+ import { corePlugins } from '@dxos/plugin-testing';
12
+ import { IconButton, Panel, Toolbar } from '@dxos/react-ui';
13
+ import { withLayout } from '@dxos/react-ui/testing';
14
+ import { type ContentBlock, type Message } from '@dxos/types';
15
+
16
+ import { useAudioTrack, useTranscriber } from '#hooks';
17
+ import { translations } from '#translations';
18
+
19
+ import { TranscriptionPlugin } from '../../TranscriptionPlugin';
20
+ import { Oracle } from './Oracle';
21
+
22
+ type DefaultStoryProps = {
23
+ delay?: number;
24
+ };
25
+
26
+ const DefaultStory = ({ delay }: DefaultStoryProps) => {
27
+ const [recording, setRecording] = useState(false);
28
+ const [text, setText] = useState('');
29
+ const elapsed = useStopwatch(recording);
30
+ const track = useAudioTrack(recording);
31
+
32
+ // Build the latest transcribed text from incoming blocks.
33
+ const handleSegments = useCallback(async (blocks: Message.Message['blocks']) => {
34
+ const phrase = blocks
35
+ .filter((block): block is ContentBlock.Transcript => block._tag === 'transcript')
36
+ .map((block) => block.text.trim())
37
+ .filter(Boolean)
38
+ .join(' ');
39
+
40
+ setText((prev) => (prev ? `${prev} ${phrase}` : phrase));
41
+ }, []);
42
+
43
+ // Drive the transcriber off the recording flag.
44
+ // Default `transcribeAfterChunksAmount` is 50 × 200ms = 10s, so the first phrase only
45
+ // surfaces after ~10s. Drop it to 15 chunks (~3s) so the TextBlock starts updating fast.
46
+ const transcriber = useTranscriber({
47
+ audioStreamTrack: track,
48
+ onSegments: handleSegments,
49
+ transcriberConfig: { transcribeAfterChunksAmount: 15, prefixBufferChunksAmount: 5 },
50
+ });
51
+ useEffect(() => {
52
+ if (!transcriber) {
53
+ return;
54
+ }
55
+
56
+ let cancelled = false;
57
+ void transcriber.open().then(() => {
58
+ if (!cancelled && recording) {
59
+ transcriber.startChunksRecording();
60
+ }
61
+ });
62
+
63
+ return () => {
64
+ cancelled = true;
65
+ transcriber.stopChunksRecording();
66
+ };
67
+ }, [transcriber, recording]);
68
+
69
+ return (
70
+ <Panel.Root>
71
+ <Panel.Toolbar asChild>
72
+ <Toolbar.Root>
73
+ <IconButton
74
+ icon={recording ? 'ph--stop-circle--regular' : 'ph--microphone--regular'}
75
+ label={recording ? 'Stop' : 'Record'}
76
+ onClick={() => setRecording((value) => !value)}
77
+ />
78
+ <IconButton disabled={recording} icon='ph--x--regular' label='Clear' onClick={() => setText('')} />
79
+ <Toolbar.Separator />
80
+ <Toolbar.Text classNames='text-right tabular-nums text-subdued'>{elapsed}s</Toolbar.Text>
81
+ </Toolbar.Root>
82
+ </Panel.Toolbar>
83
+ <Oracle.Root text={text} delay={delay}>
84
+ <Panel.Content asChild>
85
+ <Oracle.Content>
86
+ <Oracle.Canvas />
87
+ <Oracle.Text />
88
+ </Oracle.Content>
89
+ </Panel.Content>
90
+ </Oracle.Root>
91
+ </Panel.Root>
92
+ );
93
+ };
94
+
95
+ const meta = {
96
+ title: 'plugins/plugin-transcription/components/Oracle',
97
+ render: DefaultStory,
98
+ decorators: [
99
+ withLayout({ layout: 'fullscreen' }),
100
+ withPluginManager({
101
+ plugins: [
102
+ ...corePlugins(),
103
+ ClientPlugin({
104
+ onClientInitialized: ({ client }) =>
105
+ Effect.gen(function* () {
106
+ yield* initializeIdentity(client);
107
+ }),
108
+ }),
109
+ TranscriptionPlugin(),
110
+ ],
111
+ }),
112
+ ],
113
+ parameters: {
114
+ layout: 'fullscreen',
115
+ translations,
116
+ },
117
+ } satisfies Meta<typeof DefaultStory>;
118
+
119
+ export default meta;
120
+
121
+ type Story = StoryObj<typeof meta>;
122
+
123
+ export const Default: Story = {
124
+ args: {
125
+ delay: 12,
126
+ },
127
+ };
128
+
129
+ export const Instant: Story = {
130
+ args: {
131
+ delay: 0,
132
+ },
133
+ };
134
+
135
+ /** Seconds elapsed while `running`; resets to 0 each time `running` toggles back to true. */
136
+ const useStopwatch = (running: boolean): number => {
137
+ const [seconds, setSeconds] = useState(0);
138
+ useEffect(() => {
139
+ if (!running) {
140
+ return;
141
+ }
142
+ setSeconds(0);
143
+ const id = setInterval(() => setSeconds((value) => value + 1), 1_000);
144
+ return () => clearInterval(id);
145
+ }, [running]);
146
+ return seconds;
147
+ };
@@ -0,0 +1,142 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { Primitive } from '@radix-ui/react-primitive';
6
+ import { Slot } from '@radix-ui/react-slot';
7
+ import React, { type PropsWithChildren, createContext, useContext, useMemo } from 'react';
8
+
9
+ import '@dxos/react-ui-graph/styles/graph.css';
10
+ import { type ThemedClassName } from '@dxos/react-ui';
11
+ import { composableProps, slottable } from '@dxos/react-ui';
12
+ import { TextBlock } from '@dxos/react-ui-components';
13
+ import { SVG } from '@dxos/react-ui-graph';
14
+ import { mx } from '@dxos/ui-theme';
15
+ import { type SlottableProps } from '@dxos/ui-types';
16
+
17
+ //
18
+ // Context
19
+ //
20
+
21
+ type OracleContextValue = {
22
+ /** Latest utterance / phrase rendered by `Oracle.Text`. */
23
+ text: string;
24
+ /** Per-character reveal delay in ms for the streaming TextBlock. */
25
+ delay: number;
26
+ };
27
+
28
+ const OracleContext = createContext<OracleContextValue | null>(null);
29
+
30
+ const useOracleContext = (consumer: string): OracleContextValue => {
31
+ const ctx = useContext(OracleContext);
32
+ if (!ctx) {
33
+ throw new Error(`<Oracle.${consumer}> must be rendered inside <Oracle.Root>`);
34
+ }
35
+ return ctx;
36
+ };
37
+
38
+ //
39
+ // Root (headless — provides context only, renders no DOM)
40
+ //
41
+
42
+ export type OracleRootProps = PropsWithChildren<{
43
+ /** Latest utterance / phrase rendered by `Oracle.Text`. */
44
+ text?: string;
45
+ /** Per-character reveal delay in ms for the streaming TextBlock. @default 12 */
46
+ delay?: number;
47
+ }>;
48
+
49
+ /**
50
+ * Oracle surface root. Headless — provides text/delay context to subcomponents and renders
51
+ * no DOM of its own. Wrap subcomponents in `<Oracle.Content>` for the standard relative
52
+ * stacking layout, or place `<Oracle.Canvas>` / `<Oracle.Text>` inside any positioned
53
+ * container of your choice.
54
+ */
55
+ const Root = ({ children, text = '', delay = 12 }: OracleRootProps) => {
56
+ const value = useMemo(() => ({ text, delay }), [text, delay]);
57
+ return <OracleContext.Provider value={value}>{children}</OracleContext.Provider>;
58
+ };
59
+
60
+ //
61
+ // Content
62
+ //
63
+
64
+ export type OracleContentProps = SlottableProps;
65
+
66
+ /**
67
+ * Positioned container that stacks `Oracle.Canvas` (the SVG graph viewport, absolutely
68
+ * positioned to fill) under `Oracle.Text` (the centered overlay). Use this for the standard
69
+ * Oracle layout; skip it if you need custom positioning.
70
+ *
71
+ * Pass `asChild` to merge the positioning + sizing onto a parent slot (e.g. `Panel.Content`).
72
+ */
73
+ const Content = slottable<HTMLDivElement>(({ children, asChild, ...props }, forwardedRef) => {
74
+ const Comp = asChild ? Slot : Primitive.div;
75
+ return (
76
+ <Comp {...composableProps(props, { classNames: 'relative dx-expander' })} ref={forwardedRef}>
77
+ {children}
78
+ </Comp>
79
+ );
80
+ });
81
+
82
+ Content.displayName = 'Oracle.Content';
83
+
84
+ //
85
+ // Canvas
86
+ //
87
+
88
+ export type OracleCanvasProps = ThemedClassName<PropsWithChildren<{}>>;
89
+
90
+ /**
91
+ * SVG graph viewport. Renders sensible defaults (markers, grid, pan/zoom, empty graph)
92
+ * when no children are supplied; consumers can replace those by passing their own
93
+ * SVG.* children (e.g. a populated `<SVG.Graph model={…} />`).
94
+ */
95
+ const Canvas = ({ classNames, children }: OracleCanvasProps) => (
96
+ <SVG.Root centered classNames={mx('absolute inset-0', classNames)}>
97
+ {children ?? (
98
+ <>
99
+ <SVG.Markers />
100
+ <SVG.Grid />
101
+ <SVG.Zoom extent={[1 / 4, 4]}>
102
+ <SVG.Graph />
103
+ </SVG.Zoom>
104
+ </>
105
+ )}
106
+ </SVG.Root>
107
+ );
108
+
109
+ //
110
+ // Text
111
+ //
112
+
113
+ export type OracleTextProps = ThemedClassName<{}>;
114
+
115
+ /**
116
+ * Centered text overlay. Reads `text` and `delay` from `Oracle.Root` context and renders
117
+ * a streaming `TextBlock` floating above the canvas. Pointer-events are disabled so the
118
+ * underlying graph remains interactive.
119
+ */
120
+ const Text = ({ classNames }: OracleTextProps) => {
121
+ const { text, delay } = useOracleContext('Text');
122
+ return (
123
+ <div className='pointer-events-none absolute inset-0 flex items-center justify-center'>
124
+ <TextBlock
125
+ classNames={mx('max-w-xl px-6 py-4 text-center text-2xl font-medium text-balance text-subdued', classNames)}
126
+ text={text}
127
+ delay={delay}
128
+ />
129
+ </div>
130
+ );
131
+ };
132
+
133
+ //
134
+ // Namespace
135
+ //
136
+
137
+ export const Oracle = {
138
+ Root,
139
+ Content,
140
+ Canvas,
141
+ Text,
142
+ };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ export * from './Oracle';
@@ -0,0 +1,213 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import * as Effect from 'effect/Effect';
7
+ import type * as Types from 'effect/Types';
8
+ import React, { useCallback, useEffect, useMemo, useState } from 'react';
9
+
10
+ import { withPluginManager } from '@dxos/app-framework/testing';
11
+ import { Feed, Filter, Obj, Query } from '@dxos/echo';
12
+ import { ClientPlugin, initializeIdentity } from '@dxos/plugin-client/testing';
13
+ import { PreviewPlugin } from '@dxos/plugin-preview/testing';
14
+ import { StorybookPlugin, corePlugins } from '@dxos/plugin-testing';
15
+ import { random } from '@dxos/random';
16
+ import { useMembers, useQuery, useSpaces } from '@dxos/react-client/echo';
17
+ import { IconButton, Panel, Toolbar } from '@dxos/react-ui';
18
+ import { JsonHighlighter } from '@dxos/react-ui-syntax-highlighter';
19
+ import { withLayout } from '@dxos/react-ui/testing';
20
+ import { type ContentBlock, Message, Organization, Person } from '@dxos/types';
21
+
22
+ import { useFeedModelAdapter } from '#hooks';
23
+ import { MessageBuilder, TestItem, useTestTranscriptionQueue } from '#testing';
24
+ import { translations } from '#translations';
25
+
26
+ import { SerializationModel } from '../../model';
27
+ import { renderByline } from '../../util';
28
+ import { Transcription, type TranscriptionProps } from './Transcription';
29
+
30
+ random.seed(1);
31
+
32
+ type Source = 'local' | 'feed';
33
+
34
+ type DefaultStoryProps = {
35
+ /** Where transcript messages come from. */
36
+ source?: Source;
37
+ /** Number of synthetic messages to pre-populate (local source only). */
38
+ seed?: number;
39
+ };
40
+
41
+ const DefaultStory = ({ source = 'local', seed = 0, ...props }: DefaultStoryProps) => {
42
+ const [resetKey, setResetKey] = useState(0);
43
+ const handleReset = useCallback(() => setResetKey((value) => value + 1), []);
44
+ return source === 'feed' ? (
45
+ <FeedStory key={resetKey} onReset={handleReset} {...props} />
46
+ ) : (
47
+ <LocalStory key={resetKey} seed={seed} onReset={handleReset} {...props} />
48
+ );
49
+ };
50
+
51
+ type InnerProps = {
52
+ onReset: () => void;
53
+ };
54
+
55
+ const LocalStory = ({ seed = 0, onReset, ...props }: InnerProps & { seed?: number }) => {
56
+ const builder = useMemo(() => new MessageBuilder(), []);
57
+ const [initialMessages, setInitialMessages] = useState<Message.Message[]>([]);
58
+ const [ready, setReady] = useState(seed === 0);
59
+
60
+ useEffect(() => {
61
+ // Reset on every seed change so Storybook controls don't leave stale messages from a prior run.
62
+ let cancelled = false;
63
+ setInitialMessages([]);
64
+ setReady(seed === 0);
65
+
66
+ if (seed === 0) {
67
+ return () => {
68
+ cancelled = true;
69
+ };
70
+ }
71
+
72
+ void Promise.all(Array.from({ length: seed }, () => builder.createMessage())).then((messages) => {
73
+ if (cancelled) {
74
+ return;
75
+ }
76
+ setInitialMessages(messages);
77
+ setReady(true);
78
+ });
79
+
80
+ return () => {
81
+ cancelled = true;
82
+ };
83
+ }, [seed, builder]);
84
+
85
+ const model = useMemo(
86
+ () => new SerializationModel<Message.Message>(renderByline([]), initialMessages),
87
+ [initialMessages],
88
+ );
89
+
90
+ const [running, setRunning] = useState(true);
91
+ const [currentMessage, setCurrentMessage] = useState<Types.Mutable<Message.Message> | null>(null);
92
+
93
+ useEffect(() => {
94
+ if (!ready || !running) {
95
+ return;
96
+ }
97
+
98
+ if (!currentMessage) {
99
+ void builder.createMessage().then((message) => {
100
+ model.appendChunk(message);
101
+ setCurrentMessage(message);
102
+ });
103
+ return;
104
+ }
105
+
106
+ const id = setInterval(() => {
107
+ if (currentMessage.blocks.length >= 3) {
108
+ setCurrentMessage(null);
109
+ clearInterval(id);
110
+ return;
111
+ }
112
+ Obj.update(currentMessage, (currentMessage) => {
113
+ (currentMessage.blocks as ContentBlock.Any[]).push(builder.createBlock());
114
+ });
115
+ model.updateChunk(currentMessage);
116
+ }, 3_000);
117
+
118
+ return () => clearInterval(id);
119
+ }, [ready, running, currentMessage, model, builder]);
120
+
121
+ return <Shell model={model} running={running} onRunningChange={setRunning} onReset={onReset} {...props} />;
122
+ };
123
+
124
+ const FeedStory = ({ onReset, ...props }: InnerProps) => {
125
+ const [running, setRunning] = useState(true);
126
+ const [space] = useSpaces();
127
+ const members = useMembers(space?.id).map((member) => member.identity);
128
+ const feed = useTestTranscriptionQueue(space, running, 2_000);
129
+ const messages = useQuery(
130
+ space?.db,
131
+ feed ? Query.select(Filter.type(Message.Message)).from(feed) : Query.select(Filter.nothing()),
132
+ );
133
+ const model = useFeedModelAdapter(renderByline(members), messages, []);
134
+
135
+ return <Shell model={model} running={running} onRunningChange={setRunning} onReset={onReset} {...props} />;
136
+ };
137
+
138
+ type ShellProps = TranscriptionProps & {
139
+ running: boolean;
140
+ onRunningChange: (running: boolean) => void;
141
+ onReset: () => void;
142
+ };
143
+
144
+ const Shell = ({ model, running, onRunningChange, onReset, ...props }: ShellProps) => (
145
+ <Panel.Root>
146
+ <Panel.Toolbar asChild>
147
+ <Toolbar.Root classNames='justify-end'>
148
+ <IconButton
149
+ icon={running ? 'ph--pause--regular' : 'ph--play--regular'}
150
+ label={running ? 'Pause' : 'Start'}
151
+ onClick={() => onRunningChange(!running)}
152
+ />
153
+ <IconButton icon='ph--x--regular' label='Reset' onClick={onReset} />
154
+ </Toolbar.Root>
155
+ </Panel.Toolbar>
156
+ <Panel.Content className='dx-document'>
157
+ <Transcription model={model} {...props} />
158
+ </Panel.Content>
159
+ <Panel.Statusbar className='flex items-center justify-center'>
160
+ <JsonHighlighter data={model.toJSON()} indent={0} classNames='text-sm' />
161
+ </Panel.Statusbar>
162
+ </Panel.Root>
163
+ );
164
+
165
+ const meta = {
166
+ title: 'plugins/plugin-transcription/components/Transcription',
167
+ render: DefaultStory,
168
+ decorators: [
169
+ withLayout({ layout: 'fullscreen' }),
170
+ withPluginManager({
171
+ plugins: [
172
+ ...corePlugins(),
173
+ StorybookPlugin({}),
174
+ ClientPlugin({
175
+ types: [TestItem, Person.Person, Organization.Organization, Feed.Feed, Message.Message],
176
+ onClientInitialized: ({ client }) =>
177
+ Effect.gen(function* () {
178
+ yield* initializeIdentity(client);
179
+ }),
180
+ }),
181
+ PreviewPlugin(),
182
+ ],
183
+ }),
184
+ ],
185
+ parameters: {
186
+ layout: 'fullscreen',
187
+ translations,
188
+ },
189
+ } satisfies Meta<typeof DefaultStory>;
190
+
191
+ export default meta;
192
+
193
+ type Story = StoryObj<typeof meta>;
194
+
195
+ export const Default: Story = {
196
+ args: {
197
+ source: 'local',
198
+ seed: 10,
199
+ },
200
+ };
201
+
202
+ export const Empty: Story = {
203
+ args: {
204
+ source: 'local',
205
+ seed: 0,
206
+ },
207
+ };
208
+
209
+ export const WithQueue: Story = {
210
+ args: {
211
+ source: 'feed',
212
+ },
213
+ };
@@ -0,0 +1,55 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import React from 'react';
6
+
7
+ import { useThemeContext } from '@dxos/react-ui';
8
+ import { composable, composableProps } from '@dxos/react-ui';
9
+ import { useTextEditor } from '@dxos/react-ui-editor';
10
+ import { type Message, type Transcript } from '@dxos/types';
11
+ import {
12
+ createBasicExtensions,
13
+ createMarkdownExtensions,
14
+ createThemeExtensions,
15
+ decorateMarkdown,
16
+ documentSlots,
17
+ preview,
18
+ scroller,
19
+ } from '@dxos/ui-editor';
20
+
21
+ import { type SerializationModel } from '../../model';
22
+ import { transcription } from './transcription-extension';
23
+
24
+ export type TranscriptionProps = {
25
+ transcript?: Transcript.Transcript;
26
+ model: SerializationModel<Message.Message>;
27
+ };
28
+
29
+ // TODO(burdon): Remove forwardedRef/use react-ui-editor.
30
+ export const Transcription = composable<HTMLDivElement, TranscriptionProps>(
31
+ ({ transcript: object, model, children, ...props }, forwardedRef) => {
32
+ const { themeMode } = useThemeContext();
33
+ const { parentRef } = useTextEditor(() => {
34
+ return {
35
+ extensions: [
36
+ createBasicExtensions({ readOnly: true, lineWrapping: true, search: true }),
37
+ createThemeExtensions({ themeMode, slots: documentSlots }),
38
+ createMarkdownExtensions(),
39
+ decorateMarkdown(),
40
+ preview(),
41
+ transcription({ model, started: object?.started ? new Date(object.started) : undefined }),
42
+ scroller(),
43
+ ],
44
+ };
45
+ }, [model, themeMode]);
46
+
47
+ return (
48
+ <div
49
+ {...composableProps(props, { classNames: 'dx-container' })}
50
+ data-popover-collision-boundary={true}
51
+ ref={parentRef}
52
+ />
53
+ );
54
+ },
55
+ );
@@ -2,4 +2,4 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- export * from './Transcript';
5
+ export * from './Transcription';