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. |
||
|---|---|---|
| .. | ||
| crypto.js | ||
| index.html | ||
| repl.css | ||
| repl.js | ||