@dxos/plugin-transcription 0.8.4-main.2e9d522 → 0.8.4-main.548089c
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/TranscriptContainer-EKSP5DQ6.mjs +11 -0
- package/dist/lib/browser/blueprint-definition-WBWHO4OH.mjs +150 -0
- package/dist/lib/browser/blueprint-definition-WBWHO4OH.mjs.map +7 -0
- package/dist/lib/browser/{chunk-U6QBOGTN.mjs → chunk-3MKZ2MNQ.mjs} +5 -5
- package/dist/lib/browser/chunk-3MKZ2MNQ.mjs.map +7 -0
- package/dist/lib/browser/{chunk-5KPYIC3N.mjs → chunk-EHT3TE6U.mjs} +341 -366
- package/dist/lib/browser/chunk-EHT3TE6U.mjs.map +7 -0
- package/dist/lib/browser/{chunk-4FJIYH7T.mjs → chunk-OCI42DWB.mjs} +2 -2
- package/dist/lib/browser/{chunk-FFEPEPCU.mjs → chunk-PVU4XCKI.mjs} +51 -80
- package/dist/lib/browser/chunk-PVU4XCKI.mjs.map +7 -0
- package/dist/lib/browser/chunk-VBUIO677.mjs +29 -0
- package/dist/lib/browser/chunk-VBUIO677.mjs.map +7 -0
- package/dist/lib/browser/chunk-W7WKZTM4.mjs +63 -0
- package/dist/lib/browser/chunk-W7WKZTM4.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +25 -20
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/intent-resolver-ZTKTEAQX.mjs +25 -0
- package/dist/lib/browser/intent-resolver-ZTKTEAQX.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{react-surface-E5D5AE3F.mjs → react-surface-NARMYO2O.mjs} +10 -10
- package/dist/lib/browser/react-surface-NARMYO2O.mjs.map +7 -0
- package/dist/lib/browser/{transcriber-PXT4QBFY.mjs → transcriber-E2KAOXPS.mjs} +7 -7
- package/dist/lib/browser/transcriber-E2KAOXPS.mjs.map +7 -0
- package/dist/lib/browser/types/index.mjs +6 -8
- package/dist/lib/node-esm/{TranscriptContainer-VBAOM5DG.mjs → TranscriptContainer-WU3EDQR3.mjs} +4 -4
- package/dist/lib/node-esm/blueprint-definition-WUHZFRWZ.mjs +151 -0
- package/dist/lib/node-esm/blueprint-definition-WUHZFRWZ.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-TJKAO7VR.mjs → chunk-7XASA7DX.mjs} +341 -366
- package/dist/lib/node-esm/chunk-7XASA7DX.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-OLMSTF3M.mjs +64 -0
- package/dist/lib/node-esm/chunk-OLMSTF3M.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-RHF2ALML.mjs → chunk-SWUVPFKR.mjs} +5 -5
- package/dist/lib/node-esm/chunk-SWUVPFKR.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-HT3W7LDP.mjs → chunk-UVOYXXDJ.mjs} +51 -80
- package/dist/lib/node-esm/chunk-UVOYXXDJ.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-Y2B4HWSS.mjs → chunk-X5BKN32O.mjs} +2 -2
- package/dist/lib/node-esm/chunk-YVNQN2J6.mjs +30 -0
- package/dist/lib/node-esm/chunk-YVNQN2J6.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +25 -20
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/intent-resolver-55WH2GY6.mjs +26 -0
- package/dist/lib/node-esm/intent-resolver-55WH2GY6.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{react-surface-QRDJOHN5.mjs → react-surface-5MQA3IUS.mjs} +10 -10
- package/dist/lib/node-esm/react-surface-5MQA3IUS.mjs.map +7 -0
- package/dist/lib/node-esm/{transcriber-YUTEVANE.mjs → transcriber-ZPJM4U2W.mjs} +7 -7
- package/dist/lib/node-esm/transcriber-ZPJM4U2W.mjs.map +7 -0
- package/dist/lib/node-esm/types/index.mjs +6 -8
- package/dist/types/src/TranscriptionPlugin.d.ts +1 -1
- package/dist/types/src/TranscriptionPlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/blueprint-definition.d.ts +5 -0
- package/dist/types/src/capabilities/blueprint-definition.d.ts.map +1 -0
- package/dist/types/src/capabilities/capabilities.d.ts +1 -1
- package/dist/types/src/capabilities/capabilities.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts +3 -2
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts +1 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts +1 -1
- package/dist/types/src/capabilities/transcriber.d.ts +1 -1
- package/dist/types/src/capabilities/transcriber.d.ts.map +1 -1
- package/dist/types/src/components/Transcript/Transcript.d.ts +7 -7
- package/dist/types/src/components/Transcript/Transcript.d.ts.map +1 -1
- package/dist/types/src/components/Transcript/Transcript.stories.d.ts +33 -18
- package/dist/types/src/components/Transcript/Transcript.stories.d.ts.map +1 -1
- package/dist/types/src/components/Transcript/deprecated/OldTranscript.d.ts +3 -3
- package/dist/types/src/components/Transcript/deprecated/OldTranscript.d.ts.map +1 -1
- package/dist/types/src/components/Transcript/transcript-extension.d.ts +3 -7
- package/dist/types/src/components/Transcript/transcript-extension.d.ts.map +1 -1
- package/dist/types/src/components/TranscriptContainer.d.ts +2 -2
- package/dist/types/src/components/TranscriptContainer.d.ts.map +1 -1
- package/dist/types/src/components/stories/FileTranscription.stories.d.ts +5 -4
- package/dist/types/src/components/stories/FileTranscription.stories.d.ts.map +1 -1
- package/dist/types/src/components/stories/KeyWordRecognition.stories.d.ts +10 -6
- package/dist/types/src/components/stories/KeyWordRecognition.stories.d.ts.map +1 -1
- package/dist/types/src/components/stories/MicrophoneTranscription.stories.d.ts +7 -6
- package/dist/types/src/components/stories/MicrophoneTranscription.stories.d.ts.map +1 -1
- package/dist/types/src/components/stories/TranscriptionStory.d.ts +4 -3
- package/dist/types/src/components/stories/TranscriptionStory.d.ts.map +1 -1
- package/dist/types/src/functions/index.d.ts +3 -0
- package/dist/types/src/functions/index.d.ts.map +1 -0
- package/dist/types/src/functions/open.d.ts +7 -0
- package/dist/types/src/functions/open.d.ts.map +1 -0
- package/dist/types/src/functions/summarize.d.ts +11 -0
- package/dist/types/src/functions/summarize.d.ts.map +1 -0
- package/dist/types/src/hooks/useAudioFile.d.ts.map +1 -1
- package/dist/types/src/hooks/useTranscriber.d.ts.map +1 -1
- package/dist/types/src/hooks/useVoiceInput.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +0 -1
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/segments-normalization/message-normalizer.d.ts +3 -3
- package/dist/types/src/segments-normalization/message-normalizer.d.ts.map +1 -1
- package/dist/types/src/segments-normalization/normalization.d.ts +388 -328
- package/dist/types/src/segments-normalization/normalization.d.ts.map +1 -1
- package/dist/types/src/segments-normalization/utils.d.ts +2 -2
- package/dist/types/src/segments-normalization/utils.d.ts.map +1 -1
- package/dist/types/src/testing/testing.d.ts +7 -7
- package/dist/types/src/testing/testing.d.ts.map +1 -1
- package/dist/types/src/transcriber/media-stream-recorder.d.ts +1 -1
- package/dist/types/src/transcriber/media-stream-recorder.d.ts.map +1 -1
- package/dist/types/src/transcriber/transcriber.d.ts +2 -2
- package/dist/types/src/transcriber/transcriber.d.ts.map +1 -1
- package/dist/types/src/transcriber/transcription-manager.d.ts +6 -10
- package/dist/types/src/transcriber/transcription-manager.d.ts.map +1 -1
- package/dist/types/src/types/Transcript.d.ts +30 -0
- package/dist/types/src/types/Transcript.d.ts.map +1 -0
- package/dist/types/src/types/TranscriptAction.d.ts +23 -0
- package/dist/types/src/types/TranscriptAction.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +2 -1
- package/dist/types/src/types/index.d.ts.map +1 -1
- package/dist/types/src/types/types.d.ts +0 -26
- package/dist/types/src/types/types.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +66 -63
- package/src/TranscriptionPlugin.tsx +59 -54
- package/src/capabilities/blueprint-definition.ts +31 -0
- package/src/capabilities/capabilities.ts +6 -6
- package/src/capabilities/index.ts +1 -0
- package/src/capabilities/intent-resolver.ts +5 -11
- package/src/capabilities/react-surface.tsx +2 -2
- package/src/capabilities/transcriber.ts +3 -2
- package/src/components/Transcript/Transcript.stories.tsx +37 -34
- package/src/components/Transcript/Transcript.tsx +25 -31
- package/src/components/Transcript/deprecated/OldTranscript.tsx +9 -9
- package/src/components/Transcript/transcript-extension.ts +11 -44
- package/src/components/TranscriptContainer.tsx +12 -10
- package/src/components/stories/FileTranscription.stories.tsx +54 -42
- package/src/components/stories/KeyWordRecognition.stories.tsx +15 -11
- package/src/components/stories/MicrophoneTranscription.stories.tsx +49 -45
- package/src/components/stories/TranscriptionStory.tsx +12 -8
- package/src/functions/index.ts +6 -0
- package/src/functions/open.ts +39 -0
- package/src/functions/summarize.ts +103 -0
- package/src/hooks/useAudioFile.ts +49 -53
- package/src/hooks/useTranscriber.ts +7 -2
- package/src/hooks/useVoiceInput.ts +3 -2
- package/src/meta.ts +7 -4
- package/src/model/model.test.ts +12 -12
- package/src/segments-normalization/message-normalizer.ts +7 -7
- package/src/segments-normalization/normalization.test.ts +10 -10
- package/src/segments-normalization/normalization.ts +43 -42
- package/src/segments-normalization/utils.ts +2 -2
- package/src/testing/testing.ts +27 -22
- package/src/transcriber/media-stream-recorder.ts +1 -1
- package/src/transcriber/transcriber.browser.test.ts +5 -4
- package/src/transcriber/transcriber.ts +5 -4
- package/src/transcriber/transcription-manager.ts +23 -44
- package/src/types/{schema.ts → Transcript.ts} +12 -9
- package/src/types/TranscriptAction.ts +24 -0
- package/src/types/index.ts +2 -1
- package/src/types/types.ts +0 -23
- package/dist/lib/browser/TranscriptContainer-6WCKCXQ6.mjs +0 -11
- package/dist/lib/browser/chunk-5KPYIC3N.mjs.map +0 -7
- package/dist/lib/browser/chunk-5WH45KBY.mjs +0 -19
- package/dist/lib/browser/chunk-5WH45KBY.mjs.map +0 -7
- package/dist/lib/browser/chunk-FFEPEPCU.mjs.map +0 -7
- package/dist/lib/browser/chunk-R7INNNUQ.mjs +0 -55
- package/dist/lib/browser/chunk-R7INNNUQ.mjs.map +0 -7
- package/dist/lib/browser/chunk-U6QBOGTN.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-3O33MMP5.mjs +0 -30
- package/dist/lib/browser/intent-resolver-3O33MMP5.mjs.map +0 -7
- package/dist/lib/browser/react-surface-E5D5AE3F.mjs.map +0 -7
- package/dist/lib/browser/transcriber-PXT4QBFY.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-HT3W7LDP.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-RHF2ALML.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-TJKAO7VR.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-U65ZWK3L.mjs +0 -56
- package/dist/lib/node-esm/chunk-U65ZWK3L.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-XMUCZBP3.mjs +0 -21
- package/dist/lib/node-esm/chunk-XMUCZBP3.mjs.map +0 -7
- package/dist/lib/node-esm/intent-resolver-YMN5SXNC.mjs +0 -31
- package/dist/lib/node-esm/intent-resolver-YMN5SXNC.mjs.map +0 -7
- package/dist/lib/node-esm/react-surface-QRDJOHN5.mjs.map +0 -7
- package/dist/lib/node-esm/transcriber-YUTEVANE.mjs.map +0 -7
- package/dist/types/src/types/schema.d.ts +0 -41
- package/dist/types/src/types/schema.d.ts.map +0 -1
- /package/dist/lib/browser/{TranscriptContainer-6WCKCXQ6.mjs.map → TranscriptContainer-EKSP5DQ6.mjs.map} +0 -0
- /package/dist/lib/browser/{chunk-4FJIYH7T.mjs.map → chunk-OCI42DWB.mjs.map} +0 -0
- /package/dist/lib/node-esm/{TranscriptContainer-VBAOM5DG.mjs.map → TranscriptContainer-WU3EDQR3.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-Y2B4HWSS.mjs.map → chunk-X5BKN32O.mjs.map} +0 -0
|
@@ -1,36 +1,143 @@
|
|
|
1
1
|
import {
|
|
2
2
|
TranscriptionCapabilities
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-3MKZ2MNQ.mjs";
|
|
4
4
|
|
|
5
5
|
// src/components/TranscriptContainer.tsx
|
|
6
6
|
import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
|
|
7
7
|
import React2 from "react";
|
|
8
|
-
import {
|
|
8
|
+
import { getSpace } from "@dxos/client/echo";
|
|
9
|
+
import { Obj } from "@dxos/echo";
|
|
9
10
|
import { useMembers, useQueue } from "@dxos/react-client/echo";
|
|
10
11
|
import { StackItem } from "@dxos/react-ui-stack";
|
|
11
12
|
|
|
12
|
-
// src/
|
|
13
|
-
import {
|
|
14
|
-
import
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
// src/hooks/useAudioFile.ts
|
|
14
|
+
import { useEffect, useState } from "react";
|
|
15
|
+
import { scheduleTask } from "@dxos/async";
|
|
16
|
+
import { Context } from "@dxos/context";
|
|
17
|
+
import { log } from "@dxos/log";
|
|
18
|
+
var __dxlog_file = "/__w/dxos/dxos/packages/plugins/plugin-transcription/src/hooks/useAudioFile.ts";
|
|
19
|
+
var useAudioFile = (audioUrl, constraints) => {
|
|
20
|
+
const [{ audio, stream, track }, setStream] = useState({});
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
const ctx = new Context(void 0, {
|
|
23
|
+
F: __dxlog_file,
|
|
24
|
+
L: 20
|
|
25
|
+
});
|
|
26
|
+
scheduleTask(ctx, async () => {
|
|
27
|
+
try {
|
|
28
|
+
const response = await fetch(audioUrl);
|
|
29
|
+
const blob = await response.blob();
|
|
30
|
+
const objectUrl = URL.createObjectURL(blob);
|
|
31
|
+
ctx.onDispose(() => {
|
|
32
|
+
URL.revokeObjectURL(objectUrl);
|
|
33
|
+
});
|
|
34
|
+
const audio2 = new Audio();
|
|
35
|
+
audio2.src = objectUrl;
|
|
36
|
+
await new Promise((resolve, reject) => {
|
|
37
|
+
audio2.addEventListener("error", (err) => {
|
|
38
|
+
log.error("error", {
|
|
39
|
+
err
|
|
40
|
+
}, {
|
|
41
|
+
F: __dxlog_file,
|
|
42
|
+
L: 39,
|
|
43
|
+
S: void 0,
|
|
44
|
+
C: (f, a) => f(...a)
|
|
45
|
+
});
|
|
46
|
+
reject(err);
|
|
47
|
+
}, {
|
|
48
|
+
once: true
|
|
49
|
+
});
|
|
50
|
+
audio2.addEventListener("canplay", async () => {
|
|
51
|
+
resolve();
|
|
52
|
+
}, {
|
|
53
|
+
once: true
|
|
54
|
+
});
|
|
55
|
+
audio2.load();
|
|
56
|
+
});
|
|
57
|
+
const audioCtx = new AudioContext();
|
|
58
|
+
if (audioCtx.state === "suspended") {
|
|
59
|
+
await audioCtx.resume();
|
|
60
|
+
}
|
|
61
|
+
const destination = audioCtx.createMediaStreamDestination();
|
|
62
|
+
destination.channelCount = 1;
|
|
63
|
+
const source = audioCtx.createMediaElementSource(audio2);
|
|
64
|
+
source.connect(destination);
|
|
65
|
+
const track2 = destination.stream.getAudioTracks()[0];
|
|
66
|
+
if (constraints) {
|
|
67
|
+
await track2.applyConstraints(constraints).catch((err) => log.catch(err, void 0, {
|
|
68
|
+
F: __dxlog_file,
|
|
69
|
+
L: 68,
|
|
70
|
+
S: void 0,
|
|
71
|
+
C: (f, a) => f(...a)
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
setStream({
|
|
75
|
+
audio: audio2,
|
|
76
|
+
stream: destination.stream,
|
|
77
|
+
track: destination.stream.getAudioTracks()[0]
|
|
78
|
+
});
|
|
79
|
+
} catch (err) {
|
|
80
|
+
log.catch(err, void 0, {
|
|
81
|
+
F: __dxlog_file,
|
|
82
|
+
L: 78,
|
|
83
|
+
S: void 0,
|
|
84
|
+
C: (f, a) => f(...a)
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
return () => {
|
|
89
|
+
void ctx.dispose();
|
|
90
|
+
};
|
|
91
|
+
}, [
|
|
92
|
+
audioUrl
|
|
93
|
+
]);
|
|
94
|
+
return {
|
|
95
|
+
audio,
|
|
96
|
+
stream,
|
|
97
|
+
track
|
|
98
|
+
};
|
|
99
|
+
};
|
|
19
100
|
|
|
20
|
-
// src/
|
|
21
|
-
import {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
101
|
+
// src/hooks/useAudioTrack.ts
|
|
102
|
+
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
103
|
+
var useAudioTrack = (active, constraints) => {
|
|
104
|
+
const [track, setTrack] = useState2();
|
|
105
|
+
useEffect2(() => {
|
|
106
|
+
if (!active) {
|
|
107
|
+
track?.stop();
|
|
108
|
+
setTrack(void 0);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const initAudio = async () => {
|
|
112
|
+
const audio = new Audio();
|
|
113
|
+
audio.srcObject = await navigator.mediaDevices.getUserMedia({
|
|
114
|
+
audio: constraints ?? true
|
|
115
|
+
});
|
|
116
|
+
const [track2] = audio.srcObject.getAudioTracks();
|
|
117
|
+
if (track2) {
|
|
118
|
+
setTrack(track2);
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
if (active) {
|
|
122
|
+
void initAudio();
|
|
123
|
+
}
|
|
124
|
+
}, [
|
|
125
|
+
active
|
|
126
|
+
]);
|
|
127
|
+
return track;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// src/hooks/useQueueModelAdapter.ts
|
|
131
|
+
import { useEffect as useEffect3, useMemo, useState as useState3 } from "react";
|
|
26
132
|
|
|
27
133
|
// src/model/model.ts
|
|
28
134
|
import { Text } from "@codemirror/state";
|
|
29
135
|
import { Event } from "@dxos/async";
|
|
30
136
|
import { invariant } from "@dxos/invariant";
|
|
31
|
-
import { log } from "@dxos/log";
|
|
32
|
-
var
|
|
137
|
+
import { log as log2 } from "@dxos/log";
|
|
138
|
+
var __dxlog_file2 = "/__w/dxos/dxos/packages/plugins/plugin-transcription/src/model/model.ts";
|
|
33
139
|
var DocumentAdapter = class {
|
|
140
|
+
_view;
|
|
34
141
|
constructor(_view) {
|
|
35
142
|
this._view = _view;
|
|
36
143
|
}
|
|
@@ -39,13 +146,13 @@ var DocumentAdapter = class {
|
|
|
39
146
|
return this._view.state.doc.lines - 1;
|
|
40
147
|
}
|
|
41
148
|
replaceLines(from, remove, insert) {
|
|
42
|
-
|
|
149
|
+
log2("replaceLines", {
|
|
43
150
|
count: this._view.state.doc.lines,
|
|
44
151
|
from,
|
|
45
152
|
remove,
|
|
46
153
|
insert
|
|
47
154
|
}, {
|
|
48
|
-
F:
|
|
155
|
+
F: __dxlog_file2,
|
|
49
156
|
L: 39,
|
|
50
157
|
S: this,
|
|
51
158
|
C: (f, a) => f(...a)
|
|
@@ -67,13 +174,19 @@ var DocumentAdapter = class {
|
|
|
67
174
|
}
|
|
68
175
|
};
|
|
69
176
|
var SerializationModel = class {
|
|
177
|
+
_renderer;
|
|
178
|
+
/** Ordered set of chunks. */
|
|
179
|
+
_chunks = [];
|
|
180
|
+
/** Map of chunk IDs to their current line counts. */
|
|
181
|
+
_chunkLineCounts = /* @__PURE__ */ new Map();
|
|
182
|
+
/** Map of line numbers to chunk IDs. */
|
|
183
|
+
_lineToChunk = /* @__PURE__ */ new Map();
|
|
184
|
+
/** Track chunk changes since last sync. */
|
|
185
|
+
_changes = [];
|
|
186
|
+
/** Emits when the document is updated. */
|
|
187
|
+
update = new Event();
|
|
70
188
|
constructor(_renderer, initialChunks = []) {
|
|
71
189
|
this._renderer = _renderer;
|
|
72
|
-
this._chunks = [];
|
|
73
|
-
this._chunkLineCounts = /* @__PURE__ */ new Map();
|
|
74
|
-
this._lineToChunk = /* @__PURE__ */ new Map();
|
|
75
|
-
this._changes = [];
|
|
76
|
-
this.update = new Event();
|
|
77
190
|
initialChunks.forEach((chunk) => {
|
|
78
191
|
this.appendChunk(chunk);
|
|
79
192
|
});
|
|
@@ -120,7 +233,7 @@ var SerializationModel = class {
|
|
|
120
233
|
updateChunk(chunk) {
|
|
121
234
|
const index = this._chunks.findIndex((c) => c.id === chunk.id);
|
|
122
235
|
invariant(index !== -1, void 0, {
|
|
123
|
-
F:
|
|
236
|
+
F: __dxlog_file2,
|
|
124
237
|
L: 147,
|
|
125
238
|
S: this,
|
|
126
239
|
A: [
|
|
@@ -140,7 +253,7 @@ var SerializationModel = class {
|
|
|
140
253
|
deleteBlock(id) {
|
|
141
254
|
const index = this._chunks.findIndex((c) => c.id === id);
|
|
142
255
|
invariant(index !== -1, void 0, {
|
|
143
|
-
F:
|
|
256
|
+
F: __dxlog_file2,
|
|
144
257
|
L: 156,
|
|
145
258
|
S: this,
|
|
146
259
|
A: [
|
|
@@ -161,10 +274,10 @@ var SerializationModel = class {
|
|
|
161
274
|
* Syncs the tracked changes with the ChunkDocument.
|
|
162
275
|
*/
|
|
163
276
|
sync(document2) {
|
|
164
|
-
|
|
277
|
+
log2("sync", {
|
|
165
278
|
changes: this._changes
|
|
166
279
|
}, {
|
|
167
|
-
F:
|
|
280
|
+
F: __dxlog_file2,
|
|
168
281
|
L: 167,
|
|
169
282
|
S: this,
|
|
170
283
|
C: (f, a) => f(...a)
|
|
@@ -217,8 +330,172 @@ var SerializationModel = class {
|
|
|
217
330
|
}
|
|
218
331
|
};
|
|
219
332
|
|
|
333
|
+
// src/hooks/useQueueModelAdapter.ts
|
|
334
|
+
var useQueueModelAdapter = (renderer, queue, initialChunks = []) => {
|
|
335
|
+
const model = useMemo(() => new SerializationModel(renderer, initialChunks), [
|
|
336
|
+
queue
|
|
337
|
+
]);
|
|
338
|
+
const [loaded, setLoaded] = useState3(false);
|
|
339
|
+
useEffect3(() => {
|
|
340
|
+
if (!queue) {
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
const update = () => {
|
|
344
|
+
for (const block of queue?.objects ?? []) {
|
|
345
|
+
model.appendChunk(block);
|
|
346
|
+
}
|
|
347
|
+
setLoaded(true);
|
|
348
|
+
};
|
|
349
|
+
let i;
|
|
350
|
+
if (queue.isLoading) {
|
|
351
|
+
i = setInterval(() => {
|
|
352
|
+
if (!queue?.isLoading) {
|
|
353
|
+
clearInterval(i);
|
|
354
|
+
update();
|
|
355
|
+
}
|
|
356
|
+
}, 1e3);
|
|
357
|
+
} else {
|
|
358
|
+
update();
|
|
359
|
+
}
|
|
360
|
+
return () => clearTimeout(i);
|
|
361
|
+
}, [
|
|
362
|
+
model,
|
|
363
|
+
queue
|
|
364
|
+
]);
|
|
365
|
+
useEffect3(() => {
|
|
366
|
+
if (!loaded || !queue || model.chunks.length === queue.objects.length) {
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
const chunk = queue.objects.at(-1);
|
|
370
|
+
if (chunk) {
|
|
371
|
+
model.appendChunk(chunk);
|
|
372
|
+
}
|
|
373
|
+
}, [
|
|
374
|
+
model,
|
|
375
|
+
loaded,
|
|
376
|
+
queue?.objects.length
|
|
377
|
+
]);
|
|
378
|
+
return model;
|
|
379
|
+
};
|
|
380
|
+
|
|
381
|
+
// src/hooks/useTranscriber.ts
|
|
382
|
+
import { useEffect as useEffect4, useMemo as useMemo2 } from "react";
|
|
383
|
+
import { useCapabilities } from "@dxos/app-framework/react";
|
|
384
|
+
|
|
385
|
+
// src/capabilities/index.ts
|
|
386
|
+
import { lazy } from "@dxos/app-framework";
|
|
387
|
+
var BlueprintDefinition = lazy(() => import("./blueprint-definition-WBWHO4OH.mjs"));
|
|
388
|
+
var IntentResolver = lazy(() => import("./intent-resolver-ZTKTEAQX.mjs"));
|
|
389
|
+
var ReactSurface = lazy(() => import("./react-surface-NARMYO2O.mjs"));
|
|
390
|
+
var Transcriber = lazy(() => import("./transcriber-E2KAOXPS.mjs"));
|
|
391
|
+
|
|
392
|
+
// src/hooks/useTranscriber.ts
|
|
393
|
+
var useTranscriber = ({ audioStreamTrack, recorderConfig, transcriberConfig, onSegments }) => {
|
|
394
|
+
const [getTranscriber] = useCapabilities(TranscriptionCapabilities.Transcriber);
|
|
395
|
+
const transcriber = useMemo2(() => {
|
|
396
|
+
if (!getTranscriber || !audioStreamTrack || !onSegments) {
|
|
397
|
+
return void 0;
|
|
398
|
+
}
|
|
399
|
+
return getTranscriber({
|
|
400
|
+
audioStreamTrack,
|
|
401
|
+
recorderConfig,
|
|
402
|
+
transcriberConfig,
|
|
403
|
+
onSegments
|
|
404
|
+
});
|
|
405
|
+
}, [
|
|
406
|
+
getTranscriber,
|
|
407
|
+
audioStreamTrack,
|
|
408
|
+
recorderConfig,
|
|
409
|
+
transcriberConfig,
|
|
410
|
+
onSegments
|
|
411
|
+
]);
|
|
412
|
+
useEffect4(() => {
|
|
413
|
+
return () => {
|
|
414
|
+
void transcriber?.close();
|
|
415
|
+
};
|
|
416
|
+
}, [
|
|
417
|
+
transcriber
|
|
418
|
+
]);
|
|
419
|
+
return transcriber;
|
|
420
|
+
};
|
|
421
|
+
|
|
422
|
+
// src/hooks/useVoiceInput.ts
|
|
423
|
+
import { useCallback, useEffect as useEffect5, useState as useState4 } from "react";
|
|
424
|
+
import { scheduleMicroTask } from "@dxos/async";
|
|
425
|
+
import { Context as Context2 } from "@dxos/context";
|
|
426
|
+
import { log as log3 } from "@dxos/log";
|
|
427
|
+
import { useSoundEffect } from "@dxos/react-ui-sfx";
|
|
428
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/plugins/plugin-transcription/src/hooks/useVoiceInput.ts";
|
|
429
|
+
var useVoiceInput = ({ active, onUpdate }) => {
|
|
430
|
+
const soundStart = useSoundEffect("StartRecording");
|
|
431
|
+
const soundStop = useSoundEffect("StopRecording");
|
|
432
|
+
const handleSegments = useCallback(async (segments) => {
|
|
433
|
+
const text = segments.map((str) => str.text.trim().replace(/[^\w\s]/g, "")).join(" ");
|
|
434
|
+
onUpdate(text);
|
|
435
|
+
}, []);
|
|
436
|
+
const [recording, setRecording] = useState4(false);
|
|
437
|
+
const track = useAudioTrack(active);
|
|
438
|
+
const transcriber = useTranscriber({
|
|
439
|
+
audioStreamTrack: track,
|
|
440
|
+
onSegments: handleSegments
|
|
441
|
+
});
|
|
442
|
+
useEffect5(() => {
|
|
443
|
+
const ctx = new Context2(void 0, {
|
|
444
|
+
F: __dxlog_file3,
|
|
445
|
+
L: 44
|
|
446
|
+
});
|
|
447
|
+
scheduleMicroTask(ctx, async () => {
|
|
448
|
+
if (active && transcriber) {
|
|
449
|
+
await transcriber.open();
|
|
450
|
+
log3.info("starting...", void 0, {
|
|
451
|
+
F: __dxlog_file3,
|
|
452
|
+
L: 48,
|
|
453
|
+
S: void 0,
|
|
454
|
+
C: (f, a) => f(...a)
|
|
455
|
+
});
|
|
456
|
+
setRecording(true);
|
|
457
|
+
void soundStart.play();
|
|
458
|
+
transcriber.startChunksRecording();
|
|
459
|
+
} else if (!active && transcriber?.isOpen) {
|
|
460
|
+
transcriber?.stopChunksRecording();
|
|
461
|
+
await transcriber?.close();
|
|
462
|
+
log3.info("stopped", void 0, {
|
|
463
|
+
F: __dxlog_file3,
|
|
464
|
+
L: 55,
|
|
465
|
+
S: void 0,
|
|
466
|
+
C: (f, a) => f(...a)
|
|
467
|
+
});
|
|
468
|
+
setRecording(false);
|
|
469
|
+
void soundStop.play();
|
|
470
|
+
}
|
|
471
|
+
});
|
|
472
|
+
return () => {
|
|
473
|
+
void ctx.dispose();
|
|
474
|
+
};
|
|
475
|
+
}, [
|
|
476
|
+
active,
|
|
477
|
+
transcriber
|
|
478
|
+
]);
|
|
479
|
+
return {
|
|
480
|
+
recording
|
|
481
|
+
};
|
|
482
|
+
};
|
|
483
|
+
|
|
484
|
+
// src/components/Transcript/Transcript.tsx
|
|
485
|
+
import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
|
|
486
|
+
import React from "react";
|
|
487
|
+
import { useThemeContext } from "@dxos/react-ui";
|
|
488
|
+
import { autoScroll, createBasicExtensions, createMarkdownExtensions, createThemeExtensions, decorateMarkdown, editorSlots, preview, useTextEditor } from "@dxos/react-ui-editor";
|
|
489
|
+
import { mx } from "@dxos/react-ui-theme";
|
|
490
|
+
import { isTruthy } from "@dxos/util";
|
|
491
|
+
|
|
220
492
|
// src/components/Transcript/transcript-extension.ts
|
|
221
|
-
|
|
493
|
+
import { RangeSetBuilder } from "@codemirror/state";
|
|
494
|
+
import { EditorView, GutterMarker, ViewPlugin, gutter } from "@codemirror/view";
|
|
495
|
+
import { format } from "date-fns/format";
|
|
496
|
+
import { intervalToDuration } from "date-fns/intervalToDuration";
|
|
497
|
+
import { addEventListener, combine } from "@dxos/async";
|
|
498
|
+
var transcript = ({ model, started }) => {
|
|
222
499
|
return [
|
|
223
500
|
// Show timestamps in the gutter.
|
|
224
501
|
gutter({
|
|
@@ -246,8 +523,11 @@ var transcript = ({ model, started, renderButton }) => {
|
|
|
246
523
|
}),
|
|
247
524
|
// Listen for model updates.
|
|
248
525
|
ViewPlugin.fromClass(class {
|
|
526
|
+
_controls;
|
|
527
|
+
_cleanup;
|
|
528
|
+
_adapter;
|
|
529
|
+
_initialized = false;
|
|
249
530
|
constructor(view) {
|
|
250
|
-
this._initialized = false;
|
|
251
531
|
this._adapter = new DocumentAdapter(view);
|
|
252
532
|
const scroller = view.scrollDOM;
|
|
253
533
|
let isAutoScrolling = false;
|
|
@@ -269,30 +549,20 @@ var transcript = ({ model, started, renderButton }) => {
|
|
|
269
549
|
})
|
|
270
550
|
});
|
|
271
551
|
};
|
|
272
|
-
if (renderButton) {
|
|
273
|
-
this._controls = document.createElement("div");
|
|
274
|
-
this._controls.classList.add("cm-controls", "transition-opacity", "duration-300", "opacity-0");
|
|
275
|
-
view.dom.appendChild(this._controls);
|
|
276
|
-
renderButton(this._controls, {
|
|
277
|
-
onClick: () => {
|
|
278
|
-
scrollToBottom(false);
|
|
279
|
-
}
|
|
280
|
-
}, view);
|
|
281
|
-
}
|
|
282
552
|
this._cleanup = combine(addEventListener(view.scrollDOM, "scroll", () => {
|
|
283
553
|
if (!isAutoScrolling) {
|
|
284
554
|
hasScrolled = true;
|
|
285
555
|
this._controls?.classList.remove("opacity-0");
|
|
286
556
|
}
|
|
287
557
|
}), model.update.on(() => {
|
|
288
|
-
const
|
|
558
|
+
const autoScroll2 = scroller.scrollHeight - scroller.scrollTop - scroller.clientHeight === 0 || !hasScrolled;
|
|
289
559
|
model.sync(this._adapter);
|
|
290
|
-
if (
|
|
560
|
+
if (autoScroll2) {
|
|
291
561
|
scrollToBottom(true);
|
|
292
562
|
}
|
|
293
563
|
}));
|
|
294
564
|
}
|
|
295
|
-
update(
|
|
565
|
+
update(_update) {
|
|
296
566
|
if (!this._initialized) {
|
|
297
567
|
this._initialized = true;
|
|
298
568
|
setTimeout(() => {
|
|
@@ -306,27 +576,12 @@ var transcript = ({ model, started, renderButton }) => {
|
|
|
306
576
|
}
|
|
307
577
|
}),
|
|
308
578
|
EditorView.theme({
|
|
309
|
-
".cm-
|
|
310
|
-
|
|
311
|
-
},
|
|
312
|
-
".cm-hide-scrollbar": {
|
|
313
|
-
scrollbarWidth: "none",
|
|
314
|
-
"-ms-overflow-style": "none"
|
|
315
|
-
},
|
|
316
|
-
".cm-hide-scrollbar::-webkit-scrollbar": {
|
|
317
|
-
display: "none"
|
|
318
|
-
},
|
|
319
|
-
".cm-controls": {
|
|
320
|
-
position: "absolute",
|
|
321
|
-
bottom: "0.5rem",
|
|
322
|
-
right: "0.5rem",
|
|
323
|
-
zIndex: 1e3
|
|
324
|
-
},
|
|
325
|
-
".cm-line": {
|
|
326
|
-
paddingRight: "1rem"
|
|
579
|
+
".cm-gutters": {
|
|
580
|
+
backgroundColor: "var(--dx-baseSurface)"
|
|
327
581
|
},
|
|
328
582
|
".cm-timestamp-gutter": {
|
|
329
583
|
width: "6rem",
|
|
584
|
+
paddingLeft: "0.5rem",
|
|
330
585
|
paddingRight: "1rem"
|
|
331
586
|
},
|
|
332
587
|
".cm-timestamp-gutter > .cm-gutterElement > div": {
|
|
@@ -338,11 +593,14 @@ var transcript = ({ model, started, renderButton }) => {
|
|
|
338
593
|
];
|
|
339
594
|
};
|
|
340
595
|
var TimestampMarker = class extends GutterMarker {
|
|
596
|
+
_line;
|
|
597
|
+
_timestamp;
|
|
598
|
+
_started;
|
|
341
599
|
constructor(_line, _timestamp, _started) {
|
|
342
600
|
super(), this._line = _line, this._timestamp = _timestamp, this._started = _started;
|
|
343
601
|
}
|
|
344
602
|
eq(other) {
|
|
345
|
-
return
|
|
603
|
+
return this._timestamp === other._timestamp;
|
|
346
604
|
}
|
|
347
605
|
toDOM(view) {
|
|
348
606
|
const el = document.createElement("div");
|
|
@@ -382,7 +640,7 @@ var formatTimestamp = (timestamp, relative) => {
|
|
|
382
640
|
};
|
|
383
641
|
|
|
384
642
|
// src/components/Transcript/Transcript.tsx
|
|
385
|
-
var
|
|
643
|
+
var renderByline = (identities) => (message, index, debug = false) => {
|
|
386
644
|
if (message.sender.role === "assistant") {
|
|
387
645
|
return [
|
|
388
646
|
message.blocks.find((block) => block._tag === "transcript")?.text ?? "",
|
|
@@ -393,12 +651,13 @@ var renderMarkdown = (identities) => (message, index, debug = false) => {
|
|
|
393
651
|
const name = identity?.profile?.displayName ?? message.sender.contact?.target?.fullName ?? message.sender.name ?? message.sender.email ?? message.sender.identityDid;
|
|
394
652
|
const blocks = message.blocks.filter((block) => block._tag === "transcript");
|
|
395
653
|
return [
|
|
654
|
+
// TODO(thure): Use an XML tag with the bits needed here.
|
|
396
655
|
`###### ${name}` + (debug ? ` [${index}]:${message.id}` : ""),
|
|
397
656
|
blocks.map((block) => block.text.trim()).join(" "),
|
|
398
657
|
""
|
|
399
658
|
];
|
|
400
659
|
};
|
|
401
|
-
var
|
|
660
|
+
var TranscriptView = ({ classNames, space, transcript: object, model }) => {
|
|
402
661
|
var _effect = _useSignals();
|
|
403
662
|
try {
|
|
404
663
|
const { themeMode } = useThemeContext();
|
|
@@ -407,27 +666,22 @@ var Transcript = ({ classNames, transcript: object, space, model, attendableId,
|
|
|
407
666
|
extensions: [
|
|
408
667
|
createBasicExtensions({
|
|
409
668
|
readOnly: true,
|
|
410
|
-
lineWrapping: true
|
|
411
|
-
|
|
412
|
-
createMarkdownExtensions({
|
|
413
|
-
themeMode
|
|
669
|
+
lineWrapping: true,
|
|
670
|
+
search: true
|
|
414
671
|
}),
|
|
672
|
+
createMarkdownExtensions(),
|
|
415
673
|
createThemeExtensions({
|
|
416
|
-
themeMode
|
|
674
|
+
themeMode,
|
|
675
|
+
slots: editorSlots
|
|
417
676
|
}),
|
|
418
677
|
decorateMarkdown(),
|
|
419
|
-
|
|
678
|
+
preview(),
|
|
420
679
|
transcript({
|
|
421
680
|
model,
|
|
422
|
-
started: object?.started ? new Date(object.started) : void 0
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
label: "Scroll to bottom",
|
|
427
|
-
onClick
|
|
428
|
-
}))
|
|
429
|
-
})
|
|
430
|
-
].filter(isNotFalsy)
|
|
681
|
+
started: object?.started ? new Date(object.started) : void 0
|
|
682
|
+
}),
|
|
683
|
+
autoScroll()
|
|
684
|
+
].filter(isTruthy)
|
|
431
685
|
};
|
|
432
686
|
}, [
|
|
433
687
|
space,
|
|
@@ -435,7 +689,7 @@ var Transcript = ({ classNames, transcript: object, space, model, attendableId,
|
|
|
435
689
|
]);
|
|
436
690
|
return /* @__PURE__ */ React.createElement("div", {
|
|
437
691
|
ref: parentRef,
|
|
438
|
-
className: mx("flex grow overflow-hidden",
|
|
692
|
+
className: mx("flex grow overflow-hidden container-max-width", classNames),
|
|
439
693
|
"data-popover-collision-boundary": true
|
|
440
694
|
});
|
|
441
695
|
} finally {
|
|
@@ -443,298 +697,18 @@ var Transcript = ({ classNames, transcript: object, space, model, attendableId,
|
|
|
443
697
|
}
|
|
444
698
|
};
|
|
445
699
|
|
|
446
|
-
// src/hooks/useAudioFile.ts
|
|
447
|
-
import { useEffect, useState } from "react";
|
|
448
|
-
import { scheduleTask } from "@dxos/async";
|
|
449
|
-
import { Context } from "@dxos/context";
|
|
450
|
-
import { log as log2 } from "@dxos/log";
|
|
451
|
-
var __dxlog_file2 = "/__w/dxos/dxos/packages/plugins/plugin-transcription/src/hooks/useAudioFile.ts";
|
|
452
|
-
var useAudioFile = (audioUrl, constraints) => {
|
|
453
|
-
const [{ audio, stream, track }, setStream] = useState({});
|
|
454
|
-
useEffect(() => {
|
|
455
|
-
const ctx = new Context(void 0, {
|
|
456
|
-
F: __dxlog_file2,
|
|
457
|
-
L: 20
|
|
458
|
-
});
|
|
459
|
-
scheduleTask(ctx, async () => {
|
|
460
|
-
const response = await fetch(audioUrl);
|
|
461
|
-
const blob = await response.blob();
|
|
462
|
-
const objectUrl = URL.createObjectURL(blob);
|
|
463
|
-
ctx.onDispose(() => {
|
|
464
|
-
URL.revokeObjectURL(objectUrl);
|
|
465
|
-
});
|
|
466
|
-
const audio2 = new Audio();
|
|
467
|
-
audio2.src = objectUrl;
|
|
468
|
-
await new Promise((resolve, reject) => {
|
|
469
|
-
audio2.addEventListener("error", (err) => {
|
|
470
|
-
log2.error("error", {
|
|
471
|
-
err
|
|
472
|
-
}, {
|
|
473
|
-
F: __dxlog_file2,
|
|
474
|
-
L: 37,
|
|
475
|
-
S: void 0,
|
|
476
|
-
C: (f, a) => f(...a)
|
|
477
|
-
});
|
|
478
|
-
reject(err);
|
|
479
|
-
}, {
|
|
480
|
-
once: true
|
|
481
|
-
});
|
|
482
|
-
audio2.addEventListener("canplay", async () => {
|
|
483
|
-
log2.info("starting...", void 0, {
|
|
484
|
-
F: __dxlog_file2,
|
|
485
|
-
L: 45,
|
|
486
|
-
S: void 0,
|
|
487
|
-
C: (f, a) => f(...a)
|
|
488
|
-
});
|
|
489
|
-
try {
|
|
490
|
-
await audio2.play();
|
|
491
|
-
resolve();
|
|
492
|
-
} catch (playError) {
|
|
493
|
-
log2.error("Play failed", {
|
|
494
|
-
playError
|
|
495
|
-
}, {
|
|
496
|
-
F: __dxlog_file2,
|
|
497
|
-
L: 51,
|
|
498
|
-
S: void 0,
|
|
499
|
-
C: (f, a) => f(...a)
|
|
500
|
-
});
|
|
501
|
-
resolve();
|
|
502
|
-
}
|
|
503
|
-
}, {
|
|
504
|
-
once: true
|
|
505
|
-
});
|
|
506
|
-
audio2.load();
|
|
507
|
-
});
|
|
508
|
-
const audioCtx = new AudioContext();
|
|
509
|
-
if (audioCtx.state === "suspended") {
|
|
510
|
-
await audioCtx.resume();
|
|
511
|
-
}
|
|
512
|
-
const destination = audioCtx.createMediaStreamDestination();
|
|
513
|
-
destination.channelCount = 1;
|
|
514
|
-
const source = audioCtx.createMediaElementSource(audio2);
|
|
515
|
-
source.connect(destination);
|
|
516
|
-
const track2 = destination.stream.getAudioTracks()[0];
|
|
517
|
-
if (constraints) {
|
|
518
|
-
await track2.applyConstraints(constraints).catch((err) => log2.catch(err, void 0, {
|
|
519
|
-
F: __dxlog_file2,
|
|
520
|
-
L: 75,
|
|
521
|
-
S: void 0,
|
|
522
|
-
C: (f, a) => f(...a)
|
|
523
|
-
}));
|
|
524
|
-
}
|
|
525
|
-
setStream({
|
|
526
|
-
audio: audio2,
|
|
527
|
-
stream: destination.stream,
|
|
528
|
-
track: destination.stream.getAudioTracks()[0]
|
|
529
|
-
});
|
|
530
|
-
});
|
|
531
|
-
return () => {
|
|
532
|
-
void ctx.dispose();
|
|
533
|
-
};
|
|
534
|
-
}, [
|
|
535
|
-
audioUrl
|
|
536
|
-
]);
|
|
537
|
-
return {
|
|
538
|
-
audio,
|
|
539
|
-
stream,
|
|
540
|
-
track
|
|
541
|
-
};
|
|
542
|
-
};
|
|
543
|
-
|
|
544
|
-
// src/hooks/useAudioTrack.ts
|
|
545
|
-
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
546
|
-
var useAudioTrack = (active, constraints) => {
|
|
547
|
-
const [track, setTrack] = useState2();
|
|
548
|
-
useEffect2(() => {
|
|
549
|
-
if (!active) {
|
|
550
|
-
track?.stop();
|
|
551
|
-
setTrack(void 0);
|
|
552
|
-
return;
|
|
553
|
-
}
|
|
554
|
-
const initAudio = async () => {
|
|
555
|
-
const audio = new Audio();
|
|
556
|
-
audio.srcObject = await navigator.mediaDevices.getUserMedia({
|
|
557
|
-
audio: constraints ?? true
|
|
558
|
-
});
|
|
559
|
-
const [track2] = audio.srcObject.getAudioTracks();
|
|
560
|
-
if (track2) {
|
|
561
|
-
setTrack(track2);
|
|
562
|
-
}
|
|
563
|
-
};
|
|
564
|
-
if (active) {
|
|
565
|
-
void initAudio();
|
|
566
|
-
}
|
|
567
|
-
}, [
|
|
568
|
-
active
|
|
569
|
-
]);
|
|
570
|
-
return track;
|
|
571
|
-
};
|
|
572
|
-
|
|
573
|
-
// src/hooks/useQueueModelAdapter.ts
|
|
574
|
-
import { useEffect as useEffect3, useMemo, useState as useState3 } from "react";
|
|
575
|
-
var useQueueModelAdapter = (renderer, queue, initialChunks = []) => {
|
|
576
|
-
const model = useMemo(() => new SerializationModel(renderer, initialChunks), [
|
|
577
|
-
queue
|
|
578
|
-
]);
|
|
579
|
-
const [loaded, setLoaded] = useState3(false);
|
|
580
|
-
useEffect3(() => {
|
|
581
|
-
if (!queue) {
|
|
582
|
-
return;
|
|
583
|
-
}
|
|
584
|
-
const update = () => {
|
|
585
|
-
for (const block of queue?.objects ?? []) {
|
|
586
|
-
model.appendChunk(block);
|
|
587
|
-
}
|
|
588
|
-
setLoaded(true);
|
|
589
|
-
};
|
|
590
|
-
let i;
|
|
591
|
-
if (queue.isLoading) {
|
|
592
|
-
i = setInterval(() => {
|
|
593
|
-
if (!queue?.isLoading) {
|
|
594
|
-
clearInterval(i);
|
|
595
|
-
update();
|
|
596
|
-
}
|
|
597
|
-
}, 1e3);
|
|
598
|
-
} else {
|
|
599
|
-
update();
|
|
600
|
-
}
|
|
601
|
-
return () => clearTimeout(i);
|
|
602
|
-
}, [
|
|
603
|
-
model,
|
|
604
|
-
queue
|
|
605
|
-
]);
|
|
606
|
-
useEffect3(() => {
|
|
607
|
-
if (!loaded || !queue || model.chunks.length === queue.objects.length) {
|
|
608
|
-
return;
|
|
609
|
-
}
|
|
610
|
-
const chunk = queue.objects.at(-1);
|
|
611
|
-
if (chunk) {
|
|
612
|
-
model.appendChunk(chunk);
|
|
613
|
-
}
|
|
614
|
-
}, [
|
|
615
|
-
model,
|
|
616
|
-
loaded,
|
|
617
|
-
queue?.objects.length
|
|
618
|
-
]);
|
|
619
|
-
return model;
|
|
620
|
-
};
|
|
621
|
-
|
|
622
|
-
// src/hooks/useTranscriber.ts
|
|
623
|
-
import { useEffect as useEffect4, useMemo as useMemo2 } from "react";
|
|
624
|
-
import { useCapabilities } from "@dxos/app-framework";
|
|
625
|
-
|
|
626
|
-
// src/capabilities/index.ts
|
|
627
|
-
import { lazy } from "@dxos/app-framework";
|
|
628
|
-
var IntentResolver = lazy(() => import("./intent-resolver-3O33MMP5.mjs"));
|
|
629
|
-
var ReactSurface = lazy(() => import("./react-surface-E5D5AE3F.mjs"));
|
|
630
|
-
var Transcriber = lazy(() => import("./transcriber-PXT4QBFY.mjs"));
|
|
631
|
-
|
|
632
|
-
// src/hooks/useTranscriber.ts
|
|
633
|
-
var useTranscriber = ({ audioStreamTrack, recorderConfig, transcriberConfig, onSegments }) => {
|
|
634
|
-
const [getTranscriber] = useCapabilities(TranscriptionCapabilities.Transcriber);
|
|
635
|
-
const transcriber = useMemo2(() => {
|
|
636
|
-
if (!getTranscriber || !audioStreamTrack || !onSegments) {
|
|
637
|
-
return void 0;
|
|
638
|
-
}
|
|
639
|
-
return getTranscriber({
|
|
640
|
-
audioStreamTrack,
|
|
641
|
-
recorderConfig,
|
|
642
|
-
transcriberConfig,
|
|
643
|
-
onSegments
|
|
644
|
-
});
|
|
645
|
-
}, [
|
|
646
|
-
getTranscriber,
|
|
647
|
-
audioStreamTrack,
|
|
648
|
-
recorderConfig,
|
|
649
|
-
transcriberConfig,
|
|
650
|
-
onSegments
|
|
651
|
-
]);
|
|
652
|
-
useEffect4(() => {
|
|
653
|
-
return () => {
|
|
654
|
-
void transcriber?.close();
|
|
655
|
-
};
|
|
656
|
-
}, [
|
|
657
|
-
transcriber
|
|
658
|
-
]);
|
|
659
|
-
return transcriber;
|
|
660
|
-
};
|
|
661
|
-
|
|
662
|
-
// src/hooks/useVoiceInput.ts
|
|
663
|
-
import { useState as useState4, useEffect as useEffect5, useCallback } from "react";
|
|
664
|
-
import { scheduleMicroTask } from "@dxos/async";
|
|
665
|
-
import { Context as Context2 } from "@dxos/context";
|
|
666
|
-
import { log as log3 } from "@dxos/log";
|
|
667
|
-
import { useSoundEffect } from "@dxos/react-ui-sfx";
|
|
668
|
-
var __dxlog_file3 = "/__w/dxos/dxos/packages/plugins/plugin-transcription/src/hooks/useVoiceInput.ts";
|
|
669
|
-
var useVoiceInput = ({ active, onUpdate }) => {
|
|
670
|
-
const soundStart = useSoundEffect("StartRecording");
|
|
671
|
-
const soundStop = useSoundEffect("StopRecording");
|
|
672
|
-
const handleSegments = useCallback(async (segments) => {
|
|
673
|
-
const text = segments.map((str) => str.text.trim().replace(/[^\w\s]/g, "")).join(" ");
|
|
674
|
-
onUpdate(text);
|
|
675
|
-
}, []);
|
|
676
|
-
const [recording, setRecording] = useState4(false);
|
|
677
|
-
const track = useAudioTrack(active);
|
|
678
|
-
const transcriber = useTranscriber({
|
|
679
|
-
audioStreamTrack: track,
|
|
680
|
-
onSegments: handleSegments
|
|
681
|
-
});
|
|
682
|
-
useEffect5(() => {
|
|
683
|
-
const ctx = new Context2(void 0, {
|
|
684
|
-
F: __dxlog_file3,
|
|
685
|
-
L: 43
|
|
686
|
-
});
|
|
687
|
-
scheduleMicroTask(ctx, async () => {
|
|
688
|
-
if (active && transcriber) {
|
|
689
|
-
await transcriber.open();
|
|
690
|
-
log3.info("starting...", void 0, {
|
|
691
|
-
F: __dxlog_file3,
|
|
692
|
-
L: 47,
|
|
693
|
-
S: void 0,
|
|
694
|
-
C: (f, a) => f(...a)
|
|
695
|
-
});
|
|
696
|
-
setRecording(true);
|
|
697
|
-
void soundStart.play();
|
|
698
|
-
transcriber.startChunksRecording();
|
|
699
|
-
} else if (!active && transcriber?.isOpen) {
|
|
700
|
-
transcriber?.stopChunksRecording();
|
|
701
|
-
await transcriber?.close();
|
|
702
|
-
log3.info("stopped", void 0, {
|
|
703
|
-
F: __dxlog_file3,
|
|
704
|
-
L: 54,
|
|
705
|
-
S: void 0,
|
|
706
|
-
C: (f, a) => f(...a)
|
|
707
|
-
});
|
|
708
|
-
setRecording(false);
|
|
709
|
-
void soundStop.play();
|
|
710
|
-
}
|
|
711
|
-
});
|
|
712
|
-
return () => {
|
|
713
|
-
void ctx.dispose();
|
|
714
|
-
};
|
|
715
|
-
}, [
|
|
716
|
-
active,
|
|
717
|
-
transcriber
|
|
718
|
-
]);
|
|
719
|
-
return {
|
|
720
|
-
recording
|
|
721
|
-
};
|
|
722
|
-
};
|
|
723
|
-
|
|
724
700
|
// src/components/TranscriptContainer.tsx
|
|
725
701
|
var TranscriptionContainer = ({ transcript: transcript2 }) => {
|
|
726
702
|
var _effect = _useSignals2();
|
|
727
703
|
try {
|
|
728
|
-
const attendableId =
|
|
704
|
+
const attendableId = Obj.getDXN(transcript2).toString();
|
|
729
705
|
const space = getSpace(transcript2);
|
|
730
706
|
const members = useMembers(space?.key).map((member) => member.identity);
|
|
731
707
|
const queue = useQueue(transcript2.queue.dxn, {
|
|
732
708
|
pollInterval: 1e3
|
|
733
709
|
});
|
|
734
|
-
const model = useQueueModelAdapter(
|
|
735
|
-
return /* @__PURE__ */ React2.createElement(StackItem.Content, {
|
|
736
|
-
classNames: "container-max-width pli-2"
|
|
737
|
-
}, /* @__PURE__ */ React2.createElement(Transcript, {
|
|
710
|
+
const model = useQueueModelAdapter(renderByline(members), queue);
|
|
711
|
+
return /* @__PURE__ */ React2.createElement(StackItem.Content, null, /* @__PURE__ */ React2.createElement(TranscriptView, {
|
|
738
712
|
attendableId,
|
|
739
713
|
space,
|
|
740
714
|
model,
|
|
@@ -747,8 +721,8 @@ var TranscriptionContainer = ({ transcript: transcript2 }) => {
|
|
|
747
721
|
var TranscriptContainer_default = TranscriptionContainer;
|
|
748
722
|
|
|
749
723
|
export {
|
|
750
|
-
|
|
751
|
-
|
|
724
|
+
renderByline,
|
|
725
|
+
TranscriptView,
|
|
752
726
|
useAudioFile,
|
|
753
727
|
useAudioTrack,
|
|
754
728
|
useQueueModelAdapter,
|
|
@@ -756,8 +730,9 @@ export {
|
|
|
756
730
|
useVoiceInput,
|
|
757
731
|
TranscriptionContainer,
|
|
758
732
|
TranscriptContainer_default,
|
|
733
|
+
BlueprintDefinition,
|
|
759
734
|
IntentResolver,
|
|
760
735
|
ReactSurface,
|
|
761
736
|
Transcriber
|
|
762
737
|
};
|
|
763
|
-
//# sourceMappingURL=chunk-
|
|
738
|
+
//# sourceMappingURL=chunk-EHT3TE6U.mjs.map
|