Spaces:
Running
Running
| import { useEffect, useRef, useState } from "react"; | |
| import PyodideWorker from "./pyodide.worker.ts?worker"; | |
| import type { PlotData, Settings, WorkerMessage } from "./types.ts"; | |
| export default function usePyodide(initialSettings: Settings) { | |
| const [plotData, setPlotData] = useState<PlotData>({}); | |
| const [isLoading, setIsLoading] = useState<boolean>(true); | |
| const workerRef = useRef<Worker | null>(null); | |
| function sendInit(settings: Settings) { | |
| if (workerRef.current) { | |
| workerRef.current.postMessage({ type: "INIT", settings }); | |
| } | |
| } | |
| function sendNextStep() { | |
| if (workerRef.current) { | |
| workerRef.current.postMessage({ type: "NEXT_STEP" }); | |
| } | |
| } | |
| function sendPrevStep() { | |
| if (workerRef.current) { | |
| workerRef.current.postMessage({ type: "PREV_STEP" }); | |
| } | |
| } | |
| function sendReset() { | |
| if (workerRef.current) { | |
| workerRef.current.postMessage({ type: "RESET" }); | |
| } | |
| } | |
| useEffect(() => { | |
| const worker = new PyodideWorker(); | |
| workerRef.current = worker; | |
| worker.onmessage = (event) => { | |
| const message = event.data as WorkerMessage; | |
| if (message.type === "READY") { | |
| console.log("Pyodide is ready"); | |
| setIsLoading(false); | |
| sendInit(initialSettings); | |
| } else if (message.type === "RESULT") { | |
| // todo data validation / type | |
| setPlotData((prevData) => ({ | |
| functionValues: message.data.functionValues || prevData.functionValues, | |
| trajectoryValues: message.data.trajectoryValues || prevData.trajectoryValues, | |
| })) | |
| } | |
| }; | |
| return () => { | |
| worker.terminate(); | |
| }; | |
| }, []); | |
| return { | |
| isLoading, | |
| plotData, | |
| sendInit: sendInit, | |
| sendReset: sendReset, | |
| sendNextStep: sendNextStep, | |
| sendPrevStep: sendPrevStep, | |
| } | |
| } |