فهرست منبع

refactor: implement WebSocket connection management in Playground

Yuki Takei 6 ماه پیش
والد
کامیت
9ff1fc5667

+ 3 - 22
packages/editor/src/client/components-internal/playground/Playground.tsx

@@ -3,7 +3,6 @@ import {
 } from 'react';
 } from 'react';
 
 
 import { AcceptedUploadFileType } from '@growi/core';
 import { AcceptedUploadFileType } from '@growi/core';
-import { GLOBAL_SOCKET_KEY, GLOBAL_SOCKET_NS, useSWRStatic } from '@growi/core/dist/swr';
 import type { ReactCodeMirrorProps } from '@uiw/react-codemirror';
 import type { ReactCodeMirrorProps } from '@uiw/react-codemirror';
 import { toast } from 'react-toastify';
 import { toast } from 'react-toastify';
 
 
@@ -16,6 +15,7 @@ import { useCodeMirrorEditorIsolated } from '../../stores/codemirror-editor';
 
 
 import { PlaygroundController } from './PlaygroundController';
 import { PlaygroundController } from './PlaygroundController';
 import { Preview } from './Preview';
 import { Preview } from './Preview';
+import { useSetupPlaygroundSocket } from './states/socket';
 
 
 export const Playground = (): JSX.Element => {
 export const Playground = (): JSX.Element => {
 
 
@@ -28,7 +28,8 @@ export const Playground = (): JSX.Element => {
 
 
   const { data: codeMirrorEditor } = useCodeMirrorEditorIsolated(GlobalCodeMirrorEditorKey.MAIN);
   const { data: codeMirrorEditor } = useCodeMirrorEditorIsolated(GlobalCodeMirrorEditorKey.MAIN);
 
 
-  const { mutate } = useSWRStatic(GLOBAL_SOCKET_KEY);
+  // Initialize playground socket
+  useSetupPlaygroundSocket();
 
 
   // initial caret line
   // initial caret line
   useEffect(() => {
   useEffect(() => {
@@ -45,26 +46,6 @@ export const Playground = (): JSX.Element => {
     });
     });
   }, [setEditorSettings, editorKeymap, editorTheme, editorPaste]);
   }, [setEditorSettings, editorKeymap, editorTheme, editorPaste]);
 
 
-  // initialize global socket
-  useEffect(() => {
-    const setUpSocket = async() => {
-      const { io } = await import('socket.io-client');
-      const socket = io(GLOBAL_SOCKET_NS, {
-        transports: ['websocket'],
-      });
-
-      // eslint-disable-next-line no-console
-      socket.on('error', (err) => { console.error(err) });
-      // eslint-disable-next-line no-console
-      socket.on('connect_error', (err) => { console.error('Failed to connect with websocket.', err) });
-
-      mutate(socket);
-    };
-
-    setUpSocket();
-
-  }, [mutate]);
-
   // set handler to save with shortcut key
   // set handler to save with shortcut key
   const saveHandler = useCallback(() => {
   const saveHandler = useCallback(() => {
     // eslint-disable-next-line no-console
     // eslint-disable-next-line no-console

+ 56 - 0
packages/editor/src/client/components-internal/playground/states/socket.ts

@@ -0,0 +1,56 @@
+import { useCallback, useEffect } from 'react';
+
+import { atom, useAtomValue, useSetAtom } from 'jotai';
+import type { Socket } from 'socket.io-client';
+
+// Constants
+export const PLAYGROUND_SOCKET_NS = '/';
+
+// WebSocket connection atom for playground
+const playgroundSocketAtom = atom<Socket | null>(null);
+
+/**
+ * Hook to get WebSocket connection for playground
+ */
+export const usePlaygroundSocket = (): Socket | null => useAtomValue(playgroundSocketAtom);
+
+/**
+ * Hook to initialize WebSocket connection for playground
+ */
+export const useSetupPlaygroundSocket = (): void => {
+  const setSocket = useSetAtom(playgroundSocketAtom);
+  const socket = useAtomValue(playgroundSocketAtom);
+
+  const initializeSocket = useCallback(async() => {
+    try {
+      // Dynamic import of socket.io-client
+      const { io } = await import('socket.io-client');
+      const newSocket = io(PLAYGROUND_SOCKET_NS, {
+        transports: ['websocket'],
+      });
+
+      // Error handling
+      newSocket.on('error', (err) => {
+        // eslint-disable-next-line no-console
+        console.error(err);
+      });
+      newSocket.on('connect_error', (err) => {
+        // eslint-disable-next-line no-console
+        console.error('Failed to connect with websocket.', err);
+      });
+
+      // Store connection in atom
+      setSocket(newSocket);
+    }
+    catch (error) {
+      // eslint-disable-next-line no-console
+      console.error('Failed to initialize WebSocket:', error);
+    }
+  }, [setSocket]);
+
+  useEffect(() => {
+    if (socket == null) {
+      initializeSocket();
+    }
+  }, [socket, initializeSocket]);
+};