Working Demonstration of the JavaScript Library

The code examples below are the source of a working demo that shows the JSON data emitted by the three types of subscriptions.

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>BeyondTrust Real-Time State API Demo</title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width">
    <link rel="stylesheet" href="styles.css?v=228">
</head>
<body>

<div id="container">
    <div class="row">
        <section id="cust">
            <h2>Customer Messages
                <span class="subtitle">.tableInserts('customer_client'), .tableUpdates('customer_client'), .tableDeletions('customer_client')
            </h2>
            <div class="messages"></div>
        </section>
        <section id="rep">
            <h2>Representative Messages
                <span class="subtitle">.changesForTable('representative')</span>
            </h2>
            <div class="messages"></div>
        </section>
    </div>
    <div class="row">
        <section id="all">
            <h2>Raw Messages
                <span class="subtitle">.subscribe(onNext, onError, onCompleted)</span>
            </h2>
            <div class="messages"></div>
        </section>
    </div>
</div>

<script src="https://[YOUR B Series Appliance HOSTNAME HERE]/api/state.js?v=228"></script>
<script type="text/javascript">
    var repSection = document.getElementById('rep');
    var custSection = document.getElementById('cust');
    var allSection = document.getElementById('all');

    var messages$ = bomgarState({
        host: '[YOUR B Series Appliance HOSTNAME HERE]',
        port: 443,
        company: '[YOUR COMPANY NAME HERE]',
        username: '[YOUR USERNAME HERE]',
        password: '[YOUR PASSWORD HERE]',
        tables: 'all' // or an array like ['customer_client', 'representative']
    });

    var subscription = messages$.subscribe(
        function onNext(message) {
            appendMessage('Message:', message, allSection);
        },
        function onError(error) {
            appendMessage('An error occurred:', error, allSection, 'red');
            console.error('An error occurred: %s', error);
        },
        function onCompleted() {
            appendMessage('The End', 'Connection closed.', allSection, '#f50');
            console.warn('Connection closed. No more messages will be received.');
        }
    );

    messages$.changesForTable('representative')
        .subscribe(function onRepChange(message) {
            appendMessage('Change: ', message, repSection);
        });

    messages$.tableInserts('customer_client')
        .subscribe(function onCustInsert(message) {
            appendMessage('Insert: ', message, custSection, 'green');
        });

    messages$.tableUpdates('customer_client')
        .subscribe(function onCustUpdate(message) {
            appendMessage('Update: ', message, custSection, 'blue');
        });

    messages$.tableDeletions('customer_client')
        .subscribe(function onCustDeletion(message) {
            appendMessage('Deletion: ', message, custSection, 'red');
        });

    function appendMessage(label, message, section, color) {
        var messages = section.querySelector('.messages');
        var div = document.createElement('div');
        var hr = document.createElement('hr');
        var h4 = document.createElement('h4');
        h4.textContent = label;

        var p = document.createElement('p');
        p.style.color = color || 'black';
        p.textContent = JSON.stringify(message, null, '\t');

        div.appendChild(h4);
        div.appendChild(p);
        messages.appendChild(hr);
        messages.appendChild(div);
        setTimeout(function() {
            messages.scrollTop = messages.scrollHeight;
        }, 250);
}
</script>
</body>
</html>

styles.css

* {
    box-sizing: border-box;
}

html, body {
    height: 100%;
    position: relative;
    min-height: 100%;
}

body {
    font-family: 'Open Sans', 'Helvetica Neue', sans-serif;
    display: flex;
    flex-direction: column;
    margin: 0;
    padding: 0;
    overflow: hidden;
}

#container {
    display: flex;
    flex: 1 1 100%;
    max-height: 100%;
    max-width: 100%;
    flex-direction: column;
}

.row {
    display: flex;
    flex-direction: row;
    flex: 1 1 1px;
    position: relative;
    min-height: 0;
    max-height: 100%;
    max-width: 100%;
    width: 100%;
    overflow: hidden;
}

section {
    box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
    border: 1px solid #a0a0a0;
    background-color: #f5f5f5;
    padding: 19px;
    display: flex;
    flex-direction: column;
    flex: 1 1 0%;
    min-width: 0;
    max-width: 100%;
    position: relative;
}

section h2 {
    margin: 0 0 19px 0;
    text-align: right;
}

section h2 .subtitle {
    display: block;
    font-size: 12px;
    color: #828282;
}

section hr {
    border-color: #E0E0E0;
    border-style: solid;
}

section .messages {
    overflow: auto;
}

section .messages hr:first-of-type {
    display: none;
}

p {
    tab-size: 2;
    font-family: monospace;
    white-space: pre-wrap;
}