@voxdiscover/voiceserver-react 0.1.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,334 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as react from 'react';
3
+ import { ReactNode, Dispatch, SetStateAction } from 'react';
4
+ import { VoiceAgentConfig, VoiceAgent, ConnectionState, TranscriptData } from '@voxdiscover/voiceserver';
5
+ export * from '@voxdiscover/voiceserver';
6
+ export { ConnectionState, ReconnectionManager, TranscriptData, VoiceAgent, VoiceAgentConfig, VoiceAgentErrorCode, VoiceAgentEvents } from '@voxdiscover/voiceserver';
7
+
8
+ /**
9
+ * Props for VoiceAgentProvider component.
10
+ * Per user decision: Config object pattern for flexibility.
11
+ */
12
+ interface VoiceAgentProviderProps extends VoiceAgentConfig {
13
+ children: ReactNode;
14
+ /** Callback when connection is established */
15
+ onConnect?: () => void;
16
+ /** Callback when connection is closed */
17
+ onDisconnect?: () => void;
18
+ /** Callback for connection errors */
19
+ onError?: (error: Error) => void;
20
+ }
21
+ /**
22
+ * Context provider for VoiceAgent instance.
23
+ *
24
+ * Per user decisions:
25
+ * - Creates VoiceAgent instance but waits for explicit connect() call (manual connect pattern)
26
+ * - Auto-disconnects and cleans up WebRTC resources on unmount
27
+ * - Provides stable agent reference via useRef (prevents re-render cascades)
28
+ *
29
+ * @example
30
+ * ```tsx
31
+ * function App() {
32
+ * return (
33
+ * <VoiceAgentProvider
34
+ * token={sessionToken}
35
+ * onConnect={() => console.log('Connected!')}
36
+ * onError={(err) => console.error('Error:', err)}
37
+ * >
38
+ * <VoiceChat />
39
+ * </VoiceAgentProvider>
40
+ * );
41
+ * }
42
+ * ```
43
+ */
44
+ declare function VoiceAgentProvider({ children, token, baseUrl, reconnection, onConnect, onDisconnect, onError, }: VoiceAgentProviderProps): react_jsx_runtime.JSX.Element;
45
+
46
+ /**
47
+ * Context value containing VoiceAgent instance and token.
48
+ * Per user decision: Context only holds agent instance, not UI state.
49
+ * Token included for session ID extraction (transcript persistence).
50
+ */
51
+ interface VoiceAgentContextValue {
52
+ agent: VoiceAgent | null;
53
+ token: string;
54
+ }
55
+ /**
56
+ * React context for VoiceAgent instance.
57
+ * Provides stable reference to agent across component tree.
58
+ *
59
+ * @example
60
+ * ```tsx
61
+ * const context = useContext(VoiceAgentContext);
62
+ * if (!context?.agent) throw new Error('No agent available');
63
+ * ```
64
+ */
65
+ declare const VoiceAgentContext: react.Context<VoiceAgentContextValue | null>;
66
+
67
+ /**
68
+ * Retry state exposed for UI feedback.
69
+ * Per user decision: UI can display attempt count and countdown timer.
70
+ */
71
+ interface RetryState {
72
+ /** Whether a retry is currently in progress */
73
+ isRetrying: boolean;
74
+ /** Current retry attempt number (0-based) */
75
+ attempt: number;
76
+ /** Maximum retry attempts configured */
77
+ maxAttempts: number;
78
+ /** Milliseconds until next retry attempt */
79
+ nextRetryIn: number;
80
+ }
81
+ /**
82
+ * Hook providing automatic retry logic with exponential backoff.
83
+ *
84
+ * Per RESEARCH.md Pattern 4 and user decision:
85
+ * - Exponential backoff: delay = min(1000 * 2^(attempt-1), 10000)
86
+ * - Countdown timer updates every 100ms for UI feedback
87
+ * - Reset retry state on success
88
+ * - Keep attempt count on failure for next retry
89
+ *
90
+ * @param connectFn - Async function to retry (typically agent.connect)
91
+ * @param maxAttempts - Maximum retry attempts (default: 5)
92
+ * @returns Retry state and retry function
93
+ *
94
+ * @example
95
+ * ```typescript
96
+ * const { retryState, retry } = useConnectionRetry(
97
+ * async () => agent.connect(),
98
+ * 5
99
+ * );
100
+ *
101
+ * // Show retry UI
102
+ * if (retryState.isRetrying) {
103
+ * return <div>Retrying... ({retryState.attempt}/{retryState.maxAttempts})
104
+ * Next attempt in {Math.ceil(retryState.nextRetryIn / 1000)}s</div>
105
+ * }
106
+ *
107
+ * // Manual retry
108
+ * <button onClick={retry}>Retry Connection</button>
109
+ * ```
110
+ */
111
+ declare function useConnectionRetry(connectFn: () => Promise<void>, maxAttempts?: number): {
112
+ retryState: RetryState;
113
+ retry: () => Promise<void>;
114
+ };
115
+
116
+ /**
117
+ * Return type for useVoiceAgent hook.
118
+ * Per user decision: Flat return structure with all properties at top level.
119
+ */
120
+ interface UseVoiceAgentReturn {
121
+ /** Raw VoiceAgent instance for advanced use cases */
122
+ agent: VoiceAgent;
123
+ /** Current connection state */
124
+ callState: ConnectionState;
125
+ /** All transcripts accumulated during session */
126
+ transcripts: TranscriptData[];
127
+ /** Current error, if any (auto-cleared on success) */
128
+ error: Error | null;
129
+ /** Derived: true if callState === 'connected' */
130
+ isConnected: boolean;
131
+ /** Derived: true if callState === 'connecting' */
132
+ isConnecting: boolean;
133
+ /** Derived: true if callState === 'reconnecting' */
134
+ isReconnecting: boolean;
135
+ /** Retry state for UI feedback (attempt count, countdown) */
136
+ retryState: RetryState;
137
+ /** Connect to voice session */
138
+ connect: () => Promise<void>;
139
+ /** Disconnect from voice session */
140
+ disconnect: () => Promise<void>;
141
+ /** Mute microphone */
142
+ mute: () => void;
143
+ /** Unmute microphone */
144
+ unmute: () => void;
145
+ /** Manual retry connection (with exponential backoff) */
146
+ retryConnect: () => Promise<void>;
147
+ }
148
+ /**
149
+ * Comprehensive hook for VoiceAgent functionality.
150
+ *
151
+ * Per user decision:
152
+ * - Single comprehensive hook returning everything (not multiple focused hooks)
153
+ * - Flat return structure with all properties at top level
154
+ * - Includes raw agent instance for advanced use cases
155
+ * - Unlimited transcript accumulation in memory during session
156
+ * - Auto-clear errors when next action succeeds
157
+ *
158
+ * Per RESEARCH.md patterns:
159
+ * - Uses useSyncExternalStore for connection state (concurrent-safe)
160
+ * - Uses useState for transcripts and errors
161
+ * - Proper cleanup in useEffect to prevent memory leaks
162
+ * - useCallback for wrapped methods
163
+ *
164
+ * @throws {Error} When used outside VoiceAgentProvider
165
+ *
166
+ * @example
167
+ * ```tsx
168
+ * function VoiceChat() {
169
+ * const {
170
+ * connect,
171
+ * disconnect,
172
+ * mute,
173
+ * unmute,
174
+ * callState,
175
+ * transcripts,
176
+ * error,
177
+ * isConnected,
178
+ * } = useVoiceAgent();
179
+ *
180
+ * return (
181
+ * <div>
182
+ * <button onClick={connect} disabled={isConnected}>
183
+ * {isConnected ? 'Connected' : 'Connect'}
184
+ * </button>
185
+ * {error && <div>Error: {error.message}</div>}
186
+ * <div>
187
+ * {transcripts.map((t, i) => (
188
+ * <p key={i}>{t.speaker}: {t.text}</p>
189
+ * ))}
190
+ * </div>
191
+ * </div>
192
+ * );
193
+ * }
194
+ * ```
195
+ */
196
+ declare function useVoiceAgent(): UseVoiceAgentReturn;
197
+
198
+ /**
199
+ * Hook to persist transcripts to sessionStorage.
200
+ *
201
+ * Per RESEARCH.md Pattern 3 and user decision:
202
+ * - Load persisted transcripts on mount
203
+ * - Save transcripts to sessionStorage on change
204
+ * - Clear on unmount (sessionStorage auto-clears on tab close)
205
+ * - Handle errors silently (log to console, don't crash)
206
+ * - No limits on transcript array size (browser quota is the limit)
207
+ *
208
+ * Per RESEARCH.md Pitfall 4:
209
+ * - Uses SSR-safe storage utilities
210
+ * - Won't crash in Next.js/Remix server-side rendering
211
+ *
212
+ * @param sessionId - Session ID to namespace storage key
213
+ * @param transcripts - Current transcripts array
214
+ * @param setTranscripts - State setter to restore transcripts
215
+ *
216
+ * @example
217
+ * ```typescript
218
+ * const [transcripts, setTranscripts] = useState<TranscriptData[]>([]);
219
+ * useTranscriptPersistence(sessionId, transcripts, setTranscripts);
220
+ * ```
221
+ */
222
+ declare function useTranscriptPersistence(sessionId: string, transcripts: TranscriptData[], setTranscripts: Dispatch<SetStateAction<TranscriptData[]>>): void;
223
+
224
+ /**
225
+ * SSR-safe sessionStorage utilities.
226
+ *
227
+ * Per RESEARCH.md Pitfall 4:
228
+ * - Guard with typeof window !== 'undefined' check
229
+ * - Wrap in try-catch (storage can be disabled or full)
230
+ * - Return null/false on error or SSR
231
+ *
232
+ * @packageDocumentation
233
+ */
234
+ /**
235
+ * Get item from sessionStorage in SSR-safe manner.
236
+ * Returns null if running in SSR, storage disabled, or key doesn't exist.
237
+ *
238
+ * @param key - Storage key
239
+ * @returns Value or null
240
+ *
241
+ * @example
242
+ * ```typescript
243
+ * const transcripts = getSessionStorage('voice-agent-transcripts');
244
+ * if (transcripts) {
245
+ * // Use transcripts
246
+ * }
247
+ * ```
248
+ */
249
+ declare function getSessionStorage(key: string): string | null;
250
+ /**
251
+ * Set item in sessionStorage in SSR-safe manner.
252
+ * Returns true on success, false on failure (SSR, quota exceeded, disabled).
253
+ *
254
+ * @param key - Storage key
255
+ * @param value - Value to store
256
+ * @returns Success flag
257
+ *
258
+ * @example
259
+ * ```typescript
260
+ * const success = setSessionStorage('voice-agent-transcripts', JSON.stringify(transcripts));
261
+ * if (!success) {
262
+ * console.warn('Failed to persist transcripts');
263
+ * }
264
+ * ```
265
+ */
266
+ declare function setSessionStorage(key: string, value: string): boolean;
267
+ /**
268
+ * Remove item from sessionStorage in SSR-safe manner.
269
+ * Returns true on success, false on failure (SSR, disabled).
270
+ *
271
+ * @param key - Storage key
272
+ * @returns Success flag
273
+ *
274
+ * @example
275
+ * ```typescript
276
+ * removeSessionStorage('voice-agent-transcripts-session-123');
277
+ * ```
278
+ */
279
+ declare function removeSessionStorage(key: string): boolean;
280
+ /**
281
+ * Get and parse JSON from sessionStorage.
282
+ * Returns null if parsing fails, SSR, or key doesn't exist.
283
+ *
284
+ * @param key - Storage key
285
+ * @returns Parsed value or null
286
+ *
287
+ * @example
288
+ * ```typescript
289
+ * const transcripts = getSessionStorageJSON<TranscriptData[]>('voice-agent-transcripts');
290
+ * if (transcripts) {
291
+ * // Use typed transcripts array
292
+ * }
293
+ * ```
294
+ */
295
+ declare function getSessionStorageJSON<T>(key: string): T | null;
296
+ /**
297
+ * Stringify and store JSON in sessionStorage.
298
+ * Returns true on success, false on failure (SSR, quota, parse error).
299
+ *
300
+ * @param key - Storage key
301
+ * @param value - Value to stringify and store
302
+ * @returns Success flag
303
+ *
304
+ * @example
305
+ * ```typescript
306
+ * const success = setSessionStorageJSON('voice-agent-transcripts', transcripts);
307
+ * if (!success) {
308
+ * console.warn('Failed to persist transcripts');
309
+ * }
310
+ * ```
311
+ */
312
+ declare function setSessionStorageJSON<T>(key: string, value: T): boolean;
313
+
314
+ /**
315
+ * Simple JWT token decoder for extracting session ID.
316
+ * Per plan: Client-side JWT decoding (backend already validated).
317
+ */
318
+ /**
319
+ * Extract session ID from JWT session token.
320
+ * Uses atob() for browser compatibility.
321
+ *
322
+ * @param token - JWT session token
323
+ * @returns Session ID string
324
+ * @throws {Error} If token is malformed
325
+ *
326
+ * @example
327
+ * ```typescript
328
+ * const sessionId = extractSessionId(sessionToken);
329
+ * // Use sessionId for storage key
330
+ * ```
331
+ */
332
+ declare function extractSessionId(token: string): string;
333
+
334
+ export { type RetryState, type UseVoiceAgentReturn, VoiceAgentContext, type VoiceAgentContextValue, VoiceAgentProvider, type VoiceAgentProviderProps, extractSessionId, getSessionStorage, getSessionStorageJSON, removeSessionStorage, setSessionStorage, setSessionStorageJSON, useConnectionRetry, useTranscriptPersistence, useVoiceAgent };
@@ -0,0 +1,334 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as react from 'react';
3
+ import { ReactNode, Dispatch, SetStateAction } from 'react';
4
+ import { VoiceAgentConfig, VoiceAgent, ConnectionState, TranscriptData } from '@voxdiscover/voiceserver';
5
+ export * from '@voxdiscover/voiceserver';
6
+ export { ConnectionState, ReconnectionManager, TranscriptData, VoiceAgent, VoiceAgentConfig, VoiceAgentErrorCode, VoiceAgentEvents } from '@voxdiscover/voiceserver';
7
+
8
+ /**
9
+ * Props for VoiceAgentProvider component.
10
+ * Per user decision: Config object pattern for flexibility.
11
+ */
12
+ interface VoiceAgentProviderProps extends VoiceAgentConfig {
13
+ children: ReactNode;
14
+ /** Callback when connection is established */
15
+ onConnect?: () => void;
16
+ /** Callback when connection is closed */
17
+ onDisconnect?: () => void;
18
+ /** Callback for connection errors */
19
+ onError?: (error: Error) => void;
20
+ }
21
+ /**
22
+ * Context provider for VoiceAgent instance.
23
+ *
24
+ * Per user decisions:
25
+ * - Creates VoiceAgent instance but waits for explicit connect() call (manual connect pattern)
26
+ * - Auto-disconnects and cleans up WebRTC resources on unmount
27
+ * - Provides stable agent reference via useRef (prevents re-render cascades)
28
+ *
29
+ * @example
30
+ * ```tsx
31
+ * function App() {
32
+ * return (
33
+ * <VoiceAgentProvider
34
+ * token={sessionToken}
35
+ * onConnect={() => console.log('Connected!')}
36
+ * onError={(err) => console.error('Error:', err)}
37
+ * >
38
+ * <VoiceChat />
39
+ * </VoiceAgentProvider>
40
+ * );
41
+ * }
42
+ * ```
43
+ */
44
+ declare function VoiceAgentProvider({ children, token, baseUrl, reconnection, onConnect, onDisconnect, onError, }: VoiceAgentProviderProps): react_jsx_runtime.JSX.Element;
45
+
46
+ /**
47
+ * Context value containing VoiceAgent instance and token.
48
+ * Per user decision: Context only holds agent instance, not UI state.
49
+ * Token included for session ID extraction (transcript persistence).
50
+ */
51
+ interface VoiceAgentContextValue {
52
+ agent: VoiceAgent | null;
53
+ token: string;
54
+ }
55
+ /**
56
+ * React context for VoiceAgent instance.
57
+ * Provides stable reference to agent across component tree.
58
+ *
59
+ * @example
60
+ * ```tsx
61
+ * const context = useContext(VoiceAgentContext);
62
+ * if (!context?.agent) throw new Error('No agent available');
63
+ * ```
64
+ */
65
+ declare const VoiceAgentContext: react.Context<VoiceAgentContextValue | null>;
66
+
67
+ /**
68
+ * Retry state exposed for UI feedback.
69
+ * Per user decision: UI can display attempt count and countdown timer.
70
+ */
71
+ interface RetryState {
72
+ /** Whether a retry is currently in progress */
73
+ isRetrying: boolean;
74
+ /** Current retry attempt number (0-based) */
75
+ attempt: number;
76
+ /** Maximum retry attempts configured */
77
+ maxAttempts: number;
78
+ /** Milliseconds until next retry attempt */
79
+ nextRetryIn: number;
80
+ }
81
+ /**
82
+ * Hook providing automatic retry logic with exponential backoff.
83
+ *
84
+ * Per RESEARCH.md Pattern 4 and user decision:
85
+ * - Exponential backoff: delay = min(1000 * 2^(attempt-1), 10000)
86
+ * - Countdown timer updates every 100ms for UI feedback
87
+ * - Reset retry state on success
88
+ * - Keep attempt count on failure for next retry
89
+ *
90
+ * @param connectFn - Async function to retry (typically agent.connect)
91
+ * @param maxAttempts - Maximum retry attempts (default: 5)
92
+ * @returns Retry state and retry function
93
+ *
94
+ * @example
95
+ * ```typescript
96
+ * const { retryState, retry } = useConnectionRetry(
97
+ * async () => agent.connect(),
98
+ * 5
99
+ * );
100
+ *
101
+ * // Show retry UI
102
+ * if (retryState.isRetrying) {
103
+ * return <div>Retrying... ({retryState.attempt}/{retryState.maxAttempts})
104
+ * Next attempt in {Math.ceil(retryState.nextRetryIn / 1000)}s</div>
105
+ * }
106
+ *
107
+ * // Manual retry
108
+ * <button onClick={retry}>Retry Connection</button>
109
+ * ```
110
+ */
111
+ declare function useConnectionRetry(connectFn: () => Promise<void>, maxAttempts?: number): {
112
+ retryState: RetryState;
113
+ retry: () => Promise<void>;
114
+ };
115
+
116
+ /**
117
+ * Return type for useVoiceAgent hook.
118
+ * Per user decision: Flat return structure with all properties at top level.
119
+ */
120
+ interface UseVoiceAgentReturn {
121
+ /** Raw VoiceAgent instance for advanced use cases */
122
+ agent: VoiceAgent;
123
+ /** Current connection state */
124
+ callState: ConnectionState;
125
+ /** All transcripts accumulated during session */
126
+ transcripts: TranscriptData[];
127
+ /** Current error, if any (auto-cleared on success) */
128
+ error: Error | null;
129
+ /** Derived: true if callState === 'connected' */
130
+ isConnected: boolean;
131
+ /** Derived: true if callState === 'connecting' */
132
+ isConnecting: boolean;
133
+ /** Derived: true if callState === 'reconnecting' */
134
+ isReconnecting: boolean;
135
+ /** Retry state for UI feedback (attempt count, countdown) */
136
+ retryState: RetryState;
137
+ /** Connect to voice session */
138
+ connect: () => Promise<void>;
139
+ /** Disconnect from voice session */
140
+ disconnect: () => Promise<void>;
141
+ /** Mute microphone */
142
+ mute: () => void;
143
+ /** Unmute microphone */
144
+ unmute: () => void;
145
+ /** Manual retry connection (with exponential backoff) */
146
+ retryConnect: () => Promise<void>;
147
+ }
148
+ /**
149
+ * Comprehensive hook for VoiceAgent functionality.
150
+ *
151
+ * Per user decision:
152
+ * - Single comprehensive hook returning everything (not multiple focused hooks)
153
+ * - Flat return structure with all properties at top level
154
+ * - Includes raw agent instance for advanced use cases
155
+ * - Unlimited transcript accumulation in memory during session
156
+ * - Auto-clear errors when next action succeeds
157
+ *
158
+ * Per RESEARCH.md patterns:
159
+ * - Uses useSyncExternalStore for connection state (concurrent-safe)
160
+ * - Uses useState for transcripts and errors
161
+ * - Proper cleanup in useEffect to prevent memory leaks
162
+ * - useCallback for wrapped methods
163
+ *
164
+ * @throws {Error} When used outside VoiceAgentProvider
165
+ *
166
+ * @example
167
+ * ```tsx
168
+ * function VoiceChat() {
169
+ * const {
170
+ * connect,
171
+ * disconnect,
172
+ * mute,
173
+ * unmute,
174
+ * callState,
175
+ * transcripts,
176
+ * error,
177
+ * isConnected,
178
+ * } = useVoiceAgent();
179
+ *
180
+ * return (
181
+ * <div>
182
+ * <button onClick={connect} disabled={isConnected}>
183
+ * {isConnected ? 'Connected' : 'Connect'}
184
+ * </button>
185
+ * {error && <div>Error: {error.message}</div>}
186
+ * <div>
187
+ * {transcripts.map((t, i) => (
188
+ * <p key={i}>{t.speaker}: {t.text}</p>
189
+ * ))}
190
+ * </div>
191
+ * </div>
192
+ * );
193
+ * }
194
+ * ```
195
+ */
196
+ declare function useVoiceAgent(): UseVoiceAgentReturn;
197
+
198
+ /**
199
+ * Hook to persist transcripts to sessionStorage.
200
+ *
201
+ * Per RESEARCH.md Pattern 3 and user decision:
202
+ * - Load persisted transcripts on mount
203
+ * - Save transcripts to sessionStorage on change
204
+ * - Clear on unmount (sessionStorage auto-clears on tab close)
205
+ * - Handle errors silently (log to console, don't crash)
206
+ * - No limits on transcript array size (browser quota is the limit)
207
+ *
208
+ * Per RESEARCH.md Pitfall 4:
209
+ * - Uses SSR-safe storage utilities
210
+ * - Won't crash in Next.js/Remix server-side rendering
211
+ *
212
+ * @param sessionId - Session ID to namespace storage key
213
+ * @param transcripts - Current transcripts array
214
+ * @param setTranscripts - State setter to restore transcripts
215
+ *
216
+ * @example
217
+ * ```typescript
218
+ * const [transcripts, setTranscripts] = useState<TranscriptData[]>([]);
219
+ * useTranscriptPersistence(sessionId, transcripts, setTranscripts);
220
+ * ```
221
+ */
222
+ declare function useTranscriptPersistence(sessionId: string, transcripts: TranscriptData[], setTranscripts: Dispatch<SetStateAction<TranscriptData[]>>): void;
223
+
224
+ /**
225
+ * SSR-safe sessionStorage utilities.
226
+ *
227
+ * Per RESEARCH.md Pitfall 4:
228
+ * - Guard with typeof window !== 'undefined' check
229
+ * - Wrap in try-catch (storage can be disabled or full)
230
+ * - Return null/false on error or SSR
231
+ *
232
+ * @packageDocumentation
233
+ */
234
+ /**
235
+ * Get item from sessionStorage in SSR-safe manner.
236
+ * Returns null if running in SSR, storage disabled, or key doesn't exist.
237
+ *
238
+ * @param key - Storage key
239
+ * @returns Value or null
240
+ *
241
+ * @example
242
+ * ```typescript
243
+ * const transcripts = getSessionStorage('voice-agent-transcripts');
244
+ * if (transcripts) {
245
+ * // Use transcripts
246
+ * }
247
+ * ```
248
+ */
249
+ declare function getSessionStorage(key: string): string | null;
250
+ /**
251
+ * Set item in sessionStorage in SSR-safe manner.
252
+ * Returns true on success, false on failure (SSR, quota exceeded, disabled).
253
+ *
254
+ * @param key - Storage key
255
+ * @param value - Value to store
256
+ * @returns Success flag
257
+ *
258
+ * @example
259
+ * ```typescript
260
+ * const success = setSessionStorage('voice-agent-transcripts', JSON.stringify(transcripts));
261
+ * if (!success) {
262
+ * console.warn('Failed to persist transcripts');
263
+ * }
264
+ * ```
265
+ */
266
+ declare function setSessionStorage(key: string, value: string): boolean;
267
+ /**
268
+ * Remove item from sessionStorage in SSR-safe manner.
269
+ * Returns true on success, false on failure (SSR, disabled).
270
+ *
271
+ * @param key - Storage key
272
+ * @returns Success flag
273
+ *
274
+ * @example
275
+ * ```typescript
276
+ * removeSessionStorage('voice-agent-transcripts-session-123');
277
+ * ```
278
+ */
279
+ declare function removeSessionStorage(key: string): boolean;
280
+ /**
281
+ * Get and parse JSON from sessionStorage.
282
+ * Returns null if parsing fails, SSR, or key doesn't exist.
283
+ *
284
+ * @param key - Storage key
285
+ * @returns Parsed value or null
286
+ *
287
+ * @example
288
+ * ```typescript
289
+ * const transcripts = getSessionStorageJSON<TranscriptData[]>('voice-agent-transcripts');
290
+ * if (transcripts) {
291
+ * // Use typed transcripts array
292
+ * }
293
+ * ```
294
+ */
295
+ declare function getSessionStorageJSON<T>(key: string): T | null;
296
+ /**
297
+ * Stringify and store JSON in sessionStorage.
298
+ * Returns true on success, false on failure (SSR, quota, parse error).
299
+ *
300
+ * @param key - Storage key
301
+ * @param value - Value to stringify and store
302
+ * @returns Success flag
303
+ *
304
+ * @example
305
+ * ```typescript
306
+ * const success = setSessionStorageJSON('voice-agent-transcripts', transcripts);
307
+ * if (!success) {
308
+ * console.warn('Failed to persist transcripts');
309
+ * }
310
+ * ```
311
+ */
312
+ declare function setSessionStorageJSON<T>(key: string, value: T): boolean;
313
+
314
+ /**
315
+ * Simple JWT token decoder for extracting session ID.
316
+ * Per plan: Client-side JWT decoding (backend already validated).
317
+ */
318
+ /**
319
+ * Extract session ID from JWT session token.
320
+ * Uses atob() for browser compatibility.
321
+ *
322
+ * @param token - JWT session token
323
+ * @returns Session ID string
324
+ * @throws {Error} If token is malformed
325
+ *
326
+ * @example
327
+ * ```typescript
328
+ * const sessionId = extractSessionId(sessionToken);
329
+ * // Use sessionId for storage key
330
+ * ```
331
+ */
332
+ declare function extractSessionId(token: string): string;
333
+
334
+ export { type RetryState, type UseVoiceAgentReturn, VoiceAgentContext, type VoiceAgentContextValue, VoiceAgentProvider, type VoiceAgentProviderProps, extractSessionId, getSessionStorage, getSessionStorageJSON, removeSessionStorage, setSessionStorage, setSessionStorageJSON, useConnectionRetry, useTranscriptPersistence, useVoiceAgent };