Event Handling
The SDK emits several events to handle various states and messages. You can listen to these events to manage your application's behavior accordingly.
Available Events
Connection Events
- open: Emitted when the WebSocket connection is successfully opened.
- close: Emitted when the WebSocket connection is closed.
Message Events
- message: Emitted when a message is received from the server.
- superpower.response: Modern event for handling server responses (recommended).
- message.{action}: Action-specific events (e.g.,
message.summarize,message.translate).
Error Events
- error: Emitted when an error occurs.
- superpower.error: Modern event for structured errors (recommended).
Basic Event Listening
client.on('open', () => {
console.log('WebSocket connection opened.');
});
client.on('message', (payload) => {
console.log('Received message:', payload);
});
client.on('error', (error) => {
console.error('An error occurred:', error);
});
client.on('close', (event) => {
console.log('WebSocket connection closed:', event.code);
});
Modern Event Names
For new code, use the modern event names:
// Recommended: Modern event names
client.on('superpower.response', (response) => {
console.log('Received response:', response);
if (response.status === 'success') {
console.log('Action successful:', response.action);
console.log('Response data:', response.data);
}
});
client.on('superpower.error', (error) => {
console.error(`[${error.category}] ${error.code}:`, error.message);
});
Action-Specific Events
Listen to specific AI operations without manual filtering:
// Listen only to summarize responses
client.on('message.summarize', (response) => {
const results = response.payload.message.results;
if (results && results.length > 0) {
const content = results[0].response[0].content;
console.log('Summary received:', content);
displaySummary(content);
}
});
client.on('message.translate', (response) => {
const results = response.payload.message.results;
if (results && results.length > 0) {
const content = results[0].response[0].content;
console.log('Translation received:', content);
displayTranslation(content);
}
});
client.on('message.recommend', (response) => {
const results = response.payload.message.results;
if (results && results.length > 0) {
// Recommendations might have multiple items
const recommendations = results[0].response;
console.log('Recommendations:', recommendations);
displayRecommendations(recommendations);
}
});
Available action events:
message.adjustmessage.elevatemessage.interactionmessage.receptionmessage.summarizemessage.translatemessage.recommendmessage.insights
Error Handling
The SDK includes structured error handling with categorization and troubleshooting suggestions.
Error Categories
- AUTHENTICATION: Authentication and authorization errors
- WEBSOCKET: Connection and transport errors
- VALIDATION: Payload and schema validation errors
- ORCHESTRATOR: Server-side orchestration errors
Error Object Structure
{
category: 'WEBSOCKET', // Error category
code: 'INVALID_WEBSOCKET_URL', // Error code
message: 'Empty or invalid Websocket URL', // Error message
details: null, // Additional error context
suggestions: [], // Troubleshooting suggestions
correlationId: 'abc123', // Request correlation ID (if applicable)
timestamp: '2025-01-15T10:30:00.000Z' // ISO 8601 timestamp
}
Handling Errors
client.on('error', (error) => {
console.error(`[${error.category}] ${error.code}: ${error.message}`);
// Display suggestions if available
if (error.suggestions && error.suggestions.length > 0) {
console.log('Suggestions:');
error.suggestions.forEach(suggestion => {
console.log(` - ${suggestion}`);
});
}
// Category-specific handling
switch (error.category) {
case 'AUTHENTICATION':
handleAuthError(error);
break;
case 'WEBSOCKET':
handleConnectionError(error);
break;
case 'VALIDATION':
handleValidationError(error);
break;
}
});
Event Management
One-Time Listeners
Listen to an event only once:
client.once('open', () => {
console.log('First connection established');
});
Removing Listeners
// Define named function for removal
function handleMessage(message) {
console.log('Message:', message);
}
// Add listener
client.on('message', handleMessage);
// Remove specific listener
client.off('message', handleMessage);
// Remove all listeners for an event
client.removeAllListeners('message');
Cleanup Pattern
Always remove listeners when components unmount to prevent memory leaks:
// React example
useEffect(() => {
const handleMessage = (message) => console.log(message);
const handleError = (error) => console.error(error);
client.on('message', handleMessage);
client.on('error', handleError);
// Cleanup on unmount
return () => {
client.off('message', handleMessage);
client.off('error', handleError);
};
}, [client]);
Complete Example
import OptaveJavaScriptSDK from '@optave/client-sdk';
const client = new OptaveJavaScriptSDK({
websocketUrl: 'wss://ws-{{tenant}}.oco.optave.{{tld}}',
authTransport: 'subprotocol',
tokenProvider: async () => {
// Replace '/api/optave-token' with your actual backend endpoint
const response = await fetch('/api/optave-token');
return (await response.json()).token;
}
});
// Connection events
client.on('open', () => {
console.log('