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}