diff --git a/.env.example b/.env.example index b09fd4e7c..570bcff22 100644 --- a/.env.example +++ b/.env.example @@ -6,5 +6,5 @@ REACT_APP_PLAUSIBLE_DATA_DOMAIN='' REACT_APP_PLAUSIBLE_SOURCE='' REACT_APP_SENTRY_DSN='' REACT_APP_SENTRY_ENV='local' -PUBLIC_URL='http://localhost:3010' +PUBLIC_URL='http://localhost:3011' ASSETS_URL='http://localhost:3010' diff --git a/.vscode/launch.json b/.vscode/launch.json index 22dbf71bd..249490c42 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,7 +5,7 @@ "type": "chrome", "request": "launch", "name": "Launch Chrome against localhost", - "url": "http://localhost:3010", + "url": "http://localhost:3011", "webRoot": "${workspaceFolder}" } ] diff --git a/CHANGELOG.md b/CHANGELOG.md index 02ac382ac..560d5e8f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Added +- PyodideWorker setup for the editor (#1104) - Enabling `pyodide` support in the web component (#1090) - `Pyodide` `matplotlib` support (#1087) diff --git a/public/packages/p5-0.0.1-py3-none-any.whl b/public/pyodide/packages/p5-0.0.1-py3-none-any.whl similarity index 100% rename from public/packages/p5-0.0.1-py3-none-any.whl rename to public/pyodide/packages/p5-0.0.1-py3-none-any.whl diff --git a/public/packages/sense_hat-0.0.1-py3-none-any.whl b/public/pyodide/packages/sense_hat-0.0.1-py3-none-any.whl similarity index 100% rename from public/packages/sense_hat-0.0.1-py3-none-any.whl rename to public/pyodide/packages/sense_hat-0.0.1-py3-none-any.whl diff --git a/public/packages/turtle-0.0.1-py3-none-any.whl b/public/pyodide/packages/turtle-0.0.1-py3-none-any.whl similarity index 100% rename from public/packages/turtle-0.0.1-py3-none-any.whl rename to public/pyodide/packages/turtle-0.0.1-py3-none-any.whl diff --git a/public/_internal_sense_hat.js b/public/pyodide/shims/_internal_sense_hat.js similarity index 100% rename from public/_internal_sense_hat.js rename to public/pyodide/shims/_internal_sense_hat.js diff --git a/public/pygal.js b/public/pyodide/shims/pygal.js similarity index 100% rename from public/pygal.js rename to public/pyodide/shims/pygal.js diff --git a/src/PyodideWorker.js b/src/PyodideWorker.js index 497d297b1..61091e3e9 100644 --- a/src/PyodideWorker.js +++ b/src/PyodideWorker.js @@ -3,8 +3,10 @@ // Nest the PyodideWorker function inside a globalThis object so we control when its initialised. const PyodideWorker = () => { // Import scripts dynamically based on the environment - importScripts(`${process.env.PUBLIC_URL}/_internal_sense_hat.js`); - importScripts(`${process.env.PUBLIC_URL}/pygal.js`); + importScripts( + `${process.env.ASSETS_URL}/pyodide/shims/_internal_sense_hat.js`, + ); + importScripts(`${process.env.ASSETS_URL}/pyodide/shims/pygal.js`); importScripts("https://cdn.jsdelivr.net/pyodide/v0.26.2/full/pyodide.js"); const supportsAllFeatures = typeof SharedArrayBuffer !== "undefined"; @@ -164,7 +166,7 @@ const PyodideWorker = () => { before: async () => { pyodide.registerJsModule("basthon", fakeBasthonPackage); await pyodide.loadPackage( - `${process.env.ASSETS_URL}/packages/turtle-0.0.1-py3-none-any.whl`, + `${process.env.ASSETS_URL}/pyodide/packages/turtle-0.0.1-py3-none-any.whl`, ); }, after: () => @@ -182,7 +184,7 @@ const PyodideWorker = () => { pyodide.registerJsModule("basthon", fakeBasthonPackage); await pyodide.loadPackage([ "setuptools", - `${process.env.ASSETS_URL}/packages/p5-0.0.1-py3-none-any.whl`, + `${process.env.ASSETS_URL}/pyodide/packages/p5-0.0.1-py3-none-any.whl`, ]); }, after: () => {}, @@ -203,7 +205,7 @@ const PyodideWorker = () => { }); await pyodide.loadPackage([ "pillow", - `${process.env.ASSETS_URL}/packages/sense_hat-0.0.1-py3-none-any.whl`, + `${process.env.ASSETS_URL}/pyodide/packages/sense_hat-0.0.1-py3-none-any.whl`, ]); _internal_sense_hat.config.pyodide = pyodide; diff --git a/src/components/Editor/Runners/PythonRunner/PyodideRunner/PyodideRunner.jsx b/src/components/Editor/Runners/PythonRunner/PyodideRunner/PyodideRunner.jsx index be616094a..8bb232feb 100644 --- a/src/components/Editor/Runners/PythonRunner/PyodideRunner/PyodideRunner.jsx +++ b/src/components/Editor/Runners/PythonRunner/PyodideRunner/PyodideRunner.jsx @@ -1,6 +1,4 @@ -/* eslint import/no-webpack-loader-syntax: off */ /* eslint-disable react-hooks/exhaustive-deps */ - import "../../../../../assets/stylesheets/PythonRunner.scss"; import React, { useContext, useEffect, useMemo, useRef, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; @@ -20,27 +18,25 @@ import OutputViewToggle from "../OutputViewToggle"; import { SettingsContext } from "../../../../../utils/settings"; import RunnerControls from "../../../../RunButton/RunnerControls"; -const PyodideRunner = ({ active }) => { - const getWorkerURL = (url) => { - const content = ` - /* global PyodideWorker */ - console.log("Worker loading"); - importScripts("${url}"); - const pyodide = PyodideWorker(); - console.log("Worker loaded"); - `; - const blob = new Blob([content], { type: "application/javascript" }); - return URL.createObjectURL(blob); - }; +const getWorkerURL = (url) => { + const content = ` + /* global PyodideWorker */ + console.log("Worker loading"); + importScripts("${url}"); + const pyodide = PyodideWorker(); + console.log("Worker loaded"); + `; + const blob = new Blob([content], { type: "application/javascript" }); + return URL.createObjectURL(blob); +}; - const workerUrl = getWorkerURL(`${process.env.PUBLIC_URL}/PyodideWorker.js`); +const PyodideRunner = (props) => { + const { active } = props; + // Blob approach + targeted headers - no errors but headers required in host app to interrupt code + const workerUrl = getWorkerURL(`${process.env.PUBLIC_URL}/PyodideWorker.js`); const pyodideWorker = useMemo(() => new Worker(workerUrl), []); - if (!pyodideWorker) { - console.error("PyodideWorker is not initialized"); - } - const interruptBuffer = useRef(); const stdinBuffer = useRef(); const stdinClosed = useRef(); @@ -312,6 +308,11 @@ const PyodideRunner = ({ active }) => { } }; + if (!pyodideWorker) { + console.error("PyodideWorker is not initialized"); + return; + } + return (