- 后端
【免费下载链接】loro
Make your JSON data collaborative and version-controlled with CRDTs
导读
本文档深入剖析 Loro 仓库中的核心工程迁移计划(plans/20260306-merge-loro-crates.md):将当前拆分为crates/loro(公共门面)与crates/loro-internal(引擎实现)的双 crate 架构,合并为一个唯一发布的 Rust crateloro。文中完整呈现了从行为基线锁定、引擎导入、语义合并、表面塌缩到 WASM 消费者迁移、移除 shim 的七个阶段,每个阶段均给出目标、范围、工作项、退出标准、验证命令与风险;并结合仓库源码(crates/loro/Cargo.toml、crates/loro/src/lib.rs、crates/loro/src/event.rs、crates/loro-internal/src/lib.rs、crates/loro-wasm/Cargo.toml等)验证了现状描述与每项验证命令的可执行性。读完本文,你将理解该计划为何按此顺序推进、每个阶段如何定义完成,以及如何用cargo test、cargo bench和全仓搜索来守卫生成过程中不引入语义回退。
说明:该计划文档状态为
Draft(2026-03-06),所有阶段状态均为Not Started,本文是对其完整内容的展开与源码佐证,不构成对已实施变更的描述。
背景:双 crate 拆分带来的两类问题
当前 Loro 的 Rust 实现被拆分为两个 crate(见仓库 crates/loro/Cargo.toml 与 crates/loro-internal/Cargo.toml):
crates/loro:面向公众、有文档、语义稳定的门面(facade)crate。它通过 path 依赖直接引用loro-internal = { path = "../loro-internal", version = "1.16.2" }。crates/loro-internal:承载绝大部分实现的引擎 crate,其 Cargo.toml 描述本身就写着"Loro internal library. Do not use it directly as it's not stable."(内部库,请勿直接使用,它不稳定)。
这种拆分产生两类问题:
- 重复的 API 层与类型表面:门面 crate 围绕引擎类型重新包装出一套公开类型,两套类型并存。
- 层间转换开销:门面与引擎之间反复做不必要的转换。
计划明确指出,成本最高的转换并不在于外层LoroDoc包装本身,而集中在:
crates/loro/src/event.rs中的事件桥接(event bridging);ValueOrHandler到ValueOrContainer的转换;Diff与DiffBatch的重新物化(re-materialization);- 围绕内部 handler 的容器句柄重新包装(container handle re-wrapping)。
以 crates/loro/src/event.rs 为例,源码可以验证这一判断:DiffEvent<'a>通过From<DiffEventInner<'a>>桥接、ContainerDiff<'a>通过From<&'a ContainerDiffInner>桥接、Diff<'a>通过From<&'a DiffInner>桥接——每个事件触发时,list diff 中的每个插入值都要执行ValueOrContainer::from(v.clone())重新包装。这正是计划要消除的 "facade-onlyDiffEventreconstruction"。
拆分带来的长期维护成本还包括:公开语义在一个 crate、引擎行为在另一个 crate,而第一方消费者(如crates/loro-wasm)直接依赖低层内部 API。因此,仅"物理搬移文件"而不塌缩重复类型层,只能降低组织复杂度,无法消除主要运行时开销。
目的与目标状态
计划的目标是:让loro成为核心实现唯一对外发布的 Rust crate,同时保持正确性并把迁移风险控制在可管理范围。
目标状态(target state)为:
- 唯一规范实现 crate:
loro; - 唯一规范
LoroDoc; - 唯一规范的 container / value / diff / event 表面;
- 没有任何第一方 crate 依赖
loro-internal; - 热路径上不再存在重复的 facade-to-engine 转换,除非是有意保留的兼容 shim。
Goals(目标)
- 将
crates/loro与crates/loro-internal合并为一个规范的 Rust crate。 - 保持用户依赖的现有公开语义,尤其是auto-commit 默认行为。
- 移除对热路径有实质性影响的重复类型层。
- 迁移期间工作区(workspace)始终保持可构建。
- 每个迁移阶段都给出明确的进入条件(entry criteria)、交付物(deliverables)、退出标准(exit criteria)与验证步骤(validation)。
Non-Goals(非目标)
- 重写 CRDT 引擎。
- 在合并期间重新设计无关 API。
- 在第一轮迭代中移除所有逃生舱(escape hatch)。
- 改变 JS 与 WASM 行为,除非 Rust 合并本身要求如此。
- 追求无收益的纯文件搬移——除非能带来可衡量的简化或性能收益。
硬约束(Hard Constraints)
loro::LoroDoc::new()必须保持当前 auto-commit 行为,除非有显式的公开 API 决策另有规定。- 导入/导出(import/export)、diff、checkout、undo、订阅(subscription)的正确性不得回退。
loro-wasm的 pending-event flush 不变量必须保持有效。- 工作区在每一个阶段边界都必须可构建。
- 性能敏感变更必须用针对性 benchmark 验证,而不能只看编译是否通过。
成功指标(Success Metrics)
crates/loro不再依赖loro-internal。- 没有任何第一方 crate import
loro-internal。 - 第一方热路径不再需要当前的 facade-only
DiffEvent重建。 - 异构读取路径(heterogeneous read paths)在规范 API 上不再需要重复的
ValueOrHandler→ValueOrContainer转换。 crates/loro/tests仍然是有效的公开兼容测试套件。- 公开 crate 文档继续随
loro发布,而不是随隐藏的引擎 crate 发布。
现状摘要(Current-State Summary,含源码佐证)
计划文档给出的现状如下,仓库源码均可逐一印证:
crates/loro/src/lib.rs用公开门面类型包装InnerLoroDoc与内部 handlers。源码第 100-106 行可看到pub struct LoroDoc { doc: InnerLoroDoc, ... },其中InnerLoroDoc即loro_internal::LoroDoc(crates/loro/src/lib.rs);new()的实现在创建InnerLoroDoc::default()后调用doc.start_auto_commit()(crates/loro/src/lib.rs)——这正是"auto-commit 默认行为"的源码落点,也是 Phase 2 必须守护的语义。crates/loro/src/event.rs从内部表示重建 event、diff、batch 类型。前面已列举From桥实现(crates/loro/src/event.rs),包含ListDiffItem::Insert中对每个值执行ValueOrContainer::from(v.clone())的重复物化。crates/loro-internal/src/lib.rs暴露的引擎表面远超应成为长期公开契约的范围。从 crates/loro-internal/src/lib.rs 可见其顶层公开了大量模块:arena、diff、diff_calc、handler、sync、oplog、encoding、container、cursor、dag、jsonpath、kv_store、txn、version、undo、pre_commit、estimated_size等,以及LoroDoc/LoroDocInner(内部由oplog、state、arena、config、txn、auto_commit、detached等字段构成,见 crates/loro-internal/src/lib.rs)。crates/loro-wasm大量导入loro-internal的低层项,因此合并必须包含消费者迁移计划,而不仅是 crate 搬移。这一点在依赖与源码两处都有直接证据:- crates/loro-wasm/Cargo.toml 直接声明
loro-internal = { path = "../loro-internal", features = ["wasm", "counter", "jsonpath"] }; - 对
crates/loro-wasm/src的检索显示大量loro_internal引用:convert.rs11 处、lib.rs7 处、awareness.rs/container_tree.rs/counter.rs各 1 处。
- crates/loro-wasm/Cargo.toml 直接声明
阶段总览(Tracking Dashboard)
计划用一张跟踪仪表盘管理七个阶段,每个阶段标记状态(Not Started/In Progress/Blocked/Done)、依赖关系与主要产出:
| Phase | 名称 | 状态 | 依赖 | 主要产出 |
|---|---|---|---|---|
| 0 | Lock behavior and perf baseline | Not Started | 无 | 基线测试与 benchmark 数字 |
| 1 | Import engine intoloro | Not Started | Phase 0 | loro拥有实现模块 |
| 2 | Merge canonicalLoroDocsemantics | Not Started | Phase 1 | 唯一规范文档类型 |
| 3 | Collapse container and value surface | Not Started | Phase 2 | 唯一规范 container/value 层 |
| 4 | Collapse event, diff, and undo surface | Not Started | Phase 3 | 唯一规范 event/diff/undo 层 |
| 5 | Migrateloro-wasmand first-party consumers | Not Started | Phase 4 | 第一方不再依赖loro-internal |
| 6 | Remove shim and finalize cleanup | Not Started | Phase 5 | 单 crate 稳态 |
文档使用方式(How to Use This Document)
- 随工作推进更新每个阶段的状态:
Not Started、In Progress、Blocked或Done。 - 每个合并后的 PR 应同步更新本文档中相关的 checklist 项。
- 只有当某阶段的所有退出标准都满足时,该阶段才算
Done。 - 如果重大设计决策改变了计划,在继续之前先更新 "Decision Log" 一节。
Phase 0:锁定行为与性能基线
状态:Not Started
目标(Objective)
在改变 crate 边界之前,冻结当前公开行为并记录基线性能。
为什么需要这一阶段(Why This Phase Exists)
如果没有基线,后续阶段可能在编译依然通过的情况下意外改变语义。本阶段把当前行为变成一份显式契约。
主要范围(Primary Scope)
- 经由
crates/loro验证的公开 Rust 行为; - 当前由
crates/loro-internal覆盖的引擎正确性; - 受 facade-to-engine 转换影响的性能敏感路径。
工作项(Work Items)
- 盘点当前仅由
crates/loro提供的公开语义。 - 将
crates/loro/tests视为公开兼容套件。 - 确定
crates/loro-internal/tests中必须在整个迁移期间保持绿色(green)的最小测试子集。 - 增加或确认以下方向的 benchmark 覆盖:
- active subscriptions(活跃订阅)
- heterogeneous reads(异构读取)
- diff / apply-diff 路径
- undo callbacks(撤销回调)
- 记录基线命令,并在 PR 或关联产物中保存基线数字。
交付物(Deliverables)
- 一份书面基线总结;
- 一份稳定的兼容测试清单;
- 关键热路径的 benchmark 数字。
退出标准(Exit Criteria)
- 公开语义已被枚举并就绪(enumerated and agreed upon)。
- 所需测试与 benchmark 已识别且可运行。
- 已在当前拆分架构上完成一次基线测量。
验证(Validation)
计划给出的验证命令如下,与仓库现状一致:
cargo test -p lorocargo test -p loro-internalcargo bench -p loro-internal eventcargo bench -p loro-internal pendingcargo bench -p loro-internal list
其中event、pending、list三个 bench 目标在 crates/loro-internal/Cargo.toml 的[[bench]]声明中确实存在(完整的 bench 列表还包括text_r、encode、map、tree、jsonpath、shallow_export)。
风险(Risks)
- 漏掉某个公开语义边界情况,日后把它误当作实现细节处理;
- 测错路径、优化错层。
Phase 1:将引擎导入loro
状态:Not Started
目标(Objective)
在保持当前公开行为的前提下,让loro拥有实现模块。
策略(Strategy)
推荐策略是:先把实现搬进crates/loro,再在后续阶段削减重复表面。这样既保持发布的 crate 名称稳定,又避免在同一步内做大规模语义重写。
主要范围(Primary Scope)
crates/loro/Cargo.tomlcrates/loro/src/**crates/loro-internal/Cargo.tomlcrates/loro-internal/src/**
工作项(Work Items)
- 在
crates/loro内创建内部模块树以承载当前引擎实现。 - 合并
crates/loro与crates/loro-internal的依赖集合。 - 合并 feature flags,同时保留公开的
lorofeature 契约。 - 让
crates/loro直接对本地引擎模块编译,而不是通过指向loro-internal的 path 依赖。 - 将
crates/loro-internal转换为临时兼容 shim,从loro重新导出。 - 在下游消费者仍在迁移期间,通过 shim 保持工作区可构建。
关于 feature flags 的现状:当前loro的 feature 契约是default = ["counter"]、counter = ["loro-internal/counter"]、jsonpath = ["loro-internal/jsonpath"]、logging = ["loro-internal/logging"](crates/loro/Cargo.toml),而loro-internal自身还有wasm、test_utils等 feature(crates/loro-internal/Cargo.toml)。合并时必须保证这些透传关系在loro内部自洽,这正是"合并 feature flags 同时保留公开 feature 契约"的难点所在。
交付物(Deliverables)
loro在没有指向loro-internal的 path 依赖的情况下完成构建;loro-internal仍作为临时转发 crate 存在;- 尚无有意的公开行为变更。
退出标准(Exit Criteria)
cargo tree -p loro不再显示loro-internal依赖边。- 公开测试仍指向
loro并保持绿色。 - 兼容 shim 足以让第一方 crate 继续构建。
验证(Validation)
cargo test -p lorocargo test -p loro-internal- workspace 构建检查
风险(Risks)
- 导入循环或意外的 feature 漂移;
- 把过多公开表面搬进
loro的根。
Phase 2:合并规范LoroDoc语义
状态:Not Started
目标(Objective)
移除LoroDoc { doc: InnerLoroDoc }这种外层拆分,让唯一的规范LoroDoc类型拥有合并后的行为。
主要范围(Primary Scope)
- 文档构造函数(document constructors)
- auto-commit 行为
fork、fork_at、from_snapshot- 容器的
doc()行为 - 公开逃生舱(escape hatch),如
inner()、with_oplog、with_state
这些项在源码中都有对应物:fork_at(crates/loro/src/lib.rs)、from_snapshot(crates/loro/src/lib.rs)、with_oplog/with_state(crates/loro/src/lib.rs / crates/loro/src/lib.rs)、inner()返回&InnerLoroDoc(crates/loro/src/lib.rs),各容器 handler 的doc()实现分布在 lib.rs 多处(如第 1805、2098、2405、2916、3330、3628、3752 行)。合并后这些逃生舱的存废将进入显式决策。
工作项(Work Items)
- 将当前公开构造函数语义搬入规范的合并
LoroDoc。 - 为以下路径保持当前 auto-commit 行为:
new()from_snapshot()fork_at()- 从已挂载容器返回的
doc()
- 决定
inner()是保留、弃用还是被更窄的 API 替代。 - 决定
with_oplog与with_state的长期形态。 - 确保第一方构造函数(如
loro-wasm中的)保持相同行为。
交付物(Deliverables)
- 唯一规范
LoroDoc; - 文档生命周期 API 无公开行为回退。
退出标准(Exit Criteria)
- 公开
LoroDoc不再是对第二种文档类型的门面。 - 所有已知 auto-commit 语义与基线一致。
- 逃生舱行为被显式文档化,而非偶然存在。
验证(Validation)
cargo test -p loro- 针对以下项的定向测试:
new()from_snapshot()fork_at()- 已挂载容器的
doc()
风险(Risks)
- 手动提交(manual-commit)与自动提交(auto-commit)行为之间出现静默漂移;
- 意外把低层锁或状态 API 拓宽为永久公开契约。
Phase 3:塌缩容器与值表面(Container and Value Surface)
状态:Not Started
目标(Objective)
移除门面围绕内部 handlers 与值枚举重复包装的容器层与值层。
主要范围(Primary Scope)
LoroList、LoroMap、LoroText、LoroTree、LoroMovableList、LoroCounterContainerValueOrContainerContainerTrait- handler-to-container 与 value-to-value 的转换路径
工作项(Work Items)
- 为容器句柄选择规范命名策略。
- 决定是否将
LoroText等公开名称保留为别名(alias)、重命名后的规范类型,还是兼容包装器。 - 在切实可行处,将
Container与内部 handler 枚举塌缩为一个规范表示。 - 在切实可行处,将
ValueOrContainer与ValueOrHandler塌缩为一个规范表示。 - 如果
ContainerTrait仅用于桥接两个类型层,则移除或收窄它。 - 消除以下路径中转换密集的读取:
- list / map getters
for_eachvaluesget_by_pathget_by_str_pathjsonpath
交付物(Deliverables)
- 唯一规范的容器句柄层;
- 唯一规范的 value-or-container 层;
- 读取密集路径上的包装开销(wrapper churn)显著减少。
退出标准(Exit Criteria)
- 规范 API 不再需要当前重复的 handler-to-container 与 value-to-value 包装。
- 公开名称稳定,或被显式地兼容 shim 化。
loro中已存在规范容器类型的文档。
验证(Validation)
cargo test -p loro- 读取路径回归测试
- 与 Phase 0 异构读取基线对比的 benchmark
风险(Risks)
- 公开类型推断(type inference)发生变化;
- 若别名选择不当,会丢失易用的名称或公开文档。
Phase 4:塌缩事件、diff 与 undo 表面
状态:Not Started
目标(Objective)
移除当前的事件与 diff 重建层——这是合并中价值最高的运行时简化。
为什么单独成阶段(Why This Phase Is Separate)
这是最敏感的 API 表面。内部与公开的事件形态今天并不相同,因此本阶段需要显式决策,而不是隐式重构。源码可佐证这一点:crates/loro/src/event.rs中的DiffEvent<'a>、ContainerDiff<'a>、Diff<'a>、ListDiffItem、MapDelta<'a>均从loro-internal的内部类型(DiffEventInner、ContainerDiffInner、DiffInner、ValueOrHandler、ResolvedMapDelta等)经From转换而来(crates/loro/src/event.rs)。
主要范围(Primary Scope)
- subscriptions(订阅)
DiffEventContainerDiffDiffDiffBatch- undo 回调载荷(callback payloads)
决策门(Decision Gate)
在开始实现之前,必须从以下方案中选择一种并记入 Decision Log:
- 兼容优先(Compatibility-first):先引入规范化的借用(borrowed)或原始(raw)事件 API,把当前 owned 事件 API 作为兼容层保留一个或多个版本。
- 立即破坏(Break-now):在 semver-major 变更中立即替换旧事件形态。
工作项(Work Items)
- 选择规范事件模型。
- 选择规范 diff 模型。
- 决定旧
subscribe是否暂时保留为兼容包装器。 - 更新
UndoManager回调载荷以使用规范事件或 diff 类型。 - 移除第一方热路径对 facade-only 事件重建的依赖。
- 重跑活跃订阅 benchmark 并与 Phase 0 基线对比。
交付物(Deliverables)
- 唯一规范的事件与 diff 表面;
- 事件路径的分配或转换工作量可测量地下降。
退出标准(Exit Criteria)
- 第一方热路径不再需要当前的
DiffEvent::from桥。 - undo 回调不再需要重复的事件模型。
- 所选兼容策略被文档化并被强制执行。
验证(Validation)
cargo test -p loro- 订阅聚焦的回归测试
- 与 Phase 0 活跃订阅基线的 benchmark 对比
风险(Risks)
- 若借用式事件 API 公开,会带来公开生命周期(lifetime)复杂度;
- 若新旧事件 API 共存过久,会带来兼容开销。
Phase 5:迁移loro-wasm与其他第一方消费者
状态:Not Started
目标(Objective)
移除第一方对loro-internal的依赖,让loro成为工作区消费者唯一使用的 crate。
主要范围(Primary Scope)
crates/loro-wasm- examples(示例)
- benches(基准)
- 仍依赖
loro-internal的内部工具或支撑 crate
工作项(Work Items)
- 将
crates/loro-wasm的 import 从loro-internal切换到loro。 - 若仍需要低层支持,从
loro暴露一个窄范围(narrowly scoped)的内部支持模块,而不是暴露整个引擎根。 - 保持 JS pending-event flush 不变量完好。
- 审计所有工作区成员并移除对
loro-internal的直接 import。 - 更新 examples 与 benches 以使用合并后的 crate 表面。
如现状摘要所述,crates/loro-wasm当前在 Cargo.toml 中直接依赖loro-internal(含wasm、counter、jsonpath三个 feature),并在convert.rs、lib.rs、awareness.rs、container_tree.rs、counter.rs中直接引用loro_internal符号,因此本阶段需要逐文件替换 import,并处理loro-internal的wasmfeature(UTF-16 索引与 wasm-bindgen 支持)如何在合并后继续生效的问题。
交付物(Deliverables)
- 没有任何第一方 crate 直接依赖
loro-internal; loro-wasm基于loro构建。
退出标准(Exit Criteria)
- 仓库级搜索显示不存在第一方对
loro-internal的 import(临时 shim crate 本身除外)。 loro-wasm行为保持正确。- 任何隐藏的内部支持表面都被有意地划定范围并文档化。
验证(Validation)
cargo test -p loro-wasmpnpm -C crates/loro-wasm build-release- 仓库级搜索
loro_internal
风险(Risks)
- 为了迁就
loro-wasm,不小心把过多引擎 API 提升为长期公开表面; - 在改动绑定代码时破坏事件 flush 不变量。
Phase 6:移除 shim 并完成清理
状态:Not Started
目标(Objective)
删除临时兼容 crate,完成向真正单 crate 架构的过渡。
主要范围(Primary Scope)
crates/loro-internal- docs(文档)
- readmes
- release notes(发布说明)
- migration notes(迁移说明)
工作项(Work Items)
- 删除
crates/loro-internal。 - 移除不再服务于迁移目的的任何临时兼容别名或转发代码。
- 将剩余测试、bench 与文档合并进
lorocrate。 - 更新 crate 文档与仓库文档。
- 若任何用户可见 API 发生移动或变更,编写发布说明与迁移指南。
交付物(Deliverables)
- 工作区中不再存在
loro-internalcrate; - 实现与公开文档的唯一事实来源(single source of truth)。
退出标准(Exit Criteria)
- 工作区在没有
loro-internal的情况下可编译并通过测试。 - 文档只引用合并后的 crate 结构。
- 若发生任何兼容性破坏,迁移指南已就绪。
验证(Validation)
- workspace 构建与测试通过;
- 仓库级搜索确认不再有
loro-internal引用(历史 changelog 文本除外)。
风险(Risks)
- 过早删除 shim;
- 在文档、脚本或示例中遗留过期的内部引用。
跨阶段风险(Cross-Phase Risks)
- 事件形态兼容可能主导整个排期:如果不在早期做出决策,
DiffEvent的形态兼容问题会拖慢所有后续阶段。 loro-wasm可能迫使暴露比预期更宽的内部支持表面:低层依赖与 wasm feature 的迁移需求会反推loro的公开面。- 构造函数语义可能回退:如果合并时把
loro-internal::LoroDoc::new()视为与当前公开loro::LoroDoc::new()等价,就会引入语义回退(两者当前并不等价——公开门面的new()显式调用了start_auto_commit(),见 crates/loro/src/lib.rs)。 - 公开文档质量可能回退:如果内部类型在文档迁移完成之前就变成规范类型。
开放问题(Open Questions)
- 合并是否允许对事件层做一次 semver-major 的 Rust API 清理?
- 为
loro-wasm暴露的隐藏内部支持模块,确切名称应该是什么? - 合并后哪些逃生舱应保持公开,哪些应弃用?
- 规范容器类型名称应保持
LoroText/LoroList/LoroMap,还是应围绕当前内部 handler 名称重命名? - 规范 API 引入后,兼容包装器应保留多久?
决策日志(Decision Log)
- 目前尚无决策记录。
建议的 PR 顺序(Suggested PR Sequence)
test(loro): lock behavior and perf baselinerefactor(loro): import internal engine into public craterefactor(loro): merge canonical LoroDoc semanticsrefactor(loro): collapse container and value surfacerefactor(loro): collapse event, diff, and undo surfacerefactor(wasm): migrate first-party consumers to lororefactor(loro): remove internal shim and finalize cleanup
完成定义(Definition of Done)
当以下所有条件为真时,本计划才算完成:
loro是核心实现唯一的 Rust crate。loro-internal已被移除。- 第一方消费者使用
loro。 - 规范的事件 / value / container / doc 表面不再需要热路径上的门面转换层。
- 公开语义保持正确并被文档化。
附:在仓库中深入阅读的入口
- 计划全文:plans/20260306-merge-loro-crates.md
- 门面 crate 清单与依赖:crates/loro/Cargo.toml(可见
loro-internalpath 依赖与 feature 透传) - 门面
LoroDoc包装与构造函数:crates/loro/src/lib.rs - 事件重建桥:crates/loro/src/event.rs
- 引擎 crate 的公开表面:crates/loro-internal/src/lib.rs
- 引擎
LoroDocInner内部结构:crates/loro-internal/src/lib.rs - WASM 消费者依赖:crates/loro-wasm/Cargo.toml
- 引擎 benchmark 声明(验证命令对应目标):crates/loro-internal/Cargo.toml
- 后端
【免费下载链接】loro
Make your JSON data collaborative and version-controlled with CRDTs
相关推荐
Loro 内部 CRDT 核心 crate(loro-internal)开发指南:模块地图、核心不变量与验证命令
Loro 内部 CRDT 核心 crate(loro internal)开发指南:模块地图、核心不变量与验证命令 本篇技术指南以 crates/loro int
后端Loro 内部实现开发指南:loro-internal crate 的模块地图、验证命令与核心不变量
Loro 内部实现开发指南:loro internal crate 的模块地图、验证命令与核心不变量 本文是一份面向 Loro 仓库贡献者与深入研究者的 lor
后端Loro冲突解决机制:理解CRDT如何自动合并并发修改
Loro冲突解决机制:理解CRDT如何自动合并并发修改 在当今协作应用盛行的时代, Loro冲突解决机制 为开发者提供了一个革命性的解决方案。想象一下,当多个用
后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考