Compare commits

...
1 Commits
Author SHA1 Message Date
SerinaNya 8c13af680a refactor(topology)!: rename node info revision
Replace the epoch/revision freshness tuple with nodeInfoRevision.

BREAKING CHANGE: topology API clients must use nodeInfoRevision;
nodeInfoFullRevision and nodeInfoFullRevisionEpoch are removed.
2026-08-31 01:13:34 +08:00
3 changed files with 9 additions and 29 deletions
+3 -6
View File
@@ -14,8 +14,7 @@ export interface LayoutNode extends SimulationNodeDatum {
compressedAddress?: string compressedAddress?: string
isSelf: boolean isSelf: boolean
deviceName?: string deviceName?: string
nodeInfoFullRevision?: number nodeInfoRevision?: number
nodeInfoFullRevisionEpoch?: string
x: number x: number
y: number y: number
} }
@@ -121,8 +120,7 @@ export function useTopology(): UseTopologyResult {
(n) => n && typeof n.id === 'string' && n.id !== '' (n) => n && typeof n.id === 'string' && n.id !== ''
).map((n) => ({ ).map((n) => ({
...n, ...n,
nodeInfoFullRevision: n.nodeInfoFullRevision ?? 0, nodeInfoRevision: n.nodeInfoRevision ?? 0,
nodeInfoFullRevisionEpoch: n.nodeInfoFullRevisionEpoch ?? '',
})) }))
: [] : []
const topoEdgesRaw: TopologyEdge[] = Array.isArray(payload.edges) const topoEdgesRaw: TopologyEdge[] = Array.isArray(payload.edges)
@@ -180,8 +178,7 @@ export function useTopology(): UseTopologyResult {
? { ? {
...n, ...n,
deviceName: fresh.deviceName, deviceName: fresh.deviceName,
nodeInfoFullRevision: fresh.nodeInfoFullRevision, nodeInfoRevision: fresh.nodeInfoRevision,
nodeInfoFullRevisionEpoch: fresh.nodeInfoFullRevisionEpoch,
} }
: n : n
}) })
+5 -21
View File
@@ -17,22 +17,6 @@ import { TopologyCanvas } from '@/components/topology/topology-canvas'
import { NodeDetailSheet } from '@/components/topology/node-detail-sheet' import { NodeDetailSheet } from '@/components/topology/node-detail-sheet'
import type { NodeInfoDetail } from '@/types/api' import type { NodeInfoDetail } from '@/types/api'
type NodeInfoFreshnessKey = readonly [epoch: string, revision: number]
function getNodeInfoFreshnessKey(node: {
nodeInfoFullRevision?: number
nodeInfoFullRevisionEpoch?: string
}): NodeInfoFreshnessKey {
return [node.nodeInfoFullRevisionEpoch ?? '', node.nodeInfoFullRevision ?? 0]
}
function freshnessKeysEqual(
left: NodeInfoFreshnessKey | null,
right: NodeInfoFreshnessKey
): boolean {
return left?.[0] === right[0] && left?.[1] === right[1]
}
export function TopologyPage() { export function TopologyPage() {
const { nodes, edges, isLoading, error, relayout } = useTopology() const { nodes, edges, isLoading, error, relayout } = useTopology()
const [searchQuery, setSearchQuery] = useState('') const [searchQuery, setSearchQuery] = useState('')
@@ -44,7 +28,7 @@ export function TopologyPage() {
const [nodeInfo, setNodeInfo] = useState<NodeInfoDetail | null>(null) const [nodeInfo, setNodeInfo] = useState<NodeInfoDetail | null>(null)
const [nodeInfoLoading, setNodeInfoLoading] = useState(false) const [nodeInfoLoading, setNodeInfoLoading] = useState(false)
const nodeInfoSeqRef = useRef(0) const nodeInfoSeqRef = useRef(0)
const nodeInfoFreshnessRef = useRef<NodeInfoFreshnessKey | null>(null) const nodeInfoRevisionRef = useRef<number | null>(null)
const nodeInfoRevisionInitializedRef = useRef(false) const nodeInfoRevisionInitializedRef = useRef(false)
const fetchNodeInfo = useCallback((nodeId: string) => { const fetchNodeInfo = useCallback((nodeId: string) => {
@@ -73,7 +57,7 @@ export function TopologyPage() {
if (nodeId) { if (nodeId) {
setSheetOpen(true) setSheetOpen(true)
const selected = nodes.find((node) => node.id === nodeId) const selected = nodes.find((node) => node.id === nodeId)
nodeInfoFreshnessRef.current = getNodeInfoFreshnessKey(selected ?? {}) nodeInfoRevisionRef.current = selected?.nodeInfoRevision ?? 0
nodeInfoRevisionInitializedRef.current = true nodeInfoRevisionInitializedRef.current = true
fetchNodeInfo(nodeId) fetchNodeInfo(nodeId)
} else { } else {
@@ -101,10 +85,10 @@ export function TopologyPage() {
useEffect(() => { useEffect(() => {
if (!selectedNode) return if (!selectedNode) return
const freshnessKey = getNodeInfoFreshnessKey(selectedNode) const nodeInfoRevision = selectedNode.nodeInfoRevision ?? 0
if (!nodeInfoRevisionInitializedRef.current) return if (!nodeInfoRevisionInitializedRef.current) return
if (!freshnessKeysEqual(nodeInfoFreshnessRef.current, freshnessKey)) { if (nodeInfoRevisionRef.current !== nodeInfoRevision) {
nodeInfoFreshnessRef.current = freshnessKey nodeInfoRevisionRef.current = nodeInfoRevision
fetchNodeInfo(selectedNode.id) fetchNodeInfo(selectedNode.id)
} }
}, [selectedNode, fetchNodeInfo]) }, [selectedNode, fetchNodeInfo])
+1 -2
View File
@@ -80,8 +80,7 @@ export interface TopologyNode {
compressedAddress?: string compressedAddress?: string
isSelf: boolean isSelf: boolean
deviceName?: string deviceName?: string
nodeInfoFullRevision?: number nodeInfoRevision?: number
nodeInfoFullRevisionEpoch?: string
} }
export interface TopologyEdge { export interface TopologyEdge {