refactor(web): NodesPage reads node list from SDK signals

First consumer migration off the legacy Zustand nodeDBStore onto
SDK-managed nodes. Pages/Nodes/index.tsx now pulls the full node array
through useNodesLegacy() — which subscribes to the SDK NodesClient
signal underneath — and applies the existing nodeFilter predicate
client-side via useMemo.

Behavior parity:
- Same Protobuf.Mesh.NodeInfo shape rendered in the table (the legacy
  adapter ensures channel / viaMqtt / hopsAway / publicKey survive).
- Same debounce semantics — only the underlying source changed.
- hasNodeError + nodeErrors continue to come from the Zustand
  nodeDBStore until PKI-error tracking is migrated to the SDK in a
  follow-up commit (validation logic still in
  packages/web/src/core/stores/nodeDBStore/nodeValidation.ts).

The legacy nodeDBStore still populates from subscriptions.ts, so this
rewrite is reversible and runs alongside the SDK source. Web tests
(295) still green; production Vite build clean.
This commit is contained in:
Dan Ditomaso
2026-04-25 21:03:52 -04:00
parent 17ca853597
commit c7db122ee8

View File

@@ -10,11 +10,12 @@ import { Sidebar } from "@components/Sidebar.tsx";
import { Avatar } from "@components/UI/Avatar.tsx";
import { Input } from "@components/UI/Input.tsx";
import useLang from "@core/hooks/useLang.ts";
import { useNodesLegacy } from "@core/hooks/useNodesLegacy.ts";
import { useAppStore, useDevice, useNodeDB } from "@core/stores";
import { Protobuf, type Types } from "@meshtastic/sdk";
import { numberToHexUnpadded } from "@noble/curves/abstract/utils";
import { LockIcon, LockOpenIcon } from "lucide-react";
import { type JSX, useCallback, useDeferredValue, useEffect, useState } from "react";
import { type JSX, useCallback, useDeferredValue, useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { base16 } from "rfc4648";
@@ -49,12 +50,15 @@ const NodesPage = (): JSX.Element => {
[nodeFilter, deferredFilterState],
);
// subscribe to actual data (nodes array) and to nodeErrors ref for badge updates
const { nodes: filteredNodes, hasNodeError } = useNodeDB(
// Nodes come from the SDK NodesClient (signals + sqlocal-backed history).
// hasNodeError still lives on the legacy nodeDB store — node-validation /
// PKI-error tracking has not been migrated to the SDK yet.
const allSdkNodes = useNodesLegacy();
const filteredNodes = useMemo(() => allSdkNodes.filter(predicate), [allSdkNodes, predicate]);
const { hasNodeError } = useNodeDB(
(db) => ({
nodes: db.getNodes(predicate, true),
hasNodeError: db.hasNodeError,
_errorsRef: db.nodeErrors, // include the Map ref so UI also re-renders on error changes
_errorsRef: db.nodeErrors,
}),
{ debounce: NODEDB_DEBOUNCE_MS },
);