#crdt #yrs

yrs

High performance implementation of the Yjs CRDT

20 releases (9 breaking)

new 0.10.2 Jul 6, 2022
0.9.3 Jun 23, 2022
0.5.0 Mar 18, 2022
0.2.1 Dec 21, 2021
0.0.1 Oct 20, 2020

#2 in #crdt

Download history 257/week @ 2022-03-16 111/week @ 2022-03-23 313/week @ 2022-03-30 173/week @ 2022-04-06 171/week @ 2022-04-13 352/week @ 2022-04-20 167/week @ 2022-04-27 304/week @ 2022-05-04 234/week @ 2022-05-11 171/week @ 2022-05-18 264/week @ 2022-05-25 170/week @ 2022-06-01 198/week @ 2022-06-08 211/week @ 2022-06-15 225/week @ 2022-06-22 126/week @ 2022-06-29

766 downloads per month
Used in 2 crates

MIT license

7.5MB
11K SLoC

Yrs

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:

  • C foreign function interface to provide native interop that could be used by other host languages like Swift or Java.
  • ywasm which targets Web Assembly bindings and can be used directly from JavaScript.

Example

use yrs::*;

fn main() {    
    let doc = Doc::new();
    let mut txn = doc.transact(); // all Yrs operations happen in scope of a transaction
    let text = txn.get_text("name");
    // append text to our collaborative document
    text.push(&mut txn, "hello world"); 
    
    // simulate update with remote peer
    let remote_doc = Doc::new();
    let mut remote_txn = remote_doc.transact();
    let remote_text = remote_txn.get_text("name");

    // in order to exchange data with other documents 
    // we first need to create a state vector
    let state_vector = remote_doc.get_state_vector(&remote_txn);
    
    // now compute a differential update based on remote document's state vector
    let update = doc.encode_delta_as_update_v1(&txn, &state_vector);
    
    // both update and state vector are serializable, we can pass them over the wire
    // now apply update to a remote document
    remote_doc.apply_update_v1(&mut remote_txn, update.as_slice());

    println!("{}", remote_text.to_string(&remote_txn));
}

Documentation

Features

We're in ongoing process of reaching the feature compatibility with Yjs project. Current feature list:

  • Yjs update binary format (v1).
  • Yjs update binary format (v2).
  • Support for state vectors, delta diff updates and merges.
  • Subscription events for incoming updates.
  • Support for shared (CRDT) types:
    • Text
    • Array
    • Map
    • XML data types (elements and text)
    • Subdocuments
    • Subscription events on particular data type
  • Cross-platform support for unicode code points
  • Undo manager
  • Text markers

Internal Documentation

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:

Dependencies