@juspay/svelte-ui-components 2.127.0 → 2.128.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { SpeechToTextOptions } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Headless speech-to-text over the browser's SpeechRecognition API. Owns the whole
|
|
4
|
+
* lifecycle a mic button needs — support detection, a one-shot host permission hook,
|
|
5
|
+
* start-with-retry, interim/final transcript assembly, and a self-hiding error toast —
|
|
6
|
+
* and exposes it as reactive fields plus callbacks. Rendering stays entirely with the
|
|
7
|
+
* host; pair it with ChatComposer's voice control (`recording`, `onvoice`).
|
|
8
|
+
*/
|
|
9
|
+
export declare class SpeechToTextController {
|
|
10
|
+
/** True between the notified start and end of a listening session. */
|
|
11
|
+
listening: boolean;
|
|
12
|
+
/** Committed transcript plus the current interim guess; what a composer shows while listening. */
|
|
13
|
+
interimText: string;
|
|
14
|
+
errorMessage: string;
|
|
15
|
+
errorVisible: boolean;
|
|
16
|
+
supported: boolean;
|
|
17
|
+
private readonly options;
|
|
18
|
+
private readonly messages;
|
|
19
|
+
private readonly errorMessages;
|
|
20
|
+
private recognition;
|
|
21
|
+
private instanceGeneration;
|
|
22
|
+
private transcript;
|
|
23
|
+
private internalListening;
|
|
24
|
+
private everInitialized;
|
|
25
|
+
private errorTimer;
|
|
26
|
+
private permissionRequested;
|
|
27
|
+
private permissionGranted;
|
|
28
|
+
constructor(options?: SpeechToTextOptions);
|
|
29
|
+
/**
|
|
30
|
+
* Detects the API and builds a wired recognition instance. Safe to call again
|
|
31
|
+
* to rebuild after a failure; `start` calls it lazily if the host never did.
|
|
32
|
+
*/
|
|
33
|
+
initialize(): boolean;
|
|
34
|
+
start(): void;
|
|
35
|
+
stop(): void;
|
|
36
|
+
/**
|
|
37
|
+
* The mic-button handler: stops when listening, otherwise runs the permission
|
|
38
|
+
* gate (at most one proactive host request, denial remembered) and starts.
|
|
39
|
+
*/
|
|
40
|
+
toggle(): Promise<void>;
|
|
41
|
+
/** Clears the toast timer and tears the recognition instance down. */
|
|
42
|
+
destroy(): void;
|
|
43
|
+
private attemptStart;
|
|
44
|
+
private handleStart;
|
|
45
|
+
private handleResult;
|
|
46
|
+
private handleRecognitionError;
|
|
47
|
+
private handleEnd;
|
|
48
|
+
private setListening;
|
|
49
|
+
private showError;
|
|
50
|
+
private diagnose;
|
|
51
|
+
}
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
const DEFAULT_ERROR_MESSAGES = {
|
|
2
|
+
'not-allowed': 'Microphone access is blocked. Allow microphone access in your browser settings to use voice input.',
|
|
3
|
+
'service-not-allowed': 'Microphone access is blocked. Allow microphone access in your browser settings to use voice input.',
|
|
4
|
+
'no-speech': 'No speech detected. Please speak closer to your microphone and try again.',
|
|
5
|
+
'audio-capture': 'No microphone found. Please connect a microphone and try again.',
|
|
6
|
+
network: 'A network error interrupted voice input. Please check your connection and try again.'
|
|
7
|
+
};
|
|
8
|
+
const DEFAULT_MESSAGES = {
|
|
9
|
+
unsupported: 'Speech recognition not supported in this browser.',
|
|
10
|
+
initFailed: 'Failed to initialize speech recognition service.',
|
|
11
|
+
startFailed: 'Recognition service could not be initialized for starting.',
|
|
12
|
+
startRetryFailedPrefix: 'Failed to start speech recognition even after retry: ',
|
|
13
|
+
fallback: 'Could not start voice input. Please try again.',
|
|
14
|
+
permissionDenied: 'Microphone permission denied.',
|
|
15
|
+
permissionPreviouslyDenied: 'Microphone permission was previously denied.',
|
|
16
|
+
permissionRequestFailed: 'Failed to request microphone permission.'
|
|
17
|
+
};
|
|
18
|
+
const DEFAULT_ERROR_TIMEOUT_MS = 4000;
|
|
19
|
+
function defaultRecognitionConstructor() {
|
|
20
|
+
if (typeof window === 'undefined') {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
const speechWindow = window;
|
|
24
|
+
return speechWindow.SpeechRecognition ?? speechWindow.webkitSpeechRecognition ?? null;
|
|
25
|
+
}
|
|
26
|
+
function errorName(raw) {
|
|
27
|
+
return raw instanceof Error ? raw.name : 'UnknownError';
|
|
28
|
+
}
|
|
29
|
+
function errorDetail(raw) {
|
|
30
|
+
return raw instanceof Error ? raw.message : String(raw);
|
|
31
|
+
}
|
|
32
|
+
function permissionRejectionDetail(raw) {
|
|
33
|
+
if (typeof raw === 'object' &&
|
|
34
|
+
raw !== null &&
|
|
35
|
+
'error' in raw &&
|
|
36
|
+
typeof raw.error === 'string' &&
|
|
37
|
+
raw.error.length > 0) {
|
|
38
|
+
return raw.error;
|
|
39
|
+
}
|
|
40
|
+
if (raw instanceof Error && raw.message.length > 0) {
|
|
41
|
+
return raw.message;
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Headless speech-to-text over the browser's SpeechRecognition API. Owns the whole
|
|
47
|
+
* lifecycle a mic button needs — support detection, a one-shot host permission hook,
|
|
48
|
+
* start-with-retry, interim/final transcript assembly, and a self-hiding error toast —
|
|
49
|
+
* and exposes it as reactive fields plus callbacks. Rendering stays entirely with the
|
|
50
|
+
* host; pair it with ChatComposer's voice control (`recording`, `onvoice`).
|
|
51
|
+
*/
|
|
52
|
+
export class SpeechToTextController {
|
|
53
|
+
/** True between the notified start and end of a listening session. */
|
|
54
|
+
listening = $state(false);
|
|
55
|
+
/** Committed transcript plus the current interim guess; what a composer shows while listening. */
|
|
56
|
+
interimText = $state('');
|
|
57
|
+
errorMessage = $state('');
|
|
58
|
+
errorVisible = $state(false);
|
|
59
|
+
supported = $state(false);
|
|
60
|
+
options;
|
|
61
|
+
messages;
|
|
62
|
+
errorMessages;
|
|
63
|
+
recognition = null;
|
|
64
|
+
// Bumped per initialize(); handlers captured by a discarded instance compare
|
|
65
|
+
// against it so a late onend/onerror from the old engine cannot end the new
|
|
66
|
+
// session (start() rebuilds the instance on its retry path).
|
|
67
|
+
instanceGeneration = 0;
|
|
68
|
+
transcript = '';
|
|
69
|
+
internalListening = false;
|
|
70
|
+
everInitialized = false;
|
|
71
|
+
errorTimer = null;
|
|
72
|
+
permissionRequested = false;
|
|
73
|
+
permissionGranted = null;
|
|
74
|
+
constructor(options = {}) {
|
|
75
|
+
this.options = options;
|
|
76
|
+
this.messages = { ...DEFAULT_MESSAGES, ...options.messages };
|
|
77
|
+
this.errorMessages = { ...DEFAULT_ERROR_MESSAGES, ...options.errorMessages };
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Detects the API and builds a wired recognition instance. Safe to call again
|
|
81
|
+
* to rebuild after a failure; `start` calls it lazily if the host never did.
|
|
82
|
+
*/
|
|
83
|
+
initialize() {
|
|
84
|
+
this.everInitialized = true;
|
|
85
|
+
const getConstructor = this.options.getRecognitionConstructor ?? defaultRecognitionConstructor;
|
|
86
|
+
const RecognitionApi = getConstructor();
|
|
87
|
+
this.supported = RecognitionApi !== null;
|
|
88
|
+
if (RecognitionApi === null) {
|
|
89
|
+
this.recognition = null;
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
const instance = new RecognitionApi();
|
|
94
|
+
this.instanceGeneration += 1;
|
|
95
|
+
const generation = this.instanceGeneration;
|
|
96
|
+
const isCurrent = () => generation === this.instanceGeneration;
|
|
97
|
+
instance.continuous = this.options.continuous ?? false;
|
|
98
|
+
instance.interimResults = this.options.interimResults ?? true;
|
|
99
|
+
instance.lang = this.options.lang ?? 'en-US';
|
|
100
|
+
instance.onstart = () => {
|
|
101
|
+
if (isCurrent()) {
|
|
102
|
+
this.handleStart();
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
instance.onresult = (event) => {
|
|
106
|
+
if (isCurrent()) {
|
|
107
|
+
this.handleResult(event);
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
instance.onerror = (event) => {
|
|
111
|
+
if (isCurrent()) {
|
|
112
|
+
this.handleRecognitionError(event);
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
instance.onend = () => {
|
|
116
|
+
if (isCurrent()) {
|
|
117
|
+
this.handleEnd();
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
this.recognition = instance;
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
this.supported = false;
|
|
125
|
+
this.recognition = null;
|
|
126
|
+
this.diagnose('initializeFailed', { error: errorDetail(error) });
|
|
127
|
+
this.showError(this.messages.initFailed);
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
start() {
|
|
132
|
+
if (!this.everInitialized) {
|
|
133
|
+
this.initialize();
|
|
134
|
+
}
|
|
135
|
+
if (!this.supported) {
|
|
136
|
+
this.showError(this.messages.unsupported);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (this.recognition === null && !this.initialize()) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
this.attemptStart(false);
|
|
143
|
+
}
|
|
144
|
+
stop() {
|
|
145
|
+
if (this.internalListening) {
|
|
146
|
+
this.internalListening = false;
|
|
147
|
+
this.setListening(false);
|
|
148
|
+
}
|
|
149
|
+
if (this.recognition !== null) {
|
|
150
|
+
this.recognition.stop();
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* The mic-button handler: stops when listening, otherwise runs the permission
|
|
155
|
+
* gate (at most one proactive host request, denial remembered) and starts.
|
|
156
|
+
*/
|
|
157
|
+
async toggle() {
|
|
158
|
+
if (this.internalListening) {
|
|
159
|
+
this.stop();
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const requestPermission = this.options.requestPermission ?? null;
|
|
163
|
+
if (requestPermission === null) {
|
|
164
|
+
this.start();
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
if (this.permissionRequested) {
|
|
168
|
+
if (this.permissionGranted === false) {
|
|
169
|
+
this.showError(this.messages.permissionPreviouslyDenied);
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
this.start();
|
|
173
|
+
}
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
const pending = requestPermission();
|
|
177
|
+
if (pending === null) {
|
|
178
|
+
this.start();
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
this.permissionRequested = true;
|
|
182
|
+
try {
|
|
183
|
+
const result = await pending;
|
|
184
|
+
this.permissionGranted = result.granted;
|
|
185
|
+
if (result.granted) {
|
|
186
|
+
this.start();
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
const denialMessage = typeof result.error === 'string' && result.error.length > 0
|
|
190
|
+
? result.error
|
|
191
|
+
: this.messages.permissionDenied;
|
|
192
|
+
this.showError(denialMessage);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
this.permissionGranted = false;
|
|
197
|
+
this.showError(permissionRejectionDetail(error) ?? this.messages.permissionRequestFailed);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/** Clears the toast timer and tears the recognition instance down. */
|
|
201
|
+
destroy() {
|
|
202
|
+
if (this.errorTimer !== null) {
|
|
203
|
+
clearTimeout(this.errorTimer);
|
|
204
|
+
this.errorTimer = null;
|
|
205
|
+
}
|
|
206
|
+
if (this.recognition !== null) {
|
|
207
|
+
try {
|
|
208
|
+
this.recognition.abort();
|
|
209
|
+
}
|
|
210
|
+
catch (abortError) {
|
|
211
|
+
this.diagnose('recognitionAbortErrorOnDestroy', { error: errorDetail(abortError) });
|
|
212
|
+
}
|
|
213
|
+
this.recognition = null;
|
|
214
|
+
}
|
|
215
|
+
this.internalListening = false;
|
|
216
|
+
// abort() is not guaranteed to fire onend, so clear the public state too —
|
|
217
|
+
// a consumer's recording indicator must not survive teardown.
|
|
218
|
+
if (this.listening) {
|
|
219
|
+
this.setListening(false);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
attemptStart(isRetry) {
|
|
223
|
+
if (this.recognition === null) {
|
|
224
|
+
this.showError(this.messages.startFailed);
|
|
225
|
+
this.internalListening = false;
|
|
226
|
+
this.setListening(false);
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
try {
|
|
230
|
+
this.internalListening = true;
|
|
231
|
+
this.errorMessage = '';
|
|
232
|
+
this.errorVisible = false;
|
|
233
|
+
this.recognition.start();
|
|
234
|
+
}
|
|
235
|
+
catch (error) {
|
|
236
|
+
if (!isRetry) {
|
|
237
|
+
try {
|
|
238
|
+
this.recognition.abort();
|
|
239
|
+
}
|
|
240
|
+
catch (abortError) {
|
|
241
|
+
this.diagnose('recognitionAbortErrorOnRetry', {
|
|
242
|
+
error: errorDetail(abortError),
|
|
243
|
+
rawError: String(abortError)
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
if (this.initialize()) {
|
|
247
|
+
this.attemptStart(true);
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
this.internalListening = false;
|
|
251
|
+
this.setListening(false);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
this.showError(`${this.messages.startRetryFailedPrefix}${errorName(error)} - ${errorDetail(error)}`);
|
|
256
|
+
this.internalListening = false;
|
|
257
|
+
this.setListening(false);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
handleStart() {
|
|
262
|
+
this.transcript = this.options.seedTranscript ? this.options.seedTranscript() : '';
|
|
263
|
+
this.interimText = this.transcript;
|
|
264
|
+
this.internalListening = true;
|
|
265
|
+
this.setListening(true);
|
|
266
|
+
}
|
|
267
|
+
handleResult(event) {
|
|
268
|
+
let finalTranscript = '';
|
|
269
|
+
let currentInterimTranscript = '';
|
|
270
|
+
for (let index = event.resultIndex; index < event.results.length; index += 1) {
|
|
271
|
+
const result = event.results[index];
|
|
272
|
+
if (result.isFinal) {
|
|
273
|
+
finalTranscript += result[0].transcript;
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
currentInterimTranscript += result[0].transcript;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
this.interimText =
|
|
280
|
+
this.transcript + (currentInterimTranscript ? ' ' + currentInterimTranscript : '');
|
|
281
|
+
if (finalTranscript) {
|
|
282
|
+
this.transcript = this.transcript ? `${this.transcript.trimEnd()} ` : '';
|
|
283
|
+
this.transcript += finalTranscript;
|
|
284
|
+
this.options.onTranscript?.(this.transcript);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
handleRecognitionError(event) {
|
|
288
|
+
this.internalListening = false;
|
|
289
|
+
this.setListening(false);
|
|
290
|
+
this.showError(this.errorMessages[event.error] ?? this.messages.fallback, event.error);
|
|
291
|
+
}
|
|
292
|
+
handleEnd() {
|
|
293
|
+
this.internalListening = false;
|
|
294
|
+
this.setListening(false);
|
|
295
|
+
}
|
|
296
|
+
setListening(listening) {
|
|
297
|
+
this.listening = listening;
|
|
298
|
+
this.options.onListeningChange?.(listening);
|
|
299
|
+
}
|
|
300
|
+
showError(message, code = null) {
|
|
301
|
+
this.errorMessage = message;
|
|
302
|
+
this.errorVisible = true;
|
|
303
|
+
if (this.errorTimer !== null) {
|
|
304
|
+
clearTimeout(this.errorTimer);
|
|
305
|
+
}
|
|
306
|
+
this.errorTimer = setTimeout(() => {
|
|
307
|
+
this.errorVisible = false;
|
|
308
|
+
}, this.options.errorTimeoutMs ?? DEFAULT_ERROR_TIMEOUT_MS);
|
|
309
|
+
this.options.onError?.(message, code);
|
|
310
|
+
}
|
|
311
|
+
diagnose(event, detail) {
|
|
312
|
+
this.options.onDiagnostic?.(event, detail);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
export type SpeechRecognitionAlternative = {
|
|
2
|
+
transcript: string;
|
|
3
|
+
};
|
|
4
|
+
export type SpeechRecognitionResultItem = {
|
|
5
|
+
0: SpeechRecognitionAlternative;
|
|
6
|
+
isFinal: boolean;
|
|
7
|
+
};
|
|
8
|
+
export type SpeechRecognitionResultEvent = {
|
|
9
|
+
resultIndex: number;
|
|
10
|
+
results: SpeechRecognitionResultItem[];
|
|
11
|
+
};
|
|
12
|
+
export type SpeechRecognitionErrorEvent = {
|
|
13
|
+
error: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* The browser's non-standard SpeechRecognition surface, reduced to the members the
|
|
17
|
+
* controller drives. lib.dom does not declare the API, so the shape lives here and
|
|
18
|
+
* a fake implementing it can be injected for tests and demos.
|
|
19
|
+
*/
|
|
20
|
+
export type SpeechRecognitionLike = {
|
|
21
|
+
continuous: boolean;
|
|
22
|
+
interimResults: boolean;
|
|
23
|
+
lang: string;
|
|
24
|
+
start: () => void;
|
|
25
|
+
stop: () => void;
|
|
26
|
+
abort: () => void;
|
|
27
|
+
onstart: () => void;
|
|
28
|
+
onresult: (event: SpeechRecognitionResultEvent) => void;
|
|
29
|
+
onerror: (event: SpeechRecognitionErrorEvent) => void;
|
|
30
|
+
onend: () => void;
|
|
31
|
+
};
|
|
32
|
+
export type SpeechRecognitionConstructor = new () => SpeechRecognitionLike;
|
|
33
|
+
export type SpeechPermissionResult = {
|
|
34
|
+
granted: boolean;
|
|
35
|
+
error?: string;
|
|
36
|
+
};
|
|
37
|
+
/** User-facing copy the controller emits outside the per-error-code map. */
|
|
38
|
+
export type SpeechToTextMessages = {
|
|
39
|
+
unsupported: string;
|
|
40
|
+
initFailed: string;
|
|
41
|
+
startFailed: string;
|
|
42
|
+
startRetryFailedPrefix: string;
|
|
43
|
+
fallback: string;
|
|
44
|
+
permissionDenied: string;
|
|
45
|
+
permissionPreviouslyDenied: string;
|
|
46
|
+
permissionRequestFailed: string;
|
|
47
|
+
};
|
|
48
|
+
export type SpeechToTextOptions = {
|
|
49
|
+
lang?: string;
|
|
50
|
+
continuous?: boolean;
|
|
51
|
+
interimResults?: boolean;
|
|
52
|
+
/** How long an error toast stays visible. */
|
|
53
|
+
errorTimeoutMs?: number;
|
|
54
|
+
/** Per-recognition-error-code messages, merged over the built-in map. */
|
|
55
|
+
errorMessages?: Record<string, string>;
|
|
56
|
+
/** Copy overrides, merged over the built-in defaults. */
|
|
57
|
+
messages?: Partial<SpeechToTextMessages>;
|
|
58
|
+
/** Resolves the recognition constructor; defaults to the browser's. Injectable for tests. */
|
|
59
|
+
getRecognitionConstructor?: () => SpeechRecognitionConstructor | null;
|
|
60
|
+
/**
|
|
61
|
+
* Host permission hook (e.g. a native shell's microphone bridge). Called on a start
|
|
62
|
+
* attempt; return null to mean "no bridge here", which falls through to the standard
|
|
63
|
+
* browser flow without consuming the single proactive request. A resolved denial is
|
|
64
|
+
* remembered and short-circuits later attempts.
|
|
65
|
+
*/
|
|
66
|
+
requestPermission?: () => Promise<SpeechPermissionResult> | null;
|
|
67
|
+
/** Text the transcript starts from when listening begins (e.g. the composer's current value). */
|
|
68
|
+
seedTranscript?: () => string;
|
|
69
|
+
/** Fires with the accumulated transcript each time a final result lands. */
|
|
70
|
+
onTranscript?: (transcript: string) => void;
|
|
71
|
+
onListeningChange?: (listening: boolean) => void;
|
|
72
|
+
onError?: (message: string, code: string | null) => void;
|
|
73
|
+
/** Non-fatal internals worth logging; hosts wire this to their telemetry. */
|
|
74
|
+
onDiagnostic?: (event: string, detail: Record<string, string | number | boolean | null>) => void;
|
|
75
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -93,6 +93,7 @@ export { pauseAllConfirmationTimers } from './HITL/timers';
|
|
|
93
93
|
export { default as Resizable } from './Resizable/Resizable.svelte';
|
|
94
94
|
export { ChatController } from './Chat/controller.svelte';
|
|
95
95
|
export { partyOf } from './Chat/roles';
|
|
96
|
+
export { SpeechToTextController } from './SpeechToText/controller.svelte';
|
|
96
97
|
export type * from './Button/properties';
|
|
97
98
|
export type * from './Modal/properties';
|
|
98
99
|
export type * from './Input/properties';
|
|
@@ -172,6 +173,7 @@ export type * from './FileDropzoneTrigger/properties';
|
|
|
172
173
|
export type * from './_chart/highlight';
|
|
173
174
|
export type * from './Chat/properties';
|
|
174
175
|
export type * from './Chat/types';
|
|
176
|
+
export type * from './SpeechToText/types';
|
|
175
177
|
export type * from './ChatHeader/properties';
|
|
176
178
|
export type * from './ChatMessage/properties';
|
|
177
179
|
export type * from './ChatMessageList/properties';
|
package/dist/index.js
CHANGED
|
@@ -93,5 +93,6 @@ export { pauseAllConfirmationTimers } from './HITL/timers';
|
|
|
93
93
|
export { default as Resizable } from './Resizable/Resizable.svelte';
|
|
94
94
|
export { ChatController } from './Chat/controller.svelte';
|
|
95
95
|
export { partyOf } from './Chat/roles';
|
|
96
|
+
export { SpeechToTextController } from './SpeechToText/controller.svelte';
|
|
96
97
|
export { validateInput } from './utils';
|
|
97
98
|
export { formatNumberIndian } from './_chart/format';
|