From 24a3b9a167141ea341c0a7b77514f6681f855992 Mon Sep 17 00:00:00 2001 From: Vikhyath Mondreti Date: Thu, 26 Jun 2025 08:32:14 -0700 Subject: [PATCH] move socket to browser tab level --- .../app/workspace/[workspaceId]/layout.tsx | 17 ++++----- apps/sim/app/workspace/layout.tsx | 26 ++++++++++++++ apps/sim/contexts/socket-context.tsx | 36 ++++++++----------- 3 files changed, 48 insertions(+), 31 deletions(-) create mode 100644 apps/sim/app/workspace/layout.tsx diff --git a/apps/sim/app/workspace/[workspaceId]/layout.tsx b/apps/sim/app/workspace/[workspaceId]/layout.tsx index 261b5d4222..0391bffce9 100644 --- a/apps/sim/app/workspace/[workspaceId]/layout.tsx +++ b/apps/sim/app/workspace/[workspaceId]/layout.tsx @@ -1,18 +1,15 @@ -import { WorkspaceProvider } from '@/providers/workspace-provider' import Providers from './w/components/providers/providers' import { Sidebar } from './w/components/sidebar/sidebar' export default function WorkspaceLayout({ children }: { children: React.ReactNode }) { return ( - - -
-
- -
-
{children}
+ +
+
+
- - +
{children}
+
+
) } diff --git a/apps/sim/app/workspace/layout.tsx b/apps/sim/app/workspace/layout.tsx new file mode 100644 index 0000000000..7daaec19cb --- /dev/null +++ b/apps/sim/app/workspace/layout.tsx @@ -0,0 +1,26 @@ +'use client' + +import { SocketProvider } from '@/contexts/socket-context' +import { useSession } from '@/lib/auth-client' + +interface WorkspaceRootLayoutProps { + children: React.ReactNode +} + +export default function WorkspaceRootLayout({ children }: WorkspaceRootLayoutProps) { + const session = useSession() + + const user = session.data?.user + ? { + id: session.data.user.id, + name: session.data.user.name, + email: session.data.user.email, + } + : undefined + + return ( + + {children} + + ) +} diff --git a/apps/sim/contexts/socket-context.tsx b/apps/sim/contexts/socket-context.tsx index 45d612ebbe..ce4327465f 100644 --- a/apps/sim/contexts/socket-context.tsx +++ b/apps/sim/contexts/socket-context.tsx @@ -99,21 +99,13 @@ export function SocketProvider({ children, user }: SocketProviderProps) { workflowDeleted?: (data: any) => void }>({}) - // Initialize socket when user is available + // Initialize socket when user is available - only once per session useEffect(() => { if (!user?.id) return - // Prevent duplicate connections - disconnect existing socket first - if (socket) { - logger.info('Disconnecting existing socket before creating new one') - socket.disconnect() - setSocket(null) - setIsConnected(false) - } - - // Prevent multiple simultaneous initialization attempts - if (isConnecting) { - logger.info('Socket initialization already in progress, skipping') + // Only initialize if we don't have a socket and aren't already connecting + if (socket || isConnecting) { + logger.info('Socket already exists or is connecting, skipping initialization') return } @@ -296,16 +288,8 @@ export function SocketProvider({ children, user }: SocketProviderProps) { // Start the socket initialization initializeSocket() - // Cleanup on unmount or user change + // Cleanup on unmount only (not on user change since socket is session-level) return () => { - if (socket) { - logger.info('Cleaning up socket connection') - socket.disconnect() - setSocket(null) - setIsConnected(false) - setIsConnecting(false) - } - positionUpdateTimeouts.current.forEach((timeoutId) => { clearTimeout(timeoutId) }) @@ -314,6 +298,16 @@ export function SocketProvider({ children, user }: SocketProviderProps) { } }, [user?.id]) + // Cleanup socket on component unmount + useEffect(() => { + return () => { + if (socket) { + logger.info('Cleaning up socket connection on unmount') + socket.disconnect() + } + } + }, []) + // Join workflow room const joinWorkflow = useCallback( (workflowId: string) => {