@wioex/stream-sdk
Version:
WebSocket streaming SDK for real-time WioEX market data
971 lines (732 loc) • 26 kB
Markdown
# @wioex/stream-sdk
[](https://www.npmjs.com/package/@wioex/stream-sdk)
[](https://www.typescriptlang.org/)
[](https://opensource.org/licenses/MIT)
WebSocket streaming SDK for real-time WioEX market data. Receive live stock ticker updates with a simple, event-driven API.
## Features
- **Real-time streaming** - WebSocket-based live market data
- **Trading signals** - Real-time trading signals with entry/target/stop-loss levels ⭐ NEW in v1.12.0
- **High-performance** - Optimized for high-frequency data with throttling & batching
- **Multiple stocks** - Track up to 50 stocks simultaneously
- **Auto-reconnection** - Automatic reconnection with exponential backoff
- **Type-safe** - Written in TypeScript with full type definitions
- **Universal** - Works in Node.js and browsers
- **Lightweight** - ~88KB ESM, ~75KB UMD minified (includes optional MessagePack)
- **Event-driven** - Simple EventEmitter-based API
- **Production-ready** - Robust error handling and heartbeat mechanism
- **Error reporting** - Automatic error tracking with batching & deduplication
### Latest Features (v1.12.0)
- **Trading signals** ⭐ NEW - Subscribe to real-time trading signals with:
- Signal types: BUY, SELL, STRONG_BUY, STRONG_SELL, HOLD
- Entry price, target price, stop-loss levels
- Confidence score (0-100%)
- Signal triggered events (entry/target/stop-loss)
- Multiple timeframes (5m, 15m, 1h, 4h, 1d, 1w, 1M)
- **Debug mode enhancements (v1.11.1)** - Console logging now respects debug flag
- **Streamlined message format (v1.11.0)** - New type-based format for better performance
- **Browser & jQuery support (v1.10.0)** - CDN-ready with jQuery plugin wrapper
- **Binary protocol support (v1.10.0)** - Optional MessagePack encoding for 50-60% faster parsing (opt-in)
## Installation
### NPM (Node.js, React, Vue, Angular, etc.)
```bash
npm install @wioex/stream-sdk
```
### CDN (Browser - No build tools required)
**Vanilla JavaScript:**
```html
<script src="https://unpkg.com/@wioex/stream-sdk@latest/dist/wioex-stream.min.js"></script>
```
**jQuery Plugin:**
```html
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="https://unpkg.com/@wioex/stream-sdk@latest/dist/wioex-stream.jquery.min.js"></script>
```
**Specific Version (Recommended for production):**
```html
<script src="https://unpkg.com/@wioex/stream-sdk@1.10.0/dist/wioex-stream.min.js"></script>
```
### Self-Hosted
Download from NPM and host on your own server:
```bash
npm pack @wioex/stream-sdk
# Extract dist/ folder and upload to your server
```
> **Complete Browser Guide:** See [docs/BROWSER_GUIDE.md](./docs/BROWSER_GUIDE.md) for CDN options, self-hosting, jQuery integration, and framework examples.
## Anonymous Telemetry
WioEX Stream SDK collects **anonymous** usage statistics to help us improve the SDK. This happens once on first usage.
**What we collect:**
- SDK version and type
- Runtime environment (Node.js/Browser version)
- Operating system type
- Installation timestamp
- Anonymous machine ID (hash-based, no personal info)
**What we DON'T collect:**
- Personal information
- API keys or tokens
- IP addresses
- Business data or stock symbols
- Any identifiable information
**Disable telemetry:**
Set environment variable:
```bash
export WIOEX_TELEMETRY_DISABLED=1
```
Or in your code (before importing):
```javascript
process.env.WIOEX_TELEMETRY_DISABLED = '1';
// Then import
import { WioexStreamClient } from '@wioex/stream-sdk';
```
Or in browser:
```html
<script>
window.WIOEX_TELEMETRY_DISABLED = '1';
</script>
<script src="path/to/wioex-stream.min.js"></script>
```
Read our [Privacy Policy](https://wioex.com/privacy) for details.
## Quick Start
### Super Simple! Just provide your API key 🎉
**Node.js / Backend:**
```typescript
import { WioexStreamClient } from '@wioex/stream-sdk';
// Just provide your API key - SDK handles everything automatically!
const client = new WioexStreamClient({
apiKey: process.env.WIOEX_API_KEY
});
client.on('ticker', (data) => {
console.log(`${data.ticket}: $${data.last} (${data.changePercent}%)`);
});
// Lazy connect - just subscribe and SDK connects automatically!
client.subscribe(['AAPL', 'TSLA', 'GOOGL']);
```
**Browser / Frontend (Vanilla JavaScript):**
```html
<script src="https://unpkg.com/@wioex/stream-sdk@latest/dist/wioex-stream.min.js"></script>
<script>
// Initialize with token endpoint (recommended for browser)
const client = new WioexStream({
tokenEndpoint: '/api/stream/token' // Your backend endpoint
});
client.on('ticker', (data) => {
console.log(`${data.ticket}: $${data.last}`);
});
// Lazy connect - just subscribe and SDK connects automatically!
client.subscribe(['AAPL', 'TSLA']);
</script>
```
**Browser / Frontend (jQuery Plugin):**
```html
<!-- Load jQuery first -->
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<!-- Load WioEX jQuery plugin -->
<script src="https://unpkg.com/@wioex/stream-sdk@latest/dist/wioex-stream.jquery.min.js"></script>
<script>
// Initialize with jQuery
$('#app').wioexStream({
tokenEndpoint: '/api/stream/token',
stocks: ['AAPL', 'TSLA', 'GOOGL']
});
// Listen to jQuery events
$('#app').on('wioex:ticker', function(event, data) {
console.log(`${data.ticket}: $${data.last}`);
});
</script>
```
---
### Trading Signals (v1.12.0) ⭐ NEW
Subscribe to real-time trading signals with entry prices, targets, and stop-loss levels:
```typescript
import { WioexStreamClient } from '@wioex/stream-sdk';
const client = new WioexStreamClient({
apiKey: process.env.WIOEX_API_KEY
});
// Subscribe to ticker updates
client.subscribe(['AAPL', 'TSLA']);
// Subscribe to trading signals for same symbols
client.subscribeSignals(['AAPL', 'TSLA']);
// Listen to new signals
client.on('signal', (signal) => {
console.log(`🔔 ${signal.symbol} ${signal.signalType} Signal`);
console.log(` Entry: $${signal.entryPrice}`);
console.log(` Target: $${signal.targetPrice}`);
console.log(` Stop Loss: $${signal.stopLoss}`);
console.log(` Confidence: ${signal.confidence}%`);
console.log(` Reason: ${signal.reason}`);
console.log(` Timeframe: ${signal.timeframe}`);
});
// Listen to signal triggers (entry/target/stop-loss hit)
client.on('signalTriggered', (trigger) => {
console.log(`🎯 Signal Triggered: ${trigger.triggerType.toUpperCase()}`);
console.log(` ${trigger.symbol} @ $${trigger.triggeredPrice}`);
});
// Signal subscription events
client.on('signalSubscribed', (symbols) => {
console.log(`✅ Subscribed to signals for: ${symbols.join(', ')}`);
});
client.on('signalError', (error) => {
console.error('❌ Signal error:', error.message);
});
```
**Signal Types:**
- `BUY` - Buy signal
- `SELL` - Sell signal
- `STRONG_BUY` - Strong buy recommendation
- `STRONG_SELL` - Strong sell recommendation
- `HOLD` - Hold position
**Trigger Types:**
- `entry` - Price reached entry level
- `target` - Price reached target (take profit)
- `stop_loss` - Price hit stop-loss level
- `expired` - Signal expired
**Available Methods:**
```typescript
client.subscribeSignals(['AAPL', 'TSLA']); // Subscribe to signals
client.unsubscribeSignals(['AAPL']); // Unsubscribe from signals
client.getSignalSubscriptions(); // Get subscribed symbols
```
---
### **IMPORTANT: Browser Security**
**NEVER expose your API key in browser/frontend code!**
If you see your API key in browser DevTools Network tab, **you're doing it wrong!**
**WRONG (API key visible in browser):**
```javascript
// This exposes your API key in browser Network tab!
const client = new WioexStream({
apiKey: 'your-api-key-here' // INSECURE!
});
```
**CORRECT (API key stays on server):**
```javascript
// API key is safely stored on your backend
const client = new WioexStream({
tokenEndpoint: '/api/stream/token' // SECURE!
});
```
**Why this matters:**
- Anyone can inspect browser Network tab
- Exposed API keys can be stolen and abused
- Your account could be compromised
**How it works:**
```
Browser → Your Backend (/api/stream/token) → WioEX API
(token) (api_key) (token)
```
Your backend fetches the token using YOUR API key (server-side), then passes only the token to the browser.
**Backend examples:**
- PHP: [`examples/backend-token-proxy.php`](./examples/backend-token-proxy.php)
- Node.js: [`examples/backend-token-proxy.js`](./examples/backend-token-proxy.js)
- Python: [`examples/backend-token-proxy.py`](./examples/backend-token-proxy.py)
- Go: [`examples/backend-token-proxy.go`](./examples/backend-token-proxy.go)
- Java: [`examples/backend-token-proxy.java`](./examples/backend-token-proxy.java)
---
**What happens behind the scenes:**
1. SDK automatically fetches a secure token from your backend endpoint
2. Connects to WebSocket stream with the token
3. Your API key is NEVER exposed in browser code (security first!)
4. Token automatically refreshes before expiry
> **Pro Tip:** Use `lazyConnect: true` (default) so you don't need to call `connect()` - just subscribe!
> **Browser Guide:** See [docs/BROWSER_GUIDE.md](./docs/BROWSER_GUIDE.md) for comprehensive browser usage documentation including CDN, self-hosting, jQuery integration, and framework examples.
## API Reference
### Constructor
```typescript
new WioexStreamClient(config: WioexStreamConfig)
```
#### Configuration Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `apiKey` | `string` | *Backend only* | **Backend (Node.js):** Your WioEX API key - SDK auto-fetches token |
| `token` | `string` | *Frontend only* | **Frontend (Browser):** Secure token from your backend |
| `tokenExpiresAt` | `number` | - | Token expiration Unix timestamp (seconds) |
| `tokenEndpoint` | `string` | - | Backend endpoint URL to fetch token (browser only) |
| `tokenFetchHeaders` | `object` | - | Custom headers for token endpoint request |
| `tokenFetchRetry` | `object` | See below | Token fetch retry configuration |
| `onTokenExpiring` | `function` | - | Async callback to fetch new token on expiry |
| `autoRefreshToken` | `boolean` | `true`* | Auto-refresh token before expiry (*if `onTokenExpiring` provided) |
| `refreshBeforeExpiry` | `number` | `3600000` | Refresh token N ms before expiry (default: 1 hour) |
| `lazyConnect` | `boolean` | `true` | Auto-connect on first subscribe (no manual `connect()` needed) |
| `debug` | `boolean` | `false` | Enable debug logging to console |
| `maxSymbols` | `number` | `50` | Maximum symbols to track (1-50) |
| `autoReconnect` | `boolean` | `true` | Enable auto-reconnection |
| `reconnectDelay` | `number` | `3000` | Reconnection delay (ms) |
| `maxReconnectAttempts` | `number` | `0` | Max reconnect attempts (0 = infinite) |
| `streamUrl` | `string` | Auto | WebSocket URL (auto-generated) |
| `errorReportingLevel` | `string` | `'detailed'` | Error reporting level (`none`, `minimal`, `standard`, `detailed`) |
| `performance` | `object` | See below | Performance optimization options |
**Authentication:**
- **Backend (Node.js):** Use `apiKey` - SDK automatically fetches and manages tokens
- **Frontend (Browser):** Use `token` OR `tokenEndpoint` - Get from your backend (API key blocked for security)
#### Token Fetch Retry Options (`tokenFetchRetry` config)
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `maxAttempts` | `number` | `3` | Maximum number of retry attempts |
| `delay` | `number` | `1000` | Initial delay between retries in milliseconds |
| `backoff` | `'linear' \| 'exponential'` | `'exponential'` | Backoff strategy (exponential: 1s → 2s → 4s, linear: 1s → 2s → 3s) |
**Example:**
```typescript
const client = new WioexStreamClient({
tokenEndpoint: '/api/stream/token',
tokenFetchRetry: {
maxAttempts: 5,
delay: 2000,
backoff: 'exponential', // 2s → 4s → 8s → 16s → 32s
},
});
```
#### Performance Options (`performance` config)
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `tickerThrottle` | `number` | `16` | Throttle ticker events (ms). `0` = disabled, `16` = 60 FPS |
| `batchTickers` | `boolean` | `false` | Enable ticker batching mode |
| `tickerBatchSize` | `number` | `10` | Maximum ticker batch size |
| `errorBatchSize` | `number` | `10` | Error reporting batch size |
| `errorBatchInterval` | `number` | `5000` | Error flush interval (ms) |
| `errorDeduplication` | `boolean` | `true` | Enable error deduplication |
| `enableStats` | `boolean` | `true` | Enable stats tracking (disable in production for 5-10% performance gain) |
| `useBinaryProtocol` | `boolean` | `false` | Use binary protocol (MessagePack) for 50-60% faster parsing (opt-in) |
**Performance Presets:**
```typescript
// Default (balanced - 60 FPS throttling)
const client = new WioexStreamClient({ apiKey: 'xxx' });
// High-performance (no throttling, immediate events)
const client = new WioexStreamClient({
apiKey: 'xxx',
performance: {
tickerThrottle: 0, // No throttling
errorBatchSize: 1, // Immediate error reporting
errorDeduplication: false, // No deduplication
}
});
// Production-optimized (maximum performance, minimal overhead)
const client = new WioexStreamClient({
apiKey: 'xxx',
performance: {
enableStats: false, // Disable stats for 5-10% CPU reduction
tickerThrottle: 0, // No throttling
errorBatchSize: 20, // Batch errors
}
});
// Binary protocol (50-60% faster parsing, requires server support)
const client = new WioexStreamClient({
apiKey: 'xxx',
performance: {
useBinaryProtocol: true, // Enable MessagePack encoding
enableStats: false, // Disable stats for extra speed
}
});
// See BINARY_PROTOCOL.md for comprehensive guide on binary protocol
// High-volume (optimized for charts - 20 FPS batching)
const client = new WioexStreamClient({
apiKey: 'xxx',
performance: {
tickerThrottle: 50, // 20 FPS
batchTickers: true, // Enable batching
tickerBatchSize: 20, // Larger batches
}
});
// Memory-optimized (aggressive batching)
const client = new WioexStreamClient({
apiKey: 'xxx',
performance: {
errorBatchSize: 50, // Large error batches
errorBatchInterval: 10000, // 10s flush interval
}
});
```
### Methods
#### `connect(): Promise<void>`
Connect to WioEX WebSocket stream. In Node.js with `apiKey`, automatically fetches token before connecting.
```typescript
// Backend (with apiKey) - await to ensure token fetch completes
await client.connect();
// Frontend (with token) - can be called without await
client.connect();
```
#### `disconnect(): void`
Disconnect from WebSocket stream.
```typescript
client.disconnect();
```
#### `subscribe(stocks: string | string[]): void`
Subscribe to stock ticker updates.
```typescript
client.subscribe('AAPL');
client.subscribe(['AAPL', 'TSLA', 'GOOGL']);
```
**Throws:** Error if attempting to subscribe to more than `maxSymbols`.
#### `unsubscribe(stocks: string | string[]): void`
Unsubscribe from stock ticker updates.
```typescript
client.unsubscribe('AAPL');
client.unsubscribe(['AAPL', 'TSLA']);
```
#### `getState(): ConnectionState`
Get current connection state.
```typescript
const state = client.getState();
// Returns: 'disconnected' | 'connecting' | 'connected' | 'registered' | 'reconnecting' | 'failed'
```
#### `getSubscribedStocks(): string[]`
Get list of currently subscribed stocks.
```typescript
const stocks = client.getSubscribedStocks();
console.log(stocks); // ['AAPL', 'TSLA', 'GOOGL']
```
#### `getStats(): ClientStats`
Get client statistics.
```typescript
const stats = client.getStats();
console.log(stats);
// {
// connectedAt: 1704067200000,
// reconnectAttempts: 0,
// messagesReceived: 152,
// messagesSent: 3,
// tickersReceived: 148,
// subscribedStocks: ['AAPL', 'TSLA'],
// state: 'registered'
// }
```
#### `isConnected(): boolean`
Check if client is connected.
```typescript
if (client.isConnected()) {
console.log('Connected!');
}
```
#### `updateToken(token: string, expiresAt: number): void`
Manually update authentication token (useful for token refresh implementations).
```typescript
// Update token and schedule auto-refresh
client.updateToken(newToken, newExpiresAt);
```
### Events
The client extends `EventEmitter` and emits the following events:
#### `connected`
Emitted when WebSocket connection is established.
```typescript
client.on('connected', () => {
console.log('Connected to WioEX stream');
});
```
#### `registered`
Emitted when client is registered with API key.
```typescript
client.on('registered', (data) => {
console.log('Registered:', data.message);
});
```
#### `subscribed`
Emitted when subscribed to stocks.
```typescript
client.on('subscribed', (stocks: string[]) => {
console.log('Subscribed to:', stocks);
});
```
#### `unsubscribed`
Emitted when unsubscribed from stocks.
```typescript
client.on('unsubscribed', (stocks: string[]) => {
console.log('Unsubscribed from:', stocks);
});
```
#### `ticker`
Emitted when ticker data is received.
```typescript
client.on('ticker', (data: TickerData) => {
console.log(`${data.ticket}: $${data.last}`);
});
```
**TickerData Structure:**
```typescript
interface TickerData {
ticket: string; // Stock symbol
last: string; // Last price
open: string; // Opening price
high: string; // High price
low: string; // Low price
volume: string; // Trading volume
bid: string; // Bid price
ask: string; // Ask price
change: string; // Price change
changePercent: string; // Change percentage
timestamp: number; // Unix timestamp
}
```
---
## Message Format
### WebSocket Ticker Updates
WioEX Stream uses a streamlined type-based message format for real-time ticker updates.
**Message Structure:**
```json
{
"type": "ticker",
"data": {
"ticket": "AAPL",
"last": "150.25",
"open": "149.80",
"high": "151.00",
"low": "149.50",
"volume": "52847100",
"bid": "150.20",
"ask": "150.30",
"change": "0.45",
"changePercent": "0.30",
"timestamp": 1697294400
}
}
```
### Custom WebSocket Implementation
If you're building a custom WebSocket client (not using this SDK):
```javascript
const WebSocket = require('ws');
const ws = new WebSocket('wss://stream.wioex.com/...');
ws.on('message', (data) => {
const message = JSON.parse(data);
if (message.type === 'ticker') {
const ticker = message.data;
console.log(`${ticker.ticket}: $${ticker.last} (${ticker.changePercent}%)`);
}
});
```
### Benefits of v2 Format
- **37% smaller payload** with MessagePack binary protocol
- **15-20% faster parsing** (reduced nesting depth)
- **More extensible** for future message types
- **Cleaner code** and better developer experience
### Migration from v1.10.0
**Breaking Change:** If updating from v1.10.0 or earlier, update your custom implementations:
```javascript
// v1.10.0 (OLD - No longer supported)
if (message.sarex && message.sarex.ticker) {
const ticker = message.sarex.ticker;
}
// v1.11.0+ (NEW - Required)
if (message.type === 'ticker') {
const ticker = message.data;
}
```
**Note:** The official SDK handles this automatically - just update to v1.11.0+
---
#### `error`
Emitted when an error occurs.
```typescript
client.on('error', (error: Error) => {
console.error('Error:', error.message);
});
```
#### `disconnected`
Emitted when connection is closed.
```typescript
client.on('disconnected', (code: number, reason: string) => {
console.log(`Disconnected (${code}): ${reason}`);
});
```
#### `reconnecting`
Emitted when attempting to reconnect.
```typescript
client.on('reconnecting', (attempt: number) => {
console.log(`Reconnecting... (attempt ${attempt})`);
});
```
#### `stateChange`
Emitted when connection state changes.
```typescript
client.on('stateChange', (state: ConnectionState) => {
console.log(`State: ${state}`);
});
```
#### `tokenExpiring`
Emitted when token is about to expire (before auto-refresh).
```typescript
client.on('tokenExpiring', ({ currentToken, expiresAt }) => {
console.log(`Token expiring at ${new Date(expiresAt * 1000)}`);
});
```
#### `tokenRefreshed`
Emitted when token has been successfully refreshed.
```typescript
client.on('tokenRefreshed', ({ token, expiresAt }) => {
console.log(`Token refreshed! New expiry: ${new Date(expiresAt * 1000)}`);
});
```
#### `tokenRefreshFailed`
Emitted when token refresh fails.
```typescript
client.on('tokenRefreshFailed', (error: Error) => {
console.error('Token refresh failed:', error.message);
});
```
#### `tokenFetchStarted`
Emitted when token fetch starts (from endpoint or API).
```typescript
client.on('tokenFetchStarted', (source: 'endpoint' | 'api') => {
console.log(`Fetching token from ${source}...`);
});
```
#### `tokenFetchSucceeded`
Emitted when token fetch succeeds.
```typescript
client.on('tokenFetchSucceeded', ({ token, expiresAt, source }) => {
console.log(`Token fetched from ${source}`);
console.log(`Expires at: ${new Date(expiresAt * 1000)}`);
});
```
#### `tokenFetchFailed`
Emitted when token fetch fails (will retry if configured).
```typescript
client.on('tokenFetchFailed', (error: Error, attempt: number, willRetry: boolean) => {
console.error(`Token fetch failed (attempt ${attempt}):`, error.message);
if (willRetry) {
console.log('Will retry...');
}
});
```
## WebSocket Protocol
The SDK communicates with WioEX WebSocket API using JSON messages:
### Connection
```
wss://stream.wioex.com/rs/i/{max_symbols}/websocket
```
### Registration
```json
{
"action": "register",
"token": "your-temporary-token"
}
```
**Response:**
```json
{
"status": "success",
"type": "registered",
"message": "Client registered successfully"
}
```
### Subscribe
```json
{
"action": "subscribe",
"stocks": ["AAPL", "TSLA", "GOOGL"]
}
```
**Response:**
```json
{
"status": "success",
"type": "subscribed",
"message": "Subscribed to stocks",
"stocks": ["AAPL", "TSLA", "GOOGL"]
}
```
### Ticker Update
```json
{
"sarex": {
"_p": { "e": "d" },
"ticker": {
"ticket": "AAPL",
"last": "185.25",
"open": "183.50",
"high": "186.00",
"low": "183.00",
"volume": "52478963",
"bid": "185.20",
"ask": "185.30",
"change": "1.75",
"changePercent": "0.95",
"timestamp": 1704067200000
}
}
}
```
## TypeScript Support
The SDK is written in TypeScript with full type definitions included:
```typescript
import type {
WioexStreamClient,
WioexStreamConfig,
TickerData,
ConnectionState
} from '@wioex/stream-sdk';
// Full IntelliSense and type checking
const client = new WioexStreamClient({
apiKey: process.env.WIOEX_API_KEY,
maxSymbols: 50
});
client.on('ticker', (data: TickerData) => {
// TypeScript auto-complete for all properties
console.log(data.ticket, data.last, data.changePercent);
});
```
All types are automatically available when you install the package - no `@types/*` package needed!
## Browser Support
The SDK works in all modern browsers that support WebSocket:
- Chrome 16+
- Firefox 11+
- Safari 7+
- Edge 12+
- Opera 12.1+
## Node.js Support
Requires Node.js 16 or higher.
## Development
```bash
# Install dependencies
npm install
# Build the package
npm run build
# Run linter
npm run lint
# Run tests
npm test
# Development mode (watch)
npm run dev
```
## Examples
See the `examples/` directory for complete examples:
### Browser Examples
- **Simple Vanilla JS** `examples/simple-vanilla.html` - Minimal 100-line example, copy-paste ready
- **jQuery Plugin** `examples/jquery-example.html` - jQuery plugin integration with Bootstrap UI
- **Full Browser Example:** `examples/browser-example.html` - Complete UI with all features
### Framework Examples
- **Node.js Example:** `examples/node-example.js` - Backend usage with automatic token fetching
- **Next.js App Router Example:** `examples/nextjs-app-router/` - Full Next.js 15 example with token endpoint, lazy connect, and debug mode
### Quick Start
**Simple Vanilla JS (Easiest):**
1. Build the package: `npm run build`
2. Open `examples/simple-vanilla.html` in a browser
3. Works with token endpoint or pre-fetched token
**jQuery Plugin:**
1. Build the package: `npm run build`
2. Open `examples/jquery-example.html` in a browser
3. jQuery-friendly API with event delegation
**Node.js:**
```bash
cd examples
WIOEX_API_KEY=your-api-key node node-example.js
```
**Next.js:**
```bash
cd examples/nextjs-app-router
cp .env.example .env.local
# Edit .env.local and add your WIOEX_API_KEY
npm install
npm run dev
# Open http://localhost:3000
```
See `examples/nextjs-app-router/README.md` for detailed documentation.
## Documentation
- **[BROWSER_GUIDE.md](./docs/BROWSER_GUIDE.md)** - Comprehensive browser usage guide
- **[BINARY_PROTOCOL.md](./BINARY_PROTOCOL.md)** - Binary protocol guide (MessagePack)
- **[PERFORMANCE.md](./PERFORMANCE.md)** - Performance optimization guide
- **[CHANGELOG.md](./CHANGELOG.md)** - Version history and changes
## License
MIT License - see [LICENSE](LICENSE) file for details.
## Support
- **Documentation:** [https://docs.wioex.com](https://docs.wioex.com)
- **API Reference:** [https://api.wioex.com/docs](https://api.wioex.com/docs)
- **Issues:** [https://github.com/wioex/wioex-stream-sdk/issues](https://github.com/wioex/wioex-stream-sdk/issues)
## Related Projects
- [@wioex/php-sdk](https://github.com/wioex/wioex-php-sdk) - PHP SDK for WioEX API
---
Made by [WioEX](https://wioex.com)