Crates.io | yrs |
lib.rs | yrs |
version | 0.21.3 |
source | src |
created_at | 2020-10-20 22:33:36.911869 |
updated_at | 2024-10-25 10:03:15.914913 |
description | High performance implementation of the Yjs CRDT |
homepage | https://github.com/y-crdt/y-crdt/ |
repository | https://github.com/y-crdt/y-crdt/ |
max_upload_size | |
id | 303700 |
size | 1,286,780 |
Yrs (read: wires) is a Rust port of the Yjs framework.
It's a library used on collaborative document editing using Conflict-free Replicated Data Types. This enables to provide a shared document editing experience on a client devices without explicit requirement for hosting a single server - CRDTs can resolve potential update conflicts on their own with no central authority - as well as provide first-class offline editing capabilities, where document replicas are modified without having connection to each other, and then synchronize automatically once such connection is enabled.
This library contains Rust API, that's used further on by other projects in this repository:
use yrs::*;
fn main() {
let doc = Doc::new();
let text = doc.get_or_insert_text("name");
// every operation in Yrs happens in scope of a transaction
let mut txn = doc.transact_mut();
// append text to our collaborative document
text.push(&mut txn, "Hello from yrs!");
// add formatting section to part of the text
text.format(&mut txn, 11, 3, HashMap::from([
("link".into(), "https://github.com/y-crdt/y-crdt".into())
]));
// simulate update with remote peer
let remote_doc = Doc::new();
let remote_text = remote_doc.get_or_insert_text("name");
let mut remote_txn = remote_doc.transact_mut();
// in order to exchange data with other documents
// we first need to create a state vector
let state_vector = remote_txn.state_vector();
// now compute a differential update based on remote document's
// state vector
let bytes = txn.encode_diff_v1(&state_vector);
// both update and state vector are serializable, we can pass them
// over the wire now apply update to a remote document
let update = Update::decode_v1(&bytes).unwrap();
remote_txn.apply_update(update);
// display raw text (no attributes)
println!("{}", remote_text.get_string(&remote_txn));
// create sequence of text chunks with optional format attributes
let diff = remote_text.diff(&remote_txn, YChange::identity);
}
We're in ongoing process of reaching the feature compatibility with Yjs project. Current feature list:
Yrs implements the same algorithm and uses the same data structures as Yjs. We hope to achieve better performance because we can manually manage memory. Eventually Yrs might replace the Yjs module by generating a wasm module from this package.
In this package we want to use better terminology and experiment with new data structures to index data.
Each change on the document generates a small piece of information that is integrated into the document. In Yrs we call these small pieces blocks. Think of them as small Lego blocks that compose your document. Each block is uniquely identified by an identifier consisting of client id and sequence number (see: Lamport Clock). When you receive a duplicate block, you discard it. In some cases blocks can be put together to form a larger block. If necessary, blocks can be disassembled if only a part of the composed block is needed.
More information on the implemented algorithm can be found here: