Root cause: cek_run_iterative (used by eval_expr/trampoline) raised "IO suspension in non-IO context" when the CEK hit a perform. This blocked IO suspension from propagating through nested eval_expr calls (event handler → trampoline → eval_expr → for-each callback → hs-wait). Fix: added _cek_io_suspend_hook (Sx_types) that converts CEK suspension to VmSuspended, set by sx_vm.ml at init. cek_run_iterative now calls the hook instead of erroring. The VmSuspended propagates to the value_to_js wrapper which has _driveAsync handling. +42 test passes (3924→3966), zero regressions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
59 KiB
59 KiB