Files
mnote/design/06-mindmap/reference/6-mindmap-kernel-phase6-projection-editor-v1.md
T
lix-2026 5f97800489 chore: align local-first control plane and editor fixes
- wire SQLite control-plane access/session paths into Rust web local-folder routes

- preserve local Markdown attachment semantics across upload, reload, and secondary-pane resource tabs

- refresh design governance docs, Reasonix task templates, and bug records

- retire root .mcp.json local MCP config
2026-05-23 23:38:42 +08:00

16 KiB
Raw Blame History

6 [reference] Mindmap Kernel Phase 6leptos-mindmap Projection Editor v1

更新时间:2026-05-10

当前状态:reference。本文保留 mindmap Phase 6 总设计;已完成 UI shell reuse 归档到 design/06-mindmap/done/,后续新工作需另拆小 checklist。

当前口径:leptos-mindmap

旧稿归档:

  • /mnt/Data1T/mnote/recycle/design/06-mindmap/process/6-mindmap-kernel-phase6-projection-editor-v1.rust-native-2026-05-10.md

当前主线依据:

  • /mnt/Data1T/mnote/design/01-05-current-priority-overview.md
  • /mnt/Data1T/mnote/design/01-tree-first-graph-kernel/reference/1-tree-first-graph-kernel-v1.md
  • /mnt/Data1T/mnote/design/03-rust-web/reference/3-rust-web-long-term-architecture-v1.md
  • /mnt/Data1T/mnote/design/05-editor-mainline/reference/5-5-page-aggregate-single-truth-alignment-v1.md

参考实现:

  • /mnt/Data1T/mnote/design/05-editor-mainline/reference-code/lx-doc/mind-map
  • /mnt/Data1T/mnote/design/05-editor-mainline/reference-code/kmind-plugin
  • /mnt/Data1T/mnote/design/05-editor-mainline/reference-code/siyuan-kmind-plugin

1. 文档目的

这份文档重新修正 Mindmap Phase 6 的落地口径。

旧稿把 Phase 6 定义为 Rust / Leptos 原生 Projection Editor,并把 simple-mind-map 排除在本轮 runtime 主链之外。该口径在长期上最干净,但在当前阶段等同于用 Rust 重写 lx-doc/mind-map / simple-mind-map 的编辑器和布局引擎,短期会继续产出可验证但不可用的导图纵切。

当前口径改为:

leptos-mindmapRust kernel 持有导图事实源与命令语义,simple-mind-map / KMind-like runtime 作为 Leptos 文档页中的编辑器 adapter。

这份文档回答的是:

如何在不放弃 tree-first graph kernel 的前提下,先交付接近 KMind 可用度的导图编辑器。

2. 先给结论

Phase 6 不再以 Rust 自绘导图 renderer 为第一目标。

Phase 6 的主目标是建立:

kernel truth
  -> mindmap.kernel_projection.v1
  -> mindmap.simple_mind_map_scene.v1
  -> leptos-mindmap editor island
  -> simple-mind-map / KMind-like runtime
  -> adapter diff / command bridge
  -> kernel command

其中:

  • Rust kernel 是事实源。
  • simple-mind-map 是显示与交互 runtime。
  • leptos-mindmap 是二者之间的稳定 adapter。
  • lx-doc/mind-map 和 KMind 插件是行为、视觉、工具栏、侧栏和主题的参考实现。
  • 旧 React MindmapBlock.tsx 只能作为 legacy/compat 参考,不作为当前文档页主链。
  • TypeScript NodeView / bridge 只允许作为 leptos-tiptapsimple-mind-map 的薄兼容层;toolbar、sidebar、navigator、context menu 等 UI shell 的长期归属应逐步迁到 Leptos/Rust 组件,避免继续扩散 React/Vue/TS UI 运行时。

这不是“直接嵌入 lx-doc/mind-map 保存 blob”,也不是“立即 Rust 重写 lx-doc/mind-map”。它是中间路线:

Rust 内核 + lx-doc/KMind 级显示编辑体验。

3. 三条路线的定位

3.1 Rust 重写 lx-doc/mind-map

这是长期最干净的路线。

优点:

  • kernel、projection、layout、hit-test、selection、history 都能完全统一。
  • AI/CLI 可直接操作导图内核,不被前端库字段绑架。
  • 长期不受 simple-mind-map 事件粒度、数据格式和插件边界限制。

问题:

  • 实际上要重写的是 simple-mind-map 引擎,而不只是 lx-doc/mind-map 的 Vue UI。
  • 需要自研布局、节点测量、连线、概要、外框、关联线、拖拽、快捷键、导入导出、主题、MiniMap、富文本等完整编辑器能力。
  • 短期会牺牲可用体验。

结论:

保留为长期方向和后续 Rust-native engine 路线,但不再作为 Phase 6 的主验收。

3.2 Rust 内核 + lx-doc/mind-map 显示

这是当前推荐路线,即 leptos-mindmap

优点:

  • 能快速获得接近 KMind 的可用编辑体验。
  • Rust kernel 仍然持有事实源、projection 和 command。
  • 可以逐步把 simple-mind-map 字段提升为 kernel-native 语义。
  • leptos-tiptap 的定位一致:前端编辑器是 runtime,不是系统事实源。

问题:

  • simple-mind-map 的事件不一定足够细,需要 adapter diff。
  • 高级能力短期可能需要 compat_payload
  • 必须严格防止回退成“保存整棵前端 blob”。

结论:

作为 Phase 6 主线。

3.3 直接嵌入 lx-doc/mind-map

这是最快路线,但不作为主线。

优点:

  • 最快得到完整 UI。
  • 迁移成本看起来最低。

问题:

  • lx-doc/mind-map 会重新成为事实源。
  • 长期仍保存 simple-mind-map blob。
  • kernel、AI、Page Aggregate、tree realtime 只能在外围补偿。

结论:

只可作为短期 demo 或对照,不作为 mnote 主线。

4. leptos-mindmap 的边界

leptos-mindmap 是一个编辑器 adapter,不是新的事实源。

它负责:

  • leptos-tiptap NodeView 中挂载导图编辑器。
  • 把 kernel projection 转成 simple-mind-map 可消费的数据。
  • 初始化并管理 simple-mind-map runtime 和必要插件。
  • 监听导图数据与视图变化。
  • 把变化转成 kernel command 或 adapter diff。
  • 渲染 KMind-like toolbar、右侧样式栏、底部工具和错误状态。
  • 承载 floating overlay canvas shell,并逐步把 UI shell 从临时 TypeScript DOM 渲染迁回 Leptos/Rust 组件边界。

它不负责:

  • 长期保存整棵导图 blob。
  • 绕过 kernel command 直接把前端 runtime 数据写成 canonical truth。
  • 在 UI 层创造第二套树真相、顺序真相或引用边真相。
  • window.__mindmapInstance、React mount 点或占位 DOM 作为完成判定。
  • 把 TypeScript NodeView 扩写成长期 UI 框架;TS 只保留 tiptap / runtime bridge、动态加载、事件转发和最小 DOM mount 职责。

5. 数据分层

5.1 kernel truth

长期事实源应表达:

  • Mindmap
  • MindmapNode
  • parent / child order
  • collapsed state
  • summary / generalization
  • associative line
  • node style
  • link / reference edge
  • theme / layout / view state

这些字段应属于 kernel 或 kernel projection,不能只存在于 simple-mind-map blob。

5.2 mindmap.kernel_projection.v1

这是稳定投影,供 AI、CLI、独立页、文档页和后续 Rust-native renderer 使用。

它应包含:

  • schema
  • documentId
  • mindmapId
  • rootNodeId
  • revision
  • nodes
  • edges
  • summaries
  • associativeLines
  • layout
  • theme
  • view
  • capabilities
  • source

5.3 mindmap.simple_mind_map_scene.v1

这是 adapter projection,只服务 simple-mind-map runtime。

它应包含:

  • root
  • layout
  • theme
  • themeConfig
  • view
  • config
  • compatPayload
  • projectionRevision
  • kernelRevision

注意:这层可以长得像 simple-mind-map,但它不是 canonical truth。

5.4 compat_payload

短期无法语义化的字段进入 compat_payload

允许先放入:

  • 高级节点样式
  • 图片
  • 公式
  • 附件
  • 富文本片段
  • 第三方插件私有字段
  • KMind 专有扩展

但每个字段必须有提升策略,不能无限期成为黑箱。

6. 命令桥接

Phase 6 最小命令集:

  • mindmap.node.update_text
  • mindmap.node.insert_child
  • mindmap.node.insert_sibling_after
  • mindmap.node.delete
  • mindmap.node.move
  • mindmap.view.patch
  • mindmap.layout.set
  • mindmap.theme.set
  • mindmap.summary.set
  • mindmap.associative_line.upsert

桥接方式分两级。

6.1 直接命令

如果 toolbar 或快捷键能明确知道用户意图,直接发 kernel command。

示例:

  • 点击“子节点” -> mindmap.node.insert_child
  • 点击“同级节点” -> mindmap.node.insert_sibling_after
  • 节点文本提交 -> mindmap.node.update_text
  • 删除节点 -> mindmap.node.delete

6.2 adapter diff

如果 simple-mind-map 只给出 data_change,则对比上一份 adapter projection 和当前 runtime data。

diff 输出:

  • 可识别变化转 kernel command。
  • 暂不可识别变化转 compat_payload.patch,并打上 source="adapter-diff"

禁止把整棵 runtime data 直接作为 canonical success。

7. UI 对标范围

第一阶段对标 image copy 60.png 和 KMind/lx-doc 体验,但不追全量功能。

必须有:

  • 顶部工具栏:撤销、重做、编辑节点、同级节点、子节点、删除节点、标签、超链接、备注、图片、图标、概要、关联线、公式、格式刷、导入、导出。
  • 中央画布:真实节点、连线、pan、zoom、选择、双击编辑、键盘基本操作。
  • 右侧触发栏:节点样式、导图样式、主题、结构、大纲。
  • 底部工具:节点数/字数、回到根节点、搜索、缩放百分比、全屏或只读入口。
  • 错误状态:projection 获取失败、command 失败、adapter diff 失败要可定位。

可延期:

  • 完整主题设计器。
  • 多根节点。
  • 思源块悬浮预览。
  • 镜像块。
  • MOC 模式。
  • PDF 标注跳转。
  • 全量 XMind/Freemind 导入导出。

8. 代码落点建议

8.1 Rust 协议层

  • rust/crates/core-protocol/src/mindmap.rs
    • 定义 kernel projection DTO。
    • 定义 adapter projection DTO。
    • 定义 command DTO。
    • 标记旧 MindmapTreeNode / MindmapOp 为 compat。

8.2 Rust runtime 层

  • rust/crates/bridge-runtime/src/lib.rs
    • 构建 mindmap.kernel_projection.v1
    • 构建 mindmap.simple_mind_map_scene.v1
    • 执行 kernel command。
    • 维护 compat snapshot。

8.3 Rust Web 层

  • rust/crates/mnote-web/
    • 暴露 projection / command route。
    • 保持 3000 是前端公开入口。
    • 不在 Rust Web 内联第三方编辑器业务逻辑。

8.4 Leptos / Tiptap 层

  • rust/spikes/leptos-tiptap-spike/src/lib.rs
    • 提供 mindmap NodeView。
    • 挂载 leptos-mindmap island。
    • Tiptap 节点只保存 mindmapId/rootNodeId/projectionVersion 等引用。

8.5 前端 adapter 层

建议新增或收口到:

  • wolai-frontend/src/lib/mindmap/leptos-mindmap-adapter.ts
  • wolai-frontend/src/lib/mindmap/simple-mind-map-bridge.ts
  • wolai-frontend/src/lib/mindmap/mindmap-command-diff.ts

实际目录可随现有 runtime 打包方式调整,但职责必须清楚。

9. 验收标准

Phase 6 新验收不再要求 Rust 自绘 scene。

必须验证:

  • 文档页 / 插入 mindmap block 后进入 leptos-tiptap NodeView。
  • NodeView 挂载 leptos-mindmap
  • 画布由 simple-mind-map / KMind-like runtime 渲染真实节点与连线。
  • 默认骨架可见 KMIND二级节点、两个 分支主题概要
  • 修改节点文本后通过 kernel command 回写。
  • reload 后从 kernel projection 恢复修改结果。
  • smoke 输出结构化 JSON 和截图。
  • 失败时能定位到 projection、adapter init、runtime render、diff、command 或 reload 阶段。

明确不通过:

  • 只看到标题或空容器。
  • 只断言 React mount 点。
  • 只断言 window.__mindmapInstance
  • 只保存整棵 blob 且无 kernel command。
  • simple-mind-map runtime data 当成唯一事实源。

10. 2026-05-10 现实复核:当前实现差距

当前代码已打通 mindmap.simple_mind_map_scene.getmindmap.command.apply、reload 后文本保留和最小 smoke,但这只能证明 projection / command 的纵切闭环。

它还不能证明 leptos-mindmap 已完成。

已确认的差距:

  • leptos-tiptap NodeView 当前仍在 tiptap_paragraph.ts 内手写 DOM。
  • 当前所谓 simple-mind-map-runtime 只是一个带 data-runtime="simple-mind-map" 的容器,不是 new MindMap(...) 创建的真实实例。
  • 节点是手写 <button data-testid="mindmap-node">
  • 连线是手写 <svg><path>,坐标来自 adapter projection 的简化布局,因此会出现错位。
  • toolbar、右侧栏和底部栏只是静态 KMind-like chrome,并未真正绑定 simple-mind-map runtime 的 active node、history、scale、search、style、theme、layout 等能力。
  • 当前 smoke 断言的是伪 DOM/SVG 可见,而不是 runtime 布局、runtime 连线或真实 MindMap instance。

因此,当前状态应被标记为:

Phase 6-Aprojection / command 最小闭环通过;Phase 6.1:真实 simple-mind-map runtime cutover 尚未完成。

后续执行必须先完成 Phase 6.1,不能继续把手写 DOM/SVG 画布美化成最终实现。

Phase 6.1 的硬性完成判定:

  • NodeView 只创建 mount element,不再手写节点和连线。
  • browser-side adapter bundle 调用 createLeptosMindmapAdapter() 或同等桥接入口。
  • adapter 内部真实执行 new MindMap({ el, data, layout, theme, viewData, config })
  • 节点、连线、概要、外框、关联线由 simple-mind-map runtime 负责布局和渲染。
  • smoke 能证明真实 runtime 存在,且不再以 .mnote-mindmap-node / 手写 <path data-testid="mindmap-edge"> 作为成功条件。

10.1 2026-05-10 Phase 6.1 首轮落地状态

本轮已经完成真实 runtime cutover 的首轮落地:

  • leptos-tiptap NodeView 不再手写默认节点和连线,而是挂载 data-testid="simple-mind-map-runtime"
  • NodeView 通过 createLeptosMindmapAdapter() 初始化真实 simple-mind-map runtime。
  • simple-mind-map-bridge 真实执行 new MindMap(...),并注册到 window.__MNOTE_LEPTOS_MINDMAP_BRIDGES__ 供 smoke 验证。
  • task166-mindmap-phase6-block-smoke.js 已改为检查真实 runtime、bridge snapshot、非零节点树和 reload 后文本保留,不再依赖 .mnote-mindmap-node / mindmap-edge
  • 最新 smoke 输出:/mnt/Data1T/mnote/tmp/task166-mindmap-phase6-block-smoke/result.json,截图包括 01-after-insert.png02-after-edit.png03-after-reload.png

仍未视为完成的尾项:

  • view_data_change 还没有持久化为 kernel command;当前只记录 view event,避免拖拽/缩放造成 POST -> remount 循环。
  • toolbar 缩放按钮还没有真正绑定 runtime zoom command。
  • RichText 插件暂不默认启用;它会把纯文本节点转换成 HTML 字符串,当前先保护 Rust kernel 文本语义。
  • 视觉上已经是真实 simple-mind-map 工作台,但还未达到 image copy 60.png / image copy 70.png 的完整 KMind 体验对齐。

10.2 2026-05-11 UI shell reuse 收口状态

Phase 6 后续 UI 可用度收口转入:

  • /mnt/Data1T/mnote/design/06-mindmap/done/6-mindmap-phase6-leptos-ui-shell-reuse-checklist-v1.md

本轮已经把默认宿主修正为 floating overlay canvas shell,并把 toolbar、sidebar、count、navigator 迁到 Leptos/Rust shell 边界:

  • simple-mind-map runtime 充满块内画布底层。
  • toolbar、右侧栏、统计、navigator、MiniMap 作为 overlay 浮在画布上,不再挤压 runtime。
  • TypeScript NodeView 保留为 Tiptap NodeView、runtime bridge、事件转发和 context menu 过渡层,不再作为长期 UI shell 宿主。
  • simple-mind-map-bridge 默认尊重 fit:true,初始视口能看到完整示例导图。
  • task166-mindmap-phase6-block-smoke.js 已覆盖 toolbar/sidebar/navigator/context menu、command bridge、compat patch、reload 与截图证据。
  • 2026-05-11 最新截图:/mnt/Data1T/mnote/tmp/task166-mindmap-phase6-block-smoke/01-after-insert-floating-overlay.png04-after-reload.png

剩余视觉差异不改变 kernel-first 主合同:默认主题色、图标体系、工具栏分组密度和高级面板内容仍需继续对齐 KMind/lx-doc。

11. 后续 Rust-native 路线

Rust 重写仍然是长期可选路线,但应独立成后续阶段。

后续可以启动:

  • Rust mindmap engine candidate spike。
  • 布局 crate 评估:diagramma-layoutdagre/dugongmanatee
  • Headless Rust layout engine。
  • Rust scene renderer。
  • Rust hit-test / selection / history。

这些不再阻塞 Phase 6 的可用编辑器交付。

12. 迁移原则

  • 先保证可用编辑体验,再逐步提升语义。
  • adapter 可以兼容 simple-mind-map 字段,但字段所有权要写清楚。
  • 每个从 blob 中提升出来的语义,都要有 kernel command 和 projection 表达。
  • 不把 lx-doc/mind-map 的 Vue2 应用结构直接搬入 mnote。
  • 可以参考 KMind 的 UI 与行为,但不要复制它的思源插件耦合。

13. 当前执行口径

当前 Phase 6 的一句话口径:

用 leptos-mindmap 把 Rust kernel projection 接到 KMind-like 导图编辑器上,先得到可用体验,同时保持 kernel 是事实源。