Live exit watchers keep the event loop alive (Node active-handle
semantics: a child process is a ref’d handle — await proc.exited must
park the loop until the child is reaped, exactly like a pending timer).
Called from timers::drain_and_check’s loop-alive verdict.
Drive every live Bun.spawn exit watcher on the JS thread. Called from
timers::drain_and_check / drain_one_pass — the same integration point
as cluster_pump_all. For each watched pid whose exit info is published
(reaped + pipes drained), invokes the registered JS finish callback
exactly once with (exitCode, signal) and drops the watch.