@camstack/server 1.1.23 → 1.1.24

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.
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildHubHealth = buildHubHealth;
3
4
  exports.registerHealthRoutes = registerHealthRoutes;
4
5
  const AGENT_HEALTH_TIMEOUT_MS = 3_000;
5
6
  function nowIso() {
@@ -8,8 +9,9 @@ function nowIso() {
8
9
  async function buildHubHealth(deps, proc = process) {
9
10
  const nodes = await deps.agentRegistry.listNodes();
10
11
  const remote = nodes.filter((n) => !n.isHub);
11
- const online = remote.filter((n) => n.isOnline !== false).length;
12
+ const offlineNodes = remote.filter((n) => n.isOnline === false);
12
13
  const total = remote.length;
14
+ const online = total - offlineNodes.length;
13
15
  const memUsage = proc.memoryUsage();
14
16
  const totalMem = memUsage.heapTotal + memUsage.external + memUsage.arrayBuffers;
15
17
  const memoryPercent = totalMem > 0 ? Math.round((memUsage.heapUsed / totalMem) * 100) : 0;
@@ -19,7 +21,14 @@ async function buildHubHealth(deps, proc = process) {
19
21
  version: deps.hubVersion,
20
22
  uptimeSeconds: Math.round(proc.uptime()),
21
23
  pid: proc.pid,
22
- agents: { total, online, offline: total - online },
24
+ agents: {
25
+ total,
26
+ online,
27
+ offline: offlineNodes.length,
28
+ // Named so health consumers (admin-ui connection banner) can say
29
+ // WHICH node is degraded, not only how many.
30
+ offlineIds: offlineNodes.map((n) => n.info.id),
31
+ },
23
32
  cpuPercent: 0,
24
33
  memoryPercent,
25
34
  checkedAt: nowIso(),
@@ -55,6 +55,21 @@ function requireDeviceScoped(registry, capName) {
55
55
  }
56
56
  const native = registry.getNativeProvider(capName, deviceId);
57
57
  if (!native) {
58
+ // No native provider. For `getStatus`, the device may still have a
59
+ // SYNTHESIZED status from device-links (battery/consumables wired
60
+ // from sibling sensors). Consult the resolver with a null base
61
+ // (the synthesize path) before failing — it returns null when the
62
+ // device has no links for this cap, preserving today's error.
63
+ if (prop === 'getStatus') {
64
+ const deviceManager = registry.getSingleton('device-manager');
65
+ const synthesized = await deviceManager?.resolveLinkedStatus?.({
66
+ deviceId,
67
+ cap: String(capName),
68
+ baseStatus: null,
69
+ });
70
+ if (synthesized != null)
71
+ return synthesized;
72
+ }
58
73
  throw new server_1.TRPCError({
59
74
  code: 'PRECONDITION_FAILED',
60
75
  message: `Capability "${String(capName)}" not registered for device ${deviceId}`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/server",
3
- "version": "1.1.23",
3
+ "version": "1.1.24",
4
4
  "private": false,
5
5
  "files": [
6
6
  "dist",