OpLog 与 DocState
快速概览
- OpLog = 构成文档历史的事件 / 操作序列
- DocState = 文档当前具象化的状态
二者分离使得时光旅行、高效同步与灵活存储策略成为可能。
核心概念
OpLog(操作日志)
- 仅追加的操作序列
- 保存因果关系与元数据
DocState(文档状态)
- 文档当前的具象视图
- 实际的数据结构与值
- 应用读取和展示的数据来源
优势
- 内存效率:中继服务器只加载 OpLog,而不加载状态
- 时光旅行:回溯历史而不丢失操作日志
- 快速启动:先加载快照获取状态,再按需拉取历史
- 灵活存储:两者可分开存储以便优化
const = new ();
// 编辑会同时更新两者
.("text").(0, "Hello");
.(.()); // 最新已知版本
.(.()); // 当前 DocState 的版本
// 当文档处于 attached 状态时,两者相同时光旅行与分离
const = new ();
.("text").(0, "v1");
const = .();
.("text").(2, " -> v2");
// checkout 旧版本:DocState 与 OpLog 出现分歧
.();
.(.()); // 显示 v1 状态
.(.()); // 仍包含 v2
.(.()); // true
// 回到最新版本
.();Detached 状态:DocState 显示旧版本,但 OpLog 保留全部操作;默认禁用编辑。
导出策略
// update:仅导出 OpLog(用于同步)
const = .({ : "update" });
// snapshot:导出 OpLog + DocState(用于持久化)
const = .({ : "snapshot" });
// shallow:最小化 OpLog + DocState(快速启动)
const = .({ : "shallow-snapshot", : .() });常见模式
中继服务器(仅 OpLog)
class {
private : ;
constructor() {
this. = new ();
this..(); // 从不具象化状态
}
(: ) {
this..();
}
}最佳实践
- 导出模式选择:update 用于同步,snapshot 用于持久化,shallow 适合快速启动
- 按场景优化:
- 编辑器:同时在内存中保留两者
- 中继服务:只保留 OpLog
相关文档
- Attached / Detached 状态——文档与容器的状态
- 浅快照——如何裁剪历史
- 时光旅行——使用 checkout