# [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
