@dxos/plugin-transcription 0.8.4-main.69d29f4 → 0.8.4-main.6fa680abb7

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 (161) hide show
  1. package/dist/lib/browser/TranscriptionContainer-5MFETUHZ.mjs +40 -0
  2. package/dist/lib/browser/TranscriptionContainer-5MFETUHZ.mjs.map +7 -0
  3. package/dist/lib/browser/blueprint-definition-ICUHRZXS.mjs +18 -0
  4. package/dist/lib/browser/blueprint-definition-ICUHRZXS.mjs.map +7 -0
  5. package/dist/lib/browser/blueprints/index.mjs +3 -3
  6. package/dist/lib/browser/{chunk-Q5OC3WVG.mjs → chunk-7D57BEI2.mjs} +8 -26
  7. package/dist/lib/browser/chunk-7D57BEI2.mjs.map +7 -0
  8. package/dist/lib/browser/{chunk-ZZF7ICVM.mjs → chunk-DCPLHPHH.mjs} +24 -26
  9. package/dist/lib/browser/chunk-DCPLHPHH.mjs.map +7 -0
  10. package/dist/lib/browser/chunk-KYI5GIQM.mjs +22 -0
  11. package/dist/lib/browser/chunk-KYI5GIQM.mjs.map +7 -0
  12. package/dist/lib/browser/{chunk-TKFU53OZ.mjs → chunk-QWIUIEWX.mjs} +2 -2
  13. package/dist/lib/browser/{chunk-ICM7JRCO.mjs → chunk-SLZXQVQU.mjs} +361 -391
  14. package/dist/lib/browser/chunk-SLZXQVQU.mjs.map +7 -0
  15. package/dist/lib/browser/index.mjs +24 -27
  16. package/dist/lib/browser/index.mjs.map +3 -3
  17. package/dist/lib/browser/meta.json +1 -1
  18. package/dist/lib/browser/{operation-resolver-ZUWTU7C5.mjs → operation-resolver-PFR5PQTK.mjs} +5 -4
  19. package/dist/lib/browser/operation-resolver-PFR5PQTK.mjs.map +7 -0
  20. package/dist/lib/browser/react-surface-MISGR3BD.mjs +37 -0
  21. package/dist/lib/browser/react-surface-MISGR3BD.mjs.map +7 -0
  22. package/dist/lib/browser/{transcriber-EZZTUCPE.mjs → transcriber-GKFU347S.mjs} +7 -6
  23. package/dist/lib/browser/transcriber-GKFU347S.mjs.map +7 -0
  24. package/dist/lib/browser/types/index.mjs +2 -1
  25. package/dist/lib/node-esm/TranscriptionContainer-3ZP67PX6.mjs +41 -0
  26. package/dist/lib/node-esm/TranscriptionContainer-3ZP67PX6.mjs.map +7 -0
  27. package/dist/lib/node-esm/{blueprint-definition-IOX35YUX.mjs → blueprint-definition-KYLTO7UH.mjs} +6 -6
  28. package/dist/lib/node-esm/blueprint-definition-KYLTO7UH.mjs.map +7 -0
  29. package/dist/lib/node-esm/blueprints/index.mjs +3 -3
  30. package/dist/lib/node-esm/chunk-5XJY5QP5.mjs +24 -0
  31. package/dist/lib/node-esm/chunk-5XJY5QP5.mjs.map +7 -0
  32. package/dist/lib/node-esm/{chunk-4BFY6P2D.mjs → chunk-6BWAFL5Z.mjs} +8 -26
  33. package/dist/lib/node-esm/chunk-6BWAFL5Z.mjs.map +7 -0
  34. package/dist/lib/node-esm/{chunk-EPC27WWV.mjs → chunk-LSWGXNVP.mjs} +2 -2
  35. package/dist/lib/node-esm/{chunk-CWP22IHV.mjs → chunk-TRS6GDYW.mjs} +24 -26
  36. package/dist/lib/node-esm/chunk-TRS6GDYW.mjs.map +7 -0
  37. package/dist/lib/node-esm/{chunk-BX2AB7S7.mjs → chunk-WVSA6JHE.mjs} +361 -391
  38. package/dist/lib/node-esm/chunk-WVSA6JHE.mjs.map +7 -0
  39. package/dist/lib/node-esm/index.mjs +24 -27
  40. package/dist/lib/node-esm/index.mjs.map +3 -3
  41. package/dist/lib/node-esm/meta.json +1 -1
  42. package/dist/lib/node-esm/{operation-resolver-Z72B4H2Q.mjs → operation-resolver-IZ7BRISJ.mjs} +5 -4
  43. package/dist/lib/node-esm/operation-resolver-IZ7BRISJ.mjs.map +7 -0
  44. package/dist/lib/node-esm/react-surface-BCAKAGCT.mjs +38 -0
  45. package/dist/lib/node-esm/react-surface-BCAKAGCT.mjs.map +7 -0
  46. package/dist/lib/node-esm/{transcriber-RGW3YYT4.mjs → transcriber-7BSCYWMV.mjs} +7 -6
  47. package/dist/lib/node-esm/transcriber-7BSCYWMV.mjs.map +7 -0
  48. package/dist/lib/node-esm/types/index.mjs +2 -1
  49. package/dist/types/src/TranscriptionPlugin.d.ts.map +1 -1
  50. package/dist/types/src/blueprints/index.d.ts +1 -1
  51. package/dist/types/src/blueprints/index.d.ts.map +1 -1
  52. package/dist/types/src/blueprints/transcription-blueprint.d.ts +3 -20
  53. package/dist/types/src/blueprints/transcription-blueprint.d.ts.map +1 -1
  54. package/dist/types/src/capabilities/blueprint-definition/blueprint-definition.d.ts +3 -6
  55. package/dist/types/src/capabilities/blueprint-definition/blueprint-definition.d.ts.map +1 -1
  56. package/dist/types/src/capabilities/blueprint-definition/index.d.ts +1 -1
  57. package/dist/types/src/capabilities/blueprint-definition/index.d.ts.map +1 -1
  58. package/dist/types/src/capabilities/operation-handler/index.d.ts +1 -1
  59. package/dist/types/src/capabilities/operation-handler/index.d.ts.map +1 -1
  60. package/dist/types/src/capabilities/operation-handler/operation-handler.d.ts +2 -2
  61. package/dist/types/src/capabilities/operation-handler/operation-handler.d.ts.map +1 -1
  62. package/dist/types/src/capabilities/operation-resolver/index.d.ts +1 -1
  63. package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +1 -1
  64. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +2 -2
  65. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +1 -1
  66. package/dist/types/src/capabilities/react-surface/index.d.ts +1 -1
  67. package/dist/types/src/capabilities/react-surface/index.d.ts.map +1 -1
  68. package/dist/types/src/capabilities/react-surface/react-surface.d.ts +2 -2
  69. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +1 -1
  70. package/dist/types/src/capabilities/transcriber/transcriber.d.ts +1 -1
  71. package/dist/types/src/capabilities/transcriber/transcriber.d.ts.map +1 -1
  72. package/dist/types/src/components/{Transcript/Transcript.d.ts → Transcription/Transcription.d.ts} +3 -3
  73. package/dist/types/src/components/Transcription/Transcription.d.ts.map +1 -0
  74. package/dist/types/src/components/{Transcript/Transcript.stories.d.ts → Transcription/Transcription.stories.d.ts} +3 -3
  75. package/dist/types/src/components/Transcription/Transcription.stories.d.ts.map +1 -0
  76. package/dist/types/src/components/Transcription/index.d.ts +2 -0
  77. package/dist/types/src/components/Transcription/index.d.ts.map +1 -0
  78. package/dist/types/src/components/{Transcript/transcript-extension.d.ts → Transcription/transcription-extension.d.ts} +3 -3
  79. package/dist/types/src/components/Transcription/transcription-extension.d.ts.map +1 -0
  80. package/dist/types/src/components/index.d.ts +1 -3
  81. package/dist/types/src/components/index.d.ts.map +1 -1
  82. package/dist/types/src/{components/TranscriptContainer.d.ts → containers/TranscriptionContainer/TranscriptionContainer.d.ts} +3 -4
  83. package/dist/types/src/containers/TranscriptionContainer/TranscriptionContainer.d.ts.map +1 -0
  84. package/dist/types/src/containers/TranscriptionContainer/index.d.ts +3 -0
  85. package/dist/types/src/containers/TranscriptionContainer/index.d.ts.map +1 -0
  86. package/dist/types/src/containers/index.d.ts +3 -0
  87. package/dist/types/src/containers/index.d.ts.map +1 -0
  88. package/dist/types/src/functions/index.d.ts +17 -2
  89. package/dist/types/src/functions/index.d.ts.map +1 -1
  90. package/dist/types/src/functions/open.d.ts +5 -1
  91. package/dist/types/src/functions/open.d.ts.map +1 -1
  92. package/dist/types/src/segments-normalization/normalization.d.ts +19 -6
  93. package/dist/types/src/segments-normalization/normalization.d.ts.map +1 -1
  94. package/dist/types/src/types/TranscriptAction.d.ts +1 -1
  95. package/dist/types/tsconfig.tsbuildinfo +1 -1
  96. package/package.json +65 -64
  97. package/src/TranscriptionPlugin.tsx +9 -8
  98. package/src/blueprints/index.ts +1 -1
  99. package/src/blueprints/transcription-blueprint.ts +14 -6
  100. package/src/capabilities/blueprint-definition/blueprint-definition.ts +6 -12
  101. package/src/capabilities/operation-handler/operation-handler.ts +2 -2
  102. package/src/capabilities/operation-resolver/operation-resolver.ts +2 -2
  103. package/src/capabilities/react-surface/react-surface.tsx +11 -8
  104. package/src/capabilities/transcriber/transcriber.ts +3 -3
  105. package/src/components/{Transcript/Transcript.stories.tsx → Transcription/Transcription.stories.tsx} +8 -8
  106. package/src/components/{Transcript/Transcript.tsx → Transcription/Transcription.tsx} +5 -8
  107. package/src/components/{Transcript → Transcription}/index.ts +1 -1
  108. package/src/components/{Transcript/transcript-extension.ts → Transcription/transcription-extension.ts} +4 -4
  109. package/src/components/index.ts +1 -6
  110. package/src/components/stories/FileTranscription.stories.tsx +4 -4
  111. package/src/components/stories/KeyWordRecognition.stories.tsx +4 -4
  112. package/src/components/stories/MicrophoneTranscription.stories.tsx +4 -4
  113. package/src/components/stories/TranscriptionStory.tsx +3 -3
  114. package/src/{components/TranscriptContainer.tsx → containers/TranscriptionContainer/TranscriptionContainer.tsx} +11 -13
  115. package/src/containers/TranscriptionContainer/index.ts +7 -0
  116. package/src/containers/index.ts +7 -0
  117. package/src/functions/index.ts +7 -2
  118. package/src/functions/open.ts +6 -8
  119. package/src/functions/summarize.ts +1 -1
  120. package/src/hooks/useTranscriber.ts +1 -1
  121. package/src/meta.ts +1 -1
  122. package/src/segments-normalization/normalization.test.ts +1 -1
  123. package/src/testing/testing.ts +1 -1
  124. package/src/types/TranscriptAction.ts +2 -2
  125. package/src/types/capabilities.ts +2 -2
  126. package/dist/lib/browser/TranscriptContainer-6EHKWVS4.mjs +0 -12
  127. package/dist/lib/browser/TranscriptContainer-6EHKWVS4.mjs.map +0 -7
  128. package/dist/lib/browser/blueprint-definition-FTRNMLJZ.mjs +0 -18
  129. package/dist/lib/browser/blueprint-definition-FTRNMLJZ.mjs.map +0 -7
  130. package/dist/lib/browser/chunk-ICM7JRCO.mjs.map +0 -7
  131. package/dist/lib/browser/chunk-Q5OC3WVG.mjs.map +0 -7
  132. package/dist/lib/browser/chunk-SYGEFDWO.mjs +0 -8
  133. package/dist/lib/browser/chunk-SYGEFDWO.mjs.map +0 -7
  134. package/dist/lib/browser/chunk-ZZF7ICVM.mjs.map +0 -7
  135. package/dist/lib/browser/operation-resolver-ZUWTU7C5.mjs.map +0 -7
  136. package/dist/lib/browser/react-surface-ZXH5267I.mjs +0 -34
  137. package/dist/lib/browser/react-surface-ZXH5267I.mjs.map +0 -7
  138. package/dist/lib/browser/transcriber-EZZTUCPE.mjs.map +0 -7
  139. package/dist/lib/node-esm/TranscriptContainer-5YT5W73I.mjs +0 -13
  140. package/dist/lib/node-esm/TranscriptContainer-5YT5W73I.mjs.map +0 -7
  141. package/dist/lib/node-esm/blueprint-definition-IOX35YUX.mjs.map +0 -7
  142. package/dist/lib/node-esm/chunk-4BFY6P2D.mjs.map +0 -7
  143. package/dist/lib/node-esm/chunk-BX2AB7S7.mjs.map +0 -7
  144. package/dist/lib/node-esm/chunk-CWP22IHV.mjs.map +0 -7
  145. package/dist/lib/node-esm/chunk-GVAVEVZ6.mjs +0 -10
  146. package/dist/lib/node-esm/chunk-GVAVEVZ6.mjs.map +0 -7
  147. package/dist/lib/node-esm/operation-resolver-Z72B4H2Q.mjs.map +0 -7
  148. package/dist/lib/node-esm/react-surface-6GUBZX2V.mjs +0 -35
  149. package/dist/lib/node-esm/react-surface-6GUBZX2V.mjs.map +0 -7
  150. package/dist/lib/node-esm/transcriber-RGW3YYT4.mjs.map +0 -7
  151. package/dist/types/src/components/Transcript/Transcript.d.ts.map +0 -1
  152. package/dist/types/src/components/Transcript/Transcript.stories.d.ts.map +0 -1
  153. package/dist/types/src/components/Transcript/deprecated/OldTranscript.d.ts +0 -28
  154. package/dist/types/src/components/Transcript/deprecated/OldTranscript.d.ts.map +0 -1
  155. package/dist/types/src/components/Transcript/index.d.ts +0 -2
  156. package/dist/types/src/components/Transcript/index.d.ts.map +0 -1
  157. package/dist/types/src/components/Transcript/transcript-extension.d.ts.map +0 -1
  158. package/dist/types/src/components/TranscriptContainer.d.ts.map +0 -1
  159. package/src/components/Transcript/deprecated/OldTranscript.tsx +0 -260
  160. /package/dist/lib/browser/{chunk-TKFU53OZ.mjs.map → chunk-QWIUIEWX.mjs.map} +0 -0
  161. /package/dist/lib/node-esm/{chunk-EPC27WWV.mjs.map → chunk-LSWGXNVP.mjs.map} +0 -0
@@ -1,142 +1,28 @@
1
- import {
2
- renderByline
3
- } from "./chunk-HOOPZ7EM.mjs";
4
1
  import {
5
2
  TranscriptionCapabilities
6
- } from "./chunk-Q5OC3WVG.mjs";
7
-
8
- // src/components/TranscriptContainer.tsx
9
- import React2 from "react";
10
- import { Obj } from "@dxos/echo";
11
- import { useMembers, useQueue } from "@dxos/react-client/echo";
12
- import { Layout } from "@dxos/react-ui-mosaic";
13
-
14
- // src/hooks/useAudioFile.ts
15
- import { useEffect, useState } from "react";
16
- import { scheduleTask } from "@dxos/async";
17
- import { Context } from "@dxos/context";
18
- import { log } from "@dxos/log";
19
- var __dxlog_file = "/__w/dxos/dxos/packages/plugins/plugin-transcription/src/hooks/useAudioFile.ts";
20
- var useAudioFile = (audioUrl, constraints) => {
21
- const [{ audio, stream, track }, setStream] = useState({});
22
- useEffect(() => {
23
- const ctx = new Context(void 0, {
24
- F: __dxlog_file,
25
- L: 20
26
- });
27
- scheduleTask(ctx, async () => {
28
- try {
29
- const response = await fetch(audioUrl);
30
- const blob = await response.blob();
31
- const objectUrl = URL.createObjectURL(blob);
32
- ctx.onDispose(() => {
33
- URL.revokeObjectURL(objectUrl);
34
- });
35
- const audio2 = new Audio();
36
- audio2.src = objectUrl;
37
- await new Promise((resolve, reject) => {
38
- audio2.addEventListener("error", (err) => {
39
- log.error("error", {
40
- err
41
- }, {
42
- F: __dxlog_file,
43
- L: 39,
44
- S: void 0,
45
- C: (f, a) => f(...a)
46
- });
47
- reject(err);
48
- }, {
49
- once: true
50
- });
51
- audio2.addEventListener("canplay", async () => {
52
- resolve();
53
- }, {
54
- once: true
55
- });
56
- audio2.load();
57
- });
58
- const audioCtx = new AudioContext();
59
- if (audioCtx.state === "suspended") {
60
- await audioCtx.resume();
61
- }
62
- const destination = audioCtx.createMediaStreamDestination();
63
- destination.channelCount = 1;
64
- const source = audioCtx.createMediaElementSource(audio2);
65
- source.connect(destination);
66
- const track2 = destination.stream.getAudioTracks()[0];
67
- if (constraints) {
68
- await track2.applyConstraints(constraints).catch((err) => log.catch(err, void 0, {
69
- F: __dxlog_file,
70
- L: 68,
71
- S: void 0,
72
- C: (f, a) => f(...a)
73
- }));
74
- }
75
- setStream({
76
- audio: audio2,
77
- stream: destination.stream,
78
- track: destination.stream.getAudioTracks()[0]
79
- });
80
- } catch (err) {
81
- log.catch(err, void 0, {
82
- F: __dxlog_file,
83
- L: 78,
84
- S: void 0,
85
- C: (f, a) => f(...a)
86
- });
87
- }
88
- });
89
- return () => {
90
- void ctx.dispose();
91
- };
92
- }, [
93
- audioUrl
94
- ]);
95
- return {
96
- audio,
97
- stream,
98
- track
99
- };
100
- };
3
+ } from "./chunk-7D57BEI2.mjs";
101
4
 
102
- // src/hooks/useAudioTrack.ts
103
- import { useEffect as useEffect2, useState as useState2 } from "react";
104
- var useAudioTrack = (active, constraints) => {
105
- const [track, setTrack] = useState2();
106
- useEffect2(() => {
107
- if (!active) {
108
- track?.stop();
109
- setTrack(void 0);
110
- return;
111
- }
112
- const initAudio = async () => {
113
- const audio = new Audio();
114
- audio.srcObject = await navigator.mediaDevices.getUserMedia({
115
- audio: constraints ?? true
116
- });
117
- const [track2] = audio.srcObject.getAudioTracks();
118
- if (track2) {
119
- setTrack(track2);
120
- }
121
- };
122
- if (active) {
123
- void initAudio();
124
- }
125
- }, [
126
- active
127
- ]);
128
- return track;
129
- };
5
+ // src/components/Transcription/Transcription.tsx
6
+ import React from "react";
7
+ import { useThemeContext } from "@dxos/react-ui";
8
+ import { useTextEditor } from "@dxos/react-ui-editor";
9
+ import { autoScroll, createBasicExtensions, createMarkdownExtensions, createThemeExtensions, decorateMarkdown, editorSlots, preview } from "@dxos/ui-editor";
10
+ import { mx } from "@dxos/ui-theme";
11
+ import { isTruthy } from "@dxos/util";
130
12
 
131
- // src/hooks/useQueueModelAdapter.ts
132
- import { useEffect as useEffect3, useMemo, useState as useState3 } from "react";
13
+ // src/components/Transcription/transcription-extension.ts
14
+ import { RangeSetBuilder } from "@codemirror/state";
15
+ import { EditorView, GutterMarker, ViewPlugin, gutter } from "@codemirror/view";
16
+ import { format } from "date-fns/format";
17
+ import { intervalToDuration } from "date-fns/intervalToDuration";
18
+ import { addEventListener, combine } from "@dxos/async";
133
19
 
134
20
  // src/model/model.ts
135
21
  import { Text } from "@codemirror/state";
136
22
  import { Event } from "@dxos/async";
137
23
  import { invariant } from "@dxos/invariant";
138
- import { log as log2 } from "@dxos/log";
139
- var __dxlog_file2 = "/__w/dxos/dxos/packages/plugins/plugin-transcription/src/model/model.ts";
24
+ import { log } from "@dxos/log";
25
+ var __dxlog_file = "/__w/dxos/dxos/packages/plugins/plugin-transcription/src/model/model.ts";
140
26
  var DocumentAdapter = class {
141
27
  _view;
142
28
  constructor(_view) {
@@ -147,13 +33,13 @@ var DocumentAdapter = class {
147
33
  return this._view.state.doc.lines - 1;
148
34
  }
149
35
  replaceLines(from, remove, insert) {
150
- log2("replaceLines", {
36
+ log("replaceLines", {
151
37
  count: this._view.state.doc.lines,
152
38
  from,
153
39
  remove,
154
40
  insert
155
41
  }, {
156
- F: __dxlog_file2,
42
+ F: __dxlog_file,
157
43
  L: 39,
158
44
  S: this,
159
45
  C: (f, a) => f(...a)
@@ -234,7 +120,7 @@ var SerializationModel = class {
234
120
  updateChunk(chunk) {
235
121
  const index = this._chunks.findIndex((c) => c.id === chunk.id);
236
122
  invariant(index !== -1, void 0, {
237
- F: __dxlog_file2,
123
+ F: __dxlog_file,
238
124
  L: 147,
239
125
  S: this,
240
126
  A: [
@@ -254,7 +140,7 @@ var SerializationModel = class {
254
140
  deleteBlock(id) {
255
141
  const index = this._chunks.findIndex((c) => c.id === id);
256
142
  invariant(index !== -1, void 0, {
257
- F: __dxlog_file2,
143
+ F: __dxlog_file,
258
144
  L: 156,
259
145
  S: this,
260
146
  A: [
@@ -275,10 +161,10 @@ var SerializationModel = class {
275
161
  * Syncs the tracked changes with the ChunkDocument.
276
162
  */
277
163
  sync(document2) {
278
- log2("sync", {
164
+ log("sync", {
279
165
  changes: this._changes
280
166
  }, {
281
- F: __dxlog_file2,
167
+ F: __dxlog_file,
282
168
  L: 167,
283
169
  S: this,
284
170
  C: (f, a) => f(...a)
@@ -331,235 +217,80 @@ var SerializationModel = class {
331
217
  }
332
218
  };
333
219
 
334
- // src/hooks/useQueueModelAdapter.ts
335
- var useQueueModelAdapter = (renderer, queue, initialChunks = []) => {
336
- const model = useMemo(() => new SerializationModel(renderer, initialChunks), [
337
- queue
338
- ]);
339
- const [loaded, setLoaded] = useState3(false);
340
- useEffect3(() => {
341
- if (!queue) {
342
- return;
343
- }
344
- const update = () => {
345
- for (const block of queue?.objects ?? []) {
346
- model.appendChunk(block);
220
+ // src/components/Transcription/transcription-extension.ts
221
+ var transcription = ({ model, started }) => {
222
+ return [
223
+ // Show timestamps in the gutter.
224
+ gutter({
225
+ class: "cm-timestamp-gutter",
226
+ lineMarkerChange: (update) => update.docChanged || update.viewportChanged,
227
+ markers: (view) => {
228
+ const start = getStartTime(started, model.chunks[0]);
229
+ const builder = new RangeSetBuilder();
230
+ for (const { from, to } of view.visibleRanges) {
231
+ let line = view.state.doc.lineAt(from);
232
+ while (line.from <= to) {
233
+ const block = model.getChunkAtLine(line.number)?.blocks[0];
234
+ const timestamp = block?._tag === "transcript" && block.started;
235
+ if (timestamp) {
236
+ builder.add(line.from, line.from, new TimestampMarker(line.number, new Date(timestamp), start));
237
+ }
238
+ if (line.to + 1 > view.state.doc.length) {
239
+ break;
240
+ }
241
+ line = view.state.doc.lineAt(line.to + 1);
242
+ }
243
+ }
244
+ return builder.finish();
347
245
  }
348
- setLoaded(true);
349
- };
350
- let i;
351
- if (queue.isLoading) {
352
- i = setInterval(() => {
353
- if (!queue?.isLoading) {
354
- clearInterval(i);
355
- update();
356
- }
357
- }, 1e3);
358
- } else {
359
- update();
360
- }
361
- return () => clearTimeout(i);
362
- }, [
363
- model,
364
- queue
365
- ]);
366
- useEffect3(() => {
367
- if (!loaded || !queue || model.chunks.length === queue.objects.length) {
368
- return;
369
- }
370
- const chunk = queue.objects.at(-1);
371
- if (chunk) {
372
- model.appendChunk(chunk);
373
- }
374
- }, [
375
- model,
376
- loaded,
377
- queue?.objects.length
378
- ]);
379
- return model;
380
- };
381
-
382
- // src/hooks/useTranscriber.ts
383
- import { useEffect as useEffect4, useMemo as useMemo2 } from "react";
384
- import { useCapabilities } from "@dxos/app-framework/react";
385
- var useTranscriber = ({ audioStreamTrack, recorderConfig, transcriberConfig, onSegments }) => {
386
- const [getTranscriber] = useCapabilities(TranscriptionCapabilities.Transcriber);
387
- const transcriber = useMemo2(() => {
388
- if (!getTranscriber || !audioStreamTrack || !onSegments) {
389
- return void 0;
390
- }
391
- return getTranscriber({
392
- audioStreamTrack,
393
- recorderConfig,
394
- transcriberConfig,
395
- onSegments
396
- });
397
- }, [
398
- getTranscriber,
399
- audioStreamTrack,
400
- recorderConfig,
401
- transcriberConfig,
402
- onSegments
403
- ]);
404
- useEffect4(() => {
405
- return () => {
406
- void transcriber?.close();
407
- };
408
- }, [
409
- transcriber
410
- ]);
411
- return transcriber;
412
- };
413
-
414
- // src/hooks/useVoiceInput.ts
415
- import { useCallback, useEffect as useEffect5, useState as useState4 } from "react";
416
- import { scheduleMicroTask } from "@dxos/async";
417
- import { Context as Context2 } from "@dxos/context";
418
- import { log as log3 } from "@dxos/log";
419
- import { useSoundEffect } from "@dxos/react-ui-sfx";
420
- var __dxlog_file3 = "/__w/dxos/dxos/packages/plugins/plugin-transcription/src/hooks/useVoiceInput.ts";
421
- var useVoiceInput = ({ active, onUpdate }) => {
422
- const soundStart = useSoundEffect("StartRecording");
423
- const soundStop = useSoundEffect("StopRecording");
424
- const handleSegments = useCallback(async (segments) => {
425
- const text = segments.map((str) => str.text.trim().replace(/[^\w\s]/g, "")).join(" ");
426
- onUpdate(text);
427
- }, []);
428
- const [recording, setRecording] = useState4(false);
429
- const track = useAudioTrack(active);
430
- const transcriber = useTranscriber({
431
- audioStreamTrack: track,
432
- onSegments: handleSegments
433
- });
434
- useEffect5(() => {
435
- const ctx = new Context2(void 0, {
436
- F: __dxlog_file3,
437
- L: 44
438
- });
439
- scheduleMicroTask(ctx, async () => {
440
- if (active && transcriber) {
441
- await transcriber.open();
442
- log3.info("starting...", void 0, {
443
- F: __dxlog_file3,
444
- L: 48,
445
- S: void 0,
446
- C: (f, a) => f(...a)
447
- });
448
- setRecording(true);
449
- void soundStart.play();
450
- transcriber.startChunksRecording();
451
- } else if (!active && transcriber?.isOpen) {
452
- transcriber?.stopChunksRecording();
453
- await transcriber?.close();
454
- log3.info("stopped", void 0, {
455
- F: __dxlog_file3,
456
- L: 55,
457
- S: void 0,
458
- C: (f, a) => f(...a)
459
- });
460
- setRecording(false);
461
- void soundStop.play();
462
- }
463
- });
464
- return () => {
465
- void ctx.dispose();
466
- };
467
- }, [
468
- active,
469
- transcriber
470
- ]);
471
- return {
472
- recording
473
- };
474
- };
475
-
476
- // src/components/Transcript/Transcript.tsx
477
- import React from "react";
478
- import { useThemeContext } from "@dxos/react-ui";
479
- import { useTextEditor } from "@dxos/react-ui-editor";
480
- import { autoScroll, createBasicExtensions, createMarkdownExtensions, createThemeExtensions, decorateMarkdown, editorSlots, preview } from "@dxos/ui-editor";
481
- import { mx } from "@dxos/ui-theme";
482
- import { isTruthy } from "@dxos/util";
483
-
484
- // src/components/Transcript/transcript-extension.ts
485
- import { RangeSetBuilder } from "@codemirror/state";
486
- import { EditorView, GutterMarker, ViewPlugin, gutter } from "@codemirror/view";
487
- import { format } from "date-fns/format";
488
- import { intervalToDuration } from "date-fns/intervalToDuration";
489
- import { addEventListener, combine } from "@dxos/async";
490
- var transcript = ({ model, started }) => {
491
- return [
492
- // Show timestamps in the gutter.
493
- gutter({
494
- class: "cm-timestamp-gutter",
495
- lineMarkerChange: (update) => update.docChanged || update.viewportChanged,
496
- markers: (view) => {
497
- const start = getStartTime(started, model.chunks[0]);
498
- const builder = new RangeSetBuilder();
499
- for (const { from, to } of view.visibleRanges) {
500
- let line = view.state.doc.lineAt(from);
501
- while (line.from <= to) {
502
- const block = model.getChunkAtLine(line.number)?.blocks[0];
503
- const timestamp = block?._tag === "transcript" && block.started;
504
- if (timestamp) {
505
- builder.add(line.from, line.from, new TimestampMarker(line.number, new Date(timestamp), start));
506
- }
507
- if (line.to + 1 > view.state.doc.length) {
508
- break;
509
- }
510
- line = view.state.doc.lineAt(line.to + 1);
511
- }
512
- }
513
- return builder.finish();
514
- }
515
- }),
516
- // Listen for model updates.
517
- ViewPlugin.fromClass(class {
518
- _controls;
519
- _cleanup;
520
- _adapter;
521
- _initialized = false;
522
- constructor(view) {
523
- this._adapter = new DocumentAdapter(view);
524
- const scroller = view.scrollDOM;
525
- let isAutoScrolling = false;
526
- let hasScrolled = false;
527
- let timeout;
528
- const scrollToBottom = (smooth = false) => {
529
- scroller.style.scrollBehavior = smooth ? "smooth" : "";
530
- scroller.classList.add("cm-hide-scrollbar");
531
- isAutoScrolling = true;
532
- clearTimeout(timeout);
533
- timeout = setTimeout(() => {
534
- this._controls?.classList.add("opacity-0");
535
- scroller.classList.remove("cm-hide-scrollbar");
536
- isAutoScrolling = false;
537
- }, 500);
538
- view.dispatch({
539
- effects: EditorView.scrollIntoView(view.state.doc.length, {
540
- y: "end"
541
- })
542
- });
543
- };
544
- this._cleanup = combine(addEventListener(view.scrollDOM, "scroll", () => {
545
- if (!isAutoScrolling) {
546
- hasScrolled = true;
547
- this._controls?.classList.remove("opacity-0");
548
- }
549
- }), model.update.on(() => {
550
- const autoScroll2 = scroller.scrollHeight - scroller.scrollTop - scroller.clientHeight === 0 || !hasScrolled;
551
- model.sync(this._adapter);
552
- if (autoScroll2) {
553
- scrollToBottom(true);
554
- }
555
- }));
556
- }
557
- update(_update) {
558
- if (!this._initialized) {
559
- this._initialized = true;
560
- setTimeout(() => {
561
- model.sync(this._adapter);
562
- });
246
+ }),
247
+ // Listen for model updates.
248
+ ViewPlugin.fromClass(class {
249
+ _controls;
250
+ _cleanup;
251
+ _adapter;
252
+ _initialized = false;
253
+ constructor(view) {
254
+ this._adapter = new DocumentAdapter(view);
255
+ const scroller = view.scrollDOM;
256
+ let isAutoScrolling = false;
257
+ let hasScrolled = false;
258
+ let timeout;
259
+ const scrollToBottom = (smooth = false) => {
260
+ scroller.style.scrollBehavior = smooth ? "smooth" : "";
261
+ scroller.classList.add("cm-hide-scrollbar");
262
+ isAutoScrolling = true;
263
+ clearTimeout(timeout);
264
+ timeout = setTimeout(() => {
265
+ this._controls?.classList.add("opacity-0");
266
+ scroller.classList.remove("cm-hide-scrollbar");
267
+ isAutoScrolling = false;
268
+ }, 500);
269
+ view.dispatch({
270
+ effects: EditorView.scrollIntoView(view.state.doc.length, {
271
+ y: "end"
272
+ })
273
+ });
274
+ };
275
+ this._cleanup = combine(addEventListener(view.scrollDOM, "scroll", () => {
276
+ if (!isAutoScrolling) {
277
+ hasScrolled = true;
278
+ this._controls?.classList.remove("opacity-0");
279
+ }
280
+ }), model.update.on(() => {
281
+ const autoScroll2 = scroller.scrollHeight - scroller.scrollTop - scroller.clientHeight === 0 || !hasScrolled;
282
+ model.sync(this._adapter);
283
+ if (autoScroll2) {
284
+ scrollToBottom(true);
285
+ }
286
+ }));
287
+ }
288
+ update(_update) {
289
+ if (!this._initialized) {
290
+ this._initialized = true;
291
+ setTimeout(() => {
292
+ model.sync(this._adapter);
293
+ });
563
294
  }
564
295
  }
565
296
  destroy() {
@@ -569,7 +300,7 @@ var transcript = ({ model, started }) => {
569
300
  }),
570
301
  EditorView.theme({
571
302
  ".cm-gutters": {
572
- backgroundColor: "var(--dx-baseSurface)"
303
+ backgroundColor: "var(--color-base-surface)"
573
304
  },
574
305
  ".cm-timestamp-gutter": {
575
306
  width: "6rem",
@@ -596,7 +327,7 @@ var TimestampMarker = class extends GutterMarker {
596
327
  }
597
328
  toDOM(view) {
598
329
  const el = document.createElement("div");
599
- el.className = "text-sm text-subdued hover:bg-hoverSurface cursor-pointer";
330
+ el.className = "text-sm text-subdued hover:bg-hover-surface cursor-pointer";
600
331
  el.textContent = formatTimestamp(this._timestamp, this._started);
601
332
  el.onclick = () => {
602
333
  const pos = view.state.doc.line(this._line).from;
@@ -631,8 +362,8 @@ var formatTimestamp = (timestamp, relative) => {
631
362
  }
632
363
  };
633
364
 
634
- // src/components/Transcript/Transcript.tsx
635
- var TranscriptView = ({ classNames, transcript: object, model }) => {
365
+ // src/components/Transcription/Transcription.tsx
366
+ var Transcription = ({ classNames, transcript: object, model }) => {
636
367
  const { themeMode } = useThemeContext();
637
368
  const { parentRef } = useTextEditor(() => {
638
369
  return {
@@ -649,7 +380,7 @@ var TranscriptView = ({ classNames, transcript: object, model }) => {
649
380
  }),
650
381
  decorateMarkdown(),
651
382
  preview(),
652
- transcript({
383
+ transcription({
653
384
  model,
654
385
  started: object?.started ? new Date(object.started) : void 0
655
386
  }),
@@ -661,38 +392,277 @@ var TranscriptView = ({ classNames, transcript: object, model }) => {
661
392
  ]);
662
393
  return /* @__PURE__ */ React.createElement("div", {
663
394
  ref: parentRef,
664
- className: mx("flex grow overflow-hidden container-max-width", classNames),
395
+ className: mx("dx-container", classNames),
665
396
  "data-popover-collision-boundary": true
666
397
  });
667
398
  };
668
399
 
669
- // src/components/TranscriptContainer.tsx
670
- var TranscriptionContainer = ({ role, subject: transcript2 }) => {
671
- const attendableId = Obj.getDXN(transcript2).toString();
672
- const db = Obj.getDatabase(transcript2);
673
- const members = useMembers(db?.spaceId).map((member) => member.identity);
674
- const queue = useQueue(transcript2.queue.dxn, {
675
- pollInterval: 1e3
676
- });
677
- const model = useQueueModelAdapter(renderByline(members), queue);
678
- return /* @__PURE__ */ React2.createElement(Layout.Main, {
679
- role
680
- }, /* @__PURE__ */ React2.createElement(TranscriptView, {
681
- attendableId,
400
+ // src/hooks/useAudioFile.ts
401
+ import { useEffect, useState } from "react";
402
+ import { scheduleTask } from "@dxos/async";
403
+ import { Context } from "@dxos/context";
404
+ import { log as log2 } from "@dxos/log";
405
+ var __dxlog_file2 = "/__w/dxos/dxos/packages/plugins/plugin-transcription/src/hooks/useAudioFile.ts";
406
+ var useAudioFile = (audioUrl, constraints) => {
407
+ const [{ audio, stream, track }, setStream] = useState({});
408
+ useEffect(() => {
409
+ const ctx = new Context(void 0, {
410
+ F: __dxlog_file2,
411
+ L: 20
412
+ });
413
+ scheduleTask(ctx, async () => {
414
+ try {
415
+ const response = await fetch(audioUrl);
416
+ const blob = await response.blob();
417
+ const objectUrl = URL.createObjectURL(blob);
418
+ ctx.onDispose(() => {
419
+ URL.revokeObjectURL(objectUrl);
420
+ });
421
+ const audio2 = new Audio();
422
+ audio2.src = objectUrl;
423
+ await new Promise((resolve, reject) => {
424
+ audio2.addEventListener("error", (err) => {
425
+ log2.error("error", {
426
+ err
427
+ }, {
428
+ F: __dxlog_file2,
429
+ L: 39,
430
+ S: void 0,
431
+ C: (f, a) => f(...a)
432
+ });
433
+ reject(err);
434
+ }, {
435
+ once: true
436
+ });
437
+ audio2.addEventListener("canplay", async () => {
438
+ resolve();
439
+ }, {
440
+ once: true
441
+ });
442
+ audio2.load();
443
+ });
444
+ const audioCtx = new AudioContext();
445
+ if (audioCtx.state === "suspended") {
446
+ await audioCtx.resume();
447
+ }
448
+ const destination = audioCtx.createMediaStreamDestination();
449
+ destination.channelCount = 1;
450
+ const source = audioCtx.createMediaElementSource(audio2);
451
+ source.connect(destination);
452
+ const track2 = destination.stream.getAudioTracks()[0];
453
+ if (constraints) {
454
+ await track2.applyConstraints(constraints).catch((err) => log2.catch(err, void 0, {
455
+ F: __dxlog_file2,
456
+ L: 68,
457
+ S: void 0,
458
+ C: (f, a) => f(...a)
459
+ }));
460
+ }
461
+ setStream({
462
+ audio: audio2,
463
+ stream: destination.stream,
464
+ track: destination.stream.getAudioTracks()[0]
465
+ });
466
+ } catch (err) {
467
+ log2.catch(err, void 0, {
468
+ F: __dxlog_file2,
469
+ L: 78,
470
+ S: void 0,
471
+ C: (f, a) => f(...a)
472
+ });
473
+ }
474
+ });
475
+ return () => {
476
+ void ctx.dispose();
477
+ };
478
+ }, [
479
+ audioUrl
480
+ ]);
481
+ return {
482
+ audio,
483
+ stream,
484
+ track
485
+ };
486
+ };
487
+
488
+ // src/hooks/useAudioTrack.ts
489
+ import { useEffect as useEffect2, useState as useState2 } from "react";
490
+ var useAudioTrack = (active, constraints) => {
491
+ const [track, setTrack] = useState2();
492
+ useEffect2(() => {
493
+ if (!active) {
494
+ track?.stop();
495
+ setTrack(void 0);
496
+ return;
497
+ }
498
+ const initAudio = async () => {
499
+ const audio = new Audio();
500
+ audio.srcObject = await navigator.mediaDevices.getUserMedia({
501
+ audio: constraints ?? true
502
+ });
503
+ const [track2] = audio.srcObject.getAudioTracks();
504
+ if (track2) {
505
+ setTrack(track2);
506
+ }
507
+ };
508
+ if (active) {
509
+ void initAudio();
510
+ }
511
+ }, [
512
+ active
513
+ ]);
514
+ return track;
515
+ };
516
+
517
+ // src/hooks/useQueueModelAdapter.ts
518
+ import { useEffect as useEffect3, useMemo, useState as useState3 } from "react";
519
+ var useQueueModelAdapter = (renderer, queue, initialChunks = []) => {
520
+ const model = useMemo(() => new SerializationModel(renderer, initialChunks), [
521
+ queue
522
+ ]);
523
+ const [loaded, setLoaded] = useState3(false);
524
+ useEffect3(() => {
525
+ if (!queue) {
526
+ return;
527
+ }
528
+ const update = () => {
529
+ for (const block of queue?.objects ?? []) {
530
+ model.appendChunk(block);
531
+ }
532
+ setLoaded(true);
533
+ };
534
+ let i;
535
+ if (queue.isLoading) {
536
+ i = setInterval(() => {
537
+ if (!queue?.isLoading) {
538
+ clearInterval(i);
539
+ update();
540
+ }
541
+ }, 1e3);
542
+ } else {
543
+ update();
544
+ }
545
+ return () => clearTimeout(i);
546
+ }, [
682
547
  model,
683
- transcript: transcript2
684
- }));
548
+ queue
549
+ ]);
550
+ useEffect3(() => {
551
+ if (!loaded || !queue || model.chunks.length === queue.objects.length) {
552
+ return;
553
+ }
554
+ const chunk = queue.objects.at(-1);
555
+ if (chunk) {
556
+ model.appendChunk(chunk);
557
+ }
558
+ }, [
559
+ model,
560
+ loaded,
561
+ queue?.objects.length
562
+ ]);
563
+ return model;
564
+ };
565
+
566
+ // src/hooks/useTranscriber.ts
567
+ import { useEffect as useEffect4, useMemo as useMemo2 } from "react";
568
+ import { useCapabilities } from "@dxos/app-framework/ui";
569
+ var useTranscriber = ({ audioStreamTrack, recorderConfig, transcriberConfig, onSegments }) => {
570
+ const [getTranscriber] = useCapabilities(TranscriptionCapabilities.Transcriber);
571
+ const transcriber = useMemo2(() => {
572
+ if (!getTranscriber || !audioStreamTrack || !onSegments) {
573
+ return void 0;
574
+ }
575
+ return getTranscriber({
576
+ audioStreamTrack,
577
+ recorderConfig,
578
+ transcriberConfig,
579
+ onSegments
580
+ });
581
+ }, [
582
+ getTranscriber,
583
+ audioStreamTrack,
584
+ recorderConfig,
585
+ transcriberConfig,
586
+ onSegments
587
+ ]);
588
+ useEffect4(() => {
589
+ return () => {
590
+ void transcriber?.close();
591
+ };
592
+ }, [
593
+ transcriber
594
+ ]);
595
+ return transcriber;
596
+ };
597
+
598
+ // src/hooks/useVoiceInput.ts
599
+ import { useCallback, useEffect as useEffect5, useState as useState4 } from "react";
600
+ import { scheduleMicroTask } from "@dxos/async";
601
+ import { Context as Context2 } from "@dxos/context";
602
+ import { log as log3 } from "@dxos/log";
603
+ import { useSoundEffect } from "@dxos/react-ui-sfx";
604
+ var __dxlog_file3 = "/__w/dxos/dxos/packages/plugins/plugin-transcription/src/hooks/useVoiceInput.ts";
605
+ var useVoiceInput = ({ active, onUpdate }) => {
606
+ const soundStart = useSoundEffect("StartRecording");
607
+ const soundStop = useSoundEffect("StopRecording");
608
+ const handleSegments = useCallback(async (segments) => {
609
+ const text = segments.map((str) => str.text.trim().replace(/[^\w\s]/g, "")).join(" ");
610
+ onUpdate(text);
611
+ }, []);
612
+ const [recording, setRecording] = useState4(false);
613
+ const track = useAudioTrack(active);
614
+ const transcriber = useTranscriber({
615
+ audioStreamTrack: track,
616
+ onSegments: handleSegments
617
+ });
618
+ useEffect5(() => {
619
+ const ctx = new Context2(void 0, {
620
+ F: __dxlog_file3,
621
+ L: 44
622
+ });
623
+ scheduleMicroTask(ctx, async () => {
624
+ if (active && transcriber) {
625
+ await transcriber.open();
626
+ log3.info("starting...", void 0, {
627
+ F: __dxlog_file3,
628
+ L: 48,
629
+ S: void 0,
630
+ C: (f, a) => f(...a)
631
+ });
632
+ setRecording(true);
633
+ void soundStart.play();
634
+ transcriber.startChunksRecording();
635
+ } else if (!active && transcriber?.isOpen) {
636
+ transcriber?.stopChunksRecording();
637
+ await transcriber?.close();
638
+ log3.info("stopped", void 0, {
639
+ F: __dxlog_file3,
640
+ L: 55,
641
+ S: void 0,
642
+ C: (f, a) => f(...a)
643
+ });
644
+ setRecording(false);
645
+ void soundStop.play();
646
+ }
647
+ });
648
+ return () => {
649
+ void ctx.dispose();
650
+ };
651
+ }, [
652
+ active,
653
+ transcriber
654
+ ]);
655
+ return {
656
+ recording
657
+ };
685
658
  };
686
- var TranscriptContainer_default = TranscriptionContainer;
687
659
 
688
660
  export {
689
- TranscriptView,
661
+ Transcription,
690
662
  useAudioFile,
691
663
  useAudioTrack,
692
664
  useQueueModelAdapter,
693
665
  useTranscriber,
694
- useVoiceInput,
695
- TranscriptionContainer,
696
- TranscriptContainer_default
666
+ useVoiceInput
697
667
  };
698
- //# sourceMappingURL=chunk-ICM7JRCO.mjs.map
668
+ //# sourceMappingURL=chunk-SLZXQVQU.mjs.map