From 73877cca266840f616fd942d6a7c32117dec6100 Mon Sep 17 00:00:00 2001 From: Aaron LaBeau Date: Tue, 17 Feb 2026 16:53:28 -0600 Subject: [PATCH 1/8] feat: Updated to v5 preview 4 --- rust-tui/Cargo.lock | 155 ++++++++++++++++++++++++--- rust-tui/Cargo.toml | 2 +- rust-tui/README.md | 10 +- rust-tui/src/bin/integration_test.rs | 45 ++++---- rust-tui/src/bin/main.rs | 48 ++++----- rust-tui/src/tui/todolist.rs | 20 ++-- 6 files changed, 195 insertions(+), 85 deletions(-) diff --git a/rust-tui/Cargo.lock b/rust-tui/Cargo.lock index f5a306bae..be515bac3 100644 --- a/rust-tui/Cargo.lock +++ b/rust-tui/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + [[package]] name = "ahash" version = "0.8.12" @@ -304,6 +310,15 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -472,9 +487,9 @@ dependencies = [ [[package]] name = "dittolive-ditto" -version = "4.13.1" +version = "5.0.0-preview.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf555e9ddb7eb974ed842bd27cfc15f5448b3cf028b1b521745c693acffe517" +checksum = "20ea1be96fb7f214d78102c496da7ae5e70a34c3c338340ee19e167e65dd3df7" dependencies = [ "async-trait", "async_fn_traits", @@ -491,7 +506,7 @@ dependencies = [ "hashbrown 0.14.5", "macro_rules_attribute", "never-say-never", - "rand", + "rand 0.9.2", "safer-ffi", "serde", "serde-transcode", @@ -509,14 +524,17 @@ dependencies = [ [[package]] name = "dittolive-ditto-sys" -version = "4.13.1" +version = "5.0.0-preview.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0626a0f119eaf498041b86f2565742d25b8ff1bba8bb3240723a963edc4ed8e" +checksum = "fab39a2d09e6cecf184fbf87e83aee9455418d44a47b0de32d72cc6ae3109303" dependencies = [ "macro_rules_attribute", + "object", "paste", "safer-ffi", + "thiserror", "tokio", + "toml", ] [[package]] @@ -606,6 +624,16 @@ version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" +[[package]] +name = "flate2" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1151,6 +1179,16 @@ version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + [[package]] name = "mio" version = "1.1.0" @@ -1193,6 +1231,17 @@ dependencies = [ "autocfg", ] +[[package]] +name = "object" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +dependencies = [ + "flate2", + "memchr", + "ruzstd", +] + [[package]] name = "once_cell" version = "1.21.3" @@ -1352,8 +1401,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", ] [[package]] @@ -1363,7 +1422,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", ] [[package]] @@ -1375,6 +1444,15 @@ dependencies = [ "getrandom 0.2.16", ] +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + [[package]] name = "ratatui" version = "0.29.0" @@ -1470,6 +1548,15 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +[[package]] +name = "ruzstd" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ff0cc5e135c8870a775d3320910cd9b564ec036b4dc0b8741629020be63f01" +dependencies = [ + "twox-hash", +] + [[package]] name = "ryu" version = "1.0.20" @@ -1646,6 +1733,15 @@ dependencies = [ "serde_core", ] +[[package]] +name = "serde_spanned" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" +dependencies = [ + "serde_core", +] + [[package]] name = "serde_with" version = "3.16.1" @@ -1728,6 +1824,12 @@ dependencies = [ "libc", ] +[[package]] +name = "simd-adler32" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" + [[package]] name = "slab" version = "0.4.11" @@ -1787,7 +1889,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "rand", + "rand 0.8.5", "syn 1.0.109", ] @@ -1993,11 +2095,26 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml" +version = "0.9.12+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" +dependencies = [ + "indexmap 2.12.1", + "serde_core", + "serde_spanned", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow", +] + [[package]] name = "toml_datetime" -version = "0.7.3" +version = "0.7.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" dependencies = [ "serde_core", ] @@ -2016,13 +2133,19 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.4" +version = "1.0.9+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +checksum = "702d4415e08923e7e1ef96cd5727c0dfed80b4d2fa25db9647fe5eb6f7c5a4c4" dependencies = [ "winnow", ] +[[package]] +name = "toml_writer" +version = "1.0.6+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" + [[package]] name = "tracing" version = "0.1.43" @@ -2084,6 +2207,12 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "twox-hash" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" + [[package]] name = "unicode-ident" version = "1.0.22" diff --git a/rust-tui/Cargo.toml b/rust-tui/Cargo.toml index 2836f5b25..1a034d761 100644 --- a/rust-tui/Cargo.toml +++ b/rust-tui/Cargo.toml @@ -18,7 +18,7 @@ path = "src/bin/integration_test.rs" [dependencies] # Ditto dependenceis -dittolive-ditto = "4.13.1" +dittolive-ditto = "=5.0.0-preview.4" # External dependencies anyhow = "1" diff --git a/rust-tui/README.md b/rust-tui/README.md index 250b586fd..3e8376a53 100644 --- a/rust-tui/README.md +++ b/rust-tui/README.md @@ -1,19 +1,15 @@ # Ditto Rust Quickstart App 🚀 -This directory contains Ditto's quickstart app for the Rust SDK. -This app is a Terminal User Interface (TUI) that allows for creating -a todo list that syncs between multiple peers. +This directory contains Ditto's quickstart app for the Rust SDK. This app is a Terminal User Interface (TUI) that allows for creating a todo list that syncs between multiple peers. ## Getting Started -To get started, you'll first need to create an app in the [Ditto Portal][0] -with the "Online Playground" authentication type. You'll need to find your +To get started, you'll first need to create an app in the [Ditto Portal][0] with the "Online Playground" authentication type. You'll need to find your AppID and Online Playground Token, Auth URL, and Websocket URL in order to use this quickstart. [0]: https://portal.ditto.live -From the repo root, copy the `.env.sample` file to `.env`, and fill in the -fields with your AppID, Online Playground Token, Auth URL, and Websocket URL: +From the repo root, copy the `.env.sample` file to `.env`, and fill in the fields with your AppID, Online Playground Token, Auth URL, and Websocket URL: ``` cp .sample.env .env diff --git a/rust-tui/src/bin/integration_test.rs b/rust-tui/src/bin/integration_test.rs index 977b875df..0c0155f80 100644 --- a/rust-tui/src/bin/integration_test.rs +++ b/rust-tui/src/bin/integration_test.rs @@ -1,6 +1,7 @@ use anyhow::{Context, Result}; use ditto_quickstart::tui::Todolist; -use dittolive_ditto::{fs::TempRoot, identity::OnlinePlayground, AppId, Ditto}; +use dittolive_ditto::prelude::*; +use dittolive_ditto::{fs::TempRoot, Ditto}; use std::time::Duration; use std::{env, sync::Arc}; use tokio::time::sleep; @@ -12,14 +13,14 @@ async fn main() -> Result<()> { // Load environment variables dotenvy::dotenv().ok(); - let app_id: AppId = env::var("DITTO_APP_ID") - .context("DITTO_APP_ID not found")? - .parse() - .context("Invalid DITTO_APP_ID format")?; - let playground_token = + let database_id = env::var("DITTO_APP_ID") + .context("DITTO_APP_ID not found")?; + + let token = env::var("DITTO_PLAYGROUND_TOKEN").context("DITTO_PLAYGROUND_TOKEN not found")?; let custom_auth_url = env::var("DITTO_AUTH_URL").unwrap_or_else(|_| "https://auth.cloud.ditto.live".to_string()); + let websocket_url = env::var("DITTO_WEBSOCKET_URL").unwrap_or_else(|_| "wss://cloud.ditto.live".to_string()); @@ -29,34 +30,26 @@ async fn main() -> Result<()> { println!("🔍 Looking for task: {}", task_to_find); + let connect_config = DittoConfigConnect::Server { + url: custom_auth_url.parse().unwrap(), + }; + + let config = DittoConfig::new(database_id, connect_config).with_persistence_directory(Arc::new(TempRoot::new()).root_path()); + // Create Ditto instance (using same pattern as main.rs) - let ditto = Ditto::builder() - .with_root(Arc::new(TempRoot::new())) - .with_identity(|root| { - OnlinePlayground::new( - root, - app_id.clone(), - playground_token, - false, - Some(custom_auth_url.as_str()), - ) - })? - .build()?; + let ditto = Ditto::open_sync(config)?; + + //use token to authenticate with Ditto Cloud + ditto.auth().unwrap().login(token.as_str(), &identity::get_development_provider())?; ditto.update_transport_config(|config| { config.enable_all_peer_to_peer(); - config.connect.websocket_urls.insert(websocket_url.clone()); }); // Disable sync with v3 peers and DQL strict mode - let _ = ditto.disable_sync_with_v3(); - let _ = ditto - .store() - .execute_v2("ALTER SYSTEM SET DQL_STRICT_MODE = false") - .await?; // Start sync - let _ = ditto.start_sync(); + let _ = ditto.sync().start(); println!("✅ Created Ditto instance and started sync"); // Create todolist instance (loads the app) @@ -100,7 +93,7 @@ async fn main() -> Result<()> { anyhow::bail!("Integration test failed - seeded task not found"); } - todolist.ditto.stop_sync(); + todolist.ditto.sync().stop(); println!("🛑 Stopped sync"); println!("🎉 Integration test passed! App loads and syncs with Ditto Cloud successfully."); diff --git a/rust-tui/src/bin/main.rs b/rust-tui/src/bin/main.rs index d75659af3..cd3f116a5 100644 --- a/rust-tui/src/bin/main.rs +++ b/rust-tui/src/bin/main.rs @@ -3,14 +3,15 @@ use std::{path::PathBuf, sync::Arc, time::Duration}; use anyhow::{anyhow, Context, Result}; use clap::Parser; use ditto_quickstart::{term, tui::TuiTask, Shutdown}; -use dittolive_ditto::{fs::TempRoot, identity::OnlinePlayground, AppId, Ditto}; +use dittolive_ditto::{fs::TempRoot, Ditto}; +use dittolive_ditto::prelude::*; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; #[derive(Debug, Parser)] pub struct Cli { /// The Ditto App ID this app will use to initialize Ditto #[clap(long, env = "DITTO_APP_ID")] - app_id: AppId, + database_id: String, /// The Online Playground token this app should use for authentication #[clap(long, env = "DITTO_PLAYGROUND_TOKEN")] @@ -61,7 +62,7 @@ async fn main() -> Result<()> { // Initialize and launch app let ditto = try_init_ditto( - cli.app_id, + cli.database_id, cli.token, cli.custom_auth_url, cli.websocket_url.clone(), @@ -106,12 +107,19 @@ async fn main() -> Result<()> { } async fn try_init_ditto( - app_id: AppId, + database_id: String, token: String, custom_auth_url: String, websocket_url: String, p2p_enabled: bool, ) -> Result { + + + //create connect https://software.ditto.live/rust/Ditto/5.0.0-preview.4/x86_64-unknown-linux-gnu/docs/dittolive_ditto/enum.DittoConfigConnect.html + let connect_config = DittoConfigConnect::Server { + url: custom_auth_url.parse().unwrap(), + }; + // We use a temporary directory to store Ditto's local database. // This means that data will not be persistent between runs of the // application, but it allows us to run multiple instances of the @@ -119,18 +127,12 @@ async fn try_init_ditto( // application, we would want to store the database in a more permanent // location, and if multiple instances are needed, ensure that each // instance has its own persistence directory. - let ditto = Ditto::builder() - .with_root(Arc::new(TempRoot::new())) - .with_identity(|root| { - OnlinePlayground::new( - root, - app_id.clone(), - token, - false, // This is required to be set to false to use the correct URLs - Some(custom_auth_url.as_str()), - ) - })? - .build()?; + let config = DittoConfig::new(database_id.clone(), connect_config).with_persistence_directory(Arc::new(TempRoot::new()).root_path()); + + // https://software.ditto.live/rust/Ditto/5.0.0-preview.4/x86_64-unknown-linux-gnu/docs/dittolive_ditto/index.html#playground-quickstart + let ditto = Ditto::open_sync(config)?; + + ditto.auth().unwrap().login(token.as_str(), &identity::get_development_provider())?; ditto.update_transport_config(|config| { if p2p_enabled { @@ -146,20 +148,10 @@ async fn try_init_ditto( config.connect.websocket_urls.insert(websocket_url); }); - // disable sync with v3 peers, required for DQL - _ = ditto.disable_sync_with_v3(); - - // disable DQL strict mode - // https://docs.ditto.live/dql/strict-mode - _ = ditto - .store() - .execute_v2("ALTER SYSTEM SET DQL_STRICT_MODE = false") - .await?; - // Start sync - _ = ditto.start_sync(); + ditto.sync().start()?; - tracing::info!(%app_id, "Started Ditto!"); + tracing::info!(database_id = %&database_id, "Started Ditto!"); Ok(ditto) } diff --git a/rust-tui/src/tui/todolist.rs b/rust-tui/src/tui/todolist.rs index ae4c4cee8..9ff503b58 100644 --- a/rust-tui/src/tui/todolist.rs +++ b/rust-tui/src/tui/todolist.rs @@ -96,11 +96,11 @@ impl Todolist { // https://docs.ditto.live/sdk/latest/sync/syncing-data#creating-subscriptions let tasks_subscription = ditto .sync() - .register_subscription_v2("SELECT * FROM tasks")?; + .register_subscription("SELECT * FROM tasks")?; // register observer for live query // Register observer, which runs against the local database on this peer - let tasks_observer = ditto.store().register_observer_v2( + let tasks_observer = ditto.store().register_observer( "SELECT * FROM tasks WHERE deleted=false ORDER BY title ASC", move |query_result| { let docs = query_result @@ -155,7 +155,7 @@ impl Todolist { }) .collect::>(); - let sync_state = if self.ditto.is_sync_active() { + let sync_state = if self.ditto.sync().is_active() { " 🟢 Sync Active ".green() } else { " 🔴 Sync Inactive ".red() @@ -305,10 +305,10 @@ impl Todolist { } fn toggle_sync(&mut self) -> Result<()> { - if self.ditto.is_sync_active() { - self.ditto.stop_sync(); + if self.ditto.sync().is_active() { + self.ditto.sync().stop(); } else { - self.ditto.start_sync()?; + self.ditto.sync().start()?; } Ok(()) } @@ -329,7 +329,7 @@ impl Todolist { let done = selected_task.done; self.ditto .store() - .execute_v2(( + .execute(( "UPDATE tasks SET done=:done WHERE _id=:id", serde_json::json!({ "id": id, @@ -356,7 +356,7 @@ impl Todolist { let id = selected_task.id; self.ditto .store() - .execute_v2(( + .execute(( "UPDATE tasks SET deleted=true WHERE _id=:id", serde_json::json!({ "id": id @@ -372,7 +372,7 @@ impl Todolist { let task = TodoItem::new(title); self.ditto .store() - .execute_v2(( + .execute(( "INSERT INTO tasks DOCUMENTS (:task)", serde_json::json!({ "task": task @@ -386,7 +386,7 @@ impl Todolist { pub async fn try_edit_todo(&mut self, id: &str, title: &str) -> Result<()> { self.ditto .store() - .execute_v2(( + .execute(( "UPDATE tasks SET title=:title WHERE _id=:id", serde_json::json!({ "title": title, From 96fefb82c8a13b13e21aab80858f333c835d8dc4 Mon Sep 17 00:00:00 2001 From: Aaron LaBeau Date: Tue, 17 Feb 2026 17:10:25 -0600 Subject: [PATCH 2/8] feat: update CI/CD to use version 1.91.1 version of rustc --- .github/workflows/rust-tui-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/rust-tui-ci.yml b/.github/workflows/rust-tui-ci.yml index de6e3a857..ba612b5a3 100644 --- a/.github/workflows/rust-tui-ci.yml +++ b/.github/workflows/rust-tui-ci.yml @@ -22,6 +22,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: + toolchain: 1.91.1 override: true components: rustfmt, clippy @@ -78,6 +79,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: + toolchain: 1.91.1 override: true components: rustfmt, clippy From 62541c85fca541175526acc5ef44aba1e12efb41 Mon Sep 17 00:00:00 2001 From: Aaron LaBeau Date: Tue, 17 Feb 2026 17:19:02 -0600 Subject: [PATCH 3/8] feat: updated to fix linting issues --- rust-tui/src/bin/integration_test.rs | 16 +++++++++------- rust-tui/src/bin/main.rs | 12 +++++++----- rust-tui/src/tui/todolist.rs | 4 +--- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/rust-tui/src/bin/integration_test.rs b/rust-tui/src/bin/integration_test.rs index 0c0155f80..f29f8dedb 100644 --- a/rust-tui/src/bin/integration_test.rs +++ b/rust-tui/src/bin/integration_test.rs @@ -13,11 +13,9 @@ async fn main() -> Result<()> { // Load environment variables dotenvy::dotenv().ok(); - let database_id = env::var("DITTO_APP_ID") - .context("DITTO_APP_ID not found")?; - - let token = - env::var("DITTO_PLAYGROUND_TOKEN").context("DITTO_PLAYGROUND_TOKEN not found")?; + let database_id = env::var("DITTO_APP_ID").context("DITTO_APP_ID not found")?; + + let token = env::var("DITTO_PLAYGROUND_TOKEN").context("DITTO_PLAYGROUND_TOKEN not found")?; let custom_auth_url = env::var("DITTO_AUTH_URL").unwrap_or_else(|_| "https://auth.cloud.ditto.live".to_string()); @@ -34,13 +32,17 @@ async fn main() -> Result<()> { url: custom_auth_url.parse().unwrap(), }; - let config = DittoConfig::new(database_id, connect_config).with_persistence_directory(Arc::new(TempRoot::new()).root_path()); + let config = DittoConfig::new(database_id, connect_config) + .with_persistence_directory(Arc::new(TempRoot::new()).root_path()); // Create Ditto instance (using same pattern as main.rs) let ditto = Ditto::open_sync(config)?; //use token to authenticate with Ditto Cloud - ditto.auth().unwrap().login(token.as_str(), &identity::get_development_provider())?; + ditto + .auth() + .unwrap() + .login(token.as_str(), &identity::get_development_provider())?; ditto.update_transport_config(|config| { config.enable_all_peer_to_peer(); diff --git a/rust-tui/src/bin/main.rs b/rust-tui/src/bin/main.rs index cd3f116a5..ce798763f 100644 --- a/rust-tui/src/bin/main.rs +++ b/rust-tui/src/bin/main.rs @@ -3,8 +3,8 @@ use std::{path::PathBuf, sync::Arc, time::Duration}; use anyhow::{anyhow, Context, Result}; use clap::Parser; use ditto_quickstart::{term, tui::TuiTask, Shutdown}; -use dittolive_ditto::{fs::TempRoot, Ditto}; use dittolive_ditto::prelude::*; +use dittolive_ditto::{fs::TempRoot, Ditto}; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; #[derive(Debug, Parser)] @@ -113,8 +113,6 @@ async fn try_init_ditto( websocket_url: String, p2p_enabled: bool, ) -> Result { - - //create connect https://software.ditto.live/rust/Ditto/5.0.0-preview.4/x86_64-unknown-linux-gnu/docs/dittolive_ditto/enum.DittoConfigConnect.html let connect_config = DittoConfigConnect::Server { url: custom_auth_url.parse().unwrap(), @@ -127,12 +125,16 @@ async fn try_init_ditto( // application, we would want to store the database in a more permanent // location, and if multiple instances are needed, ensure that each // instance has its own persistence directory. - let config = DittoConfig::new(database_id.clone(), connect_config).with_persistence_directory(Arc::new(TempRoot::new()).root_path()); + let config = DittoConfig::new(database_id.clone(), connect_config) + .with_persistence_directory(Arc::new(TempRoot::new()).root_path()); // https://software.ditto.live/rust/Ditto/5.0.0-preview.4/x86_64-unknown-linux-gnu/docs/dittolive_ditto/index.html#playground-quickstart let ditto = Ditto::open_sync(config)?; - ditto.auth().unwrap().login(token.as_str(), &identity::get_development_provider())?; + ditto + .auth() + .unwrap() + .login(token.as_str(), &identity::get_development_provider())?; ditto.update_transport_config(|config| { if p2p_enabled { diff --git a/rust-tui/src/tui/todolist.rs b/rust-tui/src/tui/todolist.rs index 9ff503b58..1f4e8aaca 100644 --- a/rust-tui/src/tui/todolist.rs +++ b/rust-tui/src/tui/todolist.rs @@ -94,9 +94,7 @@ impl Todolist { // Register a subscription, which determines what data syncs to this peer // https://docs.ditto.live/sdk/latest/sync/syncing-data#creating-subscriptions - let tasks_subscription = ditto - .sync() - .register_subscription("SELECT * FROM tasks")?; + let tasks_subscription = ditto.sync().register_subscription("SELECT * FROM tasks")?; // register observer for live query // Register observer, which runs against the local database on this peer From 6da5b49cc613c9ae147356ed20321b085311bbe8 Mon Sep 17 00:00:00 2001 From: Aaron LaBeau Date: Tue, 17 Feb 2026 17:22:26 -0600 Subject: [PATCH 4/8] fix: forgot proper version of Rust for linux - you have to cut and paste in the yml file for each platform --- .github/workflows/rust-tui-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/rust-tui-ci.yml b/.github/workflows/rust-tui-ci.yml index ba612b5a3..d684ac1f7 100644 --- a/.github/workflows/rust-tui-ci.yml +++ b/.github/workflows/rust-tui-ci.yml @@ -55,6 +55,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: + toolchain: 1.91.1 override: true components: rustfmt, clippy @@ -100,6 +101,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: + toolchain: 1.91.1 override: true components: rustfmt, clippy From 45c1eb7e926120f39d510d72f0220ee6e7588d58 Mon Sep 17 00:00:00 2001 From: Aaron LaBeau Date: Tue, 17 Feb 2026 18:23:15 -0600 Subject: [PATCH 5/8] fix: updated to fix auth --- rust-tui/src/bin/main.rs | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/rust-tui/src/bin/main.rs b/rust-tui/src/bin/main.rs index ce798763f..e08b34422 100644 --- a/rust-tui/src/bin/main.rs +++ b/rust-tui/src/bin/main.rs @@ -106,6 +106,23 @@ async fn main() -> Result<()> { Ok(()) } +struct TokenHandler { + token: String, +} + +impl DittoAuthExpirationHandler for TokenHandler { + async fn on_expiration(&self, ditto: &Ditto, _duration_remaining: Duration) { + match ditto + .auth() + .unwrap() + .login(self.token.as_str(), &identity::get_development_provider()) + { + Ok(_) => println!("Authentication successful"), + Err(e) => println!("Authentication failed: {}", e), + } + } +} + async fn try_init_ditto( database_id: String, token: String, @@ -132,9 +149,10 @@ async fn try_init_ditto( let ditto = Ditto::open_sync(config)?; ditto - .auth() - .unwrap() - .login(token.as_str(), &identity::get_development_provider())?; + .auth() + .unwrap() + .set_expiration_handler(TokenHandler { token: token.clone() }); + ditto.update_transport_config(|config| { if p2p_enabled { From 9e7a6c7b2e20ff0b32b4f0b504da0c233af0ac95 Mon Sep 17 00:00:00 2001 From: Aaron LaBeau Date: Tue, 17 Feb 2026 18:25:25 -0600 Subject: [PATCH 6/8] fix: linting --- rust-tui/src/bin/main.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/rust-tui/src/bin/main.rs b/rust-tui/src/bin/main.rs index e08b34422..9ca23ddf8 100644 --- a/rust-tui/src/bin/main.rs +++ b/rust-tui/src/bin/main.rs @@ -148,11 +148,9 @@ async fn try_init_ditto( // https://software.ditto.live/rust/Ditto/5.0.0-preview.4/x86_64-unknown-linux-gnu/docs/dittolive_ditto/index.html#playground-quickstart let ditto = Ditto::open_sync(config)?; - ditto - .auth() - .unwrap() - .set_expiration_handler(TokenHandler { token: token.clone() }); - + ditto.auth().unwrap().set_expiration_handler(TokenHandler { + token: token.clone(), + }); ditto.update_transport_config(|config| { if p2p_enabled { From 26d5b1925487407e1e5d1d26a1004ea41db6ccb2 Mon Sep 17 00:00:00 2001 From: Aaron LaBeau <80424345+biozal@users.noreply.github.com> Date: Tue, 17 Feb 2026 21:24:13 -0600 Subject: [PATCH 7/8] fix: fixed tests running --- rust-tui/Cargo.toml | 2 +- rust-tui/src/bin/integration_test.rs | 25 ++++++++++++++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/rust-tui/Cargo.toml b/rust-tui/Cargo.toml index 1a034d761..c12c43f16 100644 --- a/rust-tui/Cargo.toml +++ b/rust-tui/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "ditto-quickstart" version = "0.0.0" -edition = "2021" +edition = "2024" default-run = "ditto-quickstart" [lib] diff --git a/rust-tui/src/bin/integration_test.rs b/rust-tui/src/bin/integration_test.rs index f29f8dedb..744930625 100644 --- a/rust-tui/src/bin/integration_test.rs +++ b/rust-tui/src/bin/integration_test.rs @@ -38,11 +38,9 @@ async fn main() -> Result<()> { // Create Ditto instance (using same pattern as main.rs) let ditto = Ditto::open_sync(config)?; - //use token to authenticate with Ditto Cloud - ditto - .auth() - .unwrap() - .login(token.as_str(), &identity::get_development_provider())?; + ditto.auth().unwrap().set_expiration_handler(TokenHandler { + token: token.clone(), + }); ditto.update_transport_config(|config| { config.enable_all_peer_to_peer(); @@ -101,3 +99,20 @@ async fn main() -> Result<()> { println!("🎉 Integration test passed! App loads and syncs with Ditto Cloud successfully."); Ok(()) } + +struct TokenHandler { + token: String, +} + +impl DittoAuthExpirationHandler for TokenHandler { + async fn on_expiration(&self, ditto: &Ditto, _duration_remaining: Duration) { + match ditto + .auth() + .unwrap() + .login(self.token.as_str(), &identity::get_development_provider()) + { + Ok(_) => println!("Authentication successful"), + Err(e) => println!("Authentication failed: {}", e), + } + } +} From 81918be907a3de9ed02ef9f5429a451620e5a383 Mon Sep 17 00:00:00 2001 From: Aaron LaBeau <80424345+biozal@users.noreply.github.com> Date: Tue, 17 Feb 2026 21:26:32 -0600 Subject: [PATCH 8/8] fixed linting and formating --- rust-tui/src/bin/integration_test.rs | 2 +- rust-tui/src/bin/main.rs | 6 +++--- rust-tui/src/term.rs | 2 +- rust-tui/src/tui/mod.rs | 4 ++-- rust-tui/src/tui/todolist.rs | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/rust-tui/src/bin/integration_test.rs b/rust-tui/src/bin/integration_test.rs index 744930625..2ef608c4a 100644 --- a/rust-tui/src/bin/integration_test.rs +++ b/rust-tui/src/bin/integration_test.rs @@ -1,7 +1,7 @@ use anyhow::{Context, Result}; use ditto_quickstart::tui::Todolist; use dittolive_ditto::prelude::*; -use dittolive_ditto::{fs::TempRoot, Ditto}; +use dittolive_ditto::{Ditto, fs::TempRoot}; use std::time::Duration; use std::{env, sync::Arc}; use tokio::time::sleep; diff --git a/rust-tui/src/bin/main.rs b/rust-tui/src/bin/main.rs index 9ca23ddf8..9954fdd48 100644 --- a/rust-tui/src/bin/main.rs +++ b/rust-tui/src/bin/main.rs @@ -1,10 +1,10 @@ use std::{path::PathBuf, sync::Arc, time::Duration}; -use anyhow::{anyhow, Context, Result}; +use anyhow::{Context, Result, anyhow}; use clap::Parser; -use ditto_quickstart::{term, tui::TuiTask, Shutdown}; +use ditto_quickstart::{Shutdown, term, tui::TuiTask}; use dittolive_ditto::prelude::*; -use dittolive_ditto::{fs::TempRoot, Ditto}; +use dittolive_ditto::{Ditto, fs::TempRoot}; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; #[derive(Debug, Parser)] diff --git a/rust-tui/src/term.rs b/rust-tui/src/term.rs index e88a29134..9447279cb 100644 --- a/rust-tui/src/term.rs +++ b/rust-tui/src/term.rs @@ -5,7 +5,7 @@ //! [0]: https://github.com/tokio-rs/console/blob/cbf6f56a16036ecf13548c4209fcc62f8a84bae2/tokio-console/src/term.rs use anyhow::{Context, Result}; -pub use ratatui::{backend::CrosstermBackend, Terminal}; +pub use ratatui::{Terminal, backend::CrosstermBackend}; use std::io; pub fn init_crossterm() -> Result<(Terminal>, OnShutdown)> { diff --git a/rust-tui/src/tui/mod.rs b/rust-tui/src/tui/mod.rs index 60037326f..33aee338a 100644 --- a/rust-tui/src/tui/mod.rs +++ b/rust-tui/src/tui/mod.rs @@ -1,4 +1,4 @@ -use anyhow::{anyhow, Context, Result}; +use anyhow::{Context, Result, anyhow}; use crossterm::event::{Event, EventStream}; use dittolive_ditto::prelude::*; use futures::{FutureExt, Stream, StreamExt}; @@ -6,7 +6,7 @@ use ratatui::prelude::*; use std::{io::Stdout, ops::ControlFlow, time::Duration}; use tokio::task::JoinHandle; -use crate::{should_quit, Shutdown}; +use crate::{Shutdown, should_quit}; pub mod todolist; diff --git a/rust-tui/src/tui/todolist.rs b/rust-tui/src/tui/todolist.rs index 1f4e8aaca..9037efd7c 100644 --- a/rust-tui/src/tui/todolist.rs +++ b/rust-tui/src/tui/todolist.rs @@ -1,9 +1,9 @@ use anyhow::Context; use anyhow::Result; use crossterm::event::Event; +use dittolive_ditto::Ditto; use dittolive_ditto::store::StoreObserver; use dittolive_ditto::sync::SyncSubscription; -use dittolive_ditto::Ditto; use ratatui::prelude::*; use ratatui::widgets::Block; use ratatui::widgets::BorderType;