clusev/resources/js/app.js

62 lines
2.4 KiB
JavaScript

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'],
});
// Live CPU chart island: seeds from server-rendered data, then appends each
// MetricsTicked broadcast and redraws the sparkline (viewBox 0 0 300 80).
document.addEventListener('alpine:init', () => {
window.Alpine.data('metricsChart', (seed = [], max = 40) => ({
points: seed.slice(-max),
max,
last: seed.length ? seed[seed.length - 1] : 0,
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) => this.push(e.cpu));
},
// Alpine calls this when the island is removed (e.g. wire:navigate) — avoid leaking subscriptions.
destroy() {
window.Echo?.leave('metrics');
window.Echo?.connector?.pusher?.connection?.unbind('state_change', this._onState);
},
push(v) {
const n = Number(v);
if (! Number.isFinite(n)) return;
this.last = n;
this.points.push(n);
if (this.points.length > this.max) this.points.shift();
},
coords() {
const n = this.points.length;
const w = 300, h = 80, pad = 6;
return this.points.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)}`;
});
},
get linePoints() { return this.coords().join(' '); },
get areaPoints() { return `0,80 ${this.coords().join(' ')} 300,80`; },
}));
});