A JSON-like data structure (a CRDT) that can be modified concurrently by different users, and merged again automatically.
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 1 个月前 | ||
| 4 年前 | ||
| 2 年前 | ||
| 6 天前 | ||
| 6 天前 | ||
| 1 个月前 | ||
| 4 年前 | ||
| 3 个月前 | ||
| 4 年前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 |
Automerge
Automerge 是一个库,提供多种 CRDT 的高性能实现、针对这些 CRDT 的紧凑压缩格式,以及一种可在网络中高效传输变更的同步协议。该项目的目标是像关系型数据库支持服务端应用一样,支持本地优先应用——通过提供持久化机制,让应用开发者无需纠结于复杂的分布式计算问题。Automerge 旨在成为你的本地优先应用的 PostgreSQL。
在我们的网站上,你可以找到 JavaScript 文档,其中包含教程和 API 参考。本仓库还包含核心 Rust 库,它会编译为 WebAssembly 并在 JavaScript 中暴露,相关文档可在 docs.rs 上查看。最后,在 rust/automerge-c 中还有一个 C 库——如需更多细节,请查看那里的 README。
如果你熟悉 CRDT,并特别关注 Automerge 的设计,请查看二进制格式规范。
最后,如果你想和我们聊聊这个项目,请加入我们的 Discord 服务器!
状态
该项目由一个核心 Rust 实现构成,通过 FFI 暴露到 JavaScript+WASM 和 C,并很快会支持其他语言。Alex(@alexjg)和 Orion(@orionz)正全职维护 automerge,Ink & Switch 的其他成员也在投入时间,另外还有几位维护者。我们最近发布了 Automerge 3,内存占用大约降低到原来的 1/10。
总体而言,我们努力遵循 semver。
JavaScript
@automerge/automerge 包已提供稳定版本。
Rust
当前 Rust 代码库主要围绕为 JavaScript 封装构建高性能后端而组织,因此 Rust 代码的 API 较为底层,文档也不够完善。未来几个月我们会重新完善这部分内容,但目前你需要通过阅读测试、提出疑问,才能弄清楚如何使用。如果你希望构建使用 automerge 的 Rust 应用,可以了解一下 autosurgeon。
仓库结构
./rust- Rust 实现,以及平台特定封装中的 Rust 组件(例如用于 WASM API 的automerge-wasm,或用于 C FFI 绑定的automerge-c)./javascript- JavaScript 库,内部使用automerge-wasm,但对外提供更符合 JavaScript 习惯的接口./scripts- 用于维护代码仓库的脚本,包括在 CI 中运行的脚本。./img- 供.md文件使用的静态资源
构建
要构建此代码库,你需要:
rustnode
如果你希望构建 automerge-c 库,
cmakecmockadoxygenninja
还需要通过 cargo install 安装以下组件:
wasm-bindgen-cliwasm-optcargo-deny
并确保已为 Rust 交叉编译添加 wasm32-unknown-unknown target。WASM 构建还需要 nightly 工具链和 rust-src 组件(具体命令见下面的 macOS 说明);这些会由 automerge-wasm 和 JS 包用于以 panic=unwind 方式构建 std,以便 panic 以 JS 异常形式呈现。
各个子项目(Rust 代码、封装项目)都有自己的构建说明,但要运行 CI 中会执行的测试,可以运行 ./scripts/ci/run。
在 macOS 上
截至 2022 年 11 月 29 日,这些说明已在 macOS 13.1(arm64)上成功用于本地构建。
# clone the repo
git clone https://github.com/automerge/automerge
cd automerge
# install rustup
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# install homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# install cmake, node, cmocka
brew install cmake node cmocka
# install javascript dependencies
npm --prefix ./javascript install
# install rust dependencies
cargo install wasm-bindgen-cli wasm-opt cargo-deny
# get nightly rust to produce optimized automerge-c builds
rustup toolchain install nightly
rustup component add rust-src --toolchain nightly
# add wasm target in addition to current architecture
rustup target add wasm32-unknown-unknown
# Run ci script
./scripts/ci/run
如果你的构建因找不到 cmocka.h 而失败,你可能需要让它了解 homebrew 的安装位置:
export CPATH=/opt/homebrew/include
export LIBRARY_PATH=/opt/homebrew/lib
./scripts/ci/run
Nix Flake
如果你已安装 Nix,这里提供一个 Flake,其中已配置好所有依赖项和一些辅助脚本。
$ nix develop
____ _
/ ___|___ _ __ ___ _ __ ___ __ _ _ __ __| |___
| | / _ \| '_ ` _ \| '_ ` _ \ / _` | '_ \ / _` / __|
| |__| (_) | | | | | | | | | | | (_| | | | | (_| \__ \
\____\___/|_| |_| |_|_| |_| |_|\__,_|_| |_|\__,_|___/
build:deno | Build Deno-wrapped Wasm library
build:host | Build for aarch64-darwin
build:node | Build JS-wrapped Wasm library
build:wasi | Build for Wasm32-WASI
build:wasm:nodejs | Build for wasm32-unknown-unknown with Node.js bindgings
build:wasm:web | Build for wasm32-unknown-unknown with web bindings
docs:build:host | Refresh the docs
docs:build:wasm | Refresh the docs with the wasm32-unknown-unknown target
docs:open:host | Open refreshed docs
docs:open:wasm | Open refreshed docs
# ✂️ SNIP ✂️
$ rustc --version
rustc 1.82.0 (f6e511eec 2024-10-15) # latest at time of writing
CI 入口点同样由 flake 暴露。GitHub Actions 会调用这些 相同的命令,因此在 Linux 上可以运行完整的非 Windows CI 套件:
$ nix run .#ci
可以在迭代时运行各个任务,例如:
$ nix run .#ci-fmt
$ nix run .#ci-lint
$ nix run .#ci-js-tests
$ nix run .#ci-node18-packaging-test
在 macOS 上,nix run .#ci 会运行 macOS CI 任务所使用的本机宿主测试。
原生 Windows 任务保持独立,因为 WSL 下的 Nix 测试的是 Linux,而不是 Windows。
贡献
请尽量将你的更改拆分为相对独立的提交,每次只修改一个子系统,并编写良好的提交信息,说明更改内容以及做出更改的原因(提交信息宁长勿短)。git blame 应能让未来的维护者大致明白某处代码为何如此。
发布
本仓库中有四个发布产物需要发布:
@automerge/automergeNPM 包@automerge/automerge-wasmNPM 包- automerge deno crate
automergerust crate
JS 包
NPM 包会在创建新的 Github 发布时由 CI 工具自动发布。这意味着发布新的 JS 版本的流程是:
- 在
@automerge/automerge以及javascript/package.json中提升版本号 - 向 main 提交包含版本号更新的 PR,等待测试运行并合并到
main - 合并到 main 后,创建形如
js/automerge-<version>的标签 - 在 Github 上创建新的发布,并指向相关标签
这依赖于 actions 环境中可用的访问令牌 NPM_TOKEN。该令牌生成后有效期为 30 天,因此需要偶尔手动刷新。
Rust 包
这要简单得多,但自动化程度较低。发布步骤如下:
- 在
automerge/Cargo.toml中提升版本号 - 推送 PR 并在检查通过后合并
- 将发布标签设置为
rust/automerge@<version> - 将标签推送到仓库
- 使用
cargo publish发布