Skip to main content

dig_events_protocol/
cursor.rs

1//! The delivery cursor and its event envelope (SPEC §4).
2//!
3//! Every delivered event is stamped with a monotonic, per-instance [`Cursor`]. A subscriber
4//! remembers the last cursor it saw; on a gap (reconnect or lag) it calls `catch_up(since)` ONCE to
5//! backfill the missed range, then resumes the live stream. [`EmittedEvent`] is the envelope that
6//! flows over the live stream AND is returned by catch-up backfill.
7
8use serde::{Deserialize, Serialize};
9
10use crate::event::WalletEvent;
11
12/// A monotonic, per-instance sequence number stamped on delivered events.
13///
14/// A subscriber remembers the last cursor it saw; on a gap (reconnect or lag) it calls
15/// `catch_up(since)` ONCE to backfill the missed range, then resumes the live stream.
16/// Serializes as a bare `u64` on the wire.
17#[derive(
18    Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Serialize, Deserialize,
19)]
20pub struct Cursor(pub u64);
21
22impl Cursor {
23    /// The next cursor in sequence.
24    pub fn next(self) -> Cursor {
25        Cursor(self.0 + 1)
26    }
27}
28
29/// A delivered event paired with its monotonic [`Cursor`].
30///
31/// The engine stamps a per-instance cursor on every event as it is emitted; subscribers remember
32/// the last cursor and pass it to `catch_up` after a gap. This envelope is what flows over the
33/// subscription stream (live) and what catch-up returns (backfill).
34#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
35pub struct EmittedEvent {
36    /// The monotonic delivery cursor.
37    pub cursor: Cursor,
38    /// The event payload.
39    pub event: WalletEvent,
40}