Crate yrs_tree

Source
Expand description

§yrs_tree

yrs_tree docs.rs

A tree CRDT for Yrs, a Rust implementation of Yjs, based on the algorithm described in Evan Wallace’s article on CRDT Mutable Tree Hierarchies. Changes among clients are guaranteed to converge to a consistent state, and the tree ensures that conflicts and cycles are handled correctly.

§Installation

cargo add yrs_tree

§Documentation

§Examples

§Basic

Show code
use std::{error::Error, sync::Arc};
use yrs_tree::{Tree, TreeUpdateEvent, NodeApi};

fn main() -> Result<(), Box<dyn Error>> {
    // Create a new Yjs document and tree
    let doc = Arc::new(yrs::Doc::new());
    let tree = Tree::new(doc.clone(), "test");

    // Subscribe to tree changes
    let sub = tree.on_change(|e| {
        let TreeUpdateEvent(tree) = e;
        // Print a textual representation of the tree
        println!("{}", tree);
    });

    // Create and manipulate nodes
    let node1 = tree.create_child_with_id("1")?;
    let node2 = tree.create_child_with_id("2")?;
    let node3 = node1.create_child_with_id("3")?;
    let node4 = node2.create_child_with_id("4")?;

    // Move nodes around
    node3.move_to(&node2, Some(0))?;     // Move node3 as first child of node2
    node1.move_after(&node2)?;           // Move node1 after node2
    node4.move_before(&node3)?;          // Move node4 before node3

    // Iterate over the tree in depth-first order
    let nodes = tree
        .traverse_dfs()
        .map(|n| (n.id().to_string(), n.depth()))
        .collect::<Vec<_>>();

    assert_eq!(
        nodes,
        vec![("<ROOT>", 0), ("2", 1), ("3", 2), ("4", 2), ("1", 1)]
            .iter()
            .map(|(id, depth)| (id.to_string(), *depth as usize))
            .collect::<Vec<_>>()
    );

    Ok(())
}

§Synchronization Between Clients

Show code
use std::{error::Error, sync::Arc};
use yrs_tree::{NodeApi, Tree};
use yrs::{updates::decoder::Decode, ReadTxn, Transact, Update};

fn main() -> Result<(), Box<dyn Error>> {
    // Create two Yjs documents and trees
    let doc1 = Arc::new(yrs::Doc::new());
    let doc2 = Arc::new(yrs::Doc::new());
    
    let tree1 = Tree::new(doc1.clone(), "test");
    let tree2 = Tree::new(doc2.clone(), "test");

    // Make changes to tree1
    let node1 = tree1.create_child_with_id("1")?;
    let node2 = tree1.create_child_with_id("2")?;
    
    // Sync changes to tree2
    let txn = doc1.transact();
    let update = txn.encode_state_as_update_v1(&Default::default());
    drop(txn);

    doc2.transact_mut()
        .apply_update(Update::decode_v1(&update).unwrap())?;

    assert_eq!(tree1, tree2);

    Ok(())
}

Structs§

DfsIter
An iterator over the nodes in the tree in depth-first order.
Node
A node in a tree.
Subscription
A subscription to a tree update event. When dropped, the subscription is automatically cancelled.
Tree
A tree CRDT backed by a Yrs document.
TreeObserver
An observer that can subscribe to tree update events.
TreeUpdateEvent
An event that is emitted when the tree changes.

Enums§

NodeId
The ID of a node in a tree.
TreeError
Errors that can occur when manipulating a tree.

Traits§

NodeApi
A trait for objects that can behave like a node in a tree; this is implemented for Node and Tree. When these methods are used on a Tree, they behave as if they were called on the root node.