@centive/aria-sdk 0.5.2 → 0.5.4

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/README.md CHANGED
@@ -12,6 +12,13 @@ A production-ready React SDK for [Anam AI](https://docs.anam.ai/) with dual-mode
12
12
  - **Center Modal Mode** - Auto-opens when WebSocket events arrive (e.g., incoming calls)
13
13
  - **Both modes work simultaneously** - Maximum flexibility for any use case
14
14
 
15
+ ### 🚀 Global Session Management
16
+ - **Session Preloading** - Session is ready before user clicks, for instant response
17
+ - **Session Persistence** - Session survives page navigation in SPAs
18
+ - **Proactive Refresh** - Automatically refreshes session before expiration
19
+ - **Tab Visibility Awareness** - Only refreshes when tab is active
20
+ - **Error Recovery** - Exponential backoff retry on failures
21
+
15
22
  ### 🔌 WebSocket Integration
16
23
  - Real-time bidirectional communication
17
24
  - Automatic session management
@@ -58,21 +65,33 @@ npm install react@^18.0.0 react-dom@^18.0.0
58
65
 
59
66
  The SDK provides an all-in-one container that handles WebSocket connection, state management, and the UI. Just import and drop it in! By default, this includes both the floating trigger button and the assistant widget.
60
67
 
68
+ > **Important:** Place `Aria` (or `AriaProvider`) at your app's root level, **above your router**. This ensures the session persists across page navigation and provides instant response when users click the trigger button.
69
+
61
70
  ```tsx
62
71
  import { Aria } from '@centive/aria-sdk';
63
72
  import '@centive/aria-sdk/styles.css';
73
+ import { BrowserRouter, Routes, Route } from 'react-router-dom';
64
74
 
65
75
  function App() {
66
76
  const config = {
67
77
  websocketUrl: 'ws://localhost:8000/ws',
68
78
  userId: 'user_123',
69
79
  theme: 'light', // or 'dark'
80
+ // Session preloading is enabled by default
81
+ preloadSession: true,
82
+ // Refresh session 5 minutes before expiry (default)
83
+ sessionRefreshBuffer: 5,
70
84
  };
71
85
 
72
86
  return (
73
- // This automatically renders the Trigger Button and Assistant Widget
87
+ // Place Aria at the root, ABOVE the router for session persistence
74
88
  <Aria config={config}>
75
- <YourApp />
89
+ <BrowserRouter>
90
+ <Routes>
91
+ <Route path="/" element={<Home />} />
92
+ <Route path="/dashboard" element={<Dashboard />} />
93
+ </Routes>
94
+ </BrowserRouter>
76
95
  </Aria>
77
96
  );
78
97
  }
@@ -84,6 +103,7 @@ If you need full control over where components are rendered, you can disable the
84
103
 
85
104
  ```tsx
86
105
  import { AriaProvider, AriaAssistant } from '@centive/aria-sdk';
106
+ import { BrowserRouter, Routes, Route } from 'react-router-dom';
87
107
 
88
108
  function App() {
89
109
  const config = {
@@ -93,8 +113,14 @@ function App() {
93
113
  };
94
114
 
95
115
  return (
116
+ // Always place AriaProvider at the root, above the router
96
117
  <AriaProvider config={config}>
97
- <YourApp />
118
+ <BrowserRouter>
119
+ <Routes>
120
+ <Route path="/" element={<Home />} />
121
+ <Route path="/dashboard" element={<Dashboard />} />
122
+ </Routes>
123
+ </BrowserRouter>
98
124
 
99
125
  {/* AriaAssistant includes both the trigger button and the widget */}
100
126
  <AriaAssistant
@@ -231,13 +257,25 @@ import { useAria } from '@centive/aria-sdk';
231
257
 
232
258
  function MyComponent() {
233
259
  const {
260
+ // UI State
234
261
  isOpen,
235
262
  isConnected,
263
+ isLoading,
236
264
  displayMode,
237
265
  triggerMode,
238
266
  theme,
239
267
  chatMessages,
268
+ liveTranscript,
269
+ isChatVisible,
270
+ isMuted,
271
+ error,
272
+
273
+ // Session State
240
274
  sessionState,
275
+ sessionManagerStatus, // 'idle' | 'connecting' | 'connected' | 'preloading' | 'ready' | 'refreshing' | 'error'
276
+ isSessionPreloaded, // True when session is ready before widget opens
277
+
278
+ // Actions
241
279
  openAssistant,
242
280
  closeAssistant,
243
281
  toggleChat,
@@ -246,7 +284,12 @@ function MyComponent() {
246
284
  startSession,
247
285
  stopSession,
248
286
  triggerSession,
249
- getSessionIdFromToken, // Extract session ID from tokens
287
+ refreshSession, // Manually refresh the session
288
+ setVideoElement,
289
+
290
+ // Utilities
291
+ getSessionId,
292
+ config,
250
293
  } = useAria();
251
294
 
252
295
  // Use the methods and state
@@ -340,6 +383,13 @@ interface AriaSDKConfig {
340
383
  onSessionEndAck?: (savedCount: number) => void;
341
384
  onSessionEndError?: (error: string, errorType: string) => void;
342
385
 
386
+ // Session preloading options (Global Session Management)
387
+ preloadSession?: boolean; // Enable session preloading on mount (default: true)
388
+ sessionRefreshBuffer?: number; // Minutes before expiry to refresh (default: 5)
389
+ onSessionPreloaded?: () => void; // Callback when session is preloaded and ready
390
+ onSessionRefresh?: () => void; // Callback when session is refreshed
391
+ onSessionRefreshError?: (error: Error) => void; // Callback when refresh fails
392
+
343
393
  // Rendering options
344
394
  showFloatingButton?: boolean; // Show the default floating button (default: true)
345
395
  showAssistant?: boolean; // Show the assistant widget (default: true)
@@ -431,6 +481,112 @@ See `example-ws-server.js` for a complete implementation.
431
481
  }
432
482
  ```
433
483
 
484
+ ## 🔄 Session Management
485
+
486
+ ### Global Session Architecture
487
+
488
+ The SDK uses a singleton pattern to maintain session state globally, ensuring:
489
+
490
+ 1. **Session Preloading** - When `AriaProvider` mounts, it automatically:
491
+ - Connects to WebSocket
492
+ - Requests a session token
493
+ - Pre-initializes the Anam client
494
+ - Prepares video streaming in a hidden element
495
+
496
+ 2. **Instant Response** - When users click the trigger button:
497
+ - Session is already ready (no loading delay)
498
+ - Video stream transfers instantly to the visible widget
499
+
500
+ 3. **Session Persistence** - During page navigation:
501
+ - Session survives component unmounts/remounts
502
+ - No reconnection needed when navigating between pages
503
+
504
+ ### Provider Placement (Critical)
505
+
506
+ **Correct:** Place at app root, above router:
507
+ ```tsx
508
+ function App() {
509
+ return (
510
+ <AriaProvider config={config}>
511
+ <BrowserRouter>
512
+ <Routes>...</Routes>
513
+ </BrowserRouter>
514
+ </AriaProvider>
515
+ );
516
+ }
517
+ ```
518
+
519
+ **Incorrect:** Inside route (session lost on navigation):
520
+ ```tsx
521
+ function App() {
522
+ return (
523
+ <BrowserRouter>
524
+ <Routes>
525
+ <Route path="/" element={
526
+ <AriaProvider config={config}> {/* Don't do this! */}
527
+ <Home />
528
+ </AriaProvider>
529
+ } />
530
+ </Routes>
531
+ </BrowserRouter>
532
+ );
533
+ }
534
+ ```
535
+
536
+ > **Note:** Even if placed incorrectly, the SDK's singleton pattern provides a safety net to maintain session continuity.
537
+
538
+ ### Session Refresh
539
+
540
+ The SDK automatically refreshes sessions before they expire:
541
+
542
+ ```tsx
543
+ const config = {
544
+ websocketUrl: 'ws://localhost:8000/ws',
545
+ userId: 'user_123',
546
+
547
+ // Session refresh configuration
548
+ sessionRefreshBuffer: 5, // Refresh 5 minutes before expiry (default)
549
+
550
+ // Callbacks
551
+ onSessionPreloaded: () => {
552
+ console.log('Session is preloaded and ready!');
553
+ },
554
+ onSessionRefresh: () => {
555
+ console.log('Session refreshed successfully');
556
+ },
557
+ onSessionRefreshError: (error) => {
558
+ console.error('Session refresh failed:', error);
559
+ },
560
+ };
561
+ ```
562
+
563
+ ### Manual Session Control
564
+
565
+ ```tsx
566
+ function SessionController() {
567
+ const {
568
+ sessionState,
569
+ sessionManagerStatus,
570
+ isSessionPreloaded,
571
+ refreshSession,
572
+ } = useAria();
573
+
574
+ return (
575
+ <div>
576
+ <p>Status: {sessionManagerStatus}</p>
577
+ <p>Preloaded: {isSessionPreloaded ? 'Yes' : 'No'}</p>
578
+ <p>Session ID: {sessionState.session_id}</p>
579
+ <p>Expires: {sessionState.expires_at}</p>
580
+
581
+ {/* Manual refresh if needed */}
582
+ <button onClick={refreshSession}>
583
+ Refresh Session
584
+ </button>
585
+ </div>
586
+ );
587
+ }
588
+ ```
589
+
434
590
  ## 💡 Advanced Usage
435
591
 
436
592
  ### Programmatic Control
@@ -1 +1 @@
1
- {"version":3,"file":"AriaTriggerButton.d.ts","sourceRoot":"","sources":["../../src/components/AriaTriggerButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAGhC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAM1D,UAAU,sBAAuB,SAAQ,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAED,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,sBAAsB,CAkHxD,CAAC"}
1
+ {"version":3,"file":"AriaTriggerButton.d.ts","sourceRoot":"","sources":["../../src/components/AriaTriggerButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAGhC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAM1D,UAAU,sBAAuB,SAAQ,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAED,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,sBAAsB,CAsHxD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"AriaWidget.d.ts","sourceRoot":"","sources":["../../src/components/AriaWidget.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAOnD,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,eAAe,CAyS1C,CAAC"}
1
+ {"version":3,"file":"AriaWidget.d.ts","sourceRoot":"","sources":["../../src/components/AriaWidget.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAOnD,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,eAAe,CA0T1C,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { ChatMessage, AriaSDKConfig, DisplayMode, TriggerMode, Theme, SessionState, TriggerSessionOptions } from '@/types';
1
+ import type { ChatMessage, AriaSDKConfig, DisplayMode, TriggerMode, Theme, SessionState, TriggerSessionOptions, SessionManagerStatus } from '@/types';
2
2
  export interface AriaContextType {
3
3
  isOpen: boolean;
4
4
  isConnected: boolean;
@@ -9,7 +9,11 @@ export interface AriaContextType {
9
9
  isMuted: boolean;
10
10
  error: string | null;
11
11
  sessionState: SessionState;
12
- openAssistant: (mode: TriggerMode) => void;
12
+ /** Current status of the session manager */
13
+ sessionManagerStatus: SessionManagerStatus;
14
+ /** Whether the session is preloaded and ready for instant use */
15
+ isSessionPreloaded: boolean;
16
+ openAssistant: (mode?: TriggerMode) => void;
13
17
  closeAssistant: () => void;
14
18
  toggleChat: () => void;
15
19
  sendMessage: (message: string) => Promise<void>;
@@ -17,6 +21,8 @@ export interface AriaContextType {
17
21
  startSession: () => Promise<void>;
18
22
  stopSession: () => Promise<void>;
19
23
  triggerSession: (options?: TriggerSessionOptions) => void;
24
+ /** Manually refresh the session (useful for error recovery) */
25
+ refreshSession: () => Promise<void>;
20
26
  setVideoElement: (element: HTMLVideoElement | null) => void;
21
27
  displayMode: DisplayMode;
22
28
  triggerMode: TriggerMode;
@@ -1 +1 @@
1
- {"version":3,"file":"AriaContext.d.ts","sourceRoot":"","sources":["../../src/context/AriaContext.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAEhI,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,YAAY,EAAE,YAAY,CAAC;IAC3B,aAAa,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IAC3C,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,YAAY,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,cAAc,EAAE,CAAC,OAAO,CAAC,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAC1D,eAAe,EAAE,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,KAAK,IAAI,CAAC;IAC5D,WAAW,EAAE,WAAW,CAAC;IACzB,WAAW,EAAE,WAAW,CAAC;IACzB,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;IACtB,YAAY,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,eAAO,MAAM,WAAW,iDAA8C,CAAC"}
1
+ {"version":3,"file":"AriaContext.d.ts","sourceRoot":"","sources":["../../src/context/AriaContext.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAEtJ,MAAM,WAAW,eAAe;IAE9B,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAGrB,YAAY,EAAE,YAAY,CAAC;IAC3B,4CAA4C;IAC5C,oBAAoB,EAAE,oBAAoB,CAAC;IAC3C,iEAAiE;IACjE,kBAAkB,EAAE,OAAO,CAAC;IAG5B,aAAa,EAAE,CAAC,IAAI,CAAC,EAAE,WAAW,KAAK,IAAI,CAAC;IAC5C,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,YAAY,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,cAAc,EAAE,CAAC,OAAO,CAAC,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAC1D,+DAA+D;IAC/D,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,eAAe,EAAE,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,KAAK,IAAI,CAAC;IAG5D,WAAW,EAAE,WAAW,CAAC;IACzB,WAAW,EAAE,WAAW,CAAC;IACzB,KAAK,EAAE,KAAK,CAAC;IAGb,MAAM,EAAE,aAAa,CAAC;IAGtB,YAAY,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,eAAO,MAAM,WAAW,iDAA8C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"AriaProvider.d.ts","sourceRoot":"","sources":["../../src/context/AriaProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA4C,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAoB1F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAM7C,UAAU,iBAAiB;IACzB,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAgGD,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CA8qB9C,CAAC"}
1
+ {"version":3,"file":"AriaProvider.d.ts","sourceRoot":"","sources":["../../src/context/AriaProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA4C,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAU1F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAK7C,UAAU,iBAAiB;IACzB,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAMD,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CA2X9C,CAAC"}