@dxos/plugin-transcription 0.8.4-main.2e9d522 → 0.8.4-main.5ea62a8
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-OX7OOODC.mjs +11 -0
- package/dist/lib/browser/blueprint-definition-QQSGTX5F.mjs +142 -0
- package/dist/lib/browser/blueprint-definition-QQSGTX5F.mjs.map +7 -0
- package/dist/lib/browser/{chunk-4FJIYH7T.mjs → chunk-26XDG6GQ.mjs} +2 -2
- package/dist/lib/browser/{chunk-5WH45KBY.mjs → chunk-3X7HP44M.mjs} +8 -1
- package/dist/lib/browser/{chunk-5WH45KBY.mjs.map → chunk-3X7HP44M.mjs.map} +1 -1
- package/dist/lib/browser/{chunk-5KPYIC3N.mjs → chunk-5I4BMOGE.mjs} +422 -402
- package/dist/lib/browser/chunk-5I4BMOGE.mjs.map +7 -0
- package/dist/lib/browser/{chunk-FFEPEPCU.mjs → chunk-BA64VLLR.mjs} +85 -94
- package/dist/lib/browser/chunk-BA64VLLR.mjs.map +7 -0
- package/dist/lib/browser/chunk-HXVGV7T6.mjs +63 -0
- package/dist/lib/browser/chunk-HXVGV7T6.mjs.map +7 -0
- package/dist/lib/browser/{chunk-U6QBOGTN.mjs → chunk-TNEQFHIU.mjs} +2 -2
- package/dist/lib/browser/{chunk-U6QBOGTN.mjs.map → chunk-TNEQFHIU.mjs.map} +1 -1
- package/dist/lib/browser/index.mjs +18 -12
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/intent-resolver-T3EGLS3L.mjs +25 -0
- package/dist/lib/browser/intent-resolver-T3EGLS3L.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{react-surface-E5D5AE3F.mjs → react-surface-QYX74JNG.mjs} +8 -8
- package/dist/lib/browser/react-surface-QYX74JNG.mjs.map +7 -0
- package/dist/lib/browser/{transcriber-PXT4QBFY.mjs → transcriber-JOOAQVYV.mjs} +5 -5
- package/dist/lib/browser/transcriber-JOOAQVYV.mjs.map +7 -0
- package/dist/lib/browser/types/index.mjs +6 -8
- package/dist/lib/node-esm/{TranscriptContainer-VBAOM5DG.mjs → TranscriptContainer-BUWK63SI.mjs} +4 -4
- package/dist/lib/node-esm/blueprint-definition-4PLCTH5Q.mjs +143 -0
- package/dist/lib/node-esm/blueprint-definition-4PLCTH5Q.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-RHF2ALML.mjs → chunk-3QAIZGMW.mjs} +2 -2
- package/dist/lib/node-esm/{chunk-RHF2ALML.mjs.map → chunk-3QAIZGMW.mjs.map} +1 -1
- package/dist/lib/node-esm/{chunk-TJKAO7VR.mjs → chunk-DT3AOC3E.mjs} +422 -402
- package/dist/lib/node-esm/chunk-DT3AOC3E.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-HT3W7LDP.mjs → chunk-J5GQ3KGX.mjs} +85 -94
- package/dist/lib/node-esm/chunk-J5GQ3KGX.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-Y2B4HWSS.mjs → chunk-NWD757KH.mjs} +2 -2
- package/dist/lib/node-esm/{chunk-XMUCZBP3.mjs → chunk-QARUDLHN.mjs} +7 -1
- package/dist/lib/node-esm/{chunk-XMUCZBP3.mjs.map → chunk-QARUDLHN.mjs.map} +1 -1
- package/dist/lib/node-esm/chunk-W72HVQMD.mjs +64 -0
- package/dist/lib/node-esm/chunk-W72HVQMD.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +18 -12
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/intent-resolver-VDHCUAIO.mjs +26 -0
- package/dist/lib/node-esm/intent-resolver-VDHCUAIO.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{react-surface-QRDJOHN5.mjs → react-surface-TM7XOQBR.mjs} +8 -8
- package/dist/lib/node-esm/react-surface-TM7XOQBR.mjs.map +7 -0
- package/dist/lib/node-esm/{transcriber-YUTEVANE.mjs → transcriber-QPS55YP2.mjs} +5 -5
- package/dist/lib/node-esm/transcriber-QPS55YP2.mjs.map +7 -0
- package/dist/lib/node-esm/types/index.mjs +6 -8
- 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 +4 -4
- package/dist/types/src/components/Transcript/Transcript.d.ts.map +1 -1
- package/dist/types/src/components/Transcript/Transcript.stories.d.ts +32 -15
- package/dist/types/src/components/Transcript/Transcript.stories.d.ts.map +1 -1
- package/dist/types/src/components/Transcript/deprecated/OldTranscript.d.ts +2 -2
- package/dist/types/src/components/Transcript/deprecated/OldTranscript.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 -2
- package/dist/types/src/components/stories/FileTranscription.stories.d.ts.map +1 -1
- package/dist/types/src/components/stories/KeyWordRecognition.stories.d.ts +10 -5
- package/dist/types/src/components/stories/KeyWordRecognition.stories.d.ts.map +1 -1
- package/dist/types/src/components/stories/MicrophoneTranscription.stories.d.ts +7 -4
- package/dist/types/src/components/stories/MicrophoneTranscription.stories.d.ts.map +1 -1
- package/dist/types/src/components/stories/TranscriptionStory.d.ts +1 -0
- 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/useVoiceInput.d.ts.map +1 -1
- package/dist/types/src/segments-normalization/normalization.d.ts +366 -321
- package/dist/types/src/segments-normalization/normalization.d.ts.map +1 -1
- package/dist/types/src/testing/testing.d.ts +1 -1
- 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.map +1 -1
- package/dist/types/src/transcriber/transcription-manager.d.ts +3 -7
- 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 +55 -53
- package/src/TranscriptionPlugin.tsx +10 -5
- package/src/capabilities/blueprint-definition.ts +31 -0
- package/src/capabilities/capabilities.ts +3 -3
- 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 +12 -13
- package/src/components/Transcript/Transcript.tsx +8 -7
- package/src/components/Transcript/deprecated/OldTranscript.tsx +4 -4
- package/src/components/TranscriptContainer.tsx +5 -4
- package/src/components/stories/FileTranscription.stories.tsx +22 -12
- package/src/components/stories/KeyWordRecognition.stories.tsx +12 -6
- package/src/components/stories/MicrophoneTranscription.stories.tsx +10 -9
- package/src/components/stories/TranscriptionStory.tsx +9 -5
- package/src/functions/index.ts +6 -0
- package/src/functions/open.ts +37 -0
- package/src/functions/summarize.ts +97 -0
- package/src/hooks/useAudioFile.ts +1 -10
- package/src/hooks/useVoiceInput.ts +3 -2
- package/src/model/model.test.ts +1 -1
- package/src/segments-normalization/message-normalizer.ts +1 -1
- package/src/segments-normalization/normalization.test.ts +4 -4
- package/src/segments-normalization/normalization.ts +37 -36
- package/src/testing/testing.ts +3 -3
- package/src/transcriber/media-stream-recorder.ts +1 -1
- package/src/transcriber/transcriber.browser.test.ts +2 -1
- package/src/transcriber/transcriber.ts +2 -1
- package/src/transcriber/transcription-manager.ts +17 -38
- package/src/types/{schema.ts → Transcript.ts} +11 -8
- 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-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/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-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/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-OX7OOODC.mjs.map} +0 -0
- /package/dist/lib/browser/{chunk-4FJIYH7T.mjs.map → chunk-26XDG6GQ.mjs.map} +0 -0
- /package/dist/lib/node-esm/{TranscriptContainer-VBAOM5DG.mjs.map → TranscriptContainer-BUWK63SI.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-Y2B4HWSS.mjs.map → chunk-NWD757KH.mjs.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
TranscriptionCapabilities
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-TNEQFHIU.mjs";
|
|
4
4
|
|
|
5
5
|
// src/components/TranscriptContainer.tsx
|
|
6
6
|
import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
|
|
@@ -9,43 +9,149 @@ import { fullyQualifiedId, getSpace } from "@dxos/client/echo";
|
|
|
9
9
|
import { useMembers, useQueue } from "@dxos/react-client/echo";
|
|
10
10
|
import { StackItem } from "@dxos/react-ui-stack";
|
|
11
11
|
|
|
12
|
-
// src/
|
|
13
|
-
import {
|
|
14
|
-
import
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
// src/hooks/useAudioFile.ts
|
|
13
|
+
import { useEffect, useState } from "react";
|
|
14
|
+
import { scheduleTask } from "@dxos/async";
|
|
15
|
+
import { Context } from "@dxos/context";
|
|
16
|
+
import { log } from "@dxos/log";
|
|
17
|
+
var __dxlog_file = "/__w/dxos/dxos/packages/plugins/plugin-transcription/src/hooks/useAudioFile.ts";
|
|
18
|
+
var useAudioFile = (audioUrl, constraints) => {
|
|
19
|
+
const [{ audio, stream, track }, setStream] = useState({});
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
const ctx = new Context(void 0, {
|
|
22
|
+
F: __dxlog_file,
|
|
23
|
+
L: 20
|
|
24
|
+
});
|
|
25
|
+
scheduleTask(ctx, async () => {
|
|
26
|
+
const response = await fetch(audioUrl);
|
|
27
|
+
const blob = await response.blob();
|
|
28
|
+
const objectUrl = URL.createObjectURL(blob);
|
|
29
|
+
ctx.onDispose(() => {
|
|
30
|
+
URL.revokeObjectURL(objectUrl);
|
|
31
|
+
});
|
|
32
|
+
const audio2 = new Audio();
|
|
33
|
+
audio2.src = objectUrl;
|
|
34
|
+
await new Promise((resolve, reject) => {
|
|
35
|
+
audio2.addEventListener("error", (err) => {
|
|
36
|
+
log.error("error", {
|
|
37
|
+
err
|
|
38
|
+
}, {
|
|
39
|
+
F: __dxlog_file,
|
|
40
|
+
L: 37,
|
|
41
|
+
S: void 0,
|
|
42
|
+
C: (f, a) => f(...a)
|
|
43
|
+
});
|
|
44
|
+
reject(err);
|
|
45
|
+
}, {
|
|
46
|
+
once: true
|
|
47
|
+
});
|
|
48
|
+
audio2.addEventListener("canplay", async () => {
|
|
49
|
+
resolve();
|
|
50
|
+
}, {
|
|
51
|
+
once: true
|
|
52
|
+
});
|
|
53
|
+
audio2.load();
|
|
54
|
+
});
|
|
55
|
+
const audioCtx = new AudioContext();
|
|
56
|
+
if (audioCtx.state === "suspended") {
|
|
57
|
+
await audioCtx.resume();
|
|
58
|
+
}
|
|
59
|
+
const destination = audioCtx.createMediaStreamDestination();
|
|
60
|
+
destination.channelCount = 1;
|
|
61
|
+
const source = audioCtx.createMediaElementSource(audio2);
|
|
62
|
+
source.connect(destination);
|
|
63
|
+
const track2 = destination.stream.getAudioTracks()[0];
|
|
64
|
+
if (constraints) {
|
|
65
|
+
await track2.applyConstraints(constraints).catch((err) => log.catch(err, void 0, {
|
|
66
|
+
F: __dxlog_file,
|
|
67
|
+
L: 66,
|
|
68
|
+
S: void 0,
|
|
69
|
+
C: (f, a) => f(...a)
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
setStream({
|
|
73
|
+
audio: audio2,
|
|
74
|
+
stream: destination.stream,
|
|
75
|
+
track: destination.stream.getAudioTracks()[0]
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
return () => {
|
|
79
|
+
void ctx.dispose();
|
|
80
|
+
};
|
|
81
|
+
}, [
|
|
82
|
+
audioUrl
|
|
83
|
+
]);
|
|
84
|
+
return {
|
|
85
|
+
audio,
|
|
86
|
+
stream,
|
|
87
|
+
track
|
|
88
|
+
};
|
|
89
|
+
};
|
|
19
90
|
|
|
20
|
-
// src/
|
|
21
|
-
import {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
91
|
+
// src/hooks/useAudioTrack.ts
|
|
92
|
+
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
93
|
+
var useAudioTrack = (active, constraints) => {
|
|
94
|
+
const [track, setTrack] = useState2();
|
|
95
|
+
useEffect2(() => {
|
|
96
|
+
if (!active) {
|
|
97
|
+
track?.stop();
|
|
98
|
+
setTrack(void 0);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const initAudio = async () => {
|
|
102
|
+
const audio = new Audio();
|
|
103
|
+
audio.srcObject = await navigator.mediaDevices.getUserMedia({
|
|
104
|
+
audio: constraints ?? true
|
|
105
|
+
});
|
|
106
|
+
const [track2] = audio.srcObject.getAudioTracks();
|
|
107
|
+
if (track2) {
|
|
108
|
+
setTrack(track2);
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
if (active) {
|
|
112
|
+
void initAudio();
|
|
113
|
+
}
|
|
114
|
+
}, [
|
|
115
|
+
active
|
|
116
|
+
]);
|
|
117
|
+
return track;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
// src/hooks/useQueueModelAdapter.ts
|
|
121
|
+
import { useEffect as useEffect3, useMemo, useState as useState3 } from "react";
|
|
26
122
|
|
|
27
123
|
// src/model/model.ts
|
|
28
124
|
import { Text } from "@codemirror/state";
|
|
29
125
|
import { Event } from "@dxos/async";
|
|
30
126
|
import { invariant } from "@dxos/invariant";
|
|
31
|
-
import { log } from "@dxos/log";
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
127
|
+
import { log as log2 } from "@dxos/log";
|
|
128
|
+
function _define_property(obj, key, value) {
|
|
129
|
+
if (key in obj) {
|
|
130
|
+
Object.defineProperty(obj, key, {
|
|
131
|
+
value,
|
|
132
|
+
enumerable: true,
|
|
133
|
+
configurable: true,
|
|
134
|
+
writable: true
|
|
135
|
+
});
|
|
136
|
+
} else {
|
|
137
|
+
obj[key] = value;
|
|
36
138
|
}
|
|
139
|
+
return obj;
|
|
140
|
+
}
|
|
141
|
+
var __dxlog_file2 = "/__w/dxos/dxos/packages/plugins/plugin-transcription/src/model/model.ts";
|
|
142
|
+
var DocumentAdapter = class {
|
|
37
143
|
/** The document must always have at least one line. */
|
|
38
144
|
lineCount() {
|
|
39
145
|
return this._view.state.doc.lines - 1;
|
|
40
146
|
}
|
|
41
147
|
replaceLines(from, remove, insert) {
|
|
42
|
-
|
|
148
|
+
log2("replaceLines", {
|
|
43
149
|
count: this._view.state.doc.lines,
|
|
44
150
|
from,
|
|
45
151
|
remove,
|
|
46
152
|
insert
|
|
47
153
|
}, {
|
|
48
|
-
F:
|
|
154
|
+
F: __dxlog_file2,
|
|
49
155
|
L: 39,
|
|
50
156
|
S: this,
|
|
51
157
|
C: (f, a) => f(...a)
|
|
@@ -65,19 +171,12 @@ var DocumentAdapter = class {
|
|
|
65
171
|
}
|
|
66
172
|
});
|
|
67
173
|
}
|
|
174
|
+
constructor(_view) {
|
|
175
|
+
_define_property(this, "_view", void 0);
|
|
176
|
+
this._view = _view;
|
|
177
|
+
}
|
|
68
178
|
};
|
|
69
179
|
var SerializationModel = class {
|
|
70
|
-
constructor(_renderer, initialChunks = []) {
|
|
71
|
-
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
|
-
initialChunks.forEach((chunk) => {
|
|
78
|
-
this.appendChunk(chunk);
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
180
|
toJSON() {
|
|
82
181
|
return {
|
|
83
182
|
chunks: this._chunks.length,
|
|
@@ -120,7 +219,7 @@ var SerializationModel = class {
|
|
|
120
219
|
updateChunk(chunk) {
|
|
121
220
|
const index = this._chunks.findIndex((c) => c.id === chunk.id);
|
|
122
221
|
invariant(index !== -1, void 0, {
|
|
123
|
-
F:
|
|
222
|
+
F: __dxlog_file2,
|
|
124
223
|
L: 147,
|
|
125
224
|
S: this,
|
|
126
225
|
A: [
|
|
@@ -140,7 +239,7 @@ var SerializationModel = class {
|
|
|
140
239
|
deleteBlock(id) {
|
|
141
240
|
const index = this._chunks.findIndex((c) => c.id === id);
|
|
142
241
|
invariant(index !== -1, void 0, {
|
|
143
|
-
F:
|
|
242
|
+
F: __dxlog_file2,
|
|
144
243
|
L: 156,
|
|
145
244
|
S: this,
|
|
146
245
|
A: [
|
|
@@ -161,10 +260,10 @@ var SerializationModel = class {
|
|
|
161
260
|
* Syncs the tracked changes with the ChunkDocument.
|
|
162
261
|
*/
|
|
163
262
|
sync(document2) {
|
|
164
|
-
|
|
263
|
+
log2("sync", {
|
|
165
264
|
changes: this._changes
|
|
166
265
|
}, {
|
|
167
|
-
F:
|
|
266
|
+
F: __dxlog_file2,
|
|
168
267
|
L: 167,
|
|
169
268
|
S: this,
|
|
170
269
|
C: (f, a) => f(...a)
|
|
@@ -215,95 +314,292 @@ var SerializationModel = class {
|
|
|
215
314
|
this._changes.length = 0;
|
|
216
315
|
return this;
|
|
217
316
|
}
|
|
317
|
+
constructor(_renderer, initialChunks = []) {
|
|
318
|
+
_define_property(this, "_renderer", void 0);
|
|
319
|
+
_define_property(this, "_chunks", void 0);
|
|
320
|
+
_define_property(this, "_chunkLineCounts", void 0);
|
|
321
|
+
_define_property(this, "_lineToChunk", void 0);
|
|
322
|
+
_define_property(this, "_changes", void 0);
|
|
323
|
+
_define_property(this, "update", void 0);
|
|
324
|
+
this._renderer = _renderer;
|
|
325
|
+
this._chunks = [];
|
|
326
|
+
this._chunkLineCounts = /* @__PURE__ */ new Map();
|
|
327
|
+
this._lineToChunk = /* @__PURE__ */ new Map();
|
|
328
|
+
this._changes = [];
|
|
329
|
+
this.update = new Event();
|
|
330
|
+
initialChunks.forEach((chunk) => {
|
|
331
|
+
this.appendChunk(chunk);
|
|
332
|
+
});
|
|
333
|
+
}
|
|
218
334
|
};
|
|
219
335
|
|
|
220
|
-
// src/
|
|
221
|
-
var
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
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();
|
|
245
|
-
}
|
|
246
|
-
}),
|
|
247
|
-
// Listen for model updates.
|
|
248
|
-
ViewPlugin.fromClass(class {
|
|
249
|
-
constructor(view) {
|
|
250
|
-
this._initialized = false;
|
|
251
|
-
this._adapter = new DocumentAdapter(view);
|
|
252
|
-
const scroller = view.scrollDOM;
|
|
253
|
-
let isAutoScrolling = false;
|
|
254
|
-
let hasScrolled = false;
|
|
255
|
-
let timeout;
|
|
256
|
-
const scrollToBottom = (smooth = false) => {
|
|
257
|
-
scroller.style.scrollBehavior = smooth ? "smooth" : "";
|
|
258
|
-
scroller.classList.add("cm-hide-scrollbar");
|
|
259
|
-
isAutoScrolling = true;
|
|
260
|
-
clearTimeout(timeout);
|
|
261
|
-
timeout = setTimeout(() => {
|
|
262
|
-
this._controls?.classList.add("opacity-0");
|
|
263
|
-
scroller.classList.remove("cm-hide-scrollbar");
|
|
264
|
-
isAutoScrolling = false;
|
|
265
|
-
}, 500);
|
|
266
|
-
view.dispatch({
|
|
267
|
-
effects: EditorView.scrollIntoView(view.state.doc.length, {
|
|
268
|
-
y: "end"
|
|
269
|
-
})
|
|
270
|
-
});
|
|
271
|
-
};
|
|
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
|
-
this._cleanup = combine(addEventListener(view.scrollDOM, "scroll", () => {
|
|
283
|
-
if (!isAutoScrolling) {
|
|
284
|
-
hasScrolled = true;
|
|
285
|
-
this._controls?.classList.remove("opacity-0");
|
|
286
|
-
}
|
|
287
|
-
}), model.update.on(() => {
|
|
288
|
-
const autoScroll = scroller.scrollHeight - scroller.scrollTop - scroller.clientHeight === 0 || !hasScrolled;
|
|
289
|
-
model.sync(this._adapter);
|
|
290
|
-
if (autoScroll) {
|
|
291
|
-
scrollToBottom(true);
|
|
292
|
-
}
|
|
293
|
-
}));
|
|
336
|
+
// src/hooks/useQueueModelAdapter.ts
|
|
337
|
+
var useQueueModelAdapter = (renderer, queue, initialChunks = []) => {
|
|
338
|
+
const model = useMemo(() => new SerializationModel(renderer, initialChunks), [
|
|
339
|
+
queue
|
|
340
|
+
]);
|
|
341
|
+
const [loaded, setLoaded] = useState3(false);
|
|
342
|
+
useEffect3(() => {
|
|
343
|
+
if (!queue) {
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
const update = () => {
|
|
347
|
+
for (const block of queue?.objects ?? []) {
|
|
348
|
+
model.appendChunk(block);
|
|
294
349
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
350
|
+
setLoaded(true);
|
|
351
|
+
};
|
|
352
|
+
let i;
|
|
353
|
+
if (queue.isLoading) {
|
|
354
|
+
i = setInterval(() => {
|
|
355
|
+
if (!queue?.isLoading) {
|
|
356
|
+
clearInterval(i);
|
|
357
|
+
update();
|
|
358
|
+
}
|
|
359
|
+
}, 1e3);
|
|
360
|
+
} else {
|
|
361
|
+
update();
|
|
362
|
+
}
|
|
363
|
+
return () => clearTimeout(i);
|
|
364
|
+
}, [
|
|
365
|
+
model,
|
|
366
|
+
queue
|
|
367
|
+
]);
|
|
368
|
+
useEffect3(() => {
|
|
369
|
+
if (!loaded || !queue || model.chunks.length === queue.objects.length) {
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
const chunk = queue.objects.at(-1);
|
|
373
|
+
if (chunk) {
|
|
374
|
+
model.appendChunk(chunk);
|
|
375
|
+
}
|
|
376
|
+
}, [
|
|
377
|
+
model,
|
|
378
|
+
loaded,
|
|
379
|
+
queue?.objects.length
|
|
380
|
+
]);
|
|
381
|
+
return model;
|
|
382
|
+
};
|
|
383
|
+
|
|
384
|
+
// src/hooks/useTranscriber.ts
|
|
385
|
+
import { useEffect as useEffect4, useMemo as useMemo2 } from "react";
|
|
386
|
+
import { useCapabilities } from "@dxos/app-framework";
|
|
387
|
+
|
|
388
|
+
// src/capabilities/index.ts
|
|
389
|
+
import { lazy } from "@dxos/app-framework";
|
|
390
|
+
var BlueprintDefinition = lazy(() => import("./blueprint-definition-QQSGTX5F.mjs"));
|
|
391
|
+
var IntentResolver = lazy(() => import("./intent-resolver-T3EGLS3L.mjs"));
|
|
392
|
+
var ReactSurface = lazy(() => import("./react-surface-QYX74JNG.mjs"));
|
|
393
|
+
var Transcriber = lazy(() => import("./transcriber-JOOAQVYV.mjs"));
|
|
394
|
+
|
|
395
|
+
// src/hooks/useTranscriber.ts
|
|
396
|
+
var useTranscriber = ({ audioStreamTrack, recorderConfig, transcriberConfig, onSegments }) => {
|
|
397
|
+
const [getTranscriber] = useCapabilities(TranscriptionCapabilities.Transcriber);
|
|
398
|
+
const transcriber = useMemo2(() => {
|
|
399
|
+
if (!getTranscriber || !audioStreamTrack || !onSegments) {
|
|
400
|
+
return void 0;
|
|
401
|
+
}
|
|
402
|
+
return getTranscriber({
|
|
403
|
+
audioStreamTrack,
|
|
404
|
+
recorderConfig,
|
|
405
|
+
transcriberConfig,
|
|
406
|
+
onSegments
|
|
407
|
+
});
|
|
408
|
+
}, [
|
|
409
|
+
getTranscriber,
|
|
410
|
+
audioStreamTrack,
|
|
411
|
+
recorderConfig,
|
|
412
|
+
transcriberConfig,
|
|
413
|
+
onSegments
|
|
414
|
+
]);
|
|
415
|
+
useEffect4(() => {
|
|
416
|
+
return () => {
|
|
417
|
+
void transcriber?.close();
|
|
418
|
+
};
|
|
419
|
+
}, [
|
|
420
|
+
transcriber
|
|
421
|
+
]);
|
|
422
|
+
return transcriber;
|
|
423
|
+
};
|
|
424
|
+
|
|
425
|
+
// src/hooks/useVoiceInput.ts
|
|
426
|
+
import { useCallback, useEffect as useEffect5, useState as useState4 } from "react";
|
|
427
|
+
import { scheduleMicroTask } from "@dxos/async";
|
|
428
|
+
import { Context as Context2 } from "@dxos/context";
|
|
429
|
+
import { log as log3 } from "@dxos/log";
|
|
430
|
+
import { useSoundEffect } from "@dxos/react-ui-sfx";
|
|
431
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/plugins/plugin-transcription/src/hooks/useVoiceInput.ts";
|
|
432
|
+
var useVoiceInput = ({ active, onUpdate }) => {
|
|
433
|
+
const soundStart = useSoundEffect("StartRecording");
|
|
434
|
+
const soundStop = useSoundEffect("StopRecording");
|
|
435
|
+
const handleSegments = useCallback(async (segments) => {
|
|
436
|
+
const text = segments.map((str) => str.text.trim().replace(/[^\w\s]/g, "")).join(" ");
|
|
437
|
+
onUpdate(text);
|
|
438
|
+
}, []);
|
|
439
|
+
const [recording, setRecording] = useState4(false);
|
|
440
|
+
const track = useAudioTrack(active);
|
|
441
|
+
const transcriber = useTranscriber({
|
|
442
|
+
audioStreamTrack: track,
|
|
443
|
+
onSegments: handleSegments
|
|
444
|
+
});
|
|
445
|
+
useEffect5(() => {
|
|
446
|
+
const ctx = new Context2(void 0, {
|
|
447
|
+
F: __dxlog_file3,
|
|
448
|
+
L: 44
|
|
449
|
+
});
|
|
450
|
+
scheduleMicroTask(ctx, async () => {
|
|
451
|
+
if (active && transcriber) {
|
|
452
|
+
await transcriber.open();
|
|
453
|
+
log3.info("starting...", void 0, {
|
|
454
|
+
F: __dxlog_file3,
|
|
455
|
+
L: 48,
|
|
456
|
+
S: void 0,
|
|
457
|
+
C: (f, a) => f(...a)
|
|
458
|
+
});
|
|
459
|
+
setRecording(true);
|
|
460
|
+
void soundStart.play();
|
|
461
|
+
transcriber.startChunksRecording();
|
|
462
|
+
} else if (!active && transcriber?.isOpen) {
|
|
463
|
+
transcriber?.stopChunksRecording();
|
|
464
|
+
await transcriber?.close();
|
|
465
|
+
log3.info("stopped", void 0, {
|
|
466
|
+
F: __dxlog_file3,
|
|
467
|
+
L: 55,
|
|
468
|
+
S: void 0,
|
|
469
|
+
C: (f, a) => f(...a)
|
|
470
|
+
});
|
|
471
|
+
setRecording(false);
|
|
472
|
+
void soundStop.play();
|
|
473
|
+
}
|
|
474
|
+
});
|
|
475
|
+
return () => {
|
|
476
|
+
void ctx.dispose();
|
|
477
|
+
};
|
|
478
|
+
}, [
|
|
479
|
+
active,
|
|
480
|
+
transcriber
|
|
481
|
+
]);
|
|
482
|
+
return {
|
|
483
|
+
recording
|
|
484
|
+
};
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
// src/components/Transcript/Transcript.tsx
|
|
488
|
+
import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
|
|
489
|
+
import React from "react";
|
|
490
|
+
import { IconButton, useThemeContext } from "@dxos/react-ui";
|
|
491
|
+
import { createBasicExtensions, createMarkdownExtensions, createRenderer, createThemeExtensions, decorateMarkdown, editorWidth, preview, useTextEditor } from "@dxos/react-ui-editor";
|
|
492
|
+
import { mx } from "@dxos/react-ui-theme";
|
|
493
|
+
import { isNotFalsy } from "@dxos/util";
|
|
494
|
+
|
|
495
|
+
// src/components/Transcript/transcript-extension.ts
|
|
496
|
+
import { RangeSetBuilder } from "@codemirror/state";
|
|
497
|
+
import { EditorView, GutterMarker, ViewPlugin, gutter } from "@codemirror/view";
|
|
498
|
+
import { format } from "date-fns/format";
|
|
499
|
+
import { intervalToDuration } from "date-fns/intervalToDuration";
|
|
500
|
+
import { addEventListener, combine } from "@dxos/async";
|
|
501
|
+
function _define_property2(obj, key, value) {
|
|
502
|
+
if (key in obj) {
|
|
503
|
+
Object.defineProperty(obj, key, {
|
|
504
|
+
value,
|
|
505
|
+
enumerable: true,
|
|
506
|
+
configurable: true,
|
|
507
|
+
writable: true
|
|
508
|
+
});
|
|
509
|
+
} else {
|
|
510
|
+
obj[key] = value;
|
|
511
|
+
}
|
|
512
|
+
return obj;
|
|
513
|
+
}
|
|
514
|
+
var transcript = ({ model, started, renderButton }) => {
|
|
515
|
+
return [
|
|
516
|
+
// Show timestamps in the gutter.
|
|
517
|
+
gutter({
|
|
518
|
+
class: "cm-timestamp-gutter",
|
|
519
|
+
lineMarkerChange: (update) => update.docChanged || update.viewportChanged,
|
|
520
|
+
markers: (view) => {
|
|
521
|
+
const start = getStartTime(started, model.chunks[0]);
|
|
522
|
+
const builder = new RangeSetBuilder();
|
|
523
|
+
for (const { from, to } of view.visibleRanges) {
|
|
524
|
+
let line = view.state.doc.lineAt(from);
|
|
525
|
+
while (line.from <= to) {
|
|
526
|
+
const block = model.getChunkAtLine(line.number)?.blocks[0];
|
|
527
|
+
const timestamp = block?._tag === "transcript" && block.started;
|
|
528
|
+
if (timestamp) {
|
|
529
|
+
builder.add(line.from, line.from, new TimestampMarker(line.number, new Date(timestamp), start));
|
|
530
|
+
}
|
|
531
|
+
if (line.to + 1 > view.state.doc.length) {
|
|
532
|
+
break;
|
|
533
|
+
}
|
|
534
|
+
line = view.state.doc.lineAt(line.to + 1);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
return builder.finish();
|
|
538
|
+
}
|
|
539
|
+
}),
|
|
540
|
+
// Listen for model updates.
|
|
541
|
+
ViewPlugin.fromClass(class {
|
|
542
|
+
update(update) {
|
|
543
|
+
if (!this._initialized) {
|
|
544
|
+
this._initialized = true;
|
|
545
|
+
setTimeout(() => {
|
|
546
|
+
model.sync(this._adapter);
|
|
547
|
+
});
|
|
301
548
|
}
|
|
302
549
|
}
|
|
303
550
|
destroy() {
|
|
304
551
|
this._controls?.remove();
|
|
305
552
|
this._cleanup();
|
|
306
553
|
}
|
|
554
|
+
constructor(view) {
|
|
555
|
+
_define_property2(this, "_controls", void 0);
|
|
556
|
+
_define_property2(this, "_cleanup", void 0);
|
|
557
|
+
_define_property2(this, "_adapter", void 0);
|
|
558
|
+
_define_property2(this, "_initialized", false);
|
|
559
|
+
this._adapter = new DocumentAdapter(view);
|
|
560
|
+
const scroller = view.scrollDOM;
|
|
561
|
+
let isAutoScrolling = false;
|
|
562
|
+
let hasScrolled = false;
|
|
563
|
+
let timeout;
|
|
564
|
+
const scrollToBottom = (smooth = false) => {
|
|
565
|
+
scroller.style.scrollBehavior = smooth ? "smooth" : "";
|
|
566
|
+
scroller.classList.add("cm-hide-scrollbar");
|
|
567
|
+
isAutoScrolling = true;
|
|
568
|
+
clearTimeout(timeout);
|
|
569
|
+
timeout = setTimeout(() => {
|
|
570
|
+
this._controls?.classList.add("opacity-0");
|
|
571
|
+
scroller.classList.remove("cm-hide-scrollbar");
|
|
572
|
+
isAutoScrolling = false;
|
|
573
|
+
}, 500);
|
|
574
|
+
view.dispatch({
|
|
575
|
+
effects: EditorView.scrollIntoView(view.state.doc.length, {
|
|
576
|
+
y: "end"
|
|
577
|
+
})
|
|
578
|
+
});
|
|
579
|
+
};
|
|
580
|
+
if (renderButton) {
|
|
581
|
+
this._controls = document.createElement("div");
|
|
582
|
+
this._controls.classList.add("cm-controls", "transition-opacity", "duration-300", "opacity-0");
|
|
583
|
+
view.dom.appendChild(this._controls);
|
|
584
|
+
renderButton(this._controls, {
|
|
585
|
+
onClick: () => {
|
|
586
|
+
scrollToBottom(false);
|
|
587
|
+
}
|
|
588
|
+
}, view);
|
|
589
|
+
}
|
|
590
|
+
this._cleanup = combine(addEventListener(view.scrollDOM, "scroll", () => {
|
|
591
|
+
if (!isAutoScrolling) {
|
|
592
|
+
hasScrolled = true;
|
|
593
|
+
this._controls?.classList.remove("opacity-0");
|
|
594
|
+
}
|
|
595
|
+
}), model.update.on(() => {
|
|
596
|
+
const autoScroll = scroller.scrollHeight - scroller.scrollTop - scroller.clientHeight === 0 || !hasScrolled;
|
|
597
|
+
model.sync(this._adapter);
|
|
598
|
+
if (autoScroll) {
|
|
599
|
+
scrollToBottom(true);
|
|
600
|
+
}
|
|
601
|
+
}));
|
|
602
|
+
}
|
|
307
603
|
}),
|
|
308
604
|
EditorView.theme({
|
|
309
605
|
".cm-scroller": {
|
|
@@ -338,9 +634,6 @@ var transcript = ({ model, started, renderButton }) => {
|
|
|
338
634
|
];
|
|
339
635
|
};
|
|
340
636
|
var TimestampMarker = class extends GutterMarker {
|
|
341
|
-
constructor(_line, _timestamp, _started) {
|
|
342
|
-
super(), this._line = _line, this._timestamp = _timestamp, this._started = _started;
|
|
343
|
-
}
|
|
344
637
|
eq(other) {
|
|
345
638
|
return other._timestamp === this._timestamp;
|
|
346
639
|
}
|
|
@@ -358,6 +651,9 @@ var TimestampMarker = class extends GutterMarker {
|
|
|
358
651
|
};
|
|
359
652
|
return el;
|
|
360
653
|
}
|
|
654
|
+
constructor(_line, _timestamp, _started) {
|
|
655
|
+
super(), _define_property2(this, "_line", void 0), _define_property2(this, "_timestamp", void 0), _define_property2(this, "_started", void 0), this._line = _line, this._timestamp = _timestamp, this._started = _started;
|
|
656
|
+
}
|
|
361
657
|
};
|
|
362
658
|
var getStartTime = (started, message) => {
|
|
363
659
|
if (started) {
|
|
@@ -398,7 +694,7 @@ var renderMarkdown = (identities) => (message, index, debug = false) => {
|
|
|
398
694
|
""
|
|
399
695
|
];
|
|
400
696
|
};
|
|
401
|
-
var
|
|
697
|
+
var TranscriptView = ({ classNames, transcript: object, space, model, attendableId, ignoreAttention }) => {
|
|
402
698
|
var _effect = _useSignals();
|
|
403
699
|
try {
|
|
404
700
|
const { themeMode } = useThemeContext();
|
|
@@ -407,7 +703,8 @@ var Transcript = ({ classNames, transcript: object, space, model, attendableId,
|
|
|
407
703
|
extensions: [
|
|
408
704
|
createBasicExtensions({
|
|
409
705
|
readOnly: true,
|
|
410
|
-
lineWrapping: true
|
|
706
|
+
lineWrapping: true,
|
|
707
|
+
search: true
|
|
411
708
|
}),
|
|
412
709
|
createMarkdownExtensions({
|
|
413
710
|
themeMode
|
|
@@ -443,284 +740,6 @@ var Transcript = ({ classNames, transcript: object, space, model, attendableId,
|
|
|
443
740
|
}
|
|
444
741
|
};
|
|
445
742
|
|
|
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
743
|
// src/components/TranscriptContainer.tsx
|
|
725
744
|
var TranscriptionContainer = ({ transcript: transcript2 }) => {
|
|
726
745
|
var _effect = _useSignals2();
|
|
@@ -734,7 +753,7 @@ var TranscriptionContainer = ({ transcript: transcript2 }) => {
|
|
|
734
753
|
const model = useQueueModelAdapter(renderMarkdown(members), queue);
|
|
735
754
|
return /* @__PURE__ */ React2.createElement(StackItem.Content, {
|
|
736
755
|
classNames: "container-max-width pli-2"
|
|
737
|
-
}, /* @__PURE__ */ React2.createElement(
|
|
756
|
+
}, /* @__PURE__ */ React2.createElement(TranscriptView, {
|
|
738
757
|
attendableId,
|
|
739
758
|
space,
|
|
740
759
|
model,
|
|
@@ -748,7 +767,7 @@ var TranscriptContainer_default = TranscriptionContainer;
|
|
|
748
767
|
|
|
749
768
|
export {
|
|
750
769
|
renderMarkdown,
|
|
751
|
-
|
|
770
|
+
TranscriptView,
|
|
752
771
|
useAudioFile,
|
|
753
772
|
useAudioTrack,
|
|
754
773
|
useQueueModelAdapter,
|
|
@@ -756,8 +775,9 @@ export {
|
|
|
756
775
|
useVoiceInput,
|
|
757
776
|
TranscriptionContainer,
|
|
758
777
|
TranscriptContainer_default,
|
|
778
|
+
BlueprintDefinition,
|
|
759
779
|
IntentResolver,
|
|
760
780
|
ReactSurface,
|
|
761
781
|
Transcriber
|
|
762
782
|
};
|
|
763
|
-
//# sourceMappingURL=chunk-
|
|
783
|
+
//# sourceMappingURL=chunk-5I4BMOGE.mjs.map
|