Skip to content

Commit 89af5b8

Browse files
Feat: Add workers for demo.
1 parent 8d9fd68 commit 89af5b8

2 files changed

Lines changed: 54 additions & 39 deletions

File tree

demo/main.js

Lines changed: 24 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -85,56 +85,41 @@ const jar = CodeJar(ed, (editor) => {
8585
addClosing: false,
8686
});
8787

88-
let wasm;
89-
9088
const fmt = (ms) => ms < 1000 ? `${ms.toFixed(0)}ms` : `${(ms / 1000).toFixed(2)}s`;
9189
const setStatus = (text, cls = CLS.ok) => (statusEl.textContent = text, statusEl.className = cls);
92-
const time = async (fn) => { const t0 = performance.now(); const r = await fn(); return [r, fmt(performance.now() - t0)]; };
93-
94-
const instantiate = async (url) => {
95-
const res = await fetch(url, FETCH_OPTS);
96-
if (!res.ok) throw new Error(`${url}: HTTP ${res.status}`);
97-
try {
98-
return await WebAssembly.instantiateStreaming(res, {});
99-
} catch {
100-
return WebAssembly.instantiate(await (await fetch(url, FETCH_OPTS)).arrayBuffer(), {});
101-
}
102-
};
10390

104-
const loadWasm = async () => {
91+
const worker = new Worker('./worker.js');
92+
93+
const loadWasm = () => {
10594
setStatus('Loading WASM...', CLS.ok);
106-
try {
107-
const [{ instance }, t] = await time(() => Promise.any(WASM_SOURCES.map(instantiate)));
108-
wasm = instance.exports;
109-
btn.disabled = false;
110-
setStatus(`Ready (${t}${DEV ? ' · Dev' : ''})`);
111-
} catch (err) {
112-
setStatus('Load failed', CLS.err);
113-
term.textContent = `Could not load WASM.\n\n${err.errors.map(e => e.message).join(' | ')}`;
114-
}
95+
worker.postMessage({
96+
type: 'load',
97+
url: WASM_SOURCES[0],
98+
opts: FETCH_OPTS ?? {},
99+
});
115100
};
116101

117-
const runCode = async () => {
118-
if (!wasm) return;
119-
const srcBytes = new TextEncoder().encode(jar.toString());
120-
if (srcBytes.length > SZ) return void (term.textContent = `Error: Source exceeds ${SZ} bytes`);
121-
102+
const runCode = () => {
122103
setStatus('Running...', CLS.ok);
123104
btn.disabled = true;
105+
worker.postMessage({ type: 'run', src: jar.toString() });
106+
};
124107

125-
await new Promise(r => requestAnimationFrame(() => requestAnimationFrame(r)));
126-
127-
const [out, t] = await time(() => {
128-
new Uint8Array(wasm.memory.buffer).set(srcBytes, wasm.src_ptr());
129-
const len = wasm.run(srcBytes.length);
130-
return new TextDecoder().decode(new Uint8Array(wasm.memory.buffer, wasm.out_ptr(), len));
131-
});
132-
133-
term.textContent = out;
134-
setStatus(`Ready (${t})`);
135-
btn.disabled = false;
108+
worker.onmessage = ({ data }) => {
109+
if (data.type === 'ready') {
110+
btn.disabled = false;
111+
setStatus(`Ready (${fmt(data.ms)}${DEV ? ' · Dev' : ''})`);
112+
} else if (data.type === 'result') {
113+
term.textContent = data.out;
114+
setStatus(`Ready (${fmt(data.ms)})`);
115+
btn.disabled = false;
116+
} else if (data.type === 'error') {
117+
setStatus('Load failed', CLS.err);
118+
term.textContent = `Could not load WASM.\n\n${data.message}`;
119+
}
136120
};
137121

122+
138123
const sync = () => {
139124
const text = jar.toString().replace(/\n$/, '');
140125
const n = Math.max(1, Math.min(text.split('\n').length, MAX_LINES));

demo/worker.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
const SZ = 1 << 20;
2+
let wasm;
3+
4+
self.onmessage = async ({ data }) => {
5+
if (data.type === 'load') {
6+
try {
7+
const res = await fetch(data.url, data.opts);
8+
const t0 = performance.now();
9+
const { instance } = await WebAssembly.instantiateStreaming(res, {});
10+
wasm = instance.exports;
11+
const ms = performance.now() - t0;
12+
self.postMessage({ type: 'ready', ms });
13+
} catch (err) {
14+
self.postMessage({ type: 'error', message: err.message });
15+
}
16+
17+
} else if (data.type === 'run') {
18+
const srcBytes = new TextEncoder().encode(data.src);
19+
if (srcBytes.length > SZ) {
20+
self.postMessage({ type: 'result', out: `Error: Source exceeds ${SZ} bytes` });
21+
return;
22+
}
23+
new Uint8Array(wasm.memory.buffer).set(srcBytes, wasm.src_ptr());
24+
const t0 = performance.now();
25+
const len = wasm.run(srcBytes.length);
26+
const ms = performance.now() - t0;
27+
const out = new TextDecoder().decode(new Uint8Array(wasm.memory.buffer, wasm.out_ptr(), len));
28+
self.postMessage({ type: 'result', out, ms });
29+
}
30+
};

0 commit comments

Comments
 (0)