feat: real-time gate messages via SSE + faster push/pull intervals

- Add Server-Sent Events endpoint at GET /api/mesh/gate/stream that
  broadcasts ALL gate events to connected frontends (privacy: no
  per-gate subscriptions, clients filter locally)
- Hook SSE broadcast into all gate event entry points: local append,
  peer push receiver, and pull loop
- Reduce push/pull intervals from 30s to 10s for faster relay sync
- Add useGateSSE hook for frontend EventSource integration
- GateView + MeshChat use SSE for instant refresh, polling demoted
  to 30s fallback

Latency: same-node instant, cross-node ~10s avg (was ~34s)
This commit is contained in:
anoracleofra-code
2026-03-27 09:35:53 -06:00
parent 40a3cbdfdc
commit c81d81ec41
4 changed files with 137 additions and 5 deletions
@@ -13,6 +13,7 @@ import {
} from '@/mesh/wormholeIdentityClient';
import { gateEnvelopeDisplayText, gateEnvelopeState, isEncryptedGateEnvelope } from '@/mesh/gateEnvelope';
import { validateEventPayload } from '@/mesh/meshSchema';
import { useGateSSE } from '@/hooks/useGateSSE';
const GATE_INTROS: Record<string, string> = {
infonet:
@@ -357,11 +358,21 @@ export default function GateView({
}
}, [gateId, hydrateMessages]);
// SSE: instant delivery when new gate events arrive
const handleSSEEvent = useCallback(
(eventGateId: string) => {
if (eventGateId === gateId) void refreshGate();
},
[gateId, refreshGate],
);
useGateSSE(handleSSEEvent);
// Fallback poll (30s) in case SSE disconnects
useEffect(() => {
void refreshGate();
const timer = window.setInterval(() => {
void refreshGate();
}, 8000);
}, 30_000);
return () => {
window.clearInterval(timer);
};