Skip to content

Commit 5c4062c

Browse files
committed
refac
1 parent cb7154c commit 5c4062c

3 files changed

Lines changed: 73 additions & 21 deletions

File tree

src/lib/components/chat/Messages/CodeBlock.svelte

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import hljs from 'highlight.js';
33
import { toast } from 'svelte-sonner';
44
import { getContext, onMount, tick, onDestroy } from 'svelte';
5-
import { config } from '$lib/stores';
5+
import { config, pyodideWorker as pyodideWorkerStore } from '$lib/stores';
66
77
import PyodideWorker from '$lib/workers/pyodide.worker?worker';
88
import { executeCode } from '$lib/apis/utils';
@@ -47,7 +47,7 @@
4747
export let editorClassName = '';
4848
export let stickyButtonsClassName = 'top-0';
4949
50-
let pyodideWorker = null;
50+
let localPyodideWorker = null;
5151
5252
let _code = '';
5353
$: if (code) {
@@ -237,27 +237,42 @@
237237
238238
console.log(packages);
239239
240-
pyodideWorker = new PyodideWorker();
240+
// Reuse the shared Pyodide worker when code interpreter is active,
241+
// so files written here are immediately visible in PyodideFileNav.
242+
// Otherwise fall back to a throwaway worker.
243+
const sharedWorker = $pyodideWorkerStore;
244+
const isShared = !!sharedWorker;
245+
const worker = sharedWorker ?? new PyodideWorker();
241246
242-
pyodideWorker.postMessage({
247+
if (!isShared) {
248+
localPyodideWorker = worker;
249+
}
250+
251+
worker.postMessage({
243252
id: id,
244253
code: code,
245254
packages: packages
246255
});
247256
248-
setTimeout(() => {
257+
const timeoutId = setTimeout(() => {
249258
if (executing) {
250259
executing = false;
251260
stderr = 'Execution Time Limit Exceeded';
252-
pyodideWorker.terminate();
261+
if (!isShared) {
262+
worker.terminate();
263+
localPyodideWorker = null;
264+
}
253265
}
254266
}, 60000);
255267
256-
pyodideWorker.onmessage = (event) => {
268+
const handler = (event) => {
269+
// Ignore messages from other requests on the shared worker
270+
if (event.data?.id !== id) return;
271+
257272
console.log('pyodideWorker.onmessage', event);
258-
const { id, ...data } = event.data;
273+
const { id: _id, ...data } = event.data;
259274
260-
console.log(id, data);
275+
console.log(_id, data);
261276
262277
if (data['stdout']) {
263278
stdout = data['stdout'];
@@ -320,11 +335,20 @@
320335
data['stderr'] && (stderr = data['stderr']);
321336
data['result'] && (result = data['result']);
322337
338+
clearTimeout(timeoutId);
339+
worker.removeEventListener('message', handler);
323340
executing = false;
341+
342+
// Signal PyodideFileNav to auto-refresh after execution
343+
window.dispatchEvent(new Event('pyodide:files'));
324344
};
325345
326-
pyodideWorker.onerror = (event) => {
346+
worker.addEventListener('message', handler);
347+
348+
worker.onerror = (event) => {
327349
console.log('pyodideWorker.onerror', event);
350+
clearTimeout(timeoutId);
351+
worker.removeEventListener('message', handler);
328352
executing = false;
329353
};
330354
};
@@ -412,8 +436,9 @@
412436
});
413437
414438
onDestroy(() => {
415-
if (pyodideWorker) {
416-
pyodideWorker.terminate();
439+
if (localPyodideWorker) {
440+
localPyodideWorker.terminate();
441+
localPyodideWorker = null;
417442
}
418443
});
419444
</script>

src/lib/components/chat/PyodideFileNav.svelte

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
</script>
44

55
<script lang="ts">
6-
import { getContext, onMount, tick } from 'svelte';
6+
import { getContext, onMount, onDestroy, tick } from 'svelte';
77
import { pyodideWorker } from '$lib/stores';
88
import PyodideWorkerConstructor from '$lib/workers/pyodide.worker?worker';
99
import type { FileEntry } from '$lib/apis/terminal';
@@ -282,9 +282,21 @@
282282
283283
// ── Lifecycle ─────────────────────────────────────────────────────────
284284
285+
const onFilesChanged = async () => {
286+
try {
287+
await sendWorkerMessage({ type: 'fs:sync' });
288+
} catch {}
289+
loadDir(currentPath);
290+
};
291+
285292
onMount(() => {
286293
ensureWorker();
287294
loadDir(currentPath);
295+
window.addEventListener('pyodide:files', onFilesChanged);
296+
});
297+
298+
onDestroy(() => {
299+
window.removeEventListener('pyodide:files', onFilesChanged);
288300
});
289301
</script>
290302

@@ -335,14 +347,18 @@
335347
{selectedFile}
336348
{loading}
337349
onNavigate={(path) => loadDir(path)}
338-
onRefresh={() => {
339-
if (selectedFile) {
340-
const name = selectedFile.split('/').pop() ?? '';
341-
openEntry({ name, type: 'file', size: 0 });
342-
} else {
343-
loadDir(currentPath);
344-
}
345-
}}
350+
onRefresh={async () => {
351+
// Sync from IndexedDB first to pick up files written by code execution
352+
try {
353+
await sendWorkerMessage({ type: 'fs:sync' });
354+
} catch {}
355+
if (selectedFile) {
356+
const name = selectedFile.split('/').pop() ?? '';
357+
openEntry({ name, type: 'file', size: 0 });
358+
} else {
359+
loadDir(currentPath);
360+
}
361+
}}
346362
onNewFolder={startNewFolder}
347363
onNewFile={startNewFile}
348364
onUploadFiles={uploadFiles}

src/lib/workers/pyodide.worker.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,17 @@ self.onmessage = async (event) => {
305305
break;
306306
}
307307

308+
case 'fs:sync': {
309+
// Re-read from IndexedDB into memory to pick up externally written files
310+
(self.pyodide.FS as any).syncfs(true, (err: Error | null) => {
311+
if (err) {
312+
console.error('Error syncing from IndexedDB:', err);
313+
}
314+
self.postMessage({ id, type: 'fs:sync', success: !err });
315+
});
316+
break;
317+
}
318+
308319
default:
309320
console.warn('Unknown message type:', type);
310321
}

0 commit comments

Comments
 (0)