Spaces:
Running
Running
Download frontends/react/src/usePyodide.ts from elvis-hf/optimization: direct link, hf CLI and curl.
- Browser
- Download file 3.47 kB
-
https://huggingface.co/spaces/elvis-hf/optimization/resolve/main/frontends/react/src/usePyodide.ts
- Command line
-
hf download hf://spaces/elvis-hf/optimization/frontends/react/src/usePyodide.ts
-
curl -L -o usePyodide.ts https://huggingface.co/spaces/elvis-hf/optimization/resolve/main/frontends/react/src/usePyodide.ts
3.47 kB
| import { useCallback, useEffect, useRef, useState } from "react"; | |
| import PyodideWorker from "./pyodide.worker.ts?worker"; | |
| import type { ComparisonTrajectory, PlotData, Settings, WorkerMessage } from "./types.ts"; | |
| export default function usePyodide(initialSettings: Settings) { | |
| const [comparison, setComparison] = useState<ComparisonTrajectory[]>([]); | |
| const [comparisonBusy, setComparisonBusy] = useState(false); | |
| const comparisonRequest = useRef(0); | |
| const compare = useCallback((settings: Settings[], ids: number[], iteration: number) => { | |
| setComparisonBusy(true); | |
| workerRef.current?.postMessage({ type: "COMPARE", requestId: ++comparisonRequest.current, settings, ids, iteration }); | |
| }, []); | |
| const [plotData, setPlotData] = useState<PlotData>({}); | |
| const [currentIteration, setCurrentIteration] = useState(0); | |
| const [isLoading, setIsLoading] = useState<boolean>(true); | |
| const workerRef = useRef<Worker | null>(null); | |
| const plotDataRef = useRef<PlotData>({}); | |
| const currentIterationRef = useRef(0); | |
| function selectIteration(iteration: number) { | |
| currentIterationRef.current = iteration; | |
| setCurrentIteration(iteration); | |
| } | |
| const sendInit = useCallback((settings: Settings) => { | |
| if (workerRef.current) { | |
| workerRef.current.postMessage({ type: "INIT", settings }); | |
| } | |
| }, []); | |
| const sendNextStep = useCallback(() => { | |
| const lastPlottedIteration = Math.max((plotDataRef.current.trajectoryValues?.x.length ?? 1) - 1, 0); | |
| if (currentIterationRef.current < lastPlottedIteration) { | |
| selectIteration(currentIterationRef.current + 1); | |
| return; | |
| } | |
| if (workerRef.current) { | |
| workerRef.current.postMessage({ type: "NEXT_STEP" }); | |
| } | |
| }, []); | |
| const sendPrevStep = useCallback(() => { | |
| selectIteration(Math.max(currentIterationRef.current - 1, 0)); | |
| }, []); | |
| const sendReset = useCallback(() => { | |
| selectIteration(0); | |
| }, []); | |
| useEffect(() => { | |
| const worker = new PyodideWorker(); | |
| workerRef.current = worker; | |
| worker.onmessage = (event) => { | |
| const message = event.data as WorkerMessage; | |
| if (message.type === "COMPARISON_RESULT") { | |
| if (message.requestId === comparisonRequest.current) { | |
| setComparison(message.trajectories); | |
| setComparisonBusy(false); | |
| } | |
| } else if (message.type === "READY") { | |
| console.log("Pyodide is ready"); | |
| setIsLoading(false); | |
| sendInit(initialSettings); | |
| } else if (message.type === "RESULT") { | |
| // todo data validation / type | |
| setPlotData((prevData) => { | |
| const nextData = { | |
| functionValues: message.data.functionValues || prevData.functionValues, | |
| trajectoryValues: message.data.trajectoryValues || prevData.trajectoryValues, | |
| }; | |
| plotDataRef.current = nextData; | |
| if (message.data.trajectoryValues) { | |
| const lastIteration = Math.max(message.data.trajectoryValues.x.length - 1, 0); | |
| if (lastIteration <= 0 || lastIteration > currentIterationRef.current) { | |
| selectIteration(lastIteration); | |
| } | |
| } | |
| return nextData; | |
| }); | |
| } | |
| }; | |
| return () => { | |
| worker.terminate(); | |
| }; | |
| }, []); | |
| return { | |
| comparison, comparisonBusy, compare, | |
| isLoading, | |
| plotData, | |
| currentIteration, | |
| sendInit: sendInit, | |
| sendReset: sendReset, | |
| sendNextStep: sendNextStep, | |
| sendPrevStep: sendPrevStep, | |
| } | |
| } | |