Portal Community

Signature

function useConnectionStatus(): UseConnectionStatusReturn

interface UseConnectionStatusReturn {
  status: ConnectionStatus;        // current overall status
  stats: ConnectionStats | null;   // message throughput counters
  health: HealthStatus | null;     // health metrics
  isReady: boolean;                // true when status === 'connected' AND health.connectionStatus === 'connected'
}

type ConnectionStatus = 'connecting' | 'connected' | 'disconnected' | 'error' | 'checking';

interface ConnectionStats {
  messagesReceived: number;
  messagesSent: number;
  averageLatency: number;       // ms
  totalUptime: number;          // ms
  lastMessageTime: Date | null;
  isReady: boolean;
}

interface HealthStatus {
  connectionStatus: ConnectionStatus;
  lastHeartbeat: Date | null;
  messageCount: number;
  errorCount: number;
  reconnectAttempts: number;
  uptime: number; // ms
}

Connection Indicator Component

import { useConnectionStatus } from 'edge-stream-js-react';

function ConnectionIndicator() {
  const { status, isReady } = useConnectionStatus();

  const colors = {
    connected: '#27ae60',
    connecting: '#f39c12',
    reconnecting: '#f39c12',
    disconnected: '#95a5a6',
    error: '#e74c3c',
    checking: '#f39c12',
  };

  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: '6px' }}>
      <div style={{
        width: '8px', height: '8px',
        borderRadius: '50%',
        background: colors[status] || '#95a5a6',
      }} />
      <span>
        {status === 'connected' ? 'Live' :
         status === 'connecting' ? 'Connecting...' :
         status === 'error' ? 'Connection Error' : status}
      </span>
    </div>
  );
}

Offline Banner

function OfflineBanner() {
  const { status } = useConnectionStatus();

  if (status === 'connected') return null;

  return (
    <div style={{
      position: 'fixed', top: 0, left: 0, right: 0,
      background: status === 'error' ? '#e74c3c' : '#f39c12',
      color: 'white', padding: '8px', textAlign: 'center',
      zIndex: 10000,
    }}>
      {status === 'error'
        ? 'Connection failed. Retrying...'
        : 'Reconnecting to server...'}
    </div>
  );
}

Stats Dashboard

function EdgeStreamStats() {
  const { stats, health } = useConnectionStatus();

  return (
    <div>
      <dl>
        <dt>Messages Received</dt>
        <dd>{stats?.messagesReceived ?? 0}</dd>

        <dt>Messages Sent</dt>
        <dd>{stats?.messagesSent ?? 0}</dd>

        <dt>Last Message</dt>
        <dd>{stats?.lastMessageTime?.toLocaleTimeString() ?? 'None'}</dd>

        <dt>Error Count</dt>
        <dd>{health?.errorCount ?? 0}</dd>

        <dt>Reconnect Attempts</dt>
        <dd>{health?.reconnectAttempts ?? 0}</dd>
      </dl>
    </div>
  );
}

Conditional Rendering on isReady

function WorkflowApp() {
  const { isReady, status } = useConnectionStatus();

  if (!isReady) {
    return (
      <div>
        <span>{status === 'error' ? 'Connection failed' : 'Connecting...'}</span>
      </div>
    );
  }

  return <WorkflowDashboard />;  // only rendered when fully connected
}

Event-Based Stats Tracking

useConnectionStatus listens to message:received and message:sent events on the EdgeStream client to increment counters without polling:

// Internal behavior (simplified):
context.client.on('message:received', () => {
  setStats(prev => prev
    ? { ...prev, messagesReceived: prev.messagesReceived + 1, lastMessageTime: new Date() }
    : null
  );
});

context.client.on('message:sent', () => {
  setStats(prev => prev
    ? { ...prev, messagesSent: prev.messagesSent + 1 }
    : null
  );
});