feat: add evidence search and stabilize pdf previews

- add document evidence parsing/search/open routes, Hermes tool wiring, local index settings/status, and the document-evidence skill plus design notes
- fix PDF resource tabs by rendering PDFs inline with pdf.js canvases instead of iframe preview pages, release PDF documents on close, and document the fourth-PDF stall bug
- keep PDF preview at 2x rendering while removing the previous lazy-load/placeholder direction, and make dev:hot bind loopback defaults externally reachable

Verification:
- node --check rust/crates/mnote-web/browser/document-resource-tab-runtime.js
- node scripts/task-dev-hot-plan-test.js
- cargo test -p mnote-web --manifest-path rust/Cargo.toml pdf_preview_page_does_not_render_visible_toolbar
- cargo test -p mnote-web --manifest-path rust/Cargo.toml document_shell_returns_page_aggregate_snapshot
- cargo build -p mnote-web --manifest-path rust/Cargo.toml
- browser smoke: sequentially opened the four tea_seed_oil_cosmetic PDFs; fourth PDF rendered 15/15 canvases, iframeCount=0, browser errors=0
This commit is contained in:
lix-2026
2026-06-04 18:51:16 +08:00
parent 9f4b5c4d48
commit 627213dc01
51 changed files with 15960 additions and 1844 deletions
@@ -0,0 +1,48 @@
# 5-13 tiptap runtime 冷加载 mindmap 重包拆分 checklist v1
## 背景
- 实测打开 `mnote-e2e``design/07-ai/done/7-45-chatonly-api-provider-runtime-v1.md` 时,FileTree scoped reveal 已降到毫秒级,但正文表格可见仍接近十几秒。
- 冷浏览器网络记录显示 `/api/leptos-tiptap-runtime/snippets/.../tiptap_paragraph.js` 响应事件被主线程阻塞拖到后段;直接 `curl` 该资源只需毫秒级。
- 生成产物 `tiptap_paragraph.js` 约 1MB,普通 paragraph extension 静态捆绑了 mindmap/simple-mind-map/KaTeX 相关代码。
## 根因假设
普通 Markdown 页面必须注册 paragraph extension,而当前 paragraph extension 在模块顶层静态导入 mindmap NodeView runtime。即使页面没有 mindmap block,浏览器也必须下载、解析和执行 mindmap 重包,导致 tiptap island 冷加载被拖慢。
## 验收标准
- [x] RED:新增测试能证明当前 `tiptap_paragraph.js` 含有 mindmap/simple-mind-map 重包。
- [x] GREEN:普通 `tiptap_paragraph.js` 不再包含 `simple-mind-map``mindmap.simple_mind_map_scene.get` 等重运行时代码。
- [x] 保留 mindmap paragraph attrs`mnoteBlockType``mindmapId``rootNodeId``projectionVersion``mindmapWidth``mindmapHeight` 仍可 parse/render。
- [x] mindmap block runtime 改为遇到 mindmap block 时再异步加载,普通文档不触发该加载。
- [x] 重建 `reference-code/leptos-tiptap/src/js/generated``rust/spikes/leptos-tiptap-spike/generated/island` 产物。
- [ ] 复测 7-45 冷加载,记录 table visible 时间与 runtime asset 体积变化。当前复测:paragraph snippet 已从约 1,025,978 bytes 降到 7,619 bytes`tiptap_mindmap_paragraph_runtime.js` 未在普通 7-45 页面请求;但 table visible 仍约 18.55s,说明还有下一层瓶颈。
## 修改边界
- 主要 owner`reference-code/leptos-tiptap/tiptap/src/extensions/tiptap_paragraph.ts`
- 可新增:`tiptap_mindmap_paragraph_runtime.ts`,用于承载 mindmap NodeView 重逻辑。
- 可补 route fallback`mnote-web``/api/leptos-tiptap-runtime/*path` 允许加载 lazily generated mindmap runtime asset。
- 不改 FileTree scoped reveal 已完成逻辑,不回滚上一轮未提交变更。
## 2026-06-02 实测补充
- `npm test``普通 paragraph 生成产物不应捆绑 mindmap 重运行时` 已从失败变为通过。
- 冷浏览器打开 7-45`domContentLoadedMs=136``editorVisibleMs=18550``tableVisibleMs=18553``mindmapRuntimeRequested=false``pageErrors=0`
- 单独在同源页面 `import + init + mount` 同一份 7-45 Tiptap document 约 `166ms`,所以 18s 不是 Tiptap document 本身渲染 194 blocks/2 tables 导致。
- 下一层根因应继续查 document shell 首屏环境下 wasm-bindgen snippets module graph 为什么在真实页面中约 18s 后才完成,而同源空页面 import 只需约 50ms。
## 2026-06-02 插入思维导图回归修复
- [x] RED:新增 `mindmap runtime 懒加载完成后会挂到稳定 loading NodeView 内` 测试,覆盖 runtime 加载完成后不能停留在 loading 的行为。
- [x] 根因:懒加载完成后仅 dispatch `setNodeMarkup(position, sameAttrs)`ProseMirror 不保证重建 NodeView;直接 `replaceWith(realNodeView.dom)` 又会破坏 ProseMirror 持有的 NodeView DOM 引用。
- [x] GREEN:保持 loading NodeView 外层 DOM 稳定,runtime 加载完成后清空 loading 文案并 `appendChild(realNodeView.dom)`,后续 `update/destroy/stopEvent/ignoreMutation` 代理到真实 NodeView。
- [x] 浏览器 smoke:临时 local-folder 页面通过 slash 插入思维导图后,请求 `tiptap_mindmap_paragraph_runtime.js`placeholder `data-stage=runtime-loaded`,内部出现 `mnote-mindmap-editor-root``leptos-mindmap-island[data-stage=ready]``simple-mind-map-runtime`
## 长期形态决策
- [ ] 参考思源 KMind 的插件/挂件形式,把完整 mindmap 编辑器迁到独立 Resource/Object tab 或 plugin host。
- [ ] Markdown 正文内的 mindmap block 长期收敛为轻量镜像块/预览块/打开按钮,不在普通正文 NodeView 内承载完整编辑器。
- [ ] 插件 host 提供 `getMindMapData/saveMindMapData/resize/destroy` 一类数据桥和生命周期,数据真相仍为 Resource Tree 下的 `.mindmap.json`