Skip to content

Tendrl JavaScript SDK

Version Node.js Version React Version License

A modern JavaScript/React SDK for real-time messaging with WebSocket support, dynamic batching, and automatic reconnection.

Features

  • WebSocket Communication: Real-time bidirectional messaging
  • Dynamic Batching: CPU/memory-aware batch processing (10-50 messages)
  • Automatic Reconnection: Exponential backoff reconnection strategy
  • Message Queuing: In-memory queue with configurable size limits
  • React Integration: Custom hooks for seamless React integration
  • Performance Monitoring: Built-in queue load and batch optimization
  • Error Handling: Robust error handling and connection management

Installation

npm install

Quick Start

Basic Usage

import TendrlClient from './utils/TendrlClient';

// Initialize client
const client = new TendrlClient({
    serverUrl: 'wss://app.tendrl.com/ws',
    apiKey: 'your_api_key',
    debug: true,
    callback: (data) => {
        console.log('Received:', data);
    }
});

// Connect to server
await client.connect();

// Publish messages
client.publish({
    event: 'user_action',
    timestamp: Date.now(),
    data: { action: 'click', button: 'submit' }
}, ['ui', 'events']);

// Check for messages
client.checkMessages(5);

React Integration

import React from 'react';
import { useTendrlClient } from './hooks/useTendrlClient';

function MyComponent() {
    const { client, isConnected, publish, messages } = useTendrlClient({
        serverUrl: 'wss://app.tendrl.com/ws',
        apiKey: process.env.REACT_APP_TENDRL_KEY
    });

    const handleButtonClick = () => {
        publish({
            event: 'button_click',
            component: 'MyComponent',
            timestamp: Date.now()
        }, ['ui', 'interaction']);
    };

    return (
        <div>
            <p>Status: {isConnected ? 'Connected' : 'Disconnected'}</p>
            <button onClick={handleButtonClick}>
                Send Event
            </button>
            <div>
                <h3>Recent Messages:</h3>
                {messages.map((msg, index) => (
                    <div key={index}>{JSON.stringify(msg)}</div>
                ))}
            </div>
        </div>
    );
}

Configuration Options

const client = new TendrlClient({
    serverUrl: 'wss://app.tendrl.com/ws',    // WebSocket server URL
    apiKey: 'your_api_key',                  // Authentication key
    debug: false,                            // Enable debug logging
    targetCpuPercent: 65.0,                  // Target CPU usage for batching
    targetMemPercent: 75.0,                  // Target memory usage for batching
    minBatchSize: 10,                        // Minimum messages per batch
    maxBatchSize: 50,                        // Maximum messages per batch
    minBatchInterval: 100,                   // Minimum batch interval (ms)
    maxBatchInterval: 1000,                  // Maximum batch interval (ms)
    maxQueueSize: 500,                       // Maximum queue size
    callback: (data) => console.log(data)   // Message callback function
});

API Reference

TendrlClient Methods

connect()

Establishes WebSocket connection with automatic reconnection.

await client.connect();

disconnect()

Closes WebSocket connection.

client.disconnect();

publish(message, tags, entity, waitResponse)

Publishes a message to the server.

// Async publishing (queued)
client.publish({
    sensor: 'temperature',
    value: 23.5
}, ['sensors', 'environment']);

// Synchronous publishing (immediate)
client.publish({
    alert: 'high_temperature',
    value: 45.0
}, ['alerts'], 'sensor-001', true);

checkMessages(limit)

Requests messages from the server.

client.checkMessages(10); // Get up to 10 messages

Message Callbacks

// Set up callback to handle incoming messages
function messageHandler(message) {
    // Process incoming message
    console.log(`Received: ${message.msg_type} from ${message.source}`);
    return true; // Return false if processing fails
}

client.setMessageCallback(messageHandler);

// Configure checking behavior (optional)
client.setMessageCheckRate(5000); // Check every 5 seconds (default: 3000ms)
client.setMessageCheckLimit(10);  // Max messages per check (default: 1)

// Manual message check (works in any mode)
const messages = client.checkMessages(5);

IncomingMessage Structure

Field Type Description Required
msg_type string Message type identifier (e.g., "command", "notification", "alert") ✅ Yes
source string Sender's resource path (set by server) ✅ Yes
dest string Destination entity identifier ❌ Optional
timestamp string RFC3339 timestamp (set by server) ✅ Yes
data any The actual message payload (can be any JSON type) ✅ Yes
context object Message metadata ❌ Optional
request_id string Request identifier (if message was a request) ❌ Optional

Message Context Structure

Field Type Description Required
tags string[] Message tags for categorization ❌ Optional
dynamicActions object Server-side validation results ❌ Optional

How It Works

  1. Background Checking: The SDK automatically checks for messages every 3 seconds (configurable)
  2. Manual Checking: You can call checkMessages() manually anytime
  3. Callback Execution: Your callback function is called for each incoming message
  4. Error Handling: Failed callbacks don't stop other message processing
  5. Connectivity Aware: Automatically handles network failures and updates connectivity state

React Hook: useTendrlClient

const {
    client,        // TendrlClient instance
    isConnected,   // Connection status
    publish,       // Publish function
    messages,      // Received messages array
    error          // Connection error (if any)
} = useTendrlClient(config);

Message Format

Publishing Messages

const message = {
    msgType: "publish",
    data: {
        // Your message data
        event: "user_action",
        timestamp: Date.now()
    },
    tags: ["ui", "events"],
    entity: "optional-entity-id",
    context: {
        wait: false  // true for synchronous response
    },
    timestamp: new Date().toISOString()
};

Checking Messages

const checkRequest = {
    msgType: "msg_check",
    data: {
        limit: 5  // Number of messages to retrieve
    },
    timestamp: new Date().toISOString()
};

Error Handling

// Connection error handling
client.connect()
    .then(() => {
        console.log('Connected successfully');
    })
    .catch((error) => {
        console.error('Connection failed:', error);
    });

// Message publishing error handling
try {
    client.publish(messageData, tags);
} catch (error) {
    console.error('Publishing failed:', error);
}

Performance Features

Dynamic Batching

  • Automatically adjusts batch size based on queue load
  • Optimizes sending intervals based on system performance
  • Prevents queue overflow with configurable limits

Automatic Reconnection

  • Exponential backoff strategy (1s to 30s delays)
  • Configurable maximum retry attempts
  • Maintains message queue during reconnection

Memory Management

  • Configurable queue size limits
  • Automatic message discarding when queue is full
  • Efficient batch processing to minimize memory usage

Development

Running the Demo

npm start

Building for Production

npm run build

Environment Variables

REACT_APP_TENDRL_KEY=your_api_key
REACT_APP_TENDRL_WS_URL=wss://app.tendrl.com/ws

Browser Compatibility

  • Chrome 88+
  • Firefox 84+
  • Safari 14+
  • Edge 88+