From 94c112c0662177c640c351b9035f98b444228c5b Mon Sep 17 00:00:00 2001 From: icarus Date: Tue, 14 Oct 2025 17:00:20 +0800 Subject: [PATCH] fix(trace): extract trace utility functions to separate module Move mergeTraceModals, updatePercentAndStart and findNodeById functions from trace page component to a dedicated utils module to fix react-hooks error --- src/renderer/src/trace/pages/index.tsx | 49 ++------------------------ src/renderer/src/trace/utils/index.ts | 45 +++++++++++++++++++++++ 2 files changed, 48 insertions(+), 46 deletions(-) create mode 100644 src/renderer/src/trace/utils/index.ts diff --git a/src/renderer/src/trace/pages/index.tsx b/src/renderer/src/trace/pages/index.tsx index 507ce813a6..1ffb638951 100644 --- a/src/renderer/src/trace/pages/index.tsx +++ b/src/renderer/src/trace/pages/index.tsx @@ -6,6 +6,7 @@ import { Divider } from 'antd/lib' import React, { useCallback, useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' +import { findNodeById, mergeTraceModals, updatePercentAndStart } from '../utils' import { Box, GridItem, SimpleGrid, Text, VStack } from './Component' import SpanDetail from './SpanDetail' import TraceTree from './TraceTree' @@ -24,39 +25,6 @@ export const TracePage: React.FC = ({ topicId, traceId, modelName const intervalRef = useRef(null) const { t } = useTranslation() - const mergeTraceModals = useCallback((oldNodes: TraceModal[], newNodes: TraceModal[]): TraceModal[] => { - const oldMap = new Map(oldNodes.map((n) => [n.id, n])) - return newNodes.map((newNode) => { - const oldNode = oldMap.get(newNode.id) - if (oldNode) { - // 如果旧节点已经结束,则直接返回旧节点 - if (oldNode.endTime) { - return oldNode - } - oldNode.children = mergeTraceModals(oldNode.children, newNode.children) - Object.assign(oldNode, newNode) - return oldNode - } else { - return newNode - } - }) - }, []) - - const updatePercentAndStart = useCallback((nodes: TraceModal[], rootStart?: number, rootEnd?: number) => { - nodes.forEach((node) => { - const _rootStart = rootStart || node.startTime - const _rootEnd = rootEnd || node.endTime || Date.now() - const endTime = node.endTime || _rootEnd - const usedTime = endTime - node.startTime - const duration = _rootEnd - _rootStart - node.start = ((node.startTime - _rootStart) * 100) / duration - node.percent = duration === 0 ? 0 : (usedTime * 100) / duration - if (node.children) { - updatePercentAndStart(node.children, _rootStart, _rootEnd) - } - }) - }, []) - const getRootSpan = (spans: SpanEntity[]): TraceModal[] => { const map: Map = new Map() @@ -78,17 +46,6 @@ export const TracePage: React.FC = ({ topicId, traceId, modelName ) } - const findNodeById = useCallback((nodes: TraceModal[], id: string): TraceModal | null => { - for (const n of nodes) { - if (n.id === id) return n - if (n.children) { - const found = findNodeById(n.children, id) - if (found) return found - } - } - return null - }, []) - const getTraceData = useCallback(async (): Promise => { const datas = topicId && traceId ? await window.api.trace.getData(topicId, traceId, modelName) : [] const matchedSpans = getRootSpan(datas) @@ -96,7 +53,7 @@ export const TracePage: React.FC = ({ topicId, traceId, modelName setSpans((prev) => mergeTraceModals(prev, matchedSpans)) const isEnded = !matchedSpans.find((e) => !e.endTime || e.endTime <= 0) return isEnded - }, [topicId, traceId, modelName, updatePercentAndStart, mergeTraceModals]) + }, [topicId, traceId, modelName]) const handleNodeClick = (nodeId: string) => { const latestNode = findNodeById(spans, nodeId) @@ -148,7 +105,7 @@ export const TracePage: React.FC = ({ topicId, traceId, modelName setSelectNode(latest) } } - }, [spans, selectNode, findNodeById]) + }, [spans, selectNode]) return (
diff --git a/src/renderer/src/trace/utils/index.ts b/src/renderer/src/trace/utils/index.ts new file mode 100644 index 0000000000..c012437463 --- /dev/null +++ b/src/renderer/src/trace/utils/index.ts @@ -0,0 +1,45 @@ +import { TraceModal } from '../pages/TraceModel' + +export const updatePercentAndStart = (nodes: TraceModal[], rootStart?: number, rootEnd?: number) => { + nodes.forEach((node) => { + const _rootStart = rootStart || node.startTime + const _rootEnd = rootEnd || node.endTime || Date.now() + const endTime = node.endTime || _rootEnd + const usedTime = endTime - node.startTime + const duration = _rootEnd - _rootStart + node.start = ((node.startTime - _rootStart) * 100) / duration + node.percent = duration === 0 ? 0 : (usedTime * 100) / duration + if (node.children) { + updatePercentAndStart(node.children, _rootStart, _rootEnd) + } + }) +} + +export const findNodeById = (nodes: TraceModal[], id: string): TraceModal | null => { + for (const n of nodes) { + if (n.id === id) return n + if (n.children) { + const found = findNodeById(n.children, id) + if (found) return found + } + } + return null +} + +export const mergeTraceModals = (oldNodes: TraceModal[], newNodes: TraceModal[]): TraceModal[] => { + const oldMap = new Map(oldNodes.map((n) => [n.id, n])) + return newNodes.map((newNode) => { + const oldNode = oldMap.get(newNode.id) + if (oldNode) { + // 如果旧节点已经结束,则直接返回旧节点 + if (oldNode.endTime) { + return oldNode + } + oldNode.children = mergeTraceModals(oldNode.children, newNode.children) + Object.assign(oldNode, newNode) + return oldNode + } else { + return newNode + } + }) +}