Skip to content

Commit 3f10d70

Browse files
committed
Added a long-living Worker example
1 parent 1c6d287 commit 3f10d70

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed

test/worker-eval.html

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Polyscript Long Running Worker</title>
7+
8+
<!-- this is the setup module script to expose long running Worker -->
9+
<script type="module">
10+
// grab utilities to bootstrap a Worker out of the blue
11+
import { Hook, XWorker } from 'https://cdn.jsdelivr.net/npm/polyscript';
12+
13+
const runtimeURL = URL.createObjectURL(new Blob(['']));
14+
15+
// instrument the XWorker context
16+
const xworker = XWorker.call(
17+
new Hook(null, {
18+
worker: {
19+
// setup the I/O + expose runAsync + init on main
20+
onReady: ({ runAsync, io }, { sync }) => {
21+
io.stdout = line => sync.stdout(line);
22+
io.stderr = line => sync.stderr(line);
23+
// from main any callback is async anyway
24+
// this is why either run or runAsync would do the same
25+
sync.runAsync = runAsync;
26+
sync.init();
27+
},
28+
},
29+
}),
30+
31+
// the "fake" URL to use as worker script
32+
runtimeURL,
33+
34+
// either pyodide or micropython
35+
{ type: 'pyodide' }
36+
);
37+
38+
// once resolved everything is ready to work
39+
const { promise, resolve } = Promise.withResolvers();
40+
41+
// expose utilities for I/O and cleanup + resolver
42+
const { sync } = xworker;
43+
sync.stdout = console.log;
44+
sync.stderr = console.error;
45+
sync.init = () => {
46+
// drop the URL as it's not needed anymore
47+
URL.revokeObjectURL(runtimeURL);
48+
// expose the proxied/bridge `runAsync` utility
49+
// as callback to await for results
50+
resolve(code => sync.runAsync(code));
51+
};
52+
53+
// define some "not so obtrusive" global entrypoint
54+
// or dispatch an event once the worker is ready
55+
globalThis[Symbol.for('pyodide-worker')] = promise;
56+
</script>
57+
58+
<!-- this is any other script on the page -->
59+
<script type="module">
60+
const runPython = code => globalThis[Symbol.for('pyodide-worker')].then(
61+
runAsync => runAsync(code)
62+
);
63+
64+
document.getElementById('sum').addEventListener(
65+
'click',
66+
async event => {
67+
event.preventDefault();
68+
const { currentTarget } = event;
69+
const result = await runPython(currentTarget.textContent);
70+
currentTarget.textContent += ` + ${result}`;
71+
document.getElementById('result').textContent = result;
72+
}
73+
);
74+
</script>
75+
</head>
76+
<body>
77+
<button id="sum">2 + 3</button>
78+
<pre id="result"></button>
79+
</body>
80+
</html>

0 commit comments

Comments
 (0)