diff --git a/src/components/Editor/Editor.tsx b/src/components/Editor/Editor.tsx index 3de298c..ea9b127 100644 --- a/src/components/Editor/Editor.tsx +++ b/src/components/Editor/Editor.tsx @@ -1,7 +1,9 @@ -import React from "react"; +import React, { useEffect } from "react"; import MonacoEditor from "@monaco-editor/react"; import "./editor.less"; import noop from "../../utils"; +import SSE from "../../server/serverSentEvent"; +import { useSSESub } from "../../hooks/useSSESub"; interface EditorProps { value?: string; @@ -25,6 +27,7 @@ export const Editor = ({ onValidate = noop, innerProps, }: EditorProps) => { + const editorProps = { value, theme, @@ -33,5 +36,15 @@ export const Editor = ({ onChange, onValidate, }; - return ; + + useEffect(() => { + const sse = new SSE(); + return sse.close; + }, []); + + useSSESub(()=>{ + + }) + + return ; }; diff --git a/src/contexts/playgroundContext.tsx b/src/contexts/playgroundContext.tsx index 19949d0..87b42f3 100644 --- a/src/contexts/playgroundContext.tsx +++ b/src/contexts/playgroundContext.tsx @@ -14,8 +14,8 @@ export const PlaygroundProvider: React.FC = ( return (
diff --git a/src/hooks/usePlayground.ts b/src/hooks/usePlayground.ts index 81ed2c1..f2e6aa0 100644 --- a/src/hooks/usePlayground.ts +++ b/src/hooks/usePlayground.ts @@ -12,18 +12,18 @@ export interface UsePlayground { * @category Hooks */ export function usePlayground(): UsePlayground { - const sandpack = React.useContext(PlaygroundReactContext); + const playgroud = React.useContext(PlaygroundReactContext); - if (sandpack === null) { + if (playgroud === null) { throw new Error( - `[sandpack-react]: "usePlayground" must be wrapped by a "SandpackProvider"` + `[playgroud-react]: "usePlayground" must be wrapped by a "SandpackProvider"` ); } - const { dispatch, listen, ...rest } = sandpack; + const { dispatch, listen, ...rest } = playgroud; return { - sandpack: { ...rest }, + playgroud: { ...rest }, dispatch, listen, }; diff --git a/src/hooks/useSSESub.ts b/src/hooks/useSSESub.ts new file mode 100644 index 0000000..54895ed --- /dev/null +++ b/src/hooks/useSSESub.ts @@ -0,0 +1,11 @@ +import { useEffect } from "react" +import SSE, { Callback } from "../server/serverSentEvent" + +// 添加sse订阅 +export const useSSESub = (callback:Callback)=>{ + useEffect(()=>{ + const sse = new SSE(); + sse.subscribe(callback); + return ()=>{sse.unsubscribe(callback)} + },[]) +} \ No newline at end of file diff --git a/src/server/index.ts b/src/server/index.ts new file mode 100644 index 0000000..95b4b0f --- /dev/null +++ b/src/server/index.ts @@ -0,0 +1,8 @@ +import { deleteRequest, getRequest, patchRequest, postRequest } from "../utils/request"; + +export const getDetails = (id: string) => getRequest(`/v1/playbooks/${id}`); +export const delatePlaygronds = (id: string) => + deleteRequest(`/v1/playbooks/${id}`); +export const updateDetails = (id: string) => + patchRequest(`/v1/playbooks/${id}`); +export const createId = () => postRequest(`/v1/playbooks`); diff --git a/src/server/serverSentEvent.ts b/src/server/serverSentEvent.ts new file mode 100644 index 0000000..0913a69 --- /dev/null +++ b/src/server/serverSentEvent.ts @@ -0,0 +1,69 @@ +// sse.js +export type Callback = (eventData: any) => void; + +// 后续添加装饰器 + +class SSE { + url: URL | undefined; + eventSource: EventSource | null | undefined; + subscribers: Callback[] = []; + static instance: null; + constructor(endpoint: string = "") { + if (SSE.instance) { + return SSE.instance; + } + + this.url = new URL(endpoint, window.location.origin); + this.eventSource = null; + } + + connect() { + if (!this.url) { + return; + } + this.eventSource = new EventSource(this.url, { withCredentials: true }); + + this.eventSource.onopen = () => { + console.log("SSE connection opened"); + }; + + this.eventSource.onmessage = (event) => { + const eventData = JSON.parse(event.data); + this.notifySubscribers(eventData); + }; + + this.eventSource.onerror = (error) => { + console.error("SSE error:", error); + this.eventSource?.close(); + }; + } + + close() { + if (this.eventSource) { + this.eventSource.close(); + console.log("SSE connection closed"); + } + } + + subscribe(callback: Callback) { + this.subscribers = this.subscribers || []; + this.subscribers.push(callback); + } + + unsubscribe(callback: Callback) { + if (this.subscribers) { + this.subscribers = this.subscribers.filter( + (subscriber) => subscriber !== callback + ); + } + } + + notifySubscribers(data: any) { + if (this.subscribers) { + this.subscribers.forEach((callback) => callback(data)); + } + } +} +new SSE("/test"); + +export default SSE; diff --git a/src/types/index.ts b/src/types/index.ts index 6fd2c43..dde1231 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,8 +1,4 @@ -export type PlaygroundContext = SandpackState & {}; - -export interface SandpackState { - status: string; -} +export type PlaygroundContext = { editorValue?: string; consoleValue?: string }; export interface Style { className?: string; diff --git a/src/utils/request.ts b/src/utils/request.ts new file mode 100644 index 0000000..528329a --- /dev/null +++ b/src/utils/request.ts @@ -0,0 +1,41 @@ +const requestFactory = + (method = "GET") => + async (interface, data = null) => { + const url = `https://example.com/api${interface}`; + const options = { + method, + headers: { + "Content-Type": "application/json", // 根据需要设置合适的 Content-Type + }, + } as RequestInit; + + if ((method === "PUT" || method === "DELETE") && data) { + options.body = JSON.stringify(data); + } else if (data) { + // 对于其他 HTTP 方法,你可以根据需要修改请求体的格式 + options.body = data; + } + + try { + const response = await fetch(url, options); + + if (!response.ok) { + throw new Error(`HTTP error! Status: ${response.status}`); + } + + // 根据实际需要,这里可以根据响应的 Content-Type 来解析数据 + const responseData = await response.json(); + + return responseData; + } catch (error) { + console.error("Error during fetch:", error.message); + throw error; + } + }; + +export const getRequest = requestFactory("GET"); +export const postRequest = requestFactory("POST"); +export const putRequest = requestFactory("PUT"); +export const deleteRequest = requestFactory("DELETE"); +export const optionsRequest = requestFactory("OPTIONS"); +export const patchRequest = requestFactory("PATCH");