optimization / frontends /react /src /usePyodide.ts
joel-woodfield's picture
Refactor file structure
7b67454
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,
}
}