From d5eeb3dde00cd69f40894925df5bf0251ab0f111 Mon Sep 17 00:00:00 2001
From: Zixuan Chen
Date: Wed, 8 May 2024 18:35:02 +0800
Subject: [PATCH] docs: update readme
---
CONTRIBUTING.md | 24 +++++++++++++
README.md | 93 ++++++++++++++++++++++++++++++++++++-------------
2 files changed, 92 insertions(+), 25 deletions(-)
create mode 100644 CONTRIBUTING.md
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 00000000..5fcb9aa7
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,24 @@
+# Contributing Guide
+
+### Development Environment Setup
+
+1. **Rust**: Install from the official Rust website.
+2. **Deno**: Download and install from Deno's website.
+3. **Node**: Install from the Node.js website.
+4. **pnpm**: Run `npm i -g pnpm` for global installation.
+5. **Rust Target**: Add with `rustup target add wasm32-unknown-unknown`.
+6. **wasm-bindgen-cli**: Install version 0.2.90 via `cargo install wasm-bindgen-cli --version 0.2.90`.
+6. **wasm-opt**: Install using `cargo install wasm-opt --locked`.
+7. **wasm-snip**: Install using `cargo install wasm-snip`.
+8. **cargo-nextest**: Install using `cargo install cargo-nextest --locked`.
+9. **cargo-fuzz**: Run `cargo install cargo-fuzz`.
+10. **cargo-llvm-cov**(to generate coverage report): Run `cargo install cargo-llvm-cov`
+
+### Test
+
+```bash
+deno task test
+
+# Build and test WASM
+deno task test-wasm
+```
diff --git a/README.md b/README.md
index ea6d0893..1a295bcb 100644
--- a/README.md
+++ b/README.md
@@ -12,6 +12,22 @@
Reimagine state management with CRDTs 🦜
Make your app state synchronized and collaborative effortlessly.
+
+
+
+
+
+ Documentations
+
+ |
+
+ Getting Started
+
+ |
+
+ Rust Doc
+
+
@@ -25,11 +41,13 @@
https://github.com/loro-dev/loro/assets/18425020/fe246c47-a120-44b3-91d4-1e7232a5b4ac
-> ⚠️ **Notice**: The current API and encoding schema of Loro are **experimental** and **subject to change**. You should not use it in production.
+> ⚠️ **Notice**: The current API and encoding schema of Loro are **experimental** and **subject to change**. You should not use it in production.
-Loro is a CRDTs(Conflict-free Replicated Data Types) library that makes building [local-first apps][local-first] easier.
+Loro is a [CRDTs(Conflict-free Replicated Data Types)](https://crdt.tech/) library that makes building [local-first apps][local-first] easier.
-Explore our vision for the local-first development paradigm in our blog post: [**Reimagine State Management with CRDTs**](https://loro.dev/blog/loro-now-open-source).
+You can use it now in JS and Rust.
+
+Explore our vision in: [**Reimagine State Management with CRDTs**](https://loro.dev/blog/loro-now-open-source).
# Features
@@ -37,15 +55,15 @@ Explore our vision for the local-first development paradigm in our blog post: [*
- **Common Data Structures**: Support for `List` for ordered collections, LWW(Last Write Win) `Map` for key-value pairs, `Tree` for hierarchical data, and `Text` for rich text manipulation, enabling various applications.
- **Text Editing with Fugue**: Loro integrates [Fugue](https://arxiv.org/abs/2305.00583), a CRDT algorithm designed to minimize interleaving anomalies in concurrent text editing.
-- **Peritext-like Rich Text CRDT**: Drawing inspiration from [Peritext](https://www.inkandswitch.com/peritext/), Loro manages rich text CRDTs that excel at merging concurrent rich text style edits, maintaining the original intent of users input as much as possible. Details on this will be explored further in an upcoming blog post.
+- **Peritext-like Rich Text CRDT**: Drawing inspiration from [Peritext](https://www.inkandswitch.com/peritext/), Loro manages rich text CRDTs that excel at merging concurrent rich text style edits, maintaining the original intent of users input as much as possible. Learn more in our blog [Introduction to Loro's Rich Text CRDT](https://loro.dev/blog/loro-richtext).
- **Moveable Tree**: For applications requiring directory-like data manipulation, Loro utilizes the algorithm from [*A Highly-Available Move Operation for Replicated Trees*](https://ieeexplore.ieee.org/document/9563274), which simplifies the process of moving hierarchical data structures.
-- [**Moveable List**](https://loro.dev/docs/tutorial/list): Both `List` and `MovableList` utilize the [*Fugue*](https://arxiv.org/abs/2305.00583) to achieve *maximal noninterleaving*. Additionally, `MovableList` uses the algorithm from [*Moving Elements in List CRDTs*](https://martin.kleppmann.com/2020/04/27/papoc-list-move.html) to implement the move operation.
+- [**Moveable List**](https://loro.dev/docs/tutorial/list): Both `List` and `MovableList` utilize Fugue to achieve *maximal noninterleaving*. Additionally, `MovableList` uses the algorithm from [*Moving Elements in List CRDTs*](https://martin.kleppmann.com/2020/04/27/papoc-list-move.html) to implement the move operation.
## Advanced Features in Loro
- **Preserve Editing History**
- With Loro, you can track changes effortlessly as it records the editing history with low overhead.
- - This feature is essential for audit trails, undo/redo functionality, and understanding the evolution of your data over time.
+ - This feature is useful for audit trails, undo/redo functionality, and version control.
- **Time Travel Through History**
- It allows users to compare and merge manually when needed, although CRDTs typically resolve conflicts well.
- **High Performance**
@@ -57,7 +75,6 @@ Explore our vision for the local-first development paradigm in our blog post: [*
https://github.com/loro-dev/loro/assets/18425020/ec2d20a3-3d8c-4483-a601-b200243c9792
-
## Features Provided by CRDTs
- **Decentralized Synchronization**: Loro allows your app's state synced via p2p connections.
@@ -66,29 +83,55 @@ https://github.com/loro-dev/loro/assets/18425020/ec2d20a3-3d8c-4483-a601-b200243
- **Scalability**: Effortlessly scale your application horizontally thanks to the inherently distributed nature of CRDTs.
- **Delta Updates**
-# Development
+# Example
-### Development Environment Setup
+[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/edit/loro-basic-test?file=test%2Floro-sync.test.ts)
-1. **Rust**: Install from the official Rust website.
-2. **Deno**: Download and install from Deno's website.
-3. **Node**: Install from the Node.js website.
-4. **pnpm**: Run `npm i -g pnpm` for global installation.
-5. **Rust Target**: Add with `rustup target add wasm32-unknown-unknown`.
-6. **wasm-bindgen-cli**: Install version 0.2.90 via `cargo install wasm-bindgen-cli --version 0.2.90`.
-6. **wasm-opt**: Install using `cargo install wasm-opt --locked`.
-7. **wasm-snip**: Install using `cargo install wasm-snip`.
-8. **cargo-nextest**: Install using `cargo install cargo-nextest --locked`.
-9. **cargo-fuzz**: Run `cargo install cargo-fuzz`.
-10. **cargo-llvm-cov**(to generate coverage report): Run `cargo install cargo-llvm-cov`
+```ts
+import { expect, test } from 'vitest';
+import { Loro, LoroList } from 'loro-crdt';
-### Test
+/**
+ * Demonstrates synchronization of two documents with two rounds of exchanges.
+ */
+// Initialize document A
+const docA = new Loro();
+const listA: LoroList = docA.getList('list');
+listA.insert(0, 'A');
+listA.insert(1, 'B');
+listA.insert(2, 'C');
-```bash
-deno task test
+// Export the state of document A as a byte array
+const bytes: Uint8Array = docA.exportFrom();
-# Build and test WASM
-deno task test-wasm
+// Simulate sending `bytes` across the network to another peer, B
+const docB = new Loro();
+// Peer B imports the updates from A
+docB.import(bytes);
+
+// Verify that B's state matches A's state
+expect(docB.toJSON()).toStrictEqual({
+ list: ['A', 'B', 'C'],
+});
+
+// Get the current operation log version of document B
+const version = docB.oplogVersion();
+
+// Simulate editing at B: delete item 'B'
+const listB: LoroList = docB.getList('list');
+listB.delete(1, 1);
+
+// Export the updates from B since the last synchronization point
+const bytesB: Uint8Array = docB.exportFrom(version);
+
+// Simulate sending `bytesB` back across the network to A
+// A imports the updates from B
+docA.import(bytesB);
+
+// Verify that the list at A now matches the list at B after merging
+expect(docA.toJSON()).toStrictEqual({
+ list: ['A', 'C'],
+});
```
# Credits