138 lines
3.5 KiB
Markdown
138 lines
3.5 KiB
Markdown
# [recycle] mnote Rust Block Editor Edita Spike v0
|
|
|
|
> 更新时间:2026-04-18
|
|
|
|
## 1. 目标
|
|
|
|
本 spike 只回答一个问题:
|
|
|
|
`edita-core` 的 `Editor / Block / Command / 无头执行` 边界,是否适合作为 `mnote` 新主编辑器第一阶段的命令核参考。
|
|
|
|
结论先写:
|
|
|
|
- 适合直接借 `Editor`
|
|
- 适合直接借 `Command`
|
|
- 适合借 `Block` 作为注册与分发思路
|
|
- 适合借 `无头执行`
|
|
- 不适合直接拿来当最终 `mnote` block document 模型
|
|
- 不适合直接拿来当最终前端胶水
|
|
|
|
## 2. 参考入口
|
|
|
|
- `/mnt/Data1T/mnote/design/05-editor-mainline/reference-code/edita/edita-core/src/lib.rs`
|
|
- `/mnt/Data1T/mnote/design/05-editor-mainline/reference-code/edita/edita/src/editor.rs`
|
|
- `/mnt/Data1T/mnote/design/05-editor-mainline/reference-code/edita/edita/src/state.rs`
|
|
|
|
## 3. 直接可复用面
|
|
|
|
### 3.1 `Editor`
|
|
|
|
`Editor<Node, State, Input>` 的价值不在 UI,而在:
|
|
|
|
- 持有统一 `state`
|
|
- 提供统一命令入口
|
|
- 提供 block registry
|
|
- 允许 fallback block
|
|
|
|
这和 `mnote` 第一阶段要的“无头编辑器容器”是对齐的。
|
|
|
|
对 `mnote` 的映射建议:
|
|
|
|
- `Node` 不直接映射前端 DOM 节点
|
|
- `State` 映射 `EditorDocument`
|
|
- `Input` 第一阶段不必暴露给外部 UI,可先收口成 `EditorCommandEnvelope`
|
|
|
|
### 3.2 `Command`
|
|
|
|
`Command<State>` 很适合当 `mnote-editor-core` 的最小命令执行边界。
|
|
|
|
建议保留这层思想,但不要照搬 trait 名:
|
|
|
|
- `replace_block`
|
|
- `insert_block_after`
|
|
- `delete_block`
|
|
- `split_block`
|
|
- `merge_with_previous`
|
|
- `move_block`
|
|
- `indent_block`
|
|
- `outdent_block`
|
|
- `toggle_heading_collapse`
|
|
|
|
这些命令应当最终作用在 `EditorDocument` 上,而不是作用在 Leptos 组件状态上。
|
|
|
|
### 3.3 `Block`
|
|
|
|
`Block` trait 适合借来做“块类型注册 + 输入接管”思路,但当前实现更偏 parser pipeline。
|
|
|
|
`mnote` 第一阶段不建议直接照抄,因为我们更需要:
|
|
|
|
- 树形 block document
|
|
- 固定字符串 ID
|
|
- `BlockProps`
|
|
- `content_node`
|
|
- 引用 token
|
|
|
|
因此这里只借“块处理器是可注册单元”的思路。
|
|
|
|
### 3.4 无头执行
|
|
|
|
这是最值得采用的点。
|
|
|
|
新主编辑器必须先做无头执行,因为:
|
|
|
|
- CLI 要共用
|
|
- AI 要共用
|
|
- Web UI 只是壳
|
|
|
|
因此 `edita-core` 的无头执行边界适合直接进入采用矩阵。
|
|
|
|
## 4. 不直接采用的部分
|
|
|
|
### 4.1 不直接采用其最终 block 形态
|
|
|
|
原因:
|
|
|
|
- `mnote` 要的是块树,不是只围绕 parser block 运转
|
|
- `mnote` 要保留 `page_reference / block_reference / media_placeholder / progress_placeholder`
|
|
- 还要和 kernel `content_node` 边界对齐
|
|
|
|
### 4.2 不直接采用其 UI/editor 外壳
|
|
|
|
原因:
|
|
|
|
- 我们的 UI 壳后面要接 Leptos / kode
|
|
- `edita-core` 当前更适合做 headless 胶水参考
|
|
|
|
## 5. Spike 结论
|
|
|
|
`edita-core` 在 `mnote` 第一阶段的定位固定为:
|
|
|
|
- 采用:`Editor`
|
|
- 采用:`Command`
|
|
- 部分采用:`Block`
|
|
- 采用:`无头执行`
|
|
- 不采用:最终产品 UI
|
|
- 不采用:最终文档模型
|
|
|
|
## 6. 后续胶水建议
|
|
|
|
后续实现时,建议在 `mnote-editor-core` 里形成下面三层:
|
|
|
|
1. `EditorDocument`
|
|
2. `EditorCommand`
|
|
3. `EditorRuntime`
|
|
|
|
其中:
|
|
|
|
- `EditorRuntime` 借 `edita-core` 的无头执行边界
|
|
- `EditorCommand` 借 `Command`
|
|
- `EditorDocument` 不直接复用 `edita-core` block 结构,而是自定义
|
|
|
|
## 7. 本结论如何进入后续任务
|
|
|
|
- `task-051` 完成判定:
|
|
- 本文明确写清 `Editor / Block / Command / 无头执行 / 胶水`
|
|
- `task-055` 开始时:
|
|
- `mnote-editor-core` 优先实现无头编辑器容器
|
|
- 不先实现 Leptos UI
|