reactions, match sse, etc

This commit is contained in:
yohlo
2025-09-19 14:08:36 -05:00
parent 602e6e3473
commit f99d6efaf9
20 changed files with 474 additions and 100 deletions

View File

@@ -2,19 +2,13 @@ import { useEffect, useRef } from "react";
import { useQueryClient } from "@tanstack/react-query";
import { Logger } from "@/lib/logger";
import { useAuth } from "@/contexts/auth-context";
/*
import { authClient } from "~/lib/auth-client";
import { getIdeaFn } from "~/routes/-fn/getIdeaFn";
import { useSession } from "~/lib/sessionContext";
*/
import { tournamentKeys, tournamentQueries } from "@/features/tournaments/queries";
// Global state for new ideas notification
let newIdeasAvailable = false;
let newIdeasCallbacks: (() => void)[] = [];
const logger = new Logger('ServerEvents');
// Event handler types for better type safety
type SSEEvent = {
type: string;
[key: string]: any;
@@ -22,29 +16,26 @@ type SSEEvent = {
type EventHandler = (event: SSEEvent, queryClient: ReturnType<typeof useQueryClient>, currentSessionId?: string) => void;
// Event handlers map - add new handlers here for easy extension
const eventHandlers: Record<string, EventHandler> = {
"connected": () => {
logger.info("ServerEvents | New Connection");
},
"ping": () => {
// Keep-alive ping, no action needed
},
"ping": () => {},
"test": (event, queryClient) => {
},
// Add new event handlers here:
// "idea-updated": (event, queryClient) => {
// queryClient.invalidateQueries({ queryKey: ["ideas"] });
// },
// "vote-changed": (event, queryClient) => {
// queryClient.invalidateQueries({ queryKey: ["idea", event.ideaId] });
// },
"match": (event, queryClient) => {
console.log(event);
queryClient.invalidateQueries(tournamentQueries.details(event.tournamentId))
queryClient.invalidateQueries(tournamentQueries.current())
}
};
// Functions to manage new ideas notification state
export function getNewIdeasAvailable(): boolean {
return newIdeasAvailable;
}
@@ -55,7 +46,6 @@ export function clearNewIdeasAvailable(): void {
export function subscribeToNewIdeas(callback: () => void): () => void {
newIdeasCallbacks.push(callback);
// Return unsubscribe function
return () => {
const index = newIdeasCallbacks.indexOf(callback);
if (index > -1) {
@@ -84,7 +74,6 @@ export function useServerEvents() {
const eventSource = new EventSource(`/api/events/$`);
eventSource.onopen = () => {
// Reset retry count on successful connection
retryCountRef.current = 0;
};
@@ -93,7 +82,6 @@ export function useServerEvents() {
const data: SSEEvent = JSON.parse(event.data);
logger.info("Event received", data);
// Use the event handler pattern for extensible event processing
const handler = eventHandlers[data.type];
if (handler) {
handler(data, queryClient, user?.id);
@@ -109,13 +97,12 @@ export function useServerEvents() {
logger.error("SSE connection error", error);
eventSource.close();
// Only retry if we should still be connecting and haven't exceeded max retries
if (shouldConnectRef.current && retryCountRef.current < 5) {
retryCountRef.current += 1;
const delay = Math.min(
1000 * Math.pow(2, retryCountRef.current - 1),
30000
); // Cap at 30 seconds
);
logger.info(
`SSE reconnection attempt ${retryCountRef.current}/5 in ${delay}ms`