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
+4 -6
View File
@@ -12,16 +12,14 @@ const { createWsStorage } = require('../../src/storage/ws');
const flush = (ms = 150) => new Promise(r => setTimeout(r, ms));
let nextPort = 5000 + Math.floor(Math.random() * 999);
async function makeStorage() {
const port = nextPort++;
const dbPath = path.join(os.tmpdir(), `ws-recon-${port}-${Date.now()}.sqlite`);
const handle = createServer({ dbPath, port });
const dbPath = path.join(os.tmpdir(), `ws-recon-${Date.now()}-${Math.random().toString(36).slice(2)}.sqlite`);
const handle = createServer({ dbPath, port: 0 });
await new Promise((resolve, reject) => {
handle.server.on('error', reject);
handle.server.listen(port, resolve);
handle.server.listen(0, resolve);
});
const port = handle.server.address().port;
const baseUrl = `http://127.0.0.1:${port}`;
const wsUrl = `ws://127.0.0.1:${port}/ws`;
const storage = createWsStorage({ baseUrl, wsUrl });