Frontiers

Frontiers 是 Loro 通过识别“前沿”操作(即尚未被后续操作覆盖的最新操作)来紧凑表示文档版本的方法。

Frontiers 是什么?

你可以把 Frontiers 看作文档历史上的书签。与列出每位协作者全部更改的版本向量不同,Frontiers 只指向边界操作,所有祖先通过因果关系被隐式包含。

基本用法

import {  } from "loro-crdt";
 
const  = new ();
const  = .("content");
.(0, "Hello World");
 
// 获取当前 frontiers(通常只有 1~2 个元素)
const  = .();
.(); // [{ peer: "...", counter: 0 }]
 
// 使用 frontiers 保存检查点
const  = .();
.(5, " Beautiful");
 
// 恢复到检查点
.();
.(.()); // 回到 "Hello World"

什么时候使用 Frontiers

Frontiers 适用于:

  1. 创建检查点——为文档历史打标签
  2. 时光旅行——高效跳转到特定操作
  3. 节省存储——即便协作者众多仍保持紧凑(通常 1~2 个元素,而版本向量需 N 项)
  4. 记录里程碑——保存重要状态

快速对比

维度Frontiers版本向量
大小通常 1~2 个元素随节点数量增长
用途检查点、时光旅行同步、差异比较
存储非常紧凑节点越多越大
未知操作无法判断包含哪些操作可以精确获知包含的操作

实战示例

import {  } from "loro-crdt";
 
const  = new ();
const  = .("content");
const  = new ();
 
// 使用 frontiers 保存检查点
.(0, "Draft version");
.("draft", .());
 
// 继续修改
.(0, 5);
.(0, "Final");
.("final", .());
 
// 恢复任意检查点
.(.("draft"));
.(.()); // "Draft version"

重要限制

Frontiers 在面对未知操作时有一个限制:

  • 当某个 Frontier 指向你尚未获取的操作时,你无法确定该版本包含了哪些具体操作 ID
  • 版本向量没有此限制:它显式记录所有 peer 及其操作计数,因此总能知道确切包含的操作

示例

import {  } from "loro-crdt";
 
// 如果你收到 frontier [{ peer: "unknown-peer", counter: 42 }]
// 在缺少 "unknown-peer" 的操作时:
// - Frontiers:无法判断包含哪些具体操作
// - 版本向量:会显示 { "unknown-peer": 43 },明确表示包含 0~42 的操作
 
const  = new ();
const  = .();
// Frontiers 虽然紧凑,但要了解完整信息需要操作历史

因此,Frontiers 更适合你能访问操作历史的场景(例如本地文档的检查点),而在不同节点之间同步时,如果无法共享完整历史,则更建议使用版本向量。

与版本向量互转

Loro 支持两种表示之间的无缝转换:

import {  } from "loro-crdt";
 
const  = new ();
const  = .();
const  = .();        // 转成版本向量
const  = .();  // 再转回 frontiers

进一步了解

想深入理解 Frontiers 如何结合 DAG 结构与因果顺序,请参阅版本深潜