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.
This commit is contained in:
@@ -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
@@ -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
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user