lumbda/wasm/dist-repl/worker.mjs
russell@unturf.com d8ffab5ea6
repl: /repl/ page with encrypted multi-tab sessions
Interactive REPL at lumbda.com/repl with:
  - multi-tab sessions (click + to add, × to close, double-click to rename)
  - per-tab tier selector (python/c/asm/all-three race)
  - persistent transcripts encrypted in localStorage via Web Crypto
    (PBKDF2 + AES-GCM, vault id = SHA-256(password || device-salt) —
    same pattern as unsandbox's vault-encryption-design.md, native
    crypto.subtle API instead of CryptoJS)
  - ephemeral mode (skip vault, transcripts vanish on reload)
  - one worker per (tab × tier) — state persists across evals in a tab
  - reboot tier button (terminate this tab's worker, fresh state next eval)
  - cancel button (kills the running worker in active tab)

Home page now links to both /playground/ and /repl/.

Tier state itself does NOT persist across reloads — the transcript does,
but defines/set!/hash-tables vanish with the worker. Portal save/resume
in WAT (deferred) will let a tier session survive close+reopen.
2026-06-14 12:50:35 -04:00

19 lines
734 B
JavaScript

// wasm/app/worker.mjs
// Tier-evaluation Web Worker. Keeps the main thread responsive so the
// live ms counter actually ticks AND so cancel works (main thread
// terminates this worker via worker.terminate()).
import { evalOnTier } from "./runner.js";
self.onmessage = async (e) => {
const { kind, runId, tier, src } = e.data;
if (kind !== "eval") return;
try {
const output = await evalOnTier(tier, src, (loadingTier) => {
self.postMessage({ kind: "loading", runId, tier: loadingTier });
});
self.postMessage({ kind: "done", runId, output });
} catch (err) {
self.postMessage({ kind: "error", runId, message: err && err.message ? err.message : String(err) });
}
};