pyodide.worker.ts 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import { loadPyodide, type PyodideInterface } from 'pyodide';
  2. declare global {
  3. interface Window {
  4. stdout: string | null;
  5. stderr: string | null;
  6. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  7. result: any;
  8. pyodide: PyodideInterface;
  9. packages: string[];
  10. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  11. [key: string]: any;
  12. }
  13. }
  14. async function loadPyodideAndPackages(packages: string[] = []) {
  15. self.stdout = null;
  16. self.stderr = null;
  17. self.result = null;
  18. self.pyodide = await loadPyodide({
  19. indexURL: '/pyodide/',
  20. stdout: (text) => {
  21. console.log('Python output:', text);
  22. if (self.stdout) {
  23. self.stdout += `${text}\n`;
  24. } else {
  25. self.stdout = `${text}\n`;
  26. }
  27. },
  28. stderr: (text) => {
  29. console.log('An error occurred:', text);
  30. if (self.stderr) {
  31. self.stderr += `${text}\n`;
  32. } else {
  33. self.stderr = `${text}\n`;
  34. }
  35. },
  36. packages: ['micropip']
  37. });
  38. const micropip = self.pyodide.pyimport('micropip');
  39. await micropip.set_index_urls('https://pypi.org/pypi/{package_name}/json');
  40. await micropip.install(packages);
  41. }
  42. self.onmessage = async (event) => {
  43. const { id, code, ...context } = event.data;
  44. console.log(event.data);
  45. // The worker copies the context in its own "memory" (an object mapping name to values)
  46. for (const key of Object.keys(context)) {
  47. self[key] = context[key];
  48. }
  49. // make sure loading is done
  50. await loadPyodideAndPackages(self.packages);
  51. try {
  52. self.result = await self.pyodide.runPythonAsync(code);
  53. } catch (error) {
  54. self.stderr = error.toString();
  55. }
  56. self.postMessage({ id, result: self.result, stdout: self.stdout, stderr: self.stderr });
  57. };
  58. export default {};