panel-raw-messages
GitHub解析RawMessages面板知识,涵盖遗留与虚拟化两种实现、树数据扁平化、展开状态管理及Diff模式。适用于需深入理解消息检查面板底层逻辑、性能优化及共享核心代码的开发场景。
Trigger Scenarios
Install
npx skills add lichtblick-suite/lichtblick --skill panel-raw-messages -g -y
SKILL.md
Frontmatter
{
"name": "panel-raw-messages",
"description": "Deep RawMessages panel knowledge: legacy (react-json-tree) vs virtual (@tanstack\/react-virtual) implementations, flattenTreeData, TreeNode shape, expansion-state management, shared logic hook, and diff mode."
}
Panel Raw Messages Skill
Message-inspection panels that display structured message data as expandable trees. There are two implementations sharing one logic/diff core.
Two Implementations
Both registered in packages/suite-base/src/panels/index.ts:
panelType: "RawMessages"— legacy (react-json-tree<Tree>, full DOM render of expanded nodes)panelType: "RawMessagesVirtual"— performant (@tanstack/react-virtualwindowed rendering)
Shared code lives in panels/RawMessagesCommon/:
types.ts(TreeNode,NodeState, configs, props)constants.ts(PATH_NAME_AGGREGATOR,CUSTOM_METHOD,PREV_MSG_METHOD)useSharedRawMessagesLogic.ts(topic resolution, expansion state)useRenderers.ts,getDiff.ts,Value.tsx,getValueActionForValue.ts,utils.ts, …
VirtualizedTree (Performant Path)
const virtualizer = useVirtualizer({
count: flatData.length,
getScrollElement,
estimateSize: () => fontSize ?? DEFAULT_FONT_SIZE, // 12px
overscan: SCROLLL_OVERSCAN, // 5
measureElement: (el) => el.getBoundingClientRect().height,
useAnimationFrameWithResizeObserver: true,
});
Key constants: ROW_HEIGHT 24px, TREE_NODE_INDENTATION 16px/level, DEFAULT_FONT_SIZE 12px,
SCROLLL_OVERSCAN 5.
flattenTreeData
Converts a nested object → flat TreeNode[] for virtualization:
function flattenTreeData(
data: unknown,
expandedNodes: Set<string>,
parentPath?: string,
depth?: number,
keyPath?: (string | number)[],
): TreeNode[]
- Skips
null, non-objects, andArrayBuffer.isViewvalues (typed arrays like point-cloud buffers) - Only recurses into children of expanded nodes
- Path keys joined with
PATH_NAME_AGGREGATORin reverse order (child~|~parent)
type TreeNode = {
key: string; // unique path string, e.g. "x~|~position~|~pose"
label: string; // display name, e.g. "x"
value: unknown;
depth: number; // nesting level for indentation
isExpandable: boolean;
keyPath: (string | number)[];
parentPath: string;
};
Expansion State
useSharedRawMessagesLogicmanagesexpansion:"all" | "none" | Record<string, NodeState>RawMessagesVirtualconverts it toSet<string>viauseMemo"all"→ all possible paths (recursivegenerateDeepKeyPaths)"none"→ empty set- object mode → keys where
state === NodeState.Expanded
toggleExpansion()flips a node Expanded ↔ Collapsed
Diff Mode
- Shared via
getDiff()— comparesbaseItem(current topic) vsdiffItem(another topic or the previous message) CUSTOM_METHODdiffs against a different topic path;PREV_MSG_METHODagainst the prior message
Key Files
packages/suite-base/src/panels/RawMessages/packages/suite-base/src/panels/RawMessagesVirtual/packages/suite-base/src/panels/RawMessagesCommon/
Skills Reference
- For message-path value actions: load
message-pathskill
Version History
- cab9317 Current 2026-07-24 12:17


