mirror of
https://github.com/loro-dev/loro.git
synced 2025-02-02 11:06:14 +00:00
feat: expose subscription to rust api (#200)
This commit is contained in:
parent
cccb4f3957
commit
ced4f4d5a5
2 changed files with 104 additions and 2 deletions
|
@ -1,5 +1,6 @@
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
use either::Either;
|
use either::Either;
|
||||||
|
use loro_internal::change::Timestamp;
|
||||||
use loro_internal::container::richtext::TextStyleInfoFlag;
|
use loro_internal::container::richtext::TextStyleInfoFlag;
|
||||||
use loro_internal::container::IntoContainerId;
|
use loro_internal::container::IntoContainerId;
|
||||||
use loro_internal::handler::TextDelta;
|
use loro_internal::handler::TextDelta;
|
||||||
|
@ -17,7 +18,10 @@ use std::ops::Range;
|
||||||
|
|
||||||
pub use loro_internal::container::richtext::ExpandType;
|
pub use loro_internal::container::richtext::ExpandType;
|
||||||
pub use loro_internal::container::{ContainerID, ContainerType};
|
pub use loro_internal::container::{ContainerID, ContainerType};
|
||||||
|
pub use loro_internal::obs::SubID;
|
||||||
|
pub use loro_internal::obs::Subscriber;
|
||||||
pub use loro_internal::version::{Frontiers, VersionVector};
|
pub use loro_internal::version::{Frontiers, VersionVector};
|
||||||
|
pub use loro_internal::DiffEvent;
|
||||||
pub use loro_internal::{LoroError, LoroResult, LoroValue, ToJson};
|
pub use loro_internal::{LoroError, LoroResult, LoroValue, ToJson};
|
||||||
|
|
||||||
/// `LoroDoc` is the entry for the whole document.
|
/// `LoroDoc` is the entry for the whole document.
|
||||||
|
@ -126,6 +130,21 @@ impl LoroDoc {
|
||||||
self.doc.commit_then_renew()
|
self.doc.commit_then_renew()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Commit the cumulative auto commit transaction with custom configure.
|
||||||
|
///
|
||||||
|
/// There is a transaction behind every operation.
|
||||||
|
/// It will automatically commit when users invoke export or import.
|
||||||
|
/// The event will be sent after a transaction is committed
|
||||||
|
pub fn commit_with(
|
||||||
|
&self,
|
||||||
|
origin: Option<&str>,
|
||||||
|
timestamp: Option<Timestamp>,
|
||||||
|
immediate_renew: bool,
|
||||||
|
) {
|
||||||
|
self.doc
|
||||||
|
.commit_with(origin.map(|x| x.into()), timestamp, immediate_renew)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_detached(&self) -> bool {
|
pub fn is_detached(&self) -> bool {
|
||||||
self.doc.is_detached()
|
self.doc.is_detached()
|
||||||
}
|
}
|
||||||
|
@ -183,10 +202,64 @@ impl LoroDoc {
|
||||||
self.doc.state_frontiers()
|
self.doc.state_frontiers()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "test_utils")]
|
/// Change the PeerID
|
||||||
|
///
|
||||||
|
/// NOTE: You need ot make sure there is no chance two peer have the same PeerID.
|
||||||
|
/// If it happens, the document will be corrupted.
|
||||||
pub fn set_peer_id(&self, peer: PeerID) -> LoroResult<()> {
|
pub fn set_peer_id(&self, peer: PeerID) -> LoroResult<()> {
|
||||||
self.doc.set_peer_id(peer)
|
self.doc.set_peer_id(peer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Subscribe the events of a container.
|
||||||
|
///
|
||||||
|
/// The callback will be invoked when the container is changed.
|
||||||
|
/// Returns a subscription id that can be used to unsubscribe.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use loro::LoroDoc;
|
||||||
|
/// # use std::sync::{atomic::AtomicBool, Arc};
|
||||||
|
/// # use loro_internal::{delta::DeltaItem, DiffEvent, LoroResult};
|
||||||
|
/// #
|
||||||
|
/// let doc = LoroDoc::new();
|
||||||
|
/// let text = doc.get_text("text");
|
||||||
|
/// let ran = Arc::new(AtomicBool::new(false));
|
||||||
|
/// let ran2 = ran.clone();
|
||||||
|
/// doc.subscribe(
|
||||||
|
/// &text.id(),
|
||||||
|
/// Arc::new(move |event: DiffEvent| {
|
||||||
|
/// assert!(event.doc.local);
|
||||||
|
/// let event = event.container.diff.as_text().unwrap();
|
||||||
|
/// let delta: Vec<_> = event.iter().cloned().collect();
|
||||||
|
/// let d = DeltaItem::Insert {
|
||||||
|
/// insert: "123".into(),
|
||||||
|
/// attributes: Default::default(),
|
||||||
|
/// };
|
||||||
|
/// assert_eq!(delta, vec![d]);
|
||||||
|
/// ran2.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||||
|
/// }),
|
||||||
|
/// );
|
||||||
|
/// text.insert(0, "123").unwrap();
|
||||||
|
/// doc.commit();
|
||||||
|
/// assert!(ran.load(std::sync::atomic::Ordering::Relaxed));
|
||||||
|
/// ```
|
||||||
|
pub fn subscribe(&self, container_id: &ContainerID, callback: Subscriber) -> SubID {
|
||||||
|
self.doc.subscribe(container_id, callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Subscribe all the events.
|
||||||
|
///
|
||||||
|
/// The callback will be invoked when any part of the [loro_internal::DocState] is changed.
|
||||||
|
/// Returns a subscription id that can be used to unsubscribe.
|
||||||
|
pub fn subscribe_root(&self, callback: Subscriber) -> SubID {
|
||||||
|
self.doc.subscribe_root(callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove a subscription.
|
||||||
|
pub fn unsubscribe(&self, id: SubID) {
|
||||||
|
self.doc.unsubscribe(id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// LoroList container. It's used to model array.
|
/// LoroList container. It's used to model array.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use loro_internal::LoroResult;
|
use loro_internal::{delta::DeltaItem, DiffEvent, LoroResult};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn list() -> LoroResult<()> {
|
fn list() -> LoroResult<()> {
|
||||||
|
@ -154,3 +154,32 @@ fn save() {
|
||||||
new_doc.import(&snapshot).unwrap();
|
new_doc.import(&snapshot).unwrap();
|
||||||
assert_eq!(new_doc.get_deep_value(), doc.get_deep_value());
|
assert_eq!(new_doc.get_deep_value(), doc.get_deep_value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn subscribe() {
|
||||||
|
use loro::LoroDoc;
|
||||||
|
use std::sync::{atomic::AtomicBool, Arc};
|
||||||
|
|
||||||
|
let doc = LoroDoc::new();
|
||||||
|
let text = doc.get_text("text");
|
||||||
|
let ran = Arc::new(AtomicBool::new(false));
|
||||||
|
let ran2 = ran.clone();
|
||||||
|
|
||||||
|
doc.subscribe(
|
||||||
|
&text.id(),
|
||||||
|
Arc::new(move |event: DiffEvent| {
|
||||||
|
assert!(event.doc.local);
|
||||||
|
let event = event.container.diff.as_text().unwrap();
|
||||||
|
let delta: Vec<_> = event.iter().cloned().collect();
|
||||||
|
let d = DeltaItem::Insert {
|
||||||
|
insert: "123".into(),
|
||||||
|
attributes: Default::default(),
|
||||||
|
};
|
||||||
|
assert_eq!(delta, vec![d]);
|
||||||
|
ran2.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
text.insert(0, "123").unwrap();
|
||||||
|
doc.commit();
|
||||||
|
assert!(ran.load(std::sync::atomic::Ordering::Relaxed));
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue