This commit is contained in:
Timothy Jaeryang Baek
2026-03-24 16:20:29 -05:00
parent cb7154cedf
commit 5c4062c648
3 changed files with 74 additions and 22 deletions
@@ -2,7 +2,7 @@
import hljs from 'highlight.js';
import { toast } from 'svelte-sonner';
import { getContext, onMount, tick, onDestroy } from 'svelte';
import { config } from '$lib/stores';
import { config, pyodideWorker as pyodideWorkerStore } from '$lib/stores';
import PyodideWorker from '$lib/workers/pyodide.worker?worker';
import { executeCode } from '$lib/apis/utils';
@@ -47,7 +47,7 @@
export let editorClassName = '';
export let stickyButtonsClassName = 'top-0';
let pyodideWorker = null;
let localPyodideWorker = null;
let _code = '';
$: if (code) {
@@ -237,27 +237,42 @@
console.log(packages);
pyodideWorker = new PyodideWorker();
// Reuse the shared Pyodide worker when code interpreter is active,
// so files written here are immediately visible in PyodideFileNav.
// Otherwise fall back to a throwaway worker.
const sharedWorker = $pyodideWorkerStore;
const isShared = !!sharedWorker;
const worker = sharedWorker ?? new PyodideWorker();
pyodideWorker.postMessage({
if (!isShared) {
localPyodideWorker = worker;
}
worker.postMessage({
id: id,
code: code,
packages: packages
});
setTimeout(() => {
const timeoutId = setTimeout(() => {
if (executing) {
executing = false;
stderr = 'Execution Time Limit Exceeded';
pyodideWorker.terminate();
if (!isShared) {
worker.terminate();
localPyodideWorker = null;
}
}
}, 60000);
pyodideWorker.onmessage = (event) => {
console.log('pyodideWorker.onmessage', event);
const { id, ...data } = event.data;
const handler = (event) => {
// Ignore messages from other requests on the shared worker
if (event.data?.id !== id) return;
console.log(id, data);
console.log('pyodideWorker.onmessage', event);
const { id: _id, ...data } = event.data;
console.log(_id, data);
if (data['stdout']) {
stdout = data['stdout'];
@@ -320,11 +335,20 @@
data['stderr'] && (stderr = data['stderr']);
data['result'] && (result = data['result']);
clearTimeout(timeoutId);
worker.removeEventListener('message', handler);
executing = false;
// Signal PyodideFileNav to auto-refresh after execution
window.dispatchEvent(new Event('pyodide:files'));
};
pyodideWorker.onerror = (event) => {
worker.addEventListener('message', handler);
worker.onerror = (event) => {
console.log('pyodideWorker.onerror', event);
clearTimeout(timeoutId);
worker.removeEventListener('message', handler);
executing = false;
};
};
@@ -412,8 +436,9 @@
});
onDestroy(() => {
if (pyodideWorker) {
pyodideWorker.terminate();
if (localPyodideWorker) {
localPyodideWorker.terminate();
localPyodideWorker = null;
}
});
</script>
+25 -9
View File
@@ -3,7 +3,7 @@
</script>
<script lang="ts">
import { getContext, onMount, tick } from 'svelte';
import { getContext, onMount, onDestroy, tick } from 'svelte';
import { pyodideWorker } from '$lib/stores';
import PyodideWorkerConstructor from '$lib/workers/pyodide.worker?worker';
import type { FileEntry } from '$lib/apis/terminal';
@@ -282,9 +282,21 @@
// ── Lifecycle ─────────────────────────────────────────────────────────
const onFilesChanged = async () => {
try {
await sendWorkerMessage({ type: 'fs:sync' });
} catch {}
loadDir(currentPath);
};
onMount(() => {
ensureWorker();
loadDir(currentPath);
window.addEventListener('pyodide:files', onFilesChanged);
});
onDestroy(() => {
window.removeEventListener('pyodide:files', onFilesChanged);
});
</script>
@@ -335,14 +347,18 @@
{selectedFile}
{loading}
onNavigate={(path) => loadDir(path)}
onRefresh={() => {
if (selectedFile) {
const name = selectedFile.split('/').pop() ?? '';
openEntry({ name, type: 'file', size: 0 });
} else {
loadDir(currentPath);
}
}}
onRefresh={async () => {
// Sync from IndexedDB first to pick up files written by code execution
try {
await sendWorkerMessage({ type: 'fs:sync' });
} catch {}
if (selectedFile) {
const name = selectedFile.split('/').pop() ?? '';
openEntry({ name, type: 'file', size: 0 });
} else {
loadDir(currentPath);
}
}}
onNewFolder={startNewFolder}
onNewFile={startNewFile}
onUploadFiles={uploadFiles}
+11
View File
@@ -305,6 +305,17 @@ self.onmessage = async (event) => {
break;
}
case 'fs:sync': {
// Re-read from IndexedDB into memory to pick up externally written files
(self.pyodide.FS as any).syncfs(true, (err: Error | null) => {
if (err) {
console.error('Error syncing from IndexedDB:', err);
}
self.postMessage({ id, type: 'fs:sync', success: !err });
});
break;
}
default:
console.warn('Unknown message type:', type);
}