let ensure_ok = (res : Result[Unit, @types.LoroError]) => match res {
Ok(_) => ()
Err(err) => fail("\{err}")
}
let doc1 = LoroDoc::new()
let doc2 = LoroDoc::new()
doc1.set_peer_id(1)
doc2.set_peer_id(2)
let list1 = doc1.get_list("todos")
let map1 = doc1.get_map("profile")
let text1 = doc1.get_text("note")
doc1.set_next_commit_origin(Some("client:alpha"))
doc1.set_next_commit_message(Some("seed profile"))
ensure_ok(doc1.begin_transaction())
ensure_ok(doc1.map_set(map1, "name", @types.LoroValue::String("Ada")))
ensure_ok(doc1.map_set(map1, "role", @types.LoroValue::String("writer")))
ensure_ok(doc1.list_push(list1, @types.LoroValue::String("draft")))
ensure_ok(doc1.text_insert(text1, 0, "Hello Lomo"))
ensure_ok(doc1.commit_transaction())
let list2 = doc2.get_list("todos")
let text2 = doc2.get_text("note")
ensure_ok(doc2.list_push(list2, @types.LoroValue::String("review")))
ensure_ok(doc2.text_insert(text2, 0, "Hey! "))
let bytes1 = match doc1.export_updates() { Ok(b) => b Err(e) => fail("\{e}") }
let bytes2 = match doc2.export_updates() { Ok(b) => b Err(e) => fail("\{e}") }
ensure_ok(doc1.import_updates(bytes2))
ensure_ok(doc2.import_updates(bytes1))
let merged1 = match doc1.text_to_string(text1) { Ok(v) => v Err(e) => fail("\{e}") }
let merged2 = match doc2.text_to_string(text2) { Ok(v) => v Err(e) => fail("\{e}") }
guard merged1 == merged2 else { fail("text did not converge") }
let snapshot = match doc1.export_bytes(@types.ExportMode::Snapshot) {
Ok(b) => b
Err(e) => fail("\{e}")
}
let doc3 = LoroDoc::new()
ensure_ok(doc3.import_bytes(snapshot))
let undo = UndoManager::new(doc1)
undo.add_exclude_origin_prefix("remote:")
ignore(undo.undo())let ensure_ok = (res : Result[Unit, @types.LoroError]) => match res {
Ok(_) => ()
Err(err) => fail("\{err}")
}
let presence1 = EphemeralStore::new(15_000)
let presence2 = EphemeralStore::new(15_000)
presence1.set(
"1", // peer id as string
@types.LoroValue::Map({ "cursor": @types.LoroValue::I64(12) }),
)
let payload = presence1.encode_all()
ensure_ok(presence2.apply(payload))let ensure_ok = (res : Result[Unit, @types.LoroError]) => match res {
Ok(_) => ()
Err(err) => fail("\{err}")
}
let doc = LoroDoc::new()
let tree = doc.get_tree("outline")
let root = match doc.tree_create(tree, None) {
Ok(id) => id
Err(e) => fail("\{e}")
}
let a = match doc.tree_create(tree, Some(root)) {
Ok(id) => id
Err(e) => fail("\{e}")
}
let b = match doc.tree_create(tree, Some(root)) {
Ok(id) => id
Err(e) => fail("\{e}")
}
// Attach metadata to a node via its meta map container.
let root_meta = doc.tree_get_meta(root)
ensure_ok(doc.map_set(root_meta, "title", @types.LoroValue::String("Chapter 1")))
// Reorder: move b before a under the same parent.
ensure_ok(doc.tree_move_before(tree, b, a))
let tree_value = match doc.tree_get_value_with_meta(tree) {
Ok(v) => v
Err(e) => fail("\{e}")
}
ignore(tree_value)let ensure_ok = (res : Result[Unit, @types.LoroError]) => match res {
Ok(_) => ()
Err(err) => fail("\{err}")
}
let doc = LoroDoc::new()
let text = doc.get_text("body")
ensure_ok(doc.text_insert(text, 0, "Hello rich text"))
ensure_ok(
doc.text_mark(
text,
0,
5,
"bold",
@types.LoroValue::Bool(true),
),
)
let delta = match doc.text_to_delta(text) {
Ok(v) => v
Err(e) => fail("\{e}")
}
ignore(delta)let ensure_ok = (res : Result[Unit, @types.LoroError]) => match res {
Ok(_) => ()
Err(err) => fail("\{err}")
}
let doc = LoroDoc::new()
let root = doc.get_map("root")
let list_id = match doc.map_insert_container(
root,
"items",
@types.ContainerType::List,
) {
Ok(id) => id
Err(e) => fail("\{e}")
}
let items = @container.ListHandler::new(list_id)
ensure_ok(doc.list_push(items, @types.LoroValue::String("one")))
let note_id = match doc.list_insert_container(
items,
1,
@types.ContainerType::Text,
) {
Ok(id) => id
Err(e) => fail("\{e}")
}
let note = @container.TextHandler::new(note_id)
ensure_ok(doc.text_insert(note, 0, "embedded text"))
let deep = doc.get_deep_value()
ignore(deep)pub struct CommitMeta {
message : String?
origin : String?
timestamp : Int64
}pub enum EphemeralEventTrigger {
Local
Import
Timeout
}impl Eq for EphemeralEventTriggerimpl Show for EphemeralEventTriggerpub struct EphemeralStore {
timeout_ms : UInt64
next_sub_id : Int
states : Map[String, EphemeralRecord]
local_subs : Array[EphemeralLocalEntry]
subs : Array[EphemeralSubscriberEntry]
}fn EphemeralStore::subscribe(self : EphemeralStore, callback : (EphemeralStoreEvent) -> Bool) -> EphemeralSubscriptionfn EphemeralStore::subscribe_local_updates(self : EphemeralStore, callback : (Bytes) -> Bool) -> EphemeralSubscriptionpub struct EphemeralStoreEvent {
by : EphemeralEventTrigger
added : Array[String]
updated : Array[String]
removed : Array[String]
}impl Show for EphemeralStoreEventpub struct LoroDoc {
oplog : OpLog
state : DocState
arena : SharedArena
text_style : StyleConfigMap
peer : UInt64
counter : Int
lamport : UInt
next_sub_id : Int
root_subs : Array[SubscriberEntry]
container_subs : Map[ContainerID, Array[SubscriberEntry]]
local_update_subs : Array[LocalUpdateEntry]
peer_id_subs : Array[PeerIdEntry]
pre_commit_subs : Array[PreCommitEntry]
next_commit_msg : String?
next_commit_origin : String?
txn_active : Bool
txn_ops : Array[Op]
txn_deps : Frontiers?
txn_base_id : ID?
txn_base_lamport : UInt
}fn LoroDoc::apply_list_op(self : LoroDoc, handler : ListHandler, op : ListOp) -> Result[Unit, LoroError]fn LoroDoc::apply_local_content_with_id(self : LoroDoc, id : ID, lamport : UInt, container_id : ContainerID, content : RawOpContent) -> Result[Unit, LoroError]fn LoroDoc::apply_map_set(self : LoroDoc, handler : MapHandler, key : String, value : LoroValue?) -> Result[Unit, LoroError]fn LoroDoc::apply_text_op(self : LoroDoc, handler : TextHandler, op : ListOp) -> Result[Unit, LoroError]fn LoroDoc::apply_tree_op(self : LoroDoc, handler : TreeHandler, op : TreeOp) -> Result[Unit, LoroError]fn LoroDoc::counter_add(self : LoroDoc, handler : CounterHandler, delta : Double) -> Result[Unit, LoroError]fn LoroDoc::counter_inc(self : LoroDoc, handler : CounterHandler, delta : Int) -> Result[Unit, LoroError]fn LoroDoc::frontiers_to_vv(self : LoroDoc, frontiers : Frontiers) -> Result[VersionVector, LoroError]fn LoroDoc::list_delete(self : LoroDoc, handler : ListHandler, pos : Int, len : Int) -> Result[Unit, LoroError]fn LoroDoc::list_get_or_create_container(self : LoroDoc, handler : ListHandler, pos : Int, container_type : ContainerType) -> Result[ContainerID, LoroError]fn LoroDoc::list_insert(self : LoroDoc, handler : ListHandler, pos : Int, value : LoroValue) -> Result[Unit, LoroError]fn LoroDoc::list_insert_container(self : LoroDoc, handler : ListHandler, pos : Int, container_type : ContainerType) -> Result[ContainerID, LoroError]fn LoroDoc::list_push(self : LoroDoc, handler : ListHandler, value : LoroValue) -> Result[Unit, LoroError]fn LoroDoc::list_push_container(self : LoroDoc, handler : ListHandler, container_type : ContainerType) -> Result[ContainerID, LoroError]fn LoroDoc::list_set(self : LoroDoc, handler : ListHandler, pos : Int, value : LoroValue) -> Result[Unit, LoroError]fn LoroDoc::map_delete(self : LoroDoc, handler : MapHandler, key : String) -> Result[Unit, LoroError]fn LoroDoc::map_get_or_create_container(self : LoroDoc, handler : MapHandler, key : String, container_type : ContainerType) -> Result[ContainerID, LoroError]fn LoroDoc::map_insert_container(self : LoroDoc, handler : MapHandler, key : String, container_type : ContainerType) -> Result[ContainerID, LoroError]fn LoroDoc::map_set(self : LoroDoc, handler : MapHandler, key : String, value : LoroValue) -> Result[Unit, LoroError]fn LoroDoc::movable_list_delete(self : LoroDoc, handler : MovableListHandler, pos : Int, len : Int) -> Result[Unit, LoroError]fn LoroDoc::movable_list_insert(self : LoroDoc, handler : MovableListHandler, pos : Int, value : LoroValue) -> Result[Unit, LoroError]fn LoroDoc::movable_list_move(self : LoroDoc, handler : MovableListHandler, from : Int, to : Int) -> Result[Unit, LoroError]fn LoroDoc::movable_list_push(self : LoroDoc, handler : MovableListHandler, value : LoroValue) -> Result[Unit, LoroError]fn LoroDoc::movable_list_set(self : LoroDoc, handler : MovableListHandler, pos : Int, value : LoroValue) -> Result[Unit, LoroError]fn LoroDoc::subscribe(self : LoroDoc, container_id : ContainerID, callback : (EventBatch) -> Bool) -> Subscriptionfn LoroDoc::text_delete(self : LoroDoc, handler : TextHandler, pos : Int, len : Int) -> Result[Unit, LoroError]fn LoroDoc::text_delete_utf16(self : LoroDoc, handler : TextHandler, pos : Int, len : Int) -> Result[Unit, LoroError]fn LoroDoc::text_delete_utf8(self : LoroDoc, handler : TextHandler, pos : Int, len : Int) -> Result[Unit, LoroError]fn LoroDoc::text_get_richtext_value(self : LoroDoc, handler : TextHandler) -> Result[LoroValue, LoroError]fn LoroDoc::text_insert(self : LoroDoc, handler : TextHandler, pos : Int, text : String) -> Result[Unit, LoroError]fn LoroDoc::text_insert_utf16(self : LoroDoc, handler : TextHandler, pos : Int, text : String) -> Result[Unit, LoroError]fn LoroDoc::text_insert_utf8(self : LoroDoc, handler : TextHandler, pos : Int, text : String) -> Result[Unit, LoroError]fn LoroDoc::text_mark(self : LoroDoc, handler : TextHandler, start : Int, end : Int, key : String, value : LoroValue) -> Result[Unit, LoroError]fn LoroDoc::text_mark_utf16(self : LoroDoc, handler : TextHandler, pos : Int, len : Int, key : String, value : LoroValue) -> Result[Unit, LoroError]fn LoroDoc::text_mark_utf8(self : LoroDoc, handler : TextHandler, pos : Int, len : Int, key : String, value : LoroValue) -> Result[Unit, LoroError]fn LoroDoc::text_slice(self : LoroDoc, handler : TextHandler, start : Int, end : Int) -> Result[String, LoroError]fn LoroDoc::text_slice_utf16(self : LoroDoc, handler : TextHandler, pos : Int, len : Int) -> Result[String, LoroError]fn LoroDoc::text_slice_utf8(self : LoroDoc, handler : TextHandler, pos : Int, len : Int) -> Result[String, LoroError]fn LoroDoc::text_unmark(self : LoroDoc, handler : TextHandler, start : Int, end : Int, key : String) -> Result[Unit, LoroError]fn LoroDoc::text_unmark_utf16(self : LoroDoc, handler : TextHandler, pos : Int, len : Int, key : String) -> Result[Unit, LoroError]fn LoroDoc::text_unmark_utf8(self : LoroDoc, handler : TextHandler, pos : Int, len : Int, key : String) -> Result[Unit, LoroError]fn LoroDoc::tree_delete(self : LoroDoc, handler : TreeHandler, target : TreeID) -> Result[Unit, LoroError]fn LoroDoc::tree_get_value_with_meta(self : LoroDoc, handler : TreeHandler) -> Result[LoroValue, LoroError]pub struct UndoManager {
doc : LoroDoc
peer_id : UInt64
undo_stack : Array[UndoStep]
redo_stack : Array[UndoStep]
seen_changes : Int
tracking_state : DocState
ignore_change_ids : Array[ID]
exclude_origin_prefixes : Array[String]
max_undo_steps : Int
merge_interval_ms : Int64
group_active : Bool
group_ops : Array[UndoOp]
}Dependencies