web / src /lib /workers /pyodide.worker.ts
github-actions[bot]
GitHub deploy: 96c865404d36637eafadb6d2dd2365c85d452648
8437908
raw
history blame
1.69 kB
import { loadPyodide, type PyodideInterface } from 'pyodide';
declare global {
interface Window {
stdout: string | null;
stderr: string | null;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
result: any;
pyodide: PyodideInterface;
packages: string[];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any;
}
}
async function loadPyodideAndPackages(packages: string[] = []) {
self.stdout = null;
self.stderr = null;
self.result = null;
self.pyodide = await loadPyodide({
indexURL: '/pyodide/',
stdout: (text) => {
console.log('Python output:', text);
if (self.stdout) {
self.stdout += `${text}\n`;
} else {
self.stdout = `${text}\n`;
}
},
stderr: (text) => {
console.log('An error occurred:', text);
if (self.stderr) {
self.stderr += `${text}\n`;
} else {
self.stderr = `${text}\n`;
}
},
packages: ['micropip']
});
const micropip = self.pyodide.pyimport('micropip');
// await micropip.set_index_urls('https://pypi.org/pypi/{package_name}/json');
await micropip.install(packages);
}
self.onmessage = async (event) => {
const { id, code, ...context } = event.data;
console.log(event.data);
// The worker copies the context in its own "memory" (an object mapping name to values)
for (const key of Object.keys(context)) {
self[key] = context[key];
}
// make sure loading is done
await loadPyodideAndPackages(self.packages);
try {
self.result = await self.pyodide.runPythonAsync(code);
} catch (error) {
self.stderr = error.toString();
}
self.postMessage({ id, result: self.result, stdout: self.stdout, stderr: self.stderr });
};
export default {};