[ty] Fix caching of imported modules in playground (#21251)

This commit is contained in:
Micha Reiser 2025-11-03 16:00:30 +01:00 committed by GitHub
parent de9df1b326
commit 1b2ed6a503
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 31 additions and 37 deletions

View File

@ -2,7 +2,7 @@ import MonacoEditor from "@monaco-editor/react";
import { AstralButton, Theme } from "shared"; import { AstralButton, Theme } from "shared";
import { ReadonlyFiles } from "../Playground"; import { ReadonlyFiles } from "../Playground";
import { Suspense, use, useState } from "react"; import { Suspense, use, useState } from "react";
import { loadPyodide, PyodideInterface } from "pyodide"; import { loadPyodide } from "pyodide";
import classNames from "classnames"; import classNames from "classnames";
export enum SecondaryTool { export enum SecondaryTool {
@ -103,41 +103,12 @@ function Content({
} }
} }
let pyodidePromise: Promise<PyodideInterface> | null = null;
function Run({ files, theme }: { files: ReadonlyFiles; theme: Theme }) { function Run({ files, theme }: { files: ReadonlyFiles; theme: Theme }) {
if (pyodidePromise == null) { const [runOutput, setRunOutput] = useState<Promise<string> | null>(null);
pyodidePromise = loadPyodide(); const handleRun = () => {
} const output = (async () => {
const pyodide = await loadPyodide();
return (
<Suspense
fallback={<div className="text-center dark:text-white">Loading</div>}
>
<RunWithPyiodide
theme={theme}
files={files}
pyodidePromise={pyodidePromise}
/>
</Suspense>
);
}
function RunWithPyiodide({
files,
pyodidePromise,
theme,
}: {
files: ReadonlyFiles;
theme: Theme;
pyodidePromise: Promise<PyodideInterface>;
}) {
const pyodide = use(pyodidePromise);
const [output, setOutput] = useState<string | null>(null);
if (output == null) {
const handleRun = () => {
let combined_output = ""; let combined_output = "";
const outputHandler = (output: string) => { const outputHandler = (output: string) => {
@ -179,14 +150,18 @@ function RunWithPyiodide({
filename: fileName, filename: fileName,
}); });
setOutput(combined_output); return combined_output;
} catch (e) { } catch (e) {
setOutput(`Failed to run Python script: ${e}`); return `Failed to run Python script: ${e}`;
} finally { } finally {
globals.destroy(); globals.destroy();
dict.destroy(); dict.destroy();
} }
}; })();
setRunOutput(output);
};
if (runOutput == null) {
return ( return (
<div className="flex flex-auto flex-col justify-center items-center"> <div className="flex flex-auto flex-col justify-center items-center">
<AstralButton <AstralButton
@ -204,6 +179,25 @@ function RunWithPyiodide({
</div> </div>
); );
} }
return (
<Suspense
fallback={<div className="text-center dark:text-white">Loading</div>}
>
<RunOutput theme={theme} runOutput={runOutput} />
</Suspense>
);
}
function RunOutput({
runOutput,
theme,
}: {
theme: Theme;
runOutput: Promise<string>;
}) {
const output = use(runOutput);
return ( return (
<pre <pre
className={classNames( className={classNames(