Skip to main content
Version: 3.2.x

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.adjust
  • message.elevate
  • message.interaction
  • message.reception
  • message.summarize
  • message.translate
  • message.recommend
  • message.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('✓ Connected');
updateStatus('connected');
});

client.on('close', (event) => {
console.log(`✗ Disconnected: ${event.code}`);
updateStatus('disconnected');

if (!event.wasClean) {
setTimeout(() => reconnect(), 5000);
}
});

// Message handling
client.on('superpower.response', (response) => {
console.log(`Response for ${response.action}:`, response);

if (response.status === 'success') {
displayResponse(response);
}
});

// Action-specific handlers
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);
}
});

// Error handling
client.on('superpower.error', (error) => {
console.error(`[${error.category}] ${error.code}:`, error.message);

switch (error.category) {
case 'AUTHENTICATION':
handleAuthenticationError(error);
break;
case 'WEBSOCKET':
handleConnectionError(error);
break;
case 'VALIDATION':
handleValidationError(error);
break;
}
});

// Connect
await client.openConnection();