@speechos/react 1.0.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.
package/dist/index.cjs ADDED
@@ -0,0 +1,550 @@
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+
23
+ //#endregion
24
+ const react = __toESM(require("react"));
25
+ const __speechos_core = __toESM(require("@speechos/core"));
26
+ const react_jsx_runtime = __toESM(require("react/jsx-runtime"));
27
+
28
+ //#region src/context.tsx
29
+ const SpeechOSContext = (0, react.createContext)(void 0);
30
+ SpeechOSContext.displayName = "SpeechOSContext";
31
+ /**
32
+ * SpeechOS Provider component
33
+ *
34
+ * Wraps your app to provide SpeechOS context to all child components.
35
+ * Can optionally auto-initialize with a config.
36
+ *
37
+ * @example
38
+ * ```tsx
39
+ * <SpeechOSProvider config={{ apiKey: 'your-key' }}>
40
+ * <App />
41
+ * </SpeechOSProvider>
42
+ * ```
43
+ */
44
+ function SpeechOSProvider({ config, children }) {
45
+ const currentState = (0, react.useSyncExternalStore)((0, react.useCallback)((onStoreChange) => {
46
+ return __speechos_core.state.subscribe(onStoreChange);
47
+ }, []), (0, react.useCallback)(() => __speechos_core.state.getState(), []), (0, react.useCallback)(() => __speechos_core.state.getState(), []));
48
+ const isInitialized = __speechos_core.speechOS.isInitialized();
49
+ if (config && !isInitialized) __speechos_core.speechOS.init(config);
50
+ const contextValue = (0, react.useMemo)(() => {
51
+ return {
52
+ state: currentState,
53
+ isInitialized: __speechos_core.speechOS.isInitialized(),
54
+ init: (cfg) => __speechos_core.speechOS.init(cfg),
55
+ dictate: () => __speechos_core.speechOS.dictate(),
56
+ stopDictation: () => __speechos_core.speechOS.stopDictation(),
57
+ edit: (text) => __speechos_core.speechOS.edit(text),
58
+ stopEdit: () => __speechos_core.speechOS.stopEdit(),
59
+ cancel: () => __speechos_core.speechOS.cancel(),
60
+ connect: () => __speechos_core.speechOS.connect(),
61
+ disconnect: () => __speechos_core.speechOS.disconnect(),
62
+ enableMicrophone: () => __speechos_core.speechOS.enableMicrophone(),
63
+ waitUntilReady: () => __speechos_core.speechOS.waitUntilReady(),
64
+ stopAndGetTranscript: () => __speechos_core.speechOS.stopAndGetTranscript(),
65
+ stopAndEdit: (originalText) => __speechos_core.speechOS.stopAndEdit(originalText),
66
+ on: (event, callback) => __speechos_core.events.on(event, callback),
67
+ off: (event, callback) => {
68
+ console.warn("SpeechOS: Use the unsubscribe function returned by on() instead of off()");
69
+ }
70
+ };
71
+ }, [currentState]);
72
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SpeechOSContext.Provider, {
73
+ value: contextValue,
74
+ children
75
+ });
76
+ }
77
+ /**
78
+ * Hook to access the SpeechOS context
79
+ *
80
+ * @throws Error if used outside of SpeechOSProvider
81
+ * @returns The SpeechOS context value
82
+ */
83
+ function useSpeechOSContext() {
84
+ const context = (0, react.useContext)(SpeechOSContext);
85
+ if (context === void 0) throw new Error("useSpeechOSContext must be used within a SpeechOSProvider");
86
+ return context;
87
+ }
88
+
89
+ //#endregion
90
+ //#region src/hooks/useSpeechOS.ts
91
+ /**
92
+ * Main hook for accessing the full SpeechOS context
93
+ *
94
+ * @example
95
+ * ```tsx
96
+ * function MyComponent() {
97
+ * const { state, dictate, cancel, connect, enableMicrophone } = useSpeechOS();
98
+ *
99
+ * // High-level usage
100
+ * const handleDictate = async () => {
101
+ * const text = await dictate();
102
+ * console.log('Transcribed:', text);
103
+ * };
104
+ *
105
+ * // Low-level usage
106
+ * const handleCustomFlow = async () => {
107
+ * await connect();
108
+ * await waitUntilReady();
109
+ * await enableMicrophone();
110
+ * // ... custom logic
111
+ * const text = await stopAndGetTranscript();
112
+ * };
113
+ * }
114
+ * ```
115
+ *
116
+ * @returns The full SpeechOS context value
117
+ */
118
+ function useSpeechOS() {
119
+ return useSpeechOSContext();
120
+ }
121
+
122
+ //#endregion
123
+ //#region src/hooks/useSpeechOSState.ts
124
+ /**
125
+ * Hook to access just the SpeechOS state
126
+ *
127
+ * Use this when you only need to read state values like
128
+ * isConnected, recordingState, etc. without needing the API methods.
129
+ *
130
+ * @example
131
+ * ```tsx
132
+ * function RecordingIndicator() {
133
+ * const state = useSpeechOSState();
134
+ *
135
+ * return (
136
+ * <div>
137
+ * {state.recordingState === 'recording' && <span>Recording...</span>}
138
+ * {state.isConnected && <span>Connected</span>}
139
+ * </div>
140
+ * );
141
+ * }
142
+ * ```
143
+ *
144
+ * @returns The current SpeechOS state
145
+ */
146
+ function useSpeechOSState() {
147
+ const context = useSpeechOSContext();
148
+ return context.state;
149
+ }
150
+
151
+ //#endregion
152
+ //#region src/hooks/useSpeechOSEvents.ts
153
+ /**
154
+ * Hook to subscribe to SpeechOS events
155
+ *
156
+ * Automatically subscribes on mount and unsubscribes on unmount.
157
+ * The callback is stable - changes to it will update the subscription.
158
+ *
159
+ * @example
160
+ * ```tsx
161
+ * function TranscriptionListener() {
162
+ * useSpeechOSEvents('transcription:complete', (payload) => {
163
+ * console.log('Transcription received:', payload.text);
164
+ * });
165
+ *
166
+ * useSpeechOSEvents('error', (payload) => {
167
+ * console.error('Error:', payload.message);
168
+ * });
169
+ *
170
+ * return <div>Listening for events...</div>;
171
+ * }
172
+ * ```
173
+ *
174
+ * @param event - The event name to subscribe to
175
+ * @param callback - The callback to invoke when the event fires
176
+ * @returns Cleanup function (automatically called on unmount)
177
+ */
178
+ function useSpeechOSEvents(event, callback) {
179
+ (0, react.useEffect)(() => {
180
+ const unsubscribe = __speechos_core.events.on(event, callback);
181
+ return unsubscribe;
182
+ }, [event, callback]);
183
+ return () => {};
184
+ }
185
+
186
+ //#endregion
187
+ //#region src/hooks/useDictation.ts
188
+ /**
189
+ * Simplified hook for dictation workflows
190
+ *
191
+ * Provides an easy-to-use interface for voice-to-text dictation
192
+ * with automatic state management.
193
+ *
194
+ * @example
195
+ * ```tsx
196
+ * function VoiceInput() {
197
+ * const { start, stop, isRecording, isProcessing, transcript, error } = useDictation();
198
+ *
199
+ * return (
200
+ * <div>
201
+ * <button onClick={isRecording ? stop : start} disabled={isProcessing}>
202
+ * {isRecording ? 'Stop' : 'Start'} Recording
203
+ * </button>
204
+ * {isProcessing && <span>Processing...</span>}
205
+ * {transcript && <p>You said: {transcript}</p>}
206
+ * {error && <p style={{ color: 'red' }}>{error}</p>}
207
+ * </div>
208
+ * );
209
+ * }
210
+ * ```
211
+ *
212
+ * @returns Dictation controls and state
213
+ */
214
+ function useDictation() {
215
+ const { state: state$1, dictate, stopDictation, cancel } = useSpeechOSContext();
216
+ const [transcript, setTranscript] = (0, react.useState)(null);
217
+ const [error, setError] = (0, react.useState)(null);
218
+ const isRecording = state$1.recordingState === "recording";
219
+ const isProcessing = state$1.recordingState === "processing";
220
+ const start = (0, react.useCallback)(async () => {
221
+ setError(null);
222
+ try {
223
+ await dictate();
224
+ } catch (err) {
225
+ const message = err instanceof Error ? err.message : "Failed to start dictation";
226
+ setError(message);
227
+ }
228
+ }, [dictate]);
229
+ const stop = (0, react.useCallback)(async () => {
230
+ try {
231
+ const result = await stopDictation();
232
+ setTranscript(result);
233
+ setError(null);
234
+ return result;
235
+ } catch (err) {
236
+ const message = err instanceof Error ? err.message : "Failed to get transcript";
237
+ setError(message);
238
+ throw err;
239
+ }
240
+ }, [stopDictation]);
241
+ const clear = (0, react.useCallback)(() => {
242
+ setTranscript(null);
243
+ setError(null);
244
+ }, []);
245
+ return {
246
+ start,
247
+ stop,
248
+ isRecording,
249
+ isProcessing,
250
+ transcript,
251
+ error,
252
+ clear
253
+ };
254
+ }
255
+
256
+ //#endregion
257
+ //#region src/hooks/useEdit.ts
258
+ /**
259
+ * Simplified hook for voice editing workflows
260
+ *
261
+ * Provides an easy-to-use interface for voice-based text editing
262
+ * with automatic state management.
263
+ *
264
+ * @example
265
+ * ```tsx
266
+ * function TextEditor() {
267
+ * const [text, setText] = useState('Hello world');
268
+ * const { start, stop, isEditing, isProcessing, result, error } = useEdit();
269
+ *
270
+ * const handleEdit = async () => {
271
+ * await start(text);
272
+ * };
273
+ *
274
+ * const handleStop = async () => {
275
+ * const edited = await stop();
276
+ * setText(edited);
277
+ * };
278
+ *
279
+ * return (
280
+ * <div>
281
+ * <textarea value={text} onChange={(e) => setText(e.target.value)} />
282
+ * <button onClick={isEditing ? handleStop : handleEdit} disabled={isProcessing}>
283
+ * {isEditing ? 'Apply Edit' : 'Edit with Voice'}
284
+ * </button>
285
+ * {isProcessing && <span>Processing...</span>}
286
+ * {error && <p style={{ color: 'red' }}>{error}</p>}
287
+ * </div>
288
+ * );
289
+ * }
290
+ * ```
291
+ *
292
+ * @returns Edit controls and state
293
+ */
294
+ function useEdit() {
295
+ const { state: state$1, edit, stopEdit, cancel } = useSpeechOSContext();
296
+ const [originalText, setOriginalText] = (0, react.useState)(null);
297
+ const [result, setResult] = (0, react.useState)(null);
298
+ const [error, setError] = (0, react.useState)(null);
299
+ const isEditing = state$1.recordingState === "recording" && state$1.activeAction === "edit";
300
+ const isProcessing = state$1.recordingState === "processing";
301
+ const start = (0, react.useCallback)(async (textToEdit) => {
302
+ setError(null);
303
+ setOriginalText(textToEdit);
304
+ try {
305
+ await edit(textToEdit);
306
+ } catch (err) {
307
+ const message = err instanceof Error ? err.message : "Failed to start edit";
308
+ setError(message);
309
+ }
310
+ }, [edit]);
311
+ const stop = (0, react.useCallback)(async () => {
312
+ try {
313
+ const editedResult = await stopEdit();
314
+ setResult(editedResult);
315
+ setError(null);
316
+ return editedResult;
317
+ } catch (err) {
318
+ const message = err instanceof Error ? err.message : "Failed to apply edit";
319
+ setError(message);
320
+ throw err;
321
+ }
322
+ }, [stopEdit]);
323
+ const clear = (0, react.useCallback)(() => {
324
+ setOriginalText(null);
325
+ setResult(null);
326
+ setError(null);
327
+ }, []);
328
+ return {
329
+ start,
330
+ stop,
331
+ isEditing,
332
+ isProcessing,
333
+ originalText,
334
+ result,
335
+ error,
336
+ clear
337
+ };
338
+ }
339
+
340
+ //#endregion
341
+ //#region src/hooks/useTranscription.ts
342
+ /**
343
+ * Low-level hook for granular transcription control
344
+ *
345
+ * Use this when you need fine-grained control over the LiveKit
346
+ * connection lifecycle. For most use cases, prefer useDictation()
347
+ * or useEdit() which provide simpler interfaces.
348
+ *
349
+ * @example
350
+ * ```tsx
351
+ * function CustomVoiceUI() {
352
+ * const {
353
+ * connect,
354
+ * waitUntilReady,
355
+ * enableMicrophone,
356
+ * getTranscript,
357
+ * disconnect,
358
+ * isConnected,
359
+ * isMicEnabled,
360
+ * recordingState,
361
+ * } = useTranscription();
362
+ *
363
+ * const handleRecord = async () => {
364
+ * // Step 1: Connect to LiveKit
365
+ * await connect();
366
+ *
367
+ * // Step 2: Wait for agent to be ready
368
+ * await waitUntilReady();
369
+ *
370
+ * // Step 3: Enable microphone
371
+ * await enableMicrophone();
372
+ *
373
+ * // ... user speaks ...
374
+ *
375
+ * // Step 4: Get transcript
376
+ * const text = await getTranscript();
377
+ * console.log('Transcribed:', text);
378
+ *
379
+ * // Step 5: Cleanup
380
+ * await disconnect();
381
+ * };
382
+ *
383
+ * return (
384
+ * <div>
385
+ * <p>Connected: {isConnected ? 'Yes' : 'No'}</p>
386
+ * <p>Mic: {isMicEnabled ? 'On' : 'Off'}</p>
387
+ * <p>State: {recordingState}</p>
388
+ * <button onClick={handleRecord}>Record</button>
389
+ * </div>
390
+ * );
391
+ * }
392
+ * ```
393
+ *
394
+ * @returns Low-level transcription controls and state
395
+ */
396
+ function useTranscription() {
397
+ const { state: state$1, connect: contextConnect, waitUntilReady: contextWaitUntilReady, enableMicrophone: contextEnableMicrophone, stopAndGetTranscript, stopAndEdit, disconnect: contextDisconnect, cancel } = useSpeechOSContext();
398
+ const connect = (0, react.useCallback)(async () => {
399
+ await contextConnect();
400
+ }, [contextConnect]);
401
+ const waitUntilReady = (0, react.useCallback)(async () => {
402
+ await contextWaitUntilReady();
403
+ }, [contextWaitUntilReady]);
404
+ const enableMicrophone = (0, react.useCallback)(async () => {
405
+ await contextEnableMicrophone();
406
+ }, [contextEnableMicrophone]);
407
+ const getTranscript = (0, react.useCallback)(async () => {
408
+ return await stopAndGetTranscript();
409
+ }, [stopAndGetTranscript]);
410
+ const getEdit = (0, react.useCallback)(async (originalText) => {
411
+ return await stopAndEdit(originalText);
412
+ }, [stopAndEdit]);
413
+ const disconnect = (0, react.useCallback)(async () => {
414
+ await contextDisconnect();
415
+ }, [contextDisconnect]);
416
+ return {
417
+ connect,
418
+ waitUntilReady,
419
+ enableMicrophone,
420
+ getTranscript,
421
+ getEdit,
422
+ disconnect,
423
+ cancel,
424
+ isConnected: state$1.isConnected,
425
+ isMicEnabled: state$1.isMicEnabled,
426
+ recordingState: state$1.recordingState
427
+ };
428
+ }
429
+
430
+ //#endregion
431
+ //#region src/components/SpeechOSWidget.tsx
432
+ /**
433
+ * SpeechOSWidget - React wrapper for the SpeechOS Web Component
434
+ *
435
+ * This component mounts the existing <speechos-widget> Lit Web Component
436
+ * and bridges React props to the Web Component's attributes and events.
437
+ *
438
+ * Note: Requires @speechos/client to be installed and imported somewhere
439
+ * in your app to register the Web Component.
440
+ *
441
+ * @example
442
+ * ```tsx
443
+ * import { SpeechOSProvider, SpeechOSWidget } from '@speechos/react';
444
+ * import '@speechos/client'; // Registers the Web Component
445
+ *
446
+ * function App() {
447
+ * return (
448
+ * <SpeechOSProvider>
449
+ * <MyForm />
450
+ * <SpeechOSWidget
451
+ * apiKey="your-key"
452
+ * onTranscription={(text) => console.log('Transcribed:', text)}
453
+ * onError={(error) => console.error(error)}
454
+ * />
455
+ * </SpeechOSProvider>
456
+ * );
457
+ * }
458
+ * ```
459
+ */
460
+ function SpeechOSWidget({ apiKey, userId, position = "bottom-center", host, zIndex, debug, onTranscription, onEdit, onError, onShow, onHide, className }) {
461
+ const containerRef = (0, react.useRef)(null);
462
+ const widgetRef = (0, react.useRef)(null);
463
+ const { init, isInitialized } = useSpeechOSContext();
464
+ (0, react.useEffect)(() => {
465
+ if (!isInitialized && apiKey) init({
466
+ apiKey,
467
+ userId,
468
+ host,
469
+ position,
470
+ zIndex,
471
+ debug
472
+ });
473
+ }, [
474
+ isInitialized,
475
+ init,
476
+ apiKey,
477
+ userId,
478
+ host,
479
+ position,
480
+ zIndex,
481
+ debug
482
+ ]);
483
+ (0, react.useEffect)(() => {
484
+ const unsubscribers = [];
485
+ if (onTranscription) unsubscribers.push(__speechos_core.events.on("transcription:inserted", (payload) => {
486
+ onTranscription(payload.text, payload.element);
487
+ }));
488
+ if (onEdit) unsubscribers.push(__speechos_core.events.on("edit:applied", (payload) => {
489
+ onEdit(payload.editedContent, payload.originalContent, payload.element);
490
+ }));
491
+ if (onError) unsubscribers.push(__speechos_core.events.on("error", (payload) => {
492
+ onError(payload);
493
+ }));
494
+ if (onShow) unsubscribers.push(__speechos_core.events.on("widget:show", () => {
495
+ onShow();
496
+ }));
497
+ if (onHide) unsubscribers.push(__speechos_core.events.on("widget:hide", () => {
498
+ onHide();
499
+ }));
500
+ return () => {
501
+ unsubscribers.forEach((unsub) => unsub());
502
+ };
503
+ }, [
504
+ onTranscription,
505
+ onEdit,
506
+ onError,
507
+ onShow,
508
+ onHide
509
+ ]);
510
+ (0, react.useEffect)(() => {
511
+ if (!containerRef.current) return;
512
+ const isWebComponentRegistered = customElements.get("speechos-widget") !== void 0;
513
+ if (!isWebComponentRegistered) {
514
+ console.warn("SpeechOSWidget: <speechos-widget> Web Component is not registered. Make sure to import @speechos/client in your app.");
515
+ return;
516
+ }
517
+ const widget = document.createElement("speechos-widget");
518
+ widget.setAttribute("position", position);
519
+ containerRef.current.appendChild(widget);
520
+ widgetRef.current = widget;
521
+ return () => {
522
+ if (widgetRef.current && containerRef.current) {
523
+ containerRef.current.removeChild(widgetRef.current);
524
+ widgetRef.current = null;
525
+ }
526
+ };
527
+ }, [position]);
528
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
529
+ ref: containerRef,
530
+ className,
531
+ style: { display: "contents" }
532
+ });
533
+ }
534
+
535
+ //#endregion
536
+ //#region src/index.ts
537
+ const VERSION = "0.1.0";
538
+
539
+ //#endregion
540
+ exports.SpeechOSContext = SpeechOSContext;
541
+ exports.SpeechOSProvider = SpeechOSProvider;
542
+ exports.SpeechOSWidget = SpeechOSWidget;
543
+ exports.VERSION = VERSION;
544
+ exports.useDictation = useDictation;
545
+ exports.useEdit = useEdit;
546
+ exports.useSpeechOS = useSpeechOS;
547
+ exports.useSpeechOSContext = useSpeechOSContext;
548
+ exports.useSpeechOSEvents = useSpeechOSEvents;
549
+ exports.useSpeechOSState = useSpeechOSState;
550
+ exports.useTranscription = useTranscription;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @speechos/react
3
+ *
4
+ * React hooks and components for SpeechOS voice integration.
5
+ *
6
+ * @example Basic usage with widget
7
+ * ```tsx
8
+ * import { SpeechOSProvider, SpeechOSWidget } from '@speechos/react';
9
+ * import '@speechos/client'; // Registers Web Component
10
+ *
11
+ * function App() {
12
+ * return (
13
+ * <SpeechOSProvider config={{ apiKey: 'your-key' }}>
14
+ * <MyForm />
15
+ * <SpeechOSWidget
16
+ * onTranscription={(text) => console.log(text)}
17
+ * />
18
+ * </SpeechOSProvider>
19
+ * );
20
+ * }
21
+ * ```
22
+ *
23
+ * @example Hook-based usage
24
+ * ```tsx
25
+ * import { SpeechOSProvider, useDictation } from '@speechos/react';
26
+ *
27
+ * function VoiceInput() {
28
+ * const { start, stop, isRecording, transcript } = useDictation();
29
+ *
30
+ * return (
31
+ * <button onClick={isRecording ? stop : start}>
32
+ * {isRecording ? 'Stop' : 'Start'}
33
+ * </button>
34
+ * );
35
+ * }
36
+ * ```
37
+ *
38
+ * @example Low-level usage
39
+ * ```tsx
40
+ * import { useSpeechOS } from '@speechos/react';
41
+ *
42
+ * function CustomUI() {
43
+ * const { connect, waitUntilReady, enableMicrophone, stopAndGetTranscript } = useSpeechOS();
44
+ *
45
+ * const handleRecord = async () => {
46
+ * await connect();
47
+ * await waitUntilReady();
48
+ * await enableMicrophone();
49
+ * // ... recording ...
50
+ * const text = await stopAndGetTranscript();
51
+ * };
52
+ * }
53
+ * ```
54
+ */
55
+ export { SpeechOSProvider, SpeechOSContext, useSpeechOSContext, type SpeechOSContextValue, type SpeechOSProviderProps, } from "./context.js";
56
+ export { useSpeechOS, useSpeechOSState, useSpeechOSEvents, useDictation, useEdit, useTranscription, type UseDictationResult, type UseEditResult, type UseTranscriptionResult, } from "./hooks/index.js";
57
+ export { SpeechOSWidget, type SpeechOSWidgetProps } from "./components/index.js";
58
+ export type { SpeechOSConfig, SpeechOSState, SpeechOSAction, SpeechOSEventMap, RecordingState, UnsubscribeFn, } from "@speechos/core";
59
+ export declare const VERSION = "0.1.0";
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @speechos/react
3
+ *
4
+ * React hooks and components for SpeechOS voice integration.
5
+ *
6
+ * @example Basic usage with widget
7
+ * ```tsx
8
+ * import { SpeechOSProvider, SpeechOSWidget } from '@speechos/react';
9
+ * import '@speechos/client'; // Registers Web Component
10
+ *
11
+ * function App() {
12
+ * return (
13
+ * <SpeechOSProvider config={{ apiKey: 'your-key' }}>
14
+ * <MyForm />
15
+ * <SpeechOSWidget
16
+ * onTranscription={(text) => console.log(text)}
17
+ * />
18
+ * </SpeechOSProvider>
19
+ * );
20
+ * }
21
+ * ```
22
+ *
23
+ * @example Hook-based usage
24
+ * ```tsx
25
+ * import { SpeechOSProvider, useDictation } from '@speechos/react';
26
+ *
27
+ * function VoiceInput() {
28
+ * const { start, stop, isRecording, transcript } = useDictation();
29
+ *
30
+ * return (
31
+ * <button onClick={isRecording ? stop : start}>
32
+ * {isRecording ? 'Stop' : 'Start'}
33
+ * </button>
34
+ * );
35
+ * }
36
+ * ```
37
+ *
38
+ * @example Low-level usage
39
+ * ```tsx
40
+ * import { useSpeechOS } from '@speechos/react';
41
+ *
42
+ * function CustomUI() {
43
+ * const { connect, waitUntilReady, enableMicrophone, stopAndGetTranscript } = useSpeechOS();
44
+ *
45
+ * const handleRecord = async () => {
46
+ * await connect();
47
+ * await waitUntilReady();
48
+ * await enableMicrophone();
49
+ * // ... recording ...
50
+ * const text = await stopAndGetTranscript();
51
+ * };
52
+ * }
53
+ * ```
54
+ */
55
+ export { SpeechOSProvider, SpeechOSContext, useSpeechOSContext, type SpeechOSContextValue, type SpeechOSProviderProps, } from "./context.js";
56
+ export { useSpeechOS, useSpeechOSState, useSpeechOSEvents, useDictation, useEdit, useTranscription, type UseDictationResult, type UseEditResult, type UseTranscriptionResult, } from "./hooks/index.js";
57
+ export { SpeechOSWidget, type SpeechOSWidgetProps } from "./components/index.js";
58
+ export type { SpeechOSConfig, SpeechOSState, SpeechOSAction, SpeechOSEventMap, RecordingState, UnsubscribeFn, } from "@speechos/core";
59
+ export declare const VERSION = "0.1.0";