fix(BUG-8): ws adapter auto-reconnect after drop

WS adapter had no reconnect. WS dies (idle/error/close) → wsReady=null,
subscribers dead forever, display frozen until full reload.

Changes (src/storage/ws.js):
- onClose: schedule reconnect via setTimeout(500ms), ensureWs re-arms.
  Guard: disposed flag stops reconnect after dispose.
- onOpen: resubscribe all existing doc/coll subscribers (backend state
  may have changed). Re-fetch current values on RECONNECT only (skip
  first connect — initial REST fetch in subscribe* already did). Added
  everConnected flag to distinguish first vs reconnect.
- reconnectTimer unref'd (Node) to avoid hanging event loop.
- dispose(cb): set disposed, clear timer, close ws, then cb.

Also fixed test teardown leaks:
- server/index.js close(): terminate all wss.clients before wss.close().
  Reconnect test spawned new ws to server; old close hung on live conn.
- both ws test factories: port 0 (OS picks free) instead of module-local
  nextPort counter. Parallel jest workers collided on EADDRINUSE.

Tests: ws-reconnect GREEN (1.7s), ws-contract 23 GREEN. No regression.
server suite 24/24. shared 90/90.
This commit is contained in:
david raistrick
2026-07-01 18:26:42 -04:00
parent afdd72e829
commit c1d982b4a4
5 changed files with 61 additions and 17 deletions
+1 -1
View File
@@ -183,7 +183,7 @@ REWORK_PLAN.md.
- [x] BUG-6: fixed structurally (1-list model)
- [x] BUG-12: fixed — campaign selection follows activeDisplay
- [x] BUG-15: fixed — DisplayView no longer re-sorts (drag order preserved)
- [ ] BUG-8: ws adapter reconnect
- [x] BUG-8: ws adapter reconnect (implemented + GREEN)
- [ ] BUG-10: deact+reactivate double-act
- [ ] BUG-11: FE Combat.scenario crash
- [ ] BUG-13: reorder cross-pointer semantics (RED + decide block/allow)