diff --git a/apps/executeJS/src/features/playground/const.ts b/apps/executeJS/src/features/playground/const.ts new file mode 100644 index 0000000..e41648f --- /dev/null +++ b/apps/executeJS/src/features/playground/const.ts @@ -0,0 +1,3 @@ +export const PLAYGROUND_STORAGE_KEY = 'executejs-playground-storage'; + +export const DEFAULT_PLAYGROUND_CODE = 'console.log("Hello, ExecuteJS!");'; diff --git a/apps/executeJS/src/features/playground/index.ts b/apps/executeJS/src/features/playground/index.ts index d406816..e221ce1 100644 --- a/apps/executeJS/src/features/playground/index.ts +++ b/apps/executeJS/src/features/playground/index.ts @@ -1 +1,2 @@ export * from './store'; +export * from './const'; diff --git a/apps/executeJS/src/features/playground/store.ts b/apps/executeJS/src/features/playground/store.ts index 0e897c9..2959510 100644 --- a/apps/executeJS/src/features/playground/store.ts +++ b/apps/executeJS/src/features/playground/store.ts @@ -1,6 +1,7 @@ import { JsExecutionResult } from '@/shared'; import { create } from 'zustand'; import { persist, createJSONStorage } from 'zustand/middleware'; +import { PLAYGROUND_STORAGE_KEY } from './const'; interface Tab { id: string; @@ -12,8 +13,6 @@ export interface Playground { id: string; result: JsExecutionResult | null; isExecuting: boolean; - // setExecuting: (executing: boolean) => void; - // executeCode: (code: string) => void; // clearResult: () => void; } @@ -25,6 +24,10 @@ interface PlaygroundState { addTab: () => void; closeTab: (tabId: Tab['id']) => void; setActiveTab: (tabId: Tab['id']) => void; + executeCode: (params: { + playgroundId: Playground['id']; + code: string; + }) => void; } const INITIAL_TAB_TITLE = '✨New Playground'; @@ -120,9 +123,78 @@ export const usePlaygroundStore = create()( }; }); }, + + // 플레이그라운드 별 코드 실행 + executeCode: async ({ + playgroundId, + code, + }: { + playgroundId: Playground['id']; + code: string; + }) => { + set((state) => { + const playgrounds = new Map(state.playgrounds); + const playground = playgrounds.get(playgroundId); + + if (playground) { + playgrounds.set(playgroundId, { ...playground, isExecuting: true }); + } + + return { playgrounds }; + }); + + try { + // Tauri 백엔드의 execute_js 명령어 호출 + const { invoke } = await import('@tauri-apps/api/core'); + const result = await invoke('execute_js', { + code, + }); + + console.log('executeCode result -', result); + + set((state) => { + const playgrounds = new Map(state.playgrounds); + const playground = playgrounds.get(playgroundId); + + if (playground) { + playgrounds.set(playgroundId, { + ...playground, + result: result, + isExecuting: false, + }); + } + + return { playgrounds }; + }); + } catch (error: any) { + //TODO: @ohah 에러 처리 더 명확하게 할 것 + const result: JsExecutionResult = { + code, + result: error?.result ?? '', + timestamp: new Date().toISOString(), + success: false, + error: error?.error ?? '알 수 없는 오류', + }; + + set((state) => { + const playgrounds = new Map(state.playgrounds); + const playground = playgrounds.get(playgroundId); + + if (playground) { + playgrounds.set(playgroundId, { + ...playground, + result: result, + isExecuting: false, + }); + } + + return { playgrounds }; + }); + } + }, }), { - name: 'executejs-playground-store', + name: PLAYGROUND_STORAGE_KEY, storage: createJSONStorage(() => localStorage, { replacer: (_, value) => { if (value instanceof Map) { diff --git a/apps/executeJS/src/widgets/playground/playground-widget.tsx b/apps/executeJS/src/widgets/playground/playground-widget.tsx index a65b468..a4c0d25 100644 --- a/apps/executeJS/src/widgets/playground/playground-widget.tsx +++ b/apps/executeJS/src/widgets/playground/playground-widget.tsx @@ -5,53 +5,30 @@ import { PlayIcon, StopIcon } from '@radix-ui/react-icons'; import { CodeEditor } from '@/widgets/code-editor'; import { OutputPanel } from '@/widgets/output-panel'; -import { useExecutionStore } from '@/features/execute-code'; -import { Playground } from '@/features/playground'; - -const getInitialCode = (): string => { - try { - const executionStorage = localStorage.getItem( - 'executejs-execution-storage' - ); - - if (executionStorage) { - const parsed = JSON.parse(executionStorage); - const code = parsed?.state?.result?.code; - - if (code) { - console.log('result from executionStorage:', code); - - return code; - } - } - } catch (error) { - console.error('error from executionStorage:', error); - } - - return 'console.log("Hello, ExecuteJS!");'; -}; +import { + DEFAULT_PLAYGROUND_CODE, + Playground, + usePlaygroundStore, +} from '@/features/playground'; interface PlaygroundProps { playground: Playground; } export const PlaygroundWidget: React.FC = ({ playground }) => { - // TODO: playground prop 로직 추가 예정 @bori - console.log('PlaygroundWidget', playground); + const { id, isExecuting, result: executionResult } = playground; + + const [code, setCode] = useState( + executionResult?.code || DEFAULT_PLAYGROUND_CODE + ); - // FIXME: tab이 여러개 생기거나 global store로 상태가 이동되면 수정되어야함 - const [code, setCode] = useState(getInitialCode); - const { - result: executionResult, - isExecuting, - executeCode, - } = useExecutionStore(); + const { executeCode } = usePlaygroundStore(); // 코드 실행 핸들러 const handleExecuteCode = (codeToExecute?: string) => { const codeToRun = codeToExecute || code; if (codeToRun.trim()) { - executeCode(codeToRun); + executeCode({ code: codeToRun, playgroundId: id }); } };