import { HubConnection, HubConnectionBuilder, HubConnectionState, LogLevel } from '@microsoft/signalr' import { TOKEN_KEY } from '@/lib/api' // Hub URL resolution: // - Dev: Vite proxy forwards /api → :5443 but SignalR bypasses axios, so we // hit the API origin directly from the browser. // - Prod: VITE_API_BASE_URL (https://api.solutions.com.vn) const HUB_URL = (import.meta.env.VITE_API_BASE_URL ?? window.location.origin) + '/hubs/notifications' let connection: HubConnection | null = null let startPromise: Promise | null = null /** Lazily starts (or reuses) a single hub connection. Token read on connect. */ export async function ensureConnection(): Promise { if (connection && connection.state === HubConnectionState.Connected) return connection if (!connection) { connection = new HubConnectionBuilder() .withUrl(HUB_URL, { accessTokenFactory: () => localStorage.getItem(TOKEN_KEY) ?? '', }) .withAutomaticReconnect([0, 2_000, 5_000, 10_000, 15_000]) // exponential-ish backoff .configureLogging(LogLevel.Warning) .build() } if (connection.state === HubConnectionState.Disconnected) { startPromise ??= connection.start().catch(err => { startPromise = null throw err }) await startPromise startPromise = null } return connection } /** Stops + forgets the connection. Call on logout. */ export async function stopConnection(): Promise { if (!connection) return try { await connection.stop() } catch { /* ignore */ } connection = null startPromise = null }