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

439 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 的主目标是建立:
```text
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-tiptap``simple-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.get``mindmap.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.png``02-after-edit.png``03-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.png``04-after-reload.png`
剩余视觉差异不改变 kernel-first 主合同:默认主题色、图标体系、工具栏分组密度和高级面板内容仍需继续对齐 KMind/lx-doc。
## 11. 后续 Rust-native 路线
Rust 重写仍然是长期可选路线,但应独立成后续阶段。
后续可以启动:
- Rust mindmap engine candidate spike。
- 布局 crate 评估:`diagramma-layout``dagre/dugong``manatee`
- 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 是事实源。**