2026-05-24 21:03:33 +08:00
|
|
|
|
# 5-28 Leptos Tiptap 编辑器 Runtime 模块拆分 v1
|
|
|
|
|
|
|
|
|
|
|
|
> 创建时间:2026-05-24
|
|
|
|
|
|
> 状态:`process`
|
|
|
|
|
|
>
|
|
|
|
|
|
> 触发背景:
|
|
|
|
|
|
> - `bugs/0524.md` 第 4 条删除本地 Markdown 附件链接后 `Ctrl+Z/Ctrl+Y` 不可用,根因是编辑器删除路径绕过 Tiptap/ProseMirror history。
|
|
|
|
|
|
> - 修复过程中 CodeGraph 能索引 Rust 符号,但 `rust/spikes/leptos-tiptap-spike/src/lib.rs` 单文件约一万行,职责过多,主控和 worker 都需要反复字面搜索。
|
|
|
|
|
|
> - `design/03-rust-web/process/3-19-rust-web-browser-runtime-module-extraction-v1.md` 解决 Rust Web shell/browser host runtime 外置化;本设计补齐编辑器主线拆分。
|
|
|
|
|
|
|
|
|
|
|
|
## 1. 结论
|
|
|
|
|
|
|
|
|
|
|
|
`leptos-tiptap-spike/src/lib.rs` 的问题不是 raw string,而是编辑器 runtime 仍以单个巨型 Rust 文件承载过多职责:Tiptap 初始化、命令执行、附件上传、附件链接增强、history、块菜单、DOM overlay、mindmap node view、page options、AI surface 都混在一起。CodeGraph 对这种文件只能给出符号位置,不能给出清晰模块边界。
|
|
|
|
|
|
|
|
|
|
|
|
后续不应继续在该文件中追加新的编辑器行为。应分阶段把编辑器命令、附件链接/上传、history 安全命令、DOM bridge/overlay、mindmap node view 拆入独立 Rust 模块;保持 `leptos-tiptap` island 仍是当前文档页主编辑器 runtime,但让每个行为域能被单独搜索、测试、派发给 worker。
|
|
|
|
|
|
|
|
|
|
|
|
## 2. 当前代码基线
|
|
|
|
|
|
|
|
|
|
|
|
- `rust/spikes/leptos-tiptap-spike/src/lib.rs`
|
|
|
|
|
|
- 约一万行。
|
|
|
|
|
|
- 同时包含 CSS、Tiptap extension 列表、slash menu、toolbar、block menu、table toolbar、attachment upload、attachment link handling、local folder path、history/undo、DOM selection、mindmap node view、runtime bridge。
|
|
|
|
|
|
- 最近第 4 条 bug 的关键函数和逻辑散落在同一文件中,例如附件链接识别、keydown 处理、`apply_html_update`、`sync_persisted_editor_command`、`delete_top_level_block_html`。
|
|
|
|
|
|
|
|
|
|
|
|
- `reference-code/leptos-tiptap/`
|
|
|
|
|
|
- 提供底层 Tiptap Rust/JS bridge。
|
|
|
|
|
|
- 已有 `TiptapEditorHandle`、`TiptapExtension`、`TiptapRange`、`delete_selection`、`delete_range`、`undo`、`redo` 等命令。
|
|
|
|
|
|
- MNote 不应把这些底层 bridge 再复制一遍,而应在 spike runtime 上方建立 MNote 编辑器行为模块。
|
|
|
|
|
|
|
|
|
|
|
|
## 3. 与 3-19 的边界
|
|
|
|
|
|
|
|
|
|
|
|
`03-rust-web` 负责:
|
|
|
|
|
|
|
|
|
|
|
|
- Rust Web SSR shell。
|
|
|
|
|
|
- document pane host adapter。
|
|
|
|
|
|
- resource tab / secondary pane / URL / conflict panel 生命周期。
|
|
|
|
|
|
- filetree / resource open / local upload 的 shell 侧适配。
|
|
|
|
|
|
|
|
|
|
|
|
`05-editor-mainline` 负责:
|
|
|
|
|
|
|
|
|
|
|
|
- Tiptap 编辑器内部命令。
|
|
|
|
|
|
- 编辑器内附件链接和上传块行为。
|
|
|
|
|
|
- undo/redo/history 安全边界。
|
|
|
|
|
|
- 编辑器 DOM selection / overlay / toolbar / block menu。
|
|
|
|
|
|
- Tiptap node view,例如 mindmap block。
|
|
|
|
|
|
|
|
|
|
|
|
交界规则:
|
|
|
|
|
|
|
|
|
|
|
|
- Shell 可以告诉 editor “打开某个文档/资源/保存状态/挂载 pane”。
|
|
|
|
|
|
- Editor 可以告诉 shell “内容变更/附件打开 intent/资源上传完成/冲突状态”。
|
|
|
|
|
|
- Shell 不应直接改 Tiptap document 内部结构。
|
|
|
|
|
|
- Editor 不应决定 workspace tree/resource 归属真相。
|
|
|
|
|
|
|
|
|
|
|
|
## 4. 目标
|
|
|
|
|
|
|
|
|
|
|
|
- 把 `src/lib.rs` 从“巨型编辑器 runtime”收敛为组件入口和模块装配层。
|
|
|
|
|
|
- 让附件、history、命令、DOM bridge 等高频 bug 区域成为独立 Rust 模块。
|
|
|
|
|
|
- 修 bug 时能把 worker 限定到单一模块和单一 smoke。
|
|
|
|
|
|
- 统一编辑器命令合同:能用 Tiptap command/transaction 的行为,不再通过 `set_content`/HTML 整文替换实现用户编辑动作。
|
|
|
|
|
|
- 建立 history 安全基线:删除、插入、重排、格式转换、附件操作都要明确是否进入 undo stack。
|
|
|
|
|
|
|
|
|
|
|
|
## 5. 非目标
|
|
|
|
|
|
|
|
|
|
|
|
- 不替换 Tiptap 或 `leptos-tiptap` bridge。
|
|
|
|
|
|
- 不把文档事实源迁回前端。
|
|
|
|
|
|
- 不一次性重写编辑器 UI。
|
|
|
|
|
|
- 不在本设计中实现 Phase C 流式 apply / review session。
|
|
|
|
|
|
- 不把 Page AI panel 或 Hermes/Reasonix 工具链混入本次编辑器 runtime 拆分。
|
|
|
|
|
|
|
|
|
|
|
|
## 6. 目标模块布局
|
|
|
|
|
|
|
|
|
|
|
|
建议新增目录:
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
rust/spikes/leptos-tiptap-spike/src/
|
|
|
|
|
|
lib.rs
|
|
|
|
|
|
editor_runtime/
|
|
|
|
|
|
mod.rs
|
|
|
|
|
|
extensions.rs
|
|
|
|
|
|
command_sync.rs
|
|
|
|
|
|
history_safe_commands.rs
|
|
|
|
|
|
attachment_links.rs
|
|
|
|
|
|
attachment_upload.rs
|
|
|
|
|
|
local_markdown_paths.rs
|
|
|
|
|
|
dom_selection.rs
|
|
|
|
|
|
overlays.rs
|
|
|
|
|
|
block_menu.rs
|
|
|
|
|
|
table_toolbar.rs
|
|
|
|
|
|
mindmap_node_view.rs
|
|
|
|
|
|
bridge_events.rs
|
|
|
|
|
|
persistence.rs
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
第一阶段可以只拆高频问题模块,不强求一次建完所有文件。
|
|
|
|
|
|
|
|
|
|
|
|
## 7. 分阶段执行清单
|
|
|
|
|
|
|
|
|
|
|
|
### P0:热点函数归属表和基线保护
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] 列出当前 `src/lib.rs` 中最近 bug 高频函数的归属模块:
|
|
|
|
|
|
- `selected_local_attachment_link_in_editor_state` -> `attachment_links.rs`
|
|
|
|
|
|
- `selected_local_attachment_link_text` -> `attachment_links.rs` / `dom_selection.rs`
|
|
|
|
|
|
- `sync_persisted_editor_command` -> `command_sync.rs`
|
|
|
|
|
|
- `apply_html_update` / `apply_document_update` -> `command_sync.rs`,并标记 history 风险
|
|
|
|
|
|
- `delete_top_level_block_html` / `reorder_top_level_block_html` -> 待替换为 `history_safe_commands.rs`
|
|
|
|
|
|
- upload slash action / local asset path -> `attachment_upload.rs` / `local_markdown_paths.rs`
|
|
|
|
|
|
- toolbar/block menu DOM anchor -> `overlays.rs` / `block_menu.rs`
|
|
|
|
|
|
- [ ] 建立 history 风险清单:所有用户编辑动作中仍调用 `set_content` 或 HTML 整文替换的路径必须登记。
|
|
|
|
|
|
- [ ] 保留当前已通过的 `scripts/task488-local-attachment-link-delete-undo-smoke.js` 作为 RED/GREEN 基线。
|
|
|
|
|
|
|
|
|
|
|
|
### P1:抽出附件链接和 history-safe delete
|
|
|
|
|
|
|
2026-05-24 22:18:44 +08:00
|
|
|
|
- [x] 新增 `editor_runtime/attachment_links.rs`。
|
|
|
|
|
|
- [x] 迁出本地附件链接识别:
|
2026-05-24 21:03:33 +08:00
|
|
|
|
- DOM selection fallback。
|
|
|
|
|
|
- Tiptap editor state link attributes 判断。
|
|
|
|
|
|
- `/api/local-folder/files/open` 链接识别。
|
2026-05-24 22:18:44 +08:00
|
|
|
|
- [x] 新增 `editor_runtime/history_safe_commands.rs`。
|
|
|
|
|
|
- [x] 将“选中附件链接文本后 Delete/Backspace”收口为命名函数,例如 `delete_selected_attachment_link_with_history(...)`。
|
|
|
|
|
|
- [x] 验证 `task488` 仍通过。
|
2026-05-24 21:03:33 +08:00
|
|
|
|
|
|
|
|
|
|
### P2:抽出 command sync / persistence
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] 新增 `editor_runtime/command_sync.rs`。
|
|
|
|
|
|
- [ ] 迁出:
|
|
|
|
|
|
- `read_editor_snapshot`
|
|
|
|
|
|
- `sync_editor_outputs`
|
|
|
|
|
|
- `sync_persisted_editor_command`
|
|
|
|
|
|
- change/status event dispatch 的编辑器侧包装
|
|
|
|
|
|
- [ ] 明确 `set_content` 只允许用于:
|
|
|
|
|
|
- 初始加载
|
|
|
|
|
|
- host 替换文档
|
|
|
|
|
|
- 外部同步/恢复
|
|
|
|
|
|
- 非用户编辑的兼容兜底
|
|
|
|
|
|
- [ ] 用户编辑动作必须优先走 Tiptap command/transaction。
|
|
|
|
|
|
|
|
|
|
|
|
### P3:抽出附件上传与本地 Markdown 路径
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] 新增 `editor_runtime/attachment_upload.rs`。
|
|
|
|
|
|
- [ ] 新增 `editor_runtime/local_markdown_paths.rs`。
|
|
|
|
|
|
- [ ] 迁出 slash 上传附件、图片、Office/PDF/code 文件的编辑器内插入逻辑。
|
|
|
|
|
|
- [ ] 明确 editor 只负责插入附件链接/块,资源保存位置和归属仍由 shell/Rust API 合同决定。
|
|
|
|
|
|
- [ ] 覆盖:
|
|
|
|
|
|
- 上传第一个/第二个附件后链接仍可点击。
|
|
|
|
|
|
- 刷新后链接不退化为普通外链。
|
|
|
|
|
|
- secondary pane 上传与 primary pane 隔离。
|
|
|
|
|
|
|
|
|
|
|
|
### P4:抽出 DOM bridge / overlay / block menu
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] 新增 `editor_runtime/dom_selection.rs`、`overlays.rs`、`block_menu.rs`。
|
|
|
|
|
|
- [ ] 迁出 selection、toolbar anchor、slash menu anchor、block menu anchor、image/table toolbar anchor。
|
|
|
|
|
|
- [ ] 对所有 keydown/click 捕获建立“谁先处理、谁 stop propagation”的规则,避免 Tiptap 原生快捷键与外层 window listener 互相吞事件。
|
|
|
|
|
|
- [ ] 覆盖:
|
|
|
|
|
|
- `Ctrl+Z/Ctrl+Y`
|
|
|
|
|
|
- slash menu
|
|
|
|
|
|
- block menu
|
|
|
|
|
|
- table toolbar
|
|
|
|
|
|
- attachment context menu
|
|
|
|
|
|
|
|
|
|
|
|
### P5:抽出 mindmap node view
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] 新增 `editor_runtime/mindmap_node_view.rs`。
|
|
|
|
|
|
- [ ] 迁出 mindmap block 的 node view、runtime mount、projection refresh、simplemindmap event bridge。
|
|
|
|
|
|
- [ ] 保持 mindmap 只是编辑器块视图,不成为正文事实源。
|
|
|
|
|
|
|
|
|
|
|
|
### P6:收尾
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] `src/lib.rs` 只保留:
|
|
|
|
|
|
- module imports
|
|
|
|
|
|
- top-level component装配
|
|
|
|
|
|
- 少量常量和 view glue
|
|
|
|
|
|
- [ ] 单个模块超过约 800 行时继续拆分。
|
|
|
|
|
|
- [ ] 运行 CodeGraph sync/index,确认新增 Rust 模块被索引。
|
|
|
|
|
|
- [ ] 更新 worker skill/task template:编辑器 bug 默认先查 `editor_runtime/*`,再回到 `lib.rs`。
|
|
|
|
|
|
|
|
|
|
|
|
## 8. History 安全规则
|
|
|
|
|
|
|
|
|
|
|
|
用户直接触发的编辑动作:
|
|
|
|
|
|
|
|
|
|
|
|
- 必须优先使用 Tiptap command/transaction。
|
|
|
|
|
|
- 如果临时必须使用 `set_content`,必须在 bug/design 中标明为什么不能走 command,并补一个 undo/redo 不支持或受限的说明。
|
|
|
|
|
|
- 新增编辑动作的 smoke 或单测应明确检查 undo/redo,除非该动作按产品定义不可撤销。
|
|
|
|
|
|
|
|
|
|
|
|
非用户编辑动作:
|
|
|
|
|
|
|
|
|
|
|
|
- 初始加载、host 替换文档、外部文件 watcher 重载、冲突恢复可以使用 `set_content`,但必须避免污染用户 undo stack。
|
|
|
|
|
|
- 外部同步应与 working copy 冲突模型结合,不能悄悄覆盖当前用户编辑。
|
|
|
|
|
|
|
|
|
|
|
|
## 9. Worker 协同规则
|
|
|
|
|
|
|
|
|
|
|
|
拆分后给 ClaudeCode / Reasonix 的任务应限定为:
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
允许读取/修改:
|
|
|
|
|
|
- rust/spikes/leptos-tiptap-spike/src/editor_runtime/attachment_links.rs
|
|
|
|
|
|
- rust/spikes/leptos-tiptap-spike/src/editor_runtime/history_safe_commands.rs
|
|
|
|
|
|
- scripts/task488-local-attachment-link-delete-undo-smoke.js
|
|
|
|
|
|
|
|
|
|
|
|
禁止:
|
|
|
|
|
|
- 修改 shell resource open 逻辑
|
|
|
|
|
|
- 修改 Rust tree command 语义
|
|
|
|
|
|
- 整文重写 src/lib.rs
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
采纳条件:
|
|
|
|
|
|
|
|
|
|
|
|
- worker handoff 明确命中哪个模块。
|
|
|
|
|
|
- diff 不跨越无关模块。
|
|
|
|
|
|
- 主控能运行对应 smoke。
|
|
|
|
|
|
- UI/浏览器行为必须有截图或 result.json 可审计证据。
|
|
|
|
|
|
|
|
|
|
|
|
## 10. 执行策略
|
|
|
|
|
|
|
|
|
|
|
|
本设计与 `3-19` 同步采用 Codex 主控、Reasonix 短跑 worker:
|
|
|
|
|
|
|
|
|
|
|
|
- Codex 负责编辑器主线边界、history 规则、最终 diff 复核和 smoke 验收。
|
|
|
|
|
|
- Reasonix 只处理短任务,不在一个 run 里同时做架构判断、代码迁移和浏览器验收。
|
|
|
|
|
|
- 同时最多 2 个 Reasonix worker;每批完成后必须先读取 `process-handoff.md/json` 和 Hindsight `reasonix` recall,再进入下一批。
|
|
|
|
|
|
- Batch 0 只读,不修改文件,用来生成 `src/lib.rs` 热点函数归属表和 `set_content` / HTML 整文替换风险表。
|
|
|
|
|
|
- 实施批次必须优先放在 `editor_runtime/*`,避免继续向 `src/lib.rs` 追加大块逻辑。
|
|
|
|
|
|
|
|
|
|
|
|
当前建议批次:
|
|
|
|
|
|
|
|
|
|
|
|
- Batch 0 / R2:只读审计 `rust/spikes/leptos-tiptap-spike/src/lib.rs` 中 history、`set_content`、附件链接删除、上传插入相关路径,输出函数归属表和风险等级。
|
|
|
|
|
|
- Batch 1:先抽出 `attachment_links.rs` 和最小 `history_safe_commands.rs`,保持 `task488` 通过;随后优先处理块菜单 delete 仍走 HTML 整文替换的 history 风险。
|
|
|
|
|
|
- Batch 2:抽出 `command_sync.rs` / `persistence.rs`,登记仍允许 `set_content` 的 host 替换和外部同步路径。
|
|
|
|
|
|
- Batch 3:抽出 `attachment_upload.rs` / `local_markdown_paths.rs`,覆盖第一个/第二个附件上传和点击打开 smoke。
|
|
|
|
|
|
- Batch 4:抽出 DOM selection / overlay / block menu,建立 keydown/click 捕获顺序规则。
|
|
|
|
|
|
|
|
|
|
|
|
Batch 0 验收标准:
|
|
|
|
|
|
|
|
|
|
|
|
- R2 必须列出搜索过的函数、文件位置、当前职责、建议目标模块、history 风险和 smoke 建议。
|
|
|
|
|
|
- R2 不允许修改源码、脚本、文档或运行 git 写操作。
|
|
|
|
|
|
- Codex 只采纳能被本地源码定位和现有 bug 证据支持的结论。
|
|
|
|
|
|
- 若 R2 输出泛化建议但无法对应具体函数,视为不可采纳,只记录为 worker 质量问题。
|
|
|
|
|
|
|
|
|
|
|
|
### 10.1 Batch 0 执行记录(2026-05-24)
|
|
|
|
|
|
|
|
|
|
|
|
Reasonix R2 run:
|
|
|
|
|
|
|
|
|
|
|
|
- run id: `reasonix-2026-05-24T12-38-22-683Z-3826b3b6`
|
|
|
|
|
|
- handoff: `/home/lix/.codex/runtime/reasonix-coding-worker/reasonix-2026-05-24T12-38-22-683Z-3826b3b6/process-handoff.md`
|
|
|
|
|
|
- 类型:只读审计,无工作区改动。
|
|
|
|
|
|
- Codex 复核:已抽样用 `rg` 核对关键符号位置;Hindsight `reasonix` bank 可 recall 到该 handoff。
|
|
|
|
|
|
|
|
|
|
|
|
可采纳结论:
|
|
|
|
|
|
|
|
|
|
|
|
- 最近已修复的附件链接 `Delete/Backspace` 路径现在使用 `editor.delete_selection()`,属于可迁入 `history_safe_commands.rs` 的正向模板。
|
|
|
|
|
|
- `selected_local_attachment_link_text` 和 `selected_local_attachment_link_in_editor_state` 可优先迁入 `attachment_links.rs`,迁移本身应保持行为不变并继续跑 `task488`。
|
|
|
|
|
|
- 仍需登记的高风险用户编辑路径:
|
|
|
|
|
|
- 块菜单 delete:`delete_top_level_block_html` -> `apply_html_update` -> `editor.set_content(TiptapContent::html(...))`,用户删除动作绕过 history,后续应替换为 Tiptap command/transaction。
|
|
|
|
|
|
- 块类型转换或 slash action 中经过 `apply_document_update` 的路径:`editor.set_content(TiptapContent::json(...))` 可能绕过 history,需要逐调用点确认。
|
|
|
|
|
|
- `run_block_turn_into_page_action` / `run_block_turn_into_page`:整文 JSON 替换,是否可撤销属于产品决策,不在第一刀默认修改。
|
|
|
|
|
|
- 可接受的 `set_content` 路径:
|
|
|
|
|
|
- `apply_host_document_payload`
|
|
|
|
|
|
- 外部 block delta listener
|
|
|
|
|
|
- 编辑器初始化恢复本地草稿
|
|
|
|
|
|
这些是非用户直接编辑动作,允许保留,但必须避免污染用户 undo stack 和覆盖当前用户编辑。
|
|
|
|
|
|
|
|
|
|
|
|
本轮发现的 worker 协同问题:
|
|
|
|
|
|
|
|
|
|
|
|
- Reasonix 对大文件只读审计有效,但输出中的“行号和风险分级”只能作为候选事实;主控必须用本地 `rg` / 源码抽样复核。
|
|
|
|
|
|
- Reasonix runner 产出 `completed` 结果后底层 `reasonix acp` 进程未自动退出;主控必须在每批结束时检查并清理本轮启动进程。
|
|
|
|
|
|
|
2026-05-24 22:18:44 +08:00
|
|
|
|
### 10.2 Batch 1 执行记录(2026-05-24)
|
|
|
|
|
|
|
|
|
|
|
|
Reasonix run:
|
|
|
|
|
|
|
|
|
|
|
|
- run id: `reasonix-2026-05-24T14-00-12-979Z-1125fb29`
|
|
|
|
|
|
- worker worktree: `/mnt/Data1T/mnote-wt-5-28-attachment-history-b1`
|
|
|
|
|
|
- handoff: `/home/lix/.codex/runtime/reasonix-coding-worker/reasonix-2026-05-24T14-00-12-979Z-1125fb29/process-handoff.md`
|
|
|
|
|
|
- 类型:窄范围机械迁移,允许修改 `src/lib.rs` 和 `src/editor_runtime/{mod.rs,attachment_links.rs,history_safe_commands.rs}`。
|
|
|
|
|
|
|
|
|
|
|
|
采纳内容:
|
|
|
|
|
|
|
|
|
|
|
|
- 新增 `editor_runtime/mod.rs`。
|
|
|
|
|
|
- 新增 `editor_runtime/attachment_links.rs`,迁出本地附件链接的 DOM selection fallback 与 Tiptap editor state link attributes 判断。
|
|
|
|
|
|
- 新增 `editor_runtime/history_safe_commands.rs`,把选中本地附件链接后的 `Delete/Backspace` 删除收口到 `delete_selected_attachment_link_with_history(...)`。
|
|
|
|
|
|
- `src/lib.rs` 只保留模块装配和 keydown handler 调用,不再直接承载本地附件链接识别函数。
|
|
|
|
|
|
|
|
|
|
|
|
Codex 主控复核修正:
|
|
|
|
|
|
|
|
|
|
|
|
- worker 初版把底层错误格式化为 `删除附件引用失败:{e}`,调用处也会加同一前缀;主控已改为 `error.to_string()`,避免用户反馈重复。
|
|
|
|
|
|
- worker 初版自报 `cargo check` 通过依赖临时 `reference-code` symlink;主控在 worktree 和主工作区分别重新验证。
|
|
|
|
|
|
- Reasonix runner 写出 completed 后底层 `reasonix acp` 残留,主控已清理本轮进程。
|
|
|
|
|
|
|
|
|
|
|
|
已通过验证:
|
|
|
|
|
|
|
|
|
|
|
|
- `cargo fmt --manifest-path rust/Cargo.toml --all --check`
|
|
|
|
|
|
- `cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`(35 个既有 warning)
|
|
|
|
|
|
- `cargo build --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml --target wasm32-unknown-unknown --release`
|
|
|
|
|
|
- `wasm-bindgen rust/spikes/leptos-tiptap-spike/target/wasm32-unknown-unknown/release/mnote_leptos_tiptap_spike.wasm --target web --out-dir rust/spikes/leptos-tiptap-spike/generated/island --out-name mnote-leptos-tiptap-spike-island`
|
|
|
|
|
|
- `node scripts/task488-local-attachment-link-delete-undo-smoke.js`
|
|
|
|
|
|
- 结果:`ok=true`
|
|
|
|
|
|
- 步骤:`uploaded -> selected -> deleted -> undo -> redo`
|
|
|
|
|
|
- 证据:`tmp/task488-local-attachment-link-delete-undo-smoke/result.json`、`tmp/task488-local-attachment-link-delete-undo-smoke/after-redo.png`
|
|
|
|
|
|
- `codegraph index . --force && codegraph status .`
|
|
|
|
|
|
- 结果:索引 318 个文件,状态 up to date。
|
|
|
|
|
|
- 复核:`delete_selected_attachment_link_with_history`、`selected_local_attachment_link_text`、`is_local_attachment_link_selected` 均可通过 CodeGraph 搜索定位到 `editor_runtime/*`。
|
|
|
|
|
|
|
2026-05-24 21:03:33 +08:00
|
|
|
|
## 11. 测试与验收
|
|
|
|
|
|
|
|
|
|
|
|
### Rust 检查
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
cargo fmt --manifest-path rust/Cargo.toml --all --check
|
|
|
|
|
|
cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml
|
|
|
|
|
|
cargo build --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml --target wasm32-unknown-unknown --release
|
|
|
|
|
|
wasm-bindgen rust/spikes/leptos-tiptap-spike/target/wasm32-unknown-unknown/release/mnote_leptos_tiptap_spike.wasm --target web --out-dir rust/spikes/leptos-tiptap-spike/generated/island --out-name mnote-leptos-tiptap-spike-island
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Browser smoke
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
node scripts/task488-local-attachment-link-delete-undo-smoke.js
|
|
|
|
|
|
node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js
|
|
|
|
|
|
node scripts/task472-side-target-secondary-pane-smoke.js
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
后续拆到 block menu / table toolbar 时,应补对应 smoke,不复用附件 smoke 代替。
|
|
|
|
|
|
|
|
|
|
|
|
## 12. 风险与控制
|
|
|
|
|
|
|
|
|
|
|
|
- 风险:拆模块时改变 Leptos signal 捕获和生命周期。
|
|
|
|
|
|
- 控制:每次只迁一个行为域;迁移后立即跑 wasm build 和浏览器 smoke。
|
|
|
|
|
|
- 风险:为了通过编译把函数参数扩得过大。
|
|
|
|
|
|
- 控制:只在边界稳定后引入小型 context struct;不要先抽象大而全 runtime context。
|
|
|
|
|
|
- 风险:把 shell/resource 语义搬进 editor 模块。
|
|
|
|
|
|
- 控制:editor 只发出 intent,不决定 workspace/resource 真相。
|
|
|
|
|
|
- 风险:继续产生新的巨型模块。
|
|
|
|
|
|
- 控制:单模块超过约 800 行必须拆出子模块。
|
|
|
|
|
|
|
|
|
|
|
|
## 13. Done Gate
|
|
|
|
|
|
|
|
|
|
|
|
本设计移动到 `done/` 前必须满足:
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] `attachment_links.rs` 和 `history_safe_commands.rs` 已落地。
|
|
|
|
|
|
- [ ] `command_sync.rs` 已落地,用户编辑动作与 host 替换动作边界明确。
|
|
|
|
|
|
- [ ] 至少一个仍使用 `set_content` 的用户编辑路径已迁到 Tiptap command/transaction。
|
|
|
|
|
|
- [ ] `task488` 通过,且至少覆盖一次真实键盘 `Ctrl+Z/Ctrl+Y`。
|
|
|
|
|
|
- [ ] 新增 editor_runtime Rust 模块能被 CodeGraph 定位。
|
|
|
|
|
|
- [ ] `src/lib.rs` 不再新增附件/history/DOM bridge 大块逻辑。
|
|
|
|
|
|
|
|
|
|
|
|
## 14. 后续问题
|
|
|
|
|
|
|
|
|
|
|
|
- 是否把 `leptos-tiptap-spike` 从 spike 正式改名:不作为本设计前置,等模块拆分后再评估。
|
|
|
|
|
|
- 是否回 upstream `reference-code/leptos-tiptap` 增加命令:只有当底层 bridge 缺少通用 Tiptap command 时才考虑;MNote 特有行为优先留在 `editor_runtime`。
|
|
|
|
|
|
- 是否引入更强类型的 editor command contract:P1-P3 完成后再评估,不作为第一阶段阻塞项。
|