@nockdev/hsa 1.2.2 → 1.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dashboard.html +37 -4
  2. package/package.json +1 -1
package/dashboard.html CHANGED
@@ -1491,6 +1491,11 @@
1491
1491
  let selectedIde = "";
1492
1492
  let selectedProject = "";
1493
1493
  let sessionSSERetryMs = 1000;
1494
+ let sessionSSERetryCount = 0;
1495
+ const MAX_SSE_RETRIES = 5;
1496
+ let fetchErrorCount = 0;
1497
+ const BASE_REFRESH_MS = 5000;
1498
+ const MAX_REFRESH_MS = 30000;
1494
1499
 
1495
1500
  document.getElementById("endpointInput").value = endpoint;
1496
1501
 
@@ -1503,8 +1508,11 @@
1503
1508
  .value.replace(/\/$/, "");
1504
1509
  localStorage.setItem("hsa_endpoint", endpoint);
1505
1510
  setStatus("connecting");
1511
+ fetchErrorCount = 0; // Reset error counter on manual connect
1512
+ sessionSSERetryCount = 0; // Reset SSE retries so reconnect works
1506
1513
  fetchDashboard();
1507
1514
  fetchSessions();
1515
+ connectSessionSSE(); // Re-establish SSE stream
1508
1516
  }
1509
1517
 
1510
1518
  function setStatus(status) {
@@ -1518,7 +1526,7 @@
1518
1526
  const badge = document.getElementById("refreshBadge");
1519
1527
  if (autoRefresh) {
1520
1528
  btn.classList.add("active");
1521
- badge.textContent = "5s";
1529
+ updateRefreshBadge(badge);
1522
1530
  startRefresh();
1523
1531
  } else {
1524
1532
  btn.classList.remove("active");
@@ -1528,10 +1536,14 @@
1528
1536
  }
1529
1537
  function startRefresh() {
1530
1538
  stopRefresh();
1539
+ const interval = Math.min(
1540
+ BASE_REFRESH_MS * Math.pow(2, fetchErrorCount),
1541
+ MAX_REFRESH_MS,
1542
+ );
1531
1543
  refreshInterval = setInterval(() => {
1532
1544
  fetchDashboard();
1533
1545
  fetchSessions();
1534
- }, 5000);
1546
+ }, interval);
1535
1547
  }
1536
1548
  function stopRefresh() {
1537
1549
  if (refreshInterval) {
@@ -1539,6 +1551,15 @@
1539
1551
  refreshInterval = null;
1540
1552
  }
1541
1553
  }
1554
+ function adjustRefreshInterval() {
1555
+ if (!autoRefresh) return;
1556
+ updateRefreshBadge(document.getElementById("refreshBadge"));
1557
+ startRefresh();
1558
+ }
1559
+ function updateRefreshBadge(badge) {
1560
+ const ms = Math.min(BASE_REFRESH_MS * Math.pow(2, fetchErrorCount), MAX_REFRESH_MS);
1561
+ badge.textContent = ms >= 1000 ? (ms / 1000) + "s" : ms + "ms";
1562
+ }
1542
1563
 
1543
1564
  /* ================================================================
1544
1565
  CONTEXT SELECTORS
@@ -1599,13 +1620,19 @@
1599
1620
  try {
1600
1621
  let url = endpoint + "/api/dashboard";
1601
1622
  // Note: /api/dashboard doesn't support session filtering yet, handled client-side
1602
- const res = await fetch(url, { signal: AbortSignal.timeout(8000) });
1623
+ const res = await fetch(url, { signal: AbortSignal.timeout(15000) });
1603
1624
  if (!res.ok) throw new Error("HTTP " + res.status);
1604
1625
  const data = await res.json();
1605
1626
  setStatus("connected");
1627
+ if (fetchErrorCount > 0) {
1628
+ fetchErrorCount = 0;
1629
+ adjustRefreshInterval();
1630
+ }
1606
1631
  render(data);
1607
1632
  } catch (err) {
1608
1633
  setStatus("error");
1634
+ fetchErrorCount++;
1635
+ adjustRefreshInterval();
1609
1636
  console.warn("HSA fetch error:", err.message);
1610
1637
  }
1611
1638
  }
@@ -2212,6 +2239,10 @@
2212
2239
  }
2213
2240
 
2214
2241
  function connectSessionSSE() {
2242
+ if (sessionSSERetryCount >= MAX_SSE_RETRIES) {
2243
+ console.warn("SSE: Max retries reached, stopping session stream reconnect");
2244
+ return;
2245
+ }
2215
2246
  if (sessionSSE) {
2216
2247
  sessionSSE.close();
2217
2248
  sessionSSE = null;
@@ -2230,10 +2261,11 @@
2230
2261
  }
2231
2262
  } catch {}
2232
2263
  };
2233
- // FE-02: Auto-reconnect with exponential backoff
2264
+ // FE-02: Auto-reconnect with exponential backoff + max retry cap
2234
2265
  sessionSSE.onerror = () => {
2235
2266
  sessionSSE.close();
2236
2267
  sessionSSE = null;
2268
+ sessionSSERetryCount++;
2237
2269
  setTimeout(() => {
2238
2270
  connectSessionSSE();
2239
2271
  sessionSSERetryMs = Math.min(sessionSSERetryMs * 2, 30000);
@@ -2241,6 +2273,7 @@
2241
2273
  };
2242
2274
  sessionSSE.onopen = () => {
2243
2275
  sessionSSERetryMs = 1000;
2276
+ sessionSSERetryCount = 0;
2244
2277
  };
2245
2278
  } catch {}
2246
2279
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nockdev/hsa",
3
- "version": "1.2.2",
3
+ "version": "1.2.4",
4
4
  "description": "HSA - Hierarchical Semantic Analysis MCP Server for AI Code Agents",
5
5
  "type": "module",
6
6
  "main": "dist/hsa-lib.bundle.js",