# Chapter 04: User Interface Architecture - Web Components and Real-Time Communication The General Bots User Interface (gbui) system implements a sophisticated, component-based architecture for creating responsive, real-time conversational experiences across multiple platforms and devices. This chapter provides comprehensive technical documentation on the UI framework, rendering pipeline, WebSocket communication protocols, and interface customization capabilities. ## Executive Summary The gbui system represents a modern approach to conversational UI development, implementing a lightweight, standards-based architecture that eliminates framework dependencies while providing enterprise-grade capabilities. The system leverages native Web Components, WebSocket protocols, and progressive enhancement strategies to deliver sub-second response times and seamless user experiences across desktop, mobile, and embedded platforms. ## System Architecture Overview ### UI Component Stack The user interface implements a layered architecture for maximum flexibility and performance: ``` ┌─────────────────────────────────────────────────────────────────┐ │ Presentation Layer │ │ (HTML5, CSS3, Web Components) │ ├─────────────────────────────────────────────────────────────────┤ │ Interaction Layer │ │ (Event Handling, Gesture Recognition, A11y) │ ├─────────────────────────────────────────────────────────────────┤ │ Communication Layer │ │ (WebSocket, Server-Sent Events, REST API) │ ├─────────────────────────────────────────────────────────────────┤ │ State Management │ │ (Session Storage, IndexedDB, Service Workers) │ ├─────────────────────────────────────────────────────────────────┤ │ Rendering Pipeline │ │ (Virtual DOM, Incremental Updates, GPU Acceleration) │ └─────────────────────────────────────────────────────────────────┘ ``` ### Technical Specifications | Component | Technology | Performance Target | Browser Support | |-----------|------------|-------------------|-----------------| | Rendering Engine | Native DOM + Virtual DOM diffing | 60 FPS animations | Chrome 90+, Firefox 88+, Safari 14+ | | Communication | WebSocket (RFC 6455) | <100ms latency | All modern browsers | | State Management | IndexedDB + LocalStorage | <5ms read/write | All modern browsers | | Component System | Web Components v1 | <50ms initialization | Chrome, Firefox, Safari, Edge | | Styling Engine | CSS Grid + Flexbox + Custom Properties | <16ms paint | All modern browsers | | Build Size | Vanilla JS (no framework) | <50KB gzipped | IE11+ with polyfills | ## Template Architecture ### Template Processing Pipeline The gbui template system implements a multi-stage processing pipeline: ```javascript class TemplateProcessor { /** * Advanced template processing with optimization */ constructor() { this.templateCache = new Map(); this.componentRegistry = new Map(); this.renderQueue = []; this.rafId = null; } processTemplate(templatePath, data) { // Stage 1: Template loading and caching const template = this.loadTemplate(templatePath); // Stage 2: Template parsing and AST generation const ast = this.parseTemplate(template); // Stage 3: Data binding and interpolation const boundAST = this.bindData(ast, data); // Stage 4: Component resolution const resolvedAST = this.resolveComponents(boundAST); // Stage 5: Optimization pass const optimizedAST = this.optimizeAST(resolvedAST); // Stage 6: DOM generation const domFragment = this.generateDOM(optimizedAST); // Stage 7: Hydration and event binding this.hydrate(domFragment); return domFragment; } parseTemplate(template) { /** * Convert HTML template to Abstract Syntax Tree */ const parser = new DOMParser(); const doc = parser.parseFromString(template, 'text/html'); return this.buildAST(doc.body); } buildAST(node) { const ast = { type: node.nodeType === 1 ? 'element' : 'text', tag: node.tagName?.toLowerCase(), attributes: {}, children: [], directives: {}, events: {} }; if (node.nodeType === 1) { // Process attributes for (const attr of node.attributes) { if (attr.name.startsWith('data-')) { ast.directives[attr.name.slice(5)] = attr.value; } else if (attr.name.startsWith('on')) { ast.events[attr.name.slice(2)] = attr.value; } else { ast.attributes[attr.name] = attr.value; } } // Process children for (const child of node.childNodes) { if (child.nodeType === 1 || child.nodeType === 3) { ast.children.push(this.buildAST(child)); } } } else if (node.nodeType === 3) { ast.content = node.textContent; } return ast; } } ``` ### Template Types and Specifications #### default.gbui - Full Desktop Interface Complete workspace implementation with modular applications: ```html
General Bots

General Bots

Connected
``` #### single.gbui - Minimalist Chat Interface Lightweight, focused chat implementation: ```html Chat
``` ## WebSocket Communication Protocol ### Protocol Specification Real-time bidirectional communication implementation: ```typescript interface WebSocketProtocol { // Message Types enum MessageType { HANDSHAKE = 'handshake', MESSAGE = 'message', TYPING = 'typing', PRESENCE = 'presence', ERROR = 'error', HEARTBEAT = 'heartbeat', ACKNOWLEDGE = 'acknowledge' } // Base Message Structure interface BaseMessage { id: string; type: MessageType; timestamp: number; version: string; } // Message Implementations interface ChatMessage extends BaseMessage { type: MessageType.MESSAGE; content: string; sender: 'user' | 'bot'; metadata?: { tokens?: number; processingTime?: number; confidence?: number; sources?: string[]; }; } interface TypingMessage extends BaseMessage { type: MessageType.TYPING; isTyping: boolean; sender: string; } interface PresenceMessage extends BaseMessage { type: MessageType.PRESENCE; status: 'online' | 'away' | 'offline'; lastSeen?: number; } } ``` ### Connection Management Robust connection handling with automatic recovery: ```javascript class WebSocketManager { constructor(url) { this.url = url; this.ws = null; this.reconnectAttempts = 0; this.maxReconnectAttempts = 5; this.reconnectDelay = 1000; this.heartbeatInterval = 30000; this.messageQueue = []; this.isConnected = false; this.connect(); } connect() { this.ws = new WebSocket(this.url); this.ws.onopen = () => { this.isConnected = true; this.reconnectAttempts = 0; // Start heartbeat this.startHeartbeat(); // Flush message queue this.flushQueue(); // Send handshake this.send({ type: 'handshake', version: '1.0.0', capabilities: ['typing', 'presence', 'files'] }); }; this.ws.onmessage = (event) => { const message = JSON.parse(event.data); this.handleMessage(message); }; this.ws.onerror = (error) => { console.error('WebSocket error:', error); }; this.ws.onclose = () => { this.isConnected = false; this.stopHeartbeat(); this.attemptReconnect(); }; } attemptReconnect() { if (this.reconnectAttempts >= this.maxReconnectAttempts) { console.error('Max reconnection attempts reached'); this.onMaxReconnectFailed(); return; } this.reconnectAttempts++; const delay = this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1); console.log(`Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts})`); setTimeout(() => { this.connect(); }, delay); } startHeartbeat() { this.heartbeatTimer = setInterval(() => { if (this.isConnected) { this.send({ type: 'heartbeat' }); } }, this.heartbeatInterval); } send(data) { const message = { ...data, id: this.generateId(), timestamp: Date.now() }; if (this.isConnected && this.ws.readyState === WebSocket.OPEN) { this.ws.send(JSON.stringify(message)); } else { // Queue message for later delivery this.messageQueue.push(message); } return message.id; } flushQueue() { while (this.messageQueue.length > 0) { const message = this.messageQueue.shift(); this.ws.send(JSON.stringify(message)); } } } ``` ## Performance Optimization ### Rendering Performance Techniques for maintaining 60 FPS: ```javascript class RenderOptimizer { constructor() { this.renderQueue = []; this.isRendering = false; this.rafId = null; // Virtual DOM for diff calculations this.virtualDOM = { messages: [], state: {} }; // DOM references cache this.domCache = new WeakMap(); } scheduleRender(updates) { // Batch updates this.renderQueue.push(...updates); if (!this.isRendering) { this.isRendering = true; this.rafId = requestAnimationFrame(() => this.performRender()); } } performRender() { const startTime = performance.now(); // Process render queue const updates = this.renderQueue.splice(0, 100); // Limit batch size // Calculate minimal DOM updates const patches = this.calculatePatches(updates); // Apply patches this.applyPatches(patches); // Continue rendering if queue not empty if (this.renderQueue.length > 0) { this.rafId = requestAnimationFrame(() => this.performRender()); } else { this.isRendering = false; } // Monitor performance const renderTime = performance.now() - startTime; if (renderTime > 16.67) { console.warn(`Render took ${renderTime}ms - possible jank`); } } calculatePatches(updates) { const patches = []; for (const update of updates) { const oldVNode = this.virtualDOM[update.path]; const newVNode = update.value; const diff = this.diff(oldVNode, newVNode); if (diff) { patches.push({ path: update.path, diff: diff }); } // Update virtual DOM this.virtualDOM[update.path] = newVNode; } return patches; } } ``` ### Resource Loading Progressive loading strategies: ```javascript class ResourceLoader { constructor() { this.loadQueue = []; this.loadingResources = new Set(); this.resourceCache = new Map(); // Intersection Observer for lazy loading this.observer = new IntersectionObserver( (entries) => this.handleIntersection(entries), { rootMargin: '50px', threshold: 0.01 } ); } async loadCriticalResources() { // Critical CSS await this.loadCSS('/css/critical.css', { priority: 'high' }); // Critical JavaScript await this.loadScript('/js/core.js', { priority: 'high' }); // Preload fonts this.preloadFonts([ '/fonts/inter-var.woff2', '/fonts/jetbrains-mono.woff2' ]); // Prefetch likely navigation targets this.prefetchResources([ '/api/user', '/api/conversations/recent' ]); } async loadCSS(href, options = {}) { return new Promise((resolve, reject) => { const link = document.createElement('link'); link.rel = 'stylesheet'; link.href = href; if (options.priority === 'high') { link.fetchpriority = 'high'; } link.onload = resolve; link.onerror = reject; document.head.appendChild(link); }); } preloadFonts(fonts) { fonts.forEach(font => { const link = document.createElement('link'); link.rel = 'preload'; link.as = 'font'; link.type = 'font/woff2'; link.href = font; link.crossOrigin = 'anonymous'; document.head.appendChild(link); }); } } ``` ## Accessibility Implementation ### WCAG 2.1 AAA Compliance Comprehensive accessibility features: ```javascript class AccessibilityManager { constructor() { this.announcer = this.createAnnouncer(); this.focusTrap = null; this.prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; this.initializeA11y(); } initializeA11y() { // Skip navigation links this.addSkipLinks(); // Keyboard navigation this.setupKeyboardNav(); // Screen reader announcements this.setupAnnouncements(); // Focus management this.setupFocusManagement(); // High contrast mode detection this.detectHighContrast(); } createAnnouncer() { const announcer = document.createElement('div'); announcer.setAttribute('role', 'status'); announcer.setAttribute('aria-live', 'polite'); announcer.setAttribute('aria-atomic', 'true'); announcer.className = 'sr-only'; document.body.appendChild(announcer); return announcer; } announce(message, priority = 'polite') { this.announcer.setAttribute('aria-live', priority); this.announcer.textContent = message; // Clear after announcement setTimeout(() => { this.announcer.textContent = ''; }, 1000); } setupKeyboardNav() { document.addEventListener('keydown', (e) => { // Keyboard shortcuts if (e.altKey) { switch(e.key) { case '1': this.navigateTo('chat'); break; case '2': this.navigateTo('drive'); break; case '3': this.navigateTo('tasks'); break; case '4': this.navigateTo('mail'); break; case '/': this.focusSearch(); break; } } // Tab trap for modals if (this.focusTrap && e.key === 'Tab') { this.handleTabTrap(e); } // Escape key handling if (e.key === 'Escape') { this.handleEscape(); } }); } } ``` ## Security Considerations ### Content Security Policy Comprehensive CSP implementation: ```html ``` ### XSS Prevention Input sanitization and output encoding: ```javascript class SecurityManager { sanitizeHTML(html) { const policy = { ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a', 'br', 'p', 'code', 'pre'], ALLOWED_ATTR: ['href', 'title', 'target'], ALLOW_DATA_ATTR: false, RETURN_DOM: false, RETURN_DOM_FRAGMENT: false, RETURN_TRUSTED_TYPE: true }; return DOMPurify.sanitize(html, policy); } escapeHTML(text) { const map = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''', '/': '/' }; return text.replace(/[&<>"'/]/g, char => map[char]); } } ``` ## Summary The gbui system provides a complete, production-ready user interface framework that delivers enterprise-grade performance while maintaining simplicity and accessibility. Through careful optimization, progressive enhancement, and standards compliance, the system achieves sub-second response times and smooth 60 FPS rendering across all supported platforms.