草稿与同步
设计意图
编辑环境中存在一个天然矛盾:用户希望内容「随时保存,永不丢失」,但网络可能不稳定,服务器可能暂时不可用。mdocs 用本地优先 + 按需发布的草稿机制来解决这个问题。
架构
用户编辑
│
▼
Lexical 编辑器 (富文本)
│
├── 自动保存(1000ms 防抖)──────────────────┐
│ │ │
│ ▼ │
│ IndexedDB(浏览器本地数据库) │
│ 存储:Lexical JSON + 元数据 │
│ │
├── 自动发布(空闲 30 秒后)───────────────────┤
│ │ │
│ ▼ │
│ 后端 API(更新 JSON 文件 + SQLite 记录) │
│ │
├── 手动「发布」──────────────────────────────┤
│ │ │
│ ▼ │
│ 后端 API(更新 JSON 文件 + SQLite 记录) │
│ │
└── 失焦 / 切换标签页 ────────────────────────┘
立即保存当前内容(防数据丢失的最后防线)
三层保存策略
| 触发时机 | 保存目标 | 说明 |
|---|
| 编辑后 1 秒无操作 | IndexedDB | 防抖,避免频繁写入 |
| 编辑器失焦(blur) | IndexedDB | 切换到其他元素时立即保存 |
| 标签页隐藏(visibilitychange) | IndexedDB | 用户切走或关闭标签时保底 |
发布流程
自动发布(推荐)
当用户停止编辑 30 秒后,系统会自动将本地草稿发布到服务器。每 10 秒扫描一次,发现空闲的未发布草稿即自动推送。
手动发布
- 编辑器中点击「发布」按钮
- 编辑器内容(Lexical JSON)序列化后发送到后端
- 后端写入 JSON 文件并更新数据库记录
- 发布成功后,清除本地草稿
发布失败
无论自动还是手动,发布失败时草稿保留在本地。
自动发布 404 场景:当服务端文档已被删除但本地仍有草稿时,自动发布会捕获 404 错误,将草稿标记为发布失败(不再重复扫描),并在顶部 Toast 提示用户。用户可前往设置页的「未发布草稿」列表,看到失败的草稿,点击「另存为新文档」即可选择域和目录,将草稿内容作为全新文档重新发布。
其他失败场景:系统会显示冲突提示,用户需要手动处理后重新发布。
断网场景
- 断网时:继续编辑,草稿保存在 IndexedDB,一切正常
- 误关页面:重新打开文档,自动从 IndexedDB 恢复上次编辑内容
- 崩溃后恢复:IndexedDB 数据持久化,不因浏览器崩溃丢失
多端冲突
当本地草稿与服务器版本不一致时,发布可能失败。系统会显示冲突提示,用户需要手动处理后再重新发布。
设计取舍
- 本地优先:编辑体验不依赖网络,断网时草稿存 IndexedDB,网络恢复后自动或手动发布到服务器,让他人可见
- 自动发布 + 失败兜底:空闲时自动推送草稿到服务器;发布失败时草稿保留本地,提示用户手动处理
- IndexedDB 而非 localStorage:IndexedDB 存储容量大(通常几十 MB 起)、支持异步读写、不会阻塞 UI 线程