☰
Loro Rust 核心 crate 合并计划:将 `loro-internal` 并入 `loro` 单一 crate 的七阶段迁移指南
2026/10/10 2:07:21 网站建设 项目流程
  • 后端

【免费下载链接】loro

Make your JSON data collaborative and version-controlled with CRDTs

项目地址:https://gitcode.com/gh_mirrors/lo/loro
点击查看免费下载

导读

本文档深入剖析 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."(内部库,请勿直接使用,它不稳定)。

这种拆分产生两类问题:

  1. 重复的 API 层与类型表面:门面 crate 围绕引擎类型重新包装出一套公开类型,两套类型并存。
  2. 层间转换开销:门面与引擎之间反复做不必要的转换。

计划明确指出,成本最高的转换并不在于外层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 importloro-internal。
  • 第一方热路径不再需要当前的 facade-onlyDiffEvent重建。
  • 异构读取路径(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 处。

阶段总览(Tracking Dashboard)

计划用一张跟踪仪表盘管理七个阶段,每个阶段标记状态(Not Started/In Progress/Blocked/Done)、依赖关系与主要产出:

Phase名称状态依赖主要产出
0Lock behavior and perf baselineNot Started无基线测试与 benchmark 数字
1Import engine intoloroNot StartedPhase 0loro拥有实现模块
2Merge canonicalLoroDocsemanticsNot StartedPhase 1唯一规范文档类型
3Collapse container and value surfaceNot StartedPhase 2唯一规范 container/value 层
4Collapse event, diff, and undo surfaceNot StartedPhase 3唯一规范 event/diff/undo 层
5Migrateloro-wasmand first-party consumersNot StartedPhase 4第一方不再依赖loro-internal
6Remove shim and finalize cleanupNot StartedPhase 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 loro
  • cargo test -p loro-internal
  • cargo bench -p loro-internal event
  • cargo bench -p loro-internal pending
  • cargo 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.toml
  • crates/loro/src/**
  • crates/loro-internal/Cargo.toml
  • crates/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 loro
  • cargo 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、LoroCounter
  • Container
  • ValueOrContainer
  • ContainerTrait
  • handler-to-container 与 value-to-value 的转换路径

工作项(Work Items)

  • 为容器句柄选择规范命名策略。
  • 决定是否将LoroText等公开名称保留为别名(alias)、重命名后的规范类型,还是兼容包装器。
  • 在切实可行处,将Container与内部 handler 枚举塌缩为一个规范表示。
  • 在切实可行处,将ValueOrContainer与ValueOrHandler塌缩为一个规范表示。
  • 如果ContainerTrait仅用于桥接两个类型层,则移除或收窄它。
  • 消除以下路径中转换密集的读取:
    • list / map getters
    • for_each
    • values
    • get_by_path
    • get_by_str_path
    • jsonpath

交付物(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(订阅)
  • DiffEvent
  • ContainerDiff
  • Diff
  • DiffBatch
  • 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-wasm
  • pnpm -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)

  1. test(loro): lock behavior and perf baseline
  2. refactor(loro): import internal engine into public crate
  3. refactor(loro): merge canonical LoroDoc semantics
  4. refactor(loro): collapse container and value surface
  5. refactor(loro): collapse event, diff, and undo surface
  6. refactor(wasm): migrate first-party consumers to loro
  7. refactor(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

项目地址:https://gitcode.com/gh_mirrors/lo/loro
点击查看免费下载

相关推荐

上一篇:PrismLauncher-Cracked:终极Minecraft离线启动解决方案指南
下一篇:KMS_VL_ALL_AIO终极指南:Windows和Office永久激活的简单免费解决方案

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询