lumbda/wasm/repl
russell@unturf.com 63808f72a5
repl: fix cancel + immediate-resubmit race that wedged the new eval
Three converging bugs let a cancel-then-send sequence land in a
broken state:

1) cancelAllPendingInActiveTab didn't touch the toolbar — the user
   had to wait for the cancelled promise's .catch.then to drain
   before send re-enabled. fox saw clicks register as noops because
   the button was still disabled.

2) Even after the rejection settled, the stale .then path
   re-enabled sendBtn from inside the FIRST run's closure — but by
   then the user had already submitted a SECOND run that set
   sendBtn disabled. The stale .then clobbered the in-flight state.

3) The OLD worker's last-queued "done" or "error" message could be
   delivered after a fresh run had already taken state.pending[k];
   the OLD handler would then delete the NEW run's pending entry.

Fixes:

* cancel handler now re-enables send / disables cancel + pause
  synchronously and clears tab.activeInput.
* The completion .then re-checks isEvalInFlight(tab) before resetting
  toolbar state, so a stale settle from a cancelled run can't
  override the fresh run's UI.
* evalInTier's done/error handler only deletes state.pending[k] when
  the entry still has the runId we started with.

Verified headlessly: long loop → cancel → submit (+ 1 2) immediately
→ first entry shows error: cancelled, second entry shows result 3,
send re-enabled.
2026-06-15 14:11:55 -04:00
..
crypto.js repl: /repl/ page with encrypted multi-tab sessions 2026-06-14 12:50:35 -04:00
index.html repl: ⏸ pause button — manual snapshot mid-eval without leaving the tab 2026-06-15 11:20:57 -04:00
repl.css repl: ⏸ pause button — manual snapshot mid-eval without leaving the tab 2026-06-15 11:20:57 -04:00
repl.js repl: fix cancel + immediate-resubmit race that wedged the new eval 2026-06-15 14:11:55 -04:00