Skip to main content

nodedb_types/sync/wire/
delta.rs

1// SPDX-License-Identifier: Apache-2.0
2
3//! Delta push / ack / reject / collection-purged messages.
4
5use serde::{Deserialize, Serialize};
6
7use crate::sync::compensation::CompensationHint;
8
9/// Delta push message (client → server, 0x10).
10#[derive(
11    Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
12)]
13pub struct DeltaPushMsg {
14    /// Collection the delta applies to.
15    pub collection: String,
16    /// Document ID.
17    pub document_id: String,
18    /// Loro CRDT delta bytes.
19    pub delta: Vec<u8>,
20    /// Client's peer ID (for CRDT identity).
21    pub peer_id: u64,
22    /// Per-mutation unique ID for dedup.
23    pub mutation_id: u64,
24    /// CRC32C checksum of `delta` bytes for integrity verification.
25    /// Computed by sender, validated by receiver. 0 for legacy clients.
26    #[serde(default)]
27    pub checksum: u32,
28    /// Device-assigned valid-time for the mutation (ms since Unix epoch).
29    ///
30    /// Populated by offline-capable clients so Origin can preserve the
31    /// application's notion of "when did this fact take effect" independently
32    /// of the Origin-assigned `system_from_ms`. `None` means the client did
33    /// not supply a valid-time — Origin will use `system_from_ms` as the
34    /// default valid-from.
35    #[serde(default)]
36    pub device_valid_time_ms: Option<i64>,
37}
38
39/// Delta acknowledgment (server → client, 0x11).
40#[derive(
41    Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
42)]
43pub struct DeltaAckMsg {
44    /// Mutation ID being acknowledged.
45    pub mutation_id: u64,
46    /// Server-assigned LSN for this mutation.
47    pub lsn: u64,
48    /// Absolute clock-skew between `device_valid_time_ms` and the Origin
49    /// wall clock at commit, in milliseconds. `None` when the client did
50    /// not supply a device valid-time, or when skew was within tolerance
51    /// (≤ 24h). Populated so clients can surface a warning UX.
52    #[serde(default)]
53    pub clock_skew_warning_ms: Option<i64>,
54}
55
56/// Delta rejection (server → client, 0x12).
57#[derive(
58    Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
59)]
60pub struct DeltaRejectMsg {
61    /// Mutation ID being rejected.
62    pub mutation_id: u64,
63    /// Reason for rejection.
64    pub reason: String,
65    /// Compensation hints for the client.
66    pub compensation: Option<CompensationHint>,
67}
68
69/// Collection purged notification (server → client, 0x14).
70///
71/// Emitted when Origin hard-deletes a collection (retention window
72/// expired after `DROP COLLECTION` or explicit `DROP COLLECTION ... PURGE`).
73/// The receiving Lite client must:
74///
75/// 1. Drop all local Loro CRDT state for the collection.
76/// 2. Remove the collection's redb record.
77/// 3. Terminate any active shape subscriptions or streaming consumers
78///    sourced from the collection.
79/// 4. Fire the `on_collection_purged` client-trait callback.
80///
81/// `purge_lsn` is the Origin WAL LSN at which the hard-delete committed.
82/// Clients persist it so that on reconnect they can replay any purge
83/// events that landed while they were offline by querying
84/// `_system.dropped_collections` / purge event log at LSN > last_seen.
85#[derive(
86    Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
87)]
88pub struct CollectionPurgedMsg {
89    /// Numeric tenant ID the collection belonged to.
90    pub tenant_id: u64,
91    /// Collection name.
92    pub name: String,
93    /// Origin WAL LSN at which the hard-delete was committed.
94    pub purge_lsn: u64,
95}