pub struct EphemeralStore { /* private fields */ }
Expand description
EphemeralStore
is a structure that tracks ephemeral key-value state across peers.
- Use it for syncing lightweight presence/state like cursors, selections, and UI hints.
- Each key uses timestamp-based LWW (Last-Write-Wins) conflict resolution.
- Timeout unit: milliseconds.
- After timeout: entries are considered expired. They are omitted from
encode
/encode_all
, and calling [remove_outdated
] will purge them and notify subscribers withEphemeralEventTrigger::Timeout
.
In Rust, you are responsible for periodically calling [remove_outdated
]
if you want timed-out entries to be removed and corresponding events to be
emitted. In the WASM/TS wrapper, a timer runs automatically while the store
is non-empty.
See: https://loro.dev/docs/tutorial/ephemeral
§Example
use loro_internal::awareness::EphemeralStore;
let mut store = EphemeralStore::new(1000);
store.set("key", "value");
let encoded = store.encode("key");
let mut store2 = EphemeralStore::new(1000);
store.subscribe_local_updates(Box::new(|data| {
println!("local update: {:?}", data);
true
}));
store2.apply(&encoded);
assert_eq!(store2.get("key"), Some("value".into()));
Implementations§
Source§impl EphemeralStore
impl EphemeralStore
Sourcepub fn new(timeout: i64) -> Self
pub fn new(timeout: i64) -> Self
Create a new EphemeralStore
.
timeout
: inactivity timeout in milliseconds. If a key does not receive updates within this duration, it is considered expired. It will be skipped byencode
/encode_all
, and removed when [remove_outdated
] is called (triggering aTimeout
event to subscribers).
Sourcepub fn encode(&self, key: &str) -> Vec<u8> ⓘ
pub fn encode(&self, key: &str) -> Vec<u8> ⓘ
Encode the latest value of key
.
Expired keys (past timeout) are omitted and produce an empty payload.
Sourcepub fn encode_all(&self) -> Vec<u8> ⓘ
pub fn encode_all(&self) -> Vec<u8> ⓘ
Encode all non-expired keys.
Entries that have exceeded the timeout are not included in the payload.
Sourcepub fn apply(&self, data: &[u8]) -> Result<(), Box<str>>
pub fn apply(&self, data: &[u8]) -> Result<(), Box<str>>
Apply encoded updates imported from another peer/process.
Subscribers receive an event with by = Import
and the lists of
added
/updated
/removed
keys as appropriate.
pub fn set(&self, key: &str, value: impl Into<LoroValue>)
pub fn delete(&self, key: &str)
pub fn get(&self, key: &str) -> Option<LoroValue>
Sourcepub fn remove_outdated(&self)
pub fn remove_outdated(&self)
Remove entries whose last update timestamp has exceeded the timeout.
If any keys are removed, subscribers receive an event with
by = Timeout
and the removed
keys. This does not run automatically
in Rust; call it on your own schedule.
pub fn get_all_states(&self) -> FxHashMap<String, LoroValue>
pub fn keys(&self) -> Vec<String>
Sourcepub fn subscribe_local_updates(
&self,
callback: LocalEphemeralCallback,
) -> Subscription
pub fn subscribe_local_updates( &self, callback: LocalEphemeralCallback, ) -> Subscription
Subscribe to local ephemeral/awareness updates.
The callback receives encoded update bytes whenever local ephemeral state changes. This is useful for syncing awareness information like cursor positions, selections, or presence data to other peers in real-time.
Auto-unsubscription: If the callback returns false
, the subscription will be
automatically removed, providing a convenient way to implement one-time or conditional
subscriptions in Rust.
§Parameters
callback
: Function that receives&Vec<u8>
(encoded ephemeral updates) and returnsbool
- Return
true
to keep the subscription active - Return
false
to automatically unsubscribe
- Return
§Example
use loro_internal::awareness::EphemeralStore;
use std::sync::{Arc, Mutex};
let store = EphemeralStore::new(30000);
let update_count = Arc::new(Mutex::new(0));
let count_clone = update_count.clone();
// Subscribe and collect first 3 updates, then auto-unsubscribe
let sub = store.subscribe_local_updates(Box::new(move |bytes| {
println!("Received {} bytes of ephemeral data", bytes.len());
let mut count = count_clone.lock().unwrap();
*count += 1;
*count < 3 // Auto-unsubscribe after 3 updates
}));
store.set("cursor", 42);
pub fn subscribe(&self, callback: EphemeralSubscriber) -> Subscription
Trait Implementations§
Source§impl Clone for EphemeralStore
impl Clone for EphemeralStore
Source§fn clone(&self) -> EphemeralStore
fn clone(&self) -> EphemeralStore
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moreAuto Trait Implementations§
impl Freeze for EphemeralStore
impl RefUnwindSafe for EphemeralStore
impl Send for EphemeralStore
impl Sync for EphemeralStore
impl Unpin for EphemeralStore
impl UnwindSafe for EphemeralStore
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
Source§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self
with the foreground set to
value
.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red()
and
green()
, which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg()
:
use yansi::{Paint, Color};
painted.fg(Color::White);
Set foreground color to white using white()
.
use yansi::Paint;
painted.white();
Source§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
Source§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
Source§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
Source§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
Source§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
Source§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
Source§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
Source§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
Source§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self
with the background set to
value
.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red()
and
on_green()
, which have the same functionality but
are pithier.
§Example
Set background color to red using fg()
:
use yansi::{Paint, Color};
painted.bg(Color::Red);
Set background color to red using on_red()
.
use yansi::Paint;
painted.on_red();
Source§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
Source§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
Source§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
Source§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
Source§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
Source§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
Source§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
Source§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
Source§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
Source§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
Source§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling Attribute
value
.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold()
and
underline()
, which have the same functionality
but are pithier.
§Example
Make text bold using attr()
:
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);
Make text bold using using bold()
.
use yansi::Paint;
painted.bold();
Source§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
Source§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi
Quirk
value
.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask()
and
wrap()
, which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk()
:
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);
Enable wrapping using wrap()
.
use yansi::Paint;
painted.wrap();
Source§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting()
due to conflicts with Vec::clear()
.
The clear()
method will be removed in a future release.
fn clear(&self) -> Painted<&T>
resetting()
due to conflicts with Vec::clear()
.
The clear()
method will be removed in a future release.Source§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the Condition
value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted
only when both stdout
and stderr
are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);