import Echo from 'laravel-echo'; import Pusher from 'pusher-js'; window.Pusher = Pusher; // Reverb (Pusher protocol). Host/port/scheme are env-driven (derived from APP_DOMAIN later). window.Echo = new Echo({ broadcaster: 'reverb', key: import.meta.env.VITE_REVERB_APP_KEY, wsHost: import.meta.env.VITE_REVERB_HOST, wsPort: Number(import.meta.env.VITE_REVERB_PORT ?? 80), wssPort: Number(import.meta.env.VITE_REVERB_PORT ?? 443), forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https', enabledTransports: ['ws', 'wss'], }); document.addEventListener('alpine:init', () => { // Live dual-series chart (CPU + MEM). Seeds from server-rendered data, then // appends each MetricsTicked broadcast and redraws (viewBox 0 0 300 100). window.Alpine.data('dualChart', (cpuSeed = [], memSeed = [], max = 40, server = null) => ({ cpu: cpuSeed.slice(-max), mem: memSeed.slice(-max), max, server, connected: false, init() { const conn = window.Echo?.connector?.pusher?.connection; this.connected = conn?.state === 'connected'; this._onState = (s) => { this.connected = s.current === 'connected'; }; conn?.bind('state_change', this._onState); this._channel = window.Echo?.channel('metrics'); this._channel?.listen('.tick', (e) => { // only react to the server this chart is showing if (this.server && e.server && e.server !== this.server) return; this.append(this.cpu, e.cpu); this.append(this.mem, e.mem); }); }, destroy() { window.Echo?.leave('metrics'); window.Echo?.connector?.pusher?.connection?.unbind('state_change', this._onState); }, append(arr, v) { const n = Number(v); if (! Number.isFinite(n)) return; arr.push(n); if (arr.length > this.max) arr.shift(); }, _coords(arr) { const n = arr.length, w = 300, h = 100, pad = 6; return arr .map((v, i) => { const x = n > 1 ? (i / (n - 1)) * w : 0; const y = h - pad - (Math.max(0, Math.min(100, v)) / 100) * (h - 2 * pad); return `${x.toFixed(1)},${y.toFixed(1)}`; }) .join(' '); }, get cpuLine() { return this._coords(this.cpu); }, get cpuArea() { return `0,100 ${this._coords(this.cpu)} 300,100`; }, get memLine() { return this._coords(this.mem); }, get memArea() { return `0,100 ${this._coords(this.mem)} 300,100`; }, })); });