Ver Fonte

Fix race condition: pre-initialize apiClient base URL from localStorage

WebSocket connections were being established before TableContext had
a chance to set the base URL, causing connections to go to the wrong
server when switching tables.

Solution: Initialize the base URL synchronously at module load time,
before React renders. This ensures the correct URL is available
immediately when components mount and create WebSocket connections.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
tuanchris há 2 semanas atrás
pai
commit
cf8e31cf89
1 ficheiros alterados com 44 adições e 3 exclusões
  1. 44 3
      frontend/src/lib/apiClient.ts

+ 44 - 3
frontend/src/lib/apiClient.ts

@@ -201,10 +201,51 @@ class ApiClient {
 }
 
 // Export singleton instance
-// Note: Base URL is managed by TableContext after it validates table connectivity.
-// We intentionally don't pre-initialize from localStorage here to avoid pointing
-// to stale/unreachable servers which would cause silent API failures.
 export const apiClient = new ApiClient()
 
+// Pre-initialize base URL from localStorage to avoid race conditions.
+// This runs synchronously at module load time, before React renders,
+// ensuring WebSocket connections use the correct URL from the start.
+function initializeBaseUrlFromStorage(): void {
+  try {
+    const STORAGE_KEY = 'duneweaver_tables'
+    const ACTIVE_TABLE_KEY = 'duneweaver_active_table'
+
+    const stored = localStorage.getItem(STORAGE_KEY)
+    const activeId = localStorage.getItem(ACTIVE_TABLE_KEY)
+
+    if (!stored || !activeId) return
+
+    const data = JSON.parse(stored)
+    const tables = data.tables || []
+    const active = tables.find((t: { id: string }) => t.id === activeId)
+
+    if (!active?.url) return
+
+    // Normalize URL for comparison (handles port differences like :80)
+    const normalizeOrigin = (url: string): string => {
+      try {
+        return new URL(url).origin
+      } catch {
+        return url
+      }
+    }
+
+    const normalizedActiveUrl = normalizeOrigin(active.url)
+    const currentOrigin = window.location.origin
+
+    // Only set base URL for remote tables (different origin)
+    if (normalizedActiveUrl !== currentOrigin) {
+      console.log('[ApiClient] Pre-initializing base URL from localStorage:', active.url)
+      apiClient.setBaseUrl(active.url)
+    }
+  } catch (e) {
+    console.error('[ApiClient] Failed to pre-initialize base URL:', e)
+  }
+}
+
+// Run initialization immediately at module load
+initializeBaseUrlFromStorage()
+
 // Export class for testing
 export { ApiClient }