feat(xmind): Import relationships as associative lines#1349
Open
mike-lsadigital wants to merge 1 commit intowanglin2:mainfrom
Open
feat(xmind): Import relationships as associative lines#1349mike-lsadigital wants to merge 1 commit intowanglin2:mainfrom
mike-lsadigital wants to merge 1 commit intowanglin2:mainfrom
Conversation
When parsing XMind files, the relationships array is now processed to create associative lines between nodes. Each relationship's source and target nodes are mapped to SimpleMindMap UIDs, and the relationship title is preserved as the associative line label. This enables users to import XMind files that contain non-hierarchical relationships and see them rendered as associative lines in SimpleMindMap. Co-authored-by: Cursor <cursoragent@cursor.com>
|
@MonkeyCode-AI review 一下 |
|
MonkeyCode-AI 正在分析任务... |
MonkeyCode-AI
left a comment
There was a problem hiding this comment.
我是 MonkeyCode AI 编程助手,你可以在 GitHub 仓库的 PR 中 at @MonkeyCode-AI 来呼唤我。
任务执行细节请参考: https://monkeycode-ai.com/tasks/public?id=11f21799-8856-414e-9406-a3625f83f9a4
代码审查结果
实现了从 XMind relationships 导入关联线的核心逻辑,但 walk 异步未等待与 UID 覆盖风险会导致关系映射不稳定,需要修正后再合并。
✨ 代码亮点
- relationships 导入逻辑与节点映射表设计直观,能够保留关系标题到 associativeLineText
- 对重复 targetUid 做了去重处理,避免重复关联线目标
| 🚨 Critical | 💡 Suggestion | |
|---|---|---|
| 1 | 0 | 0 |
|
|
||
| // 节点备注 | ||
| if (node.notes) { | ||
| const notesData = node.notes.realHTML || node.notes.plain |
There was a problem hiding this comment.
Caution
🚨 异步递归 walk 未 await,relationships 处理可能早于节点映射完成
walk 被声明为 async,并且内部会调用 handleNodeImageFromXmind(可能向 waitLoadImageList 推入异步任务/依赖 files),但调用处 walk(nodeTree, newTree) 没有 await。随后立刻 await Promise.all(waitLoadImageList) 并处理 data.relationships。这会导致:
- 节点遍历/映射(xmindIdToUid、uidToNewNode)可能尚未完成就开始处理 relationships,从而丢失关联线;
- waitLoadImageList 可能在 walk 继续进行时才被 push,Promise.all 可能等待不完整。
即便当前 walk 内部没有显式 await,也属于易碎实现,后续任何在 walk 内引入 await 都会立刻触发该竞态问题。
建议: 将 walk 的递归调用与根调用都改为 await,保证遍历完成后再等待图片任务、再处理 relationships。
Suggested change
| const notesData = node.notes.realHTML || node.notes.plain | |
| const walk = async (node, newNode) => { | |
| // PATCH: Generate UID for this node | |
| const nodeUid = uuid() | |
| newNode.data = { | |
| // 节点内容 | |
| text: isUndef(node.title) ? '' : node.title, | |
| // PATCH: Assign UID to node | |
| uid: nodeUid | |
| } | |
| // PATCH: Store mapping from xmind ID to our UID | |
| if (node.id) { | |
| xmindIdToUid.set(node.id, nodeUid) | |
| uidToNewNode.set(nodeUid, newNode) | |
| } | |
| // 节点备注 | |
| if (node.notes) { | |
| const notesData = node.notes.realHTML || node.notes.plain | |
| newNode.data.note = notesData ? notesData.content || '' : '' | |
| } | |
| // 超链接 | |
| if (node.href && /^https?:\/\//.test(node.href)) { | |
| newNode.data.hyperlink = node.href | |
| } | |
| // 标签 | |
| if (node.labels && node.labels.length > 0) { | |
| newNode.data.tag = node.labels | |
| } | |
| // 图片 | |
| handleNodeImageFromXmind(node, newNode, waitLoadImageList, files) | |
| // 概要 | |
| const selfSummary = [] | |
| const childrenSummary = [] | |
| if (newNode._summary) { | |
| selfSummary.push(newNode._summary) | |
| } | |
| if (Array.isArray(node.summaries) && node.summaries.length > 0) { | |
| node.summaries.forEach(item => { | |
| addSummaryData( | |
| selfSummary, | |
| childrenSummary, | |
| () => { | |
| return getSummaryText(node, item.topicId) | |
| }, | |
| item.range | |
| ) | |
| }) | |
| } | |
| newNode.data.generalization = selfSummary | |
| // 子节点 | |
| newNode.children = [] | |
| if ( | |
| node.children && | |
| node.children.attached && | |
| node.children.attached.length > 0 | |
| ) { | |
| for (let index = 0; index < node.children.attached.length; index++) { | |
| const item = node.children.attached[index] | |
| const newChild = {} | |
| newNode.children.push(newChild) | |
| if (childrenSummary[index]) { | |
| newChild._summary = childrenSummary[index] | |
| } | |
| await walk(item, newChild) | |
| } | |
| } | |
| } | |
| await walk(nodeTree, newTree) | |
| await Promise.all(waitLoadImageList) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
relationshipsarray is now processed to connect nodes via associative linesBackground
XMind supports non-hierarchical relationships between nodes (called "relationships"). These are stored in the
relationshipsarray incontent.json. Previously, SimpleMindMap ignored this data during import.Changes
Modified
simple-mind-map/src/parse/xmind.js:relationshipsarray to populateassociativeLineTargetsandassociativeLineTexton source nodesTest plan
Made with Cursor