//! SyncKit Client SDK — end-to-end encrypted cloud sync. //! //! All row data is encrypted client-side before leaving the device. //! The server only ever sees ciphertext. //! //! # Quick start //! //! ```no_run //! use synckit_client::{SyncKitClient, SyncKitConfig, ChangeEntry, ChangeOp}; //! use chrono::Utc; //! //! # async fn example() -> synckit_client::Result<()> { //! let client = SyncKitClient::new(SyncKitConfig { //! server_url: "https://makenot.work".into(), //! api_key: "your-api-key".into(), //! }); //! //! // Authenticate //! let (user_id, app_id) = client.authenticate("user@example.com", "password").await?; //! //! // Set up encryption (first device) //! client.setup_encryption_new("password").await?; //! //! // Register this device //! let device = client.register_device("MacBook Pro", "macos").await?; //! //! // Push encrypted data //! let cursor = client.push(device.id, vec![ //! ChangeEntry { //! table: "tasks".into(), //! op: ChangeOp::Insert, //! row_id: uuid::Uuid::new_v4().to_string(), //! timestamp: Utc::now(), //! data: Some(serde_json::json!({"title": "Buy milk"})), //! }, //! ]).await?; //! //! // Pull and auto-decrypt //! let (changes, cursor, has_more) = client.pull(device.id, 0).await?; //! # Ok(()) //! # } //! ``` pub mod client; pub mod conflict; pub mod crypto; pub mod error; pub mod keystore; pub mod types; // Re-exports for convenience pub use client::{validate_api_key, SessionInfo, SyncKitClient, SyncKitConfig, SyncNotifyStream}; pub use conflict::{ detect_conflicts, resolve_field_merge, resolve_lww, ConflictPair, ConflictResolver, Resolution, }; pub use error::{Result, SyncKitError}; pub use types::{ChangeEntry, ChangeOp, Device, PullFilter, PulledChange, SyncStatus};