Skip to content

Commit bd56306

Browse files
authored
Create playground-runtime.js
1 parent c00686a commit bd56306

1 file changed

Lines changed: 109 additions & 0 deletions

File tree

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
(function () {
2+
'use strict';
3+
4+
var WALL_CLOCK_TIMEOUT_MS = 5000;
5+
var worker = null;
6+
var timeoutHandle = null;
7+
8+
function freshWorker() {
9+
if (worker) { try { worker.terminate(); } catch (e) {} }
10+
worker = new Worker('playground/worker.js', { type: 'module' });
11+
return worker;
12+
}
13+
14+
function setStatus(el, text, cls) {
15+
el.textContent = text;
16+
el.className = 'pg-status' + (cls ? ' ' + cls : '');
17+
}
18+
19+
function renderResult(outEl, statusEl, data) {
20+
clearTimeout(timeoutHandle);
21+
outEl.textContent = '';
22+
23+
if (data.__init_error) {
24+
setStatus(statusEl, 'Nie udało się załadować WASM: ' + data.__init_error, 'pg-status-err');
25+
return;
26+
}
27+
if (data.__panic) {
28+
setStatus(statusEl, 'Wewnętrzny błąd interpretera (panic): ' + data.__panic, 'pg-status-err');
29+
return;
30+
}
31+
32+
var r;
33+
try { r = JSON.parse(data.result); }
34+
catch (e) { setStatus(statusEl, 'Nieoczekiwana odpowiedź workera.', 'pg-status-err'); return; }
35+
36+
var lines = [];
37+
if (r.parse_errors && r.parse_errors.length) {
38+
r.parse_errors.forEach(function (d) { lines.push(d.message); });
39+
}
40+
if (r.type_errors && r.type_errors.length) {
41+
r.type_errors.forEach(function (d) { lines.push(d.message); });
42+
}
43+
if (r.stdout) lines.push(r.stdout.replace(/\n$/, ''));
44+
if (r.runtime_error) lines.push(r.runtime_error);
45+
46+
outEl.textContent = lines.join('\n') || '(brak wyjścia)';
47+
setStatus(statusEl, r.ok ? 'OK' : 'Błąd', r.ok ? 'pg-status-ok' : 'pg-status-err');
48+
}
49+
50+
function run(sourceEl, outEl, statusEl, runBtn) {
51+
var w = freshWorker();
52+
setStatus(statusEl, 'Uruchamianie…', '');
53+
outEl.textContent = '';
54+
runBtn.disabled = true;
55+
56+
var done = false;
57+
w.onmessage = function (ev) {
58+
done = true;
59+
runBtn.disabled = false;
60+
renderResult(outEl, statusEl, ev.data);
61+
};
62+
w.onerror = function (ev) {
63+
done = true;
64+
runBtn.disabled = false;
65+
clearTimeout(timeoutHandle);
66+
setStatus(statusEl, 'Błąd workera: ' + (ev.message || 'nieznany'), 'pg-status-err');
67+
};
68+
69+
timeoutHandle = setTimeout(function () {
70+
if (done) return;
71+
w.terminate();
72+
worker = null;
73+
runBtn.disabled = false;
74+
setStatus(statusEl, 'Przekroczono limit czasu (' + (WALL_CLOCK_TIMEOUT_MS / 1000) + 's) — program przerwany.', 'pg-status-err');
75+
}, WALL_CLOCK_TIMEOUT_MS);
76+
77+
w.postMessage({ source: sourceEl.value });
78+
}
79+
80+
function initPlayground() {
81+
var root = document.getElementById('pg-root');
82+
if (!root) return; // section not injected (yet, or at all) — nothing to wire up
83+
var sourceEl = document.getElementById('pg-source');
84+
var outEl = document.getElementById('pg-output');
85+
var statusEl = document.getElementById('pg-status');
86+
var runBtn = document.getElementById('pg-run');
87+
if (!sourceEl || !outEl || !statusEl || !runBtn) return;
88+
89+
runBtn.addEventListener('click', function () {
90+
run(sourceEl, outEl, statusEl, runBtn);
91+
});
92+
sourceEl.addEventListener('keydown', function (ev) {
93+
if ((ev.ctrlKey || ev.metaKey) && ev.key === 'Enter') {
94+
ev.preventDefault();
95+
run(sourceEl, outEl, statusEl, runBtn);
96+
}
97+
});
98+
}
99+
100+
// The playground section's HTML is injected asynchronously by
101+
// script.js's injectSections() — wait for that instead of
102+
// DOMContentLoaded, since #pg-root won't exist yet at that point.
103+
var tries = 0;
104+
(function waitForSection() {
105+
if (document.getElementById('pg-root')) { initPlayground(); return; }
106+
if (++tries > 100) return; // ~5s — give up quietly, section may not be on this page
107+
setTimeout(waitForSection, 50);
108+
})();
109+
})();

0 commit comments

Comments
 (0)