Installation & Configuration
Installation
The Optave Client SDK is distributed via npm and supports multiple installation methods. The package provides optimized builds for different environments (browser and Node.js) with automatic build selection.
Quick Install
Install via npm (recommended):
npm install @optave/client-sdk
Or using Yarn:
yarn add @optave/client-sdk
Requirements
- Node.js: 20.0.0 or higher (for server-side usage)
- Modern Browsers: Chrome 80+, Firefox 74+, Safari 14.1+, Edge 80+
- Package Manager: npm 10.8.1+ or Yarn 1.22+
Optional Performance Dependencies
For enhanced WebSocket performance in Node.js server environments, install these optional native dependencies:
npm install --save-optional bufferutil utf-8-validate
Benefits:
- bufferutil: Up to 2x faster WebSocket frame masking and unmasking using native C++ implementations
- utf-8-validate: Efficient UTF-8 validation for WebSocket messages (RFC compliance)
- Reduced CPU usage for high-throughput applications
- Automatic fallback to JavaScript implementations if unavailable
Note: These are only beneficial in Node.js server environments. Browser applications do not need them and the SDK works perfectly without them.
Build System & Imports
The SDK provides four optimized builds for different deployment scenarios. The package automatically selects the appropriate build based on your environment.
Available Builds
| Build | Module Format | Client Secrets | AJV Validation | CSP Safe | Size (Gzipped) | Use Cases |
|---|---|---|---|---|---|---|
| Browser ESM | ES Module | ❌ No | External Only | ✅ Yes | ~14KB | Modern bundlers (Vite, Webpack 5+), React, Vue |
| Browser UMD | UMD | ❌ No | External Only | ✅ Yes | ~15KB | Salesforce Lightning, CDN, legacy browsers |
| Server ESM | ES Module | ✅ Yes | Full (bundled) | ❌ No | ~25KB | Node.js servers, Express, Fastify, microservices |
| Server UMD | UMD | ✅ Yes | External Only | ✅ Yes | ~14KB | Node.js CommonJS, mixed environments |
Automatic Build Selection (Recommended)
The SDK automatically selects the correct build based on your environment:
import OptaveJavaScriptSDK from '@optave/client-sdk';
// Automatically resolves to:
// - browser.mjs in browser environments (Vite, Webpack, bundlers)
// - server.mjs in Node.js environments
This method is recommended as it ensures optimal build selection without manual configuration.
Explicit Build Selection
For advanced use cases requiring specific builds:
Browser Environments:
// ES Module (recommended for modern bundlers)
import OptaveJavaScriptSDK from '@optave/client-sdk/browser';
// UMD (for legacy browsers, Salesforce Lightning, or CDN usage)
import OptaveJavaScriptSDK from '@optave/client-sdk/browser-umd';
Node.js Environments:
// ES Module (recommended for modern Node.js with "type": "module")
import OptaveJavaScriptSDK from '@optave/client-sdk/server';
// UMD (CommonJS compatible - works with require())
const OptaveJavaScriptSDK = require('@optave/client-sdk/server-umd');
CDN Usage (Browser Only)
ES Module from CDN (unpkg):
<script type="module">
import OptaveJavaScriptSDK from 'https://app.unpkg.com/@optave/client-sdk@3.2.4/files/dist/browser.mjs';
const client = new OptaveJavaScriptSDK({
websocketUrl: 'wss://ws-{{tenant}}.oco.optave.{{tld}}',
authTransport: 'subprotocol',
tokenProvider: async () => {
// Fetch token from your backend
// Replace '/api/optave-token' with your actual backend endpoint
const response = await fetch('/api/optave-token');
const { token } = await response.json();
return token;
}
});
</script>
UMD from CDN (global variable):
<script src="https://app.unpkg.com/@optave/client-sdk@3.2.4/files/dist/browser.umd.js"></script>
<script>
// OptaveJavaScriptSDK is now globally available
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');
const { token } = await response.json();
return token;
}
});
</script>
Framework-Specific Examples
React (Create React App, Vite, Next.js):
import OptaveJavaScriptSDK from '@optave/client-sdk';
function App() {
const [client] = useState(() => 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 response.json().then(data => data.token);
}
}));
// Use client...
}
Vue 3 (Vite):
import { ref, onMounted } from 'vue';
import OptaveJavaScriptSDK from '@optave/client-sdk';
export default {
setup() {
const client = ref(null);
onMounted(() => {
client.value = 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');
const data = await response.json();
return data.token;
}
});
});
return { client };
}
};
Node.js (Express, Fastify):
import OptaveJavaScriptSDK from '@optave/client-sdk/server';
import express from 'express';
const app = express();
// Initialize SDK with client credentials
const client = new OptaveJavaScriptSDK({
websocketUrl: process.env.OPTAVE_WEBSOCKET_URL,
authenticationUrl: process.env.OPTAVE_AUTHENTICATION_URL,
clientId: process.env.OPTAVE_CLIENT_ID,
clientSecret: process.env.OPTAVE_CLIENT_SECRET
});
app.listen(3000);
TypeScript (Full Type Support):
import OptaveJavaScriptSDK from '@optave/client-sdk';
import type { SDKConfiguration } from '@optave/client-sdk';
const config: SDKConfiguration = {
websocketUrl: 'wss://ws-{{tenant}}.oco.optave.{{tld}}',
authTransport: 'subprotocol',
tokenProvider: async (): Promise<string> => {
// Replace '/api/optave-token' with your actual backend endpoint
const response = await fetch('/api/optave-token');
const data = await response.json();
return data.token;
}
};
const client = new OptaveJavaScriptSDK(config);
Salesforce Lightning Component:
import OptaveJavaScriptSDK from '@optave/client-sdk/browser-umd';
export default class OptaveIntegration extends LightningElement {
connectedCallback() {
this.client = new OptaveJavaScriptSDK({
websocketUrl: 'wss://ws-{{tenant}}.oco.optave.{{tld}}',
authTransport: 'subprotocol',
tokenProvider: async () => {
// Use Salesforce Apex to fetch token
return getOptaveToken();
}
});
}
}
Configuration
The SDK requires specific configuration parameters depending on your authentication method and deployment environment.
Configuration Options
| Parameter | Type | Required | Environment | Description |
|---|---|---|---|---|
websocketUrl | string | ✅ Yes | All | WebSocket endpoint URL (e.g., wss://ws-{{tenant}}.oco.optave.{{tld}}) |
tokenProvider | async function | Browser | Browser | Async function that returns a valid authentication token |
authenticationUrl | string | Server* | Server | Authentication API endpoint URL |
clientId | string | Server* | Server | Client ID for OAuth2 client credentials flow |
clientSecret | string | Server* | Server | Client secret for OAuth2 client credentials flow |
authTransport | string | No | All | How to send token: 'subprotocol' (default, recommended) or 'query' |
connectionTimeoutMs | number | No | All | Connection timeout in milliseconds (default: 30000) |
requestTimeoutMs | number | No | All | Request timeout in milliseconds (default: 30000) |
strictValidation | boolean | No | All | Enable payload validation (default: true in dev, false in production) |
*Note: For server environments, either tokenProvider OR (authenticationUrl + clientId + clientSecret) is required.
Configuration Examples
Browser Configuration (Token Provider Pattern)
Recommended approach for browser/frontend applications:
import OptaveJavaScriptSDK from '@optave/client-sdk';
const client = new OptaveJavaScriptSDK({
websocketUrl: 'wss://ws-{{tenant}}.oco.optave.{{tld}}',
authTransport: 'subprotocol', // How to send authentication token (default: 'subprotocol', or 'query')
// Token provider function - called automatically when SDK needs authentication
tokenProvider: async () => {
// Fetch token from your secure backend endpoint
// Replace '/api/optave-token' with your actual backend endpoint
const response = await fetch('/api/optave-token', {
method: 'POST',
credentials: 'include', // Include cookies for session validation
headers: {
'Content-Type': 'application/json'
}
});
if (!response.ok) {
throw new Error('Failed to fetch Optave token');
}
const data = await response.json();
return data.token; // Return the token string
}
});
Why use tokenProvider in browsers?
- ✅ Never exposes client secrets in frontend code
- ✅ Backend controls authentication and token issuance
- ✅ Follows OAuth2 best practices for public clients
- ✅ Supports session-based authentication
Server Configuration (Client Credentials)
Recommended approach for backend/server applications:
import OptaveJavaScriptSDK from '@optave/client-sdk/server';
const client = new OptaveJavaScriptSDK({
websocketUrl: process.env.OPTAVE_WEBSOCKET_URL,
authenticationUrl: process.env.OPTAVE_AUTHENTICATION_URL,
clientId: process.env.OPTAVE_CLIENT_ID,
clientSecret: process.env.OPTAVE_CLIENT_SECRET
});
Environment Variables (.env file):
OPTAVE_WEBSOCKET_URL=wss://ws-{{tenant}}.oco.optave.{{tld}}
OPTAVE_AUTHENTICATION_URL=https://auth.optave.tech/oauth/token
OPTAVE_CLIENT_ID=your_client_id_here
OPTAVE_CLIENT_SECRET=your_client_secret_here
Why use client credentials on servers?
- ✅ Secure server-to-server authentication
- ✅ Full OAuth2 client credentials flow
- ✅ Automatic token refresh and management
- ✅ Suitable for backend APIs, microservices, and server jobs
Server Configuration (Token Provider Alternative)
Servers can also use tokenProvider for custom authentication flows:
import OptaveJavaScriptSDK from '@optave/client-sdk/server';
const client = new OptaveJavaScriptSDK({
websocketUrl: process.env.OPTAVE_WEBSOCKET_URL,
tokenProvider: async () => {
// Custom token acquisition logic
// Example: Fetch from external identity provider, cache, or vault
const token = await yourCustomTokenService.getToken();
return token;
}
});
Complete Configuration Example (Server)
import OptaveJavaScriptSDK from '@optave/client-sdk/server';
import dotenv from 'dotenv';
// Load environment variables
dotenv.config();
const client = new OptaveJavaScriptSDK({
// Required: WebSocket connection URL
websocketUrl: process.env.OPTAVE_WEBSOCKET_URL,
// Required for client credentials flow
authenticationUrl: process.env.OPTAVE_AUTHENTICATION_URL,
clientId: process.env.OPTAVE_CLIENT_ID,
clientSecret: process.env.OPTAVE_CLIENT_SECRET,
// Optional: Custom configuration
timeout: 30000, // Connection timeout in milliseconds (default: 30000)
maxReconnectAttempts: 5, // Max reconnection attempts (default: Infinity)
reconnectDelay: 1000 // Delay between reconnect attempts in ms (default: 1000)
});
// Event handlers
client.on('connected', () => {
console.log('Connected to Optave WebSocket');
});
client.on('authenticated', () => {
console.log('Successfully authenticated');
});
client.on('error', (error) => {
console.error('SDK Error:', error);
});
// Establish connection
await client.connect();
Security Best Practices
Browser Applications
- Never expose client secrets in frontend code or environment variables accessible to the browser
- Always use
tokenProviderpattern to fetch tokens from your secure backend - Validate user sessions on your backend before issuing Optave tokens
- Implement rate limiting on your token endpoint to prevent abuse
- Use HTTPS for all token fetch requests
- Set appropriate CORS policies on your token endpoint
Example Secure Backend Token Endpoint (Node.js/Express):
// This is an example endpoint - replace '/api/optave-token' with your preferred route
app.post('/api/optave-token', authenticateUser, async (req, res) => {
// Verify user is authenticated
if (!req.user) {
return res.status(401).json({ error: 'Unauthorized' });
}
try {
// Use server SDK to get token via client credentials
const response = await fetch(process.env.OPTAVE_AUTHENTICATION_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
grant_type: 'client_credentials',
client_id: process.env.OPTAVE_CLIENT_ID,
client_secret: process.env.OPTAVE_CLIENT_SECRET
})
});
const data = await response.json();
// Return token to authenticated frontend
res.json({ token: data.access_token });
} catch (error) {
res.status(500).json({ error: 'Failed to obtain token' });
}
});
Server Applications
- Store credentials securely using environment variables or secret management systems (AWS Secrets Manager, HashiCorp Vault, etc.)
- Never commit secrets to version control (use
.gitignorefor.envfiles) - Rotate credentials regularly as part of security maintenance
- Use least-privilege principle - only grant necessary API scopes
- Monitor authentication failures and implement alerting
- Implement connection retry logic with exponential backoff
Building from Source (Optional)
Most users don't need to build from source - the npm package includes pre-built bundles. However, if you need to customize or build the SDK yourself:
# Clone the repository
git clone https://github.com/optave/SDK-optave-client-integration.git
cd SDK-optave-client-integration/sdks/javascript
# Install dependencies
npm install
# Build production bundles
npm run build:all:prod
Build outputs:
dist/browser.mjs- Browser ES moduledist/server.mjs- Server ES moduledist/browser.umd.js- Browser UMD bundledist/server.umd.js- Server UMD bundle