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.
server/tests/ws-reconnect.test.js: subscribe, write (fires), force-drop WS,
write again (must still fire). RED on current. wsReady=null after drop,
no reconnect, subscribers dead forever. Display frozen.
src/storage/ws.js: added _test accessor (getWs, forceDrop, getReady,
docSubs, collSubs) for reconnect test. Test-only, no behavior change.
TODO: BUG-7 (reorder no undo), BUG-8 (ws reconnect) added.