Add frontend loading imporvements
This commit is contained in:
@@ -39,8 +39,19 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
|
||||
const initializeAuth = async () => {
|
||||
setIsInitializing(true);
|
||||
|
||||
// Wait a bit for zustand persist to rehydrate
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
// Check if zustand has already rehydrated
|
||||
if (!(useAuthStore.persist as any).hasHydrated?.()) {
|
||||
// Wait for rehydration event with minimal timeout fallback
|
||||
await Promise.race([
|
||||
new Promise<void>(resolve => {
|
||||
const unsubscribe = useAuthStore.persist.onFinishHydration(() => {
|
||||
unsubscribe();
|
||||
resolve();
|
||||
});
|
||||
}),
|
||||
new Promise(resolve => setTimeout(resolve, 50))
|
||||
]);
|
||||
}
|
||||
|
||||
// Check if we have stored auth data
|
||||
if (authStore.token && authStore.refreshToken) {
|
||||
|
||||
@@ -35,12 +35,15 @@ interface SSEProviderProps {
|
||||
export const SSEProvider: React.FC<SSEProviderProps> = ({ children }) => {
|
||||
const [isConnected, setIsConnected] = useState(false);
|
||||
const [lastEvent, setLastEvent] = useState<SSEEvent | null>(null);
|
||||
|
||||
|
||||
const eventSourceRef = useRef<EventSource | null>(null);
|
||||
const eventListenersRef = useRef<Map<string, Set<(data: any) => void>>>(new Map());
|
||||
const reconnectTimeoutRef = useRef<NodeJS.Timeout>();
|
||||
const reconnectAttempts = useRef(0);
|
||||
|
||||
|
||||
// Global deduplication: Track processed event IDs to prevent duplicate callbacks
|
||||
const processedEventIdsRef = useRef<Set<string>>(new Set());
|
||||
|
||||
const { isAuthenticated, token } = useAuthStore();
|
||||
const currentTenant = useCurrentTenant();
|
||||
|
||||
@@ -130,6 +133,23 @@ export const SSEProvider: React.FC<SSEProviderProps> = ({ children }) => {
|
||||
eventSource.addEventListener('alert', (event) => {
|
||||
try {
|
||||
const data = JSON.parse(event.data);
|
||||
|
||||
// GLOBAL DEDUPLICATION: Skip if this event was already processed
|
||||
if (data.id && processedEventIdsRef.current.has(data.id)) {
|
||||
console.log('⏭️ [SSE] Skipping duplicate alert:', data.id);
|
||||
return;
|
||||
}
|
||||
|
||||
// Mark event as processed
|
||||
if (data.id) {
|
||||
processedEventIdsRef.current.add(data.id);
|
||||
// Limit cache size (keep last 1000 event IDs)
|
||||
if (processedEventIdsRef.current.size > 1000) {
|
||||
const firstId = Array.from(processedEventIdsRef.current)[0];
|
||||
processedEventIdsRef.current.delete(firstId);
|
||||
}
|
||||
}
|
||||
|
||||
const sseEvent: SSEEvent = {
|
||||
type: 'alert',
|
||||
data,
|
||||
@@ -208,6 +228,22 @@ export const SSEProvider: React.FC<SSEProviderProps> = ({ children }) => {
|
||||
eventSource.addEventListener('notification', (event) => {
|
||||
try {
|
||||
const data = JSON.parse(event.data);
|
||||
|
||||
// GLOBAL DEDUPLICATION: Skip if this event was already processed
|
||||
if (data.id && processedEventIdsRef.current.has(data.id)) {
|
||||
console.log('⏭️ [SSE] Skipping duplicate notification:', data.id);
|
||||
return;
|
||||
}
|
||||
|
||||
// Mark event as processed
|
||||
if (data.id) {
|
||||
processedEventIdsRef.current.add(data.id);
|
||||
if (processedEventIdsRef.current.size > 1000) {
|
||||
const firstId = Array.from(processedEventIdsRef.current)[0];
|
||||
processedEventIdsRef.current.delete(firstId);
|
||||
}
|
||||
}
|
||||
|
||||
const sseEvent: SSEEvent = {
|
||||
type: 'notification',
|
||||
data,
|
||||
|
||||
Reference in New Issue
Block a user