lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README

commit e686fed05fd696eb0b41a945bb86c6f48b41ac9f
parent 7f92d1e26548d0d1c400c4bfae7480a2d451ba1a
Author: triesap <tyson@radroots.org>
Date:   Mon, 27 Jul 2026 02:37:21 +0000

outbox: isolate storage feature profiles

- make runtime Tokio imply SQLite support
- gate SQLite APIs behind the SQLite feature
- isolate event-store integration behind an adapter
- verify bare, SQLite, adapter, and full profiles

Diffstat:
Mcrates/outbox/Cargo.toml | 15+++++++++------
Mcrates/outbox/src/error.rs | 2++
Mcrates/outbox/src/lib.rs | 4++++
Mcrates/outbox/src/store.rs | 20++++++++++++++------
4 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/crates/outbox/Cargo.toml b/crates/outbox/Cargo.toml @@ -12,19 +12,22 @@ homepage.workspace = true readme = "README" [features] -default = ["sqlite", "runtime-tokio"] +default = ["event-store-adapter"] sqlite = ["dep:sqlx", "sqlx/sqlite-bundled"] -runtime-tokio = ["sqlx/runtime-tokio"] +runtime-tokio = ["sqlite", "sqlx/runtime-tokio"] +event-store-adapter = [ + "runtime-tokio", + "dep:radroots_event_store", + "radroots_event_store/sqlite", + "radroots_event_store/runtime-tokio", +] [dependencies] radroots_event = { workspace = true, default-features = false, features = [ "std", "serde", ] } -radroots_event_store = { workspace = true, default-features = false, features = [ - "sqlite", - "runtime-tokio", -] } +radroots_event_store = { workspace = true, default-features = false, optional = true } radroots_transport = { workspace = true, default-features = false } hex = { workspace = true } serde = { workspace = true, features = ["std"] } diff --git a/crates/outbox/src/error.rs b/crates/outbox/src/error.rs @@ -5,12 +5,14 @@ use thiserror::Error; #[derive(Debug, Error)] pub enum RadrootsOutboxError { + #[cfg(feature = "sqlite")] #[error("SQLx error: {0}")] Sqlx(#[from] sqlx::Error), #[error("JSON error: {0}")] Json(#[from] serde_json::Error), + #[cfg(feature = "event-store-adapter")] #[error("Event store error: {0}")] EventStore(#[from] radroots_event_store::RadrootsEventStoreError), diff --git a/crates/outbox/src/lib.rs b/crates/outbox/src/lib.rs @@ -2,11 +2,14 @@ #![forbid(unsafe_code)] mod error; +#[cfg(feature = "sqlite")] mod migrations; mod model; +#[cfg(feature = "sqlite")] mod store; pub use error::RadrootsOutboxError; +#[cfg(feature = "sqlite")] pub use migrations::{OUTBOX_MIGRATION_DOWN, OUTBOX_MIGRATION_UP}; pub use model::{ RadrootsOutboxClaimedEvent, RadrootsOutboxDeliveryAttemptRecord, @@ -20,4 +23,5 @@ pub use model::{ RadrootsOutboxSignedTradeMutationInput, RadrootsOutboxStatusSummary, RadrootsOutboxTradeMutationInput, }; +#[cfg(feature = "sqlite")] pub use store::RadrootsOutbox; diff --git a/crates/outbox/src/store.rs b/crates/outbox/src/store.rs @@ -2,17 +2,18 @@ use crate::RadrootsOutboxError; use crate::migrations::{OUTBOX_MIGRATION_DOWN, OUTBOX_MIGRATION_UP}; +#[cfg(feature = "event-store-adapter")] +use crate::model::RadrootsOutboxEventStoreIngestReceipt; use crate::model::{ RadrootsOutboxClaimedEvent, RadrootsOutboxDeliveryAttemptRecord, RadrootsOutboxDeliveryPlanInput, RadrootsOutboxDeliveryPlanRecord, RadrootsOutboxDeliveryPlanStatus, RadrootsOutboxDeliveryTargetRecord, RadrootsOutboxDeliveryTargetStatus, RadrootsOutboxEnqueueReceipt, RadrootsOutboxEnqueueStatus, - RadrootsOutboxEventRecord, RadrootsOutboxEventState, RadrootsOutboxEventStoreIngestReceipt, - RadrootsOutboxIdempotencyPreflight, RadrootsOutboxOperationInput, - RadrootsOutboxOperationRecord, RadrootsOutboxOperationStatus, RadrootsOutboxReticulumBehavior, - RadrootsOutboxReticulumEventRecord, RadrootsOutboxSignedOperationInput, - RadrootsOutboxSignedTradeMutationInput, RadrootsOutboxStatusSummary, - RadrootsOutboxTradeMutationInput, + RadrootsOutboxEventRecord, RadrootsOutboxEventState, RadrootsOutboxIdempotencyPreflight, + RadrootsOutboxOperationInput, RadrootsOutboxOperationRecord, RadrootsOutboxOperationStatus, + RadrootsOutboxReticulumBehavior, RadrootsOutboxReticulumEventRecord, + RadrootsOutboxSignedOperationInput, RadrootsOutboxSignedTradeMutationInput, + RadrootsOutboxStatusSummary, RadrootsOutboxTradeMutationInput, }; use radroots_event::RadrootsEventKindClass; use radroots_event::draft::{ @@ -22,6 +23,7 @@ use radroots_event::ids::{RadrootsTradeId, RadrootsTradeMutationId}; use radroots_event::kinds::TRADE_MUTATION_EVENT_KINDS; use radroots_event::trade::trade_mutation_from_canonical_content; use radroots_event::wire::RadrootsNip01EventWire; +#[cfg(feature = "event-store-adapter")] use radroots_event_store::{ RadrootsEventIngest, RadrootsEventStore, RadrootsTransportObservation, RadrootsTransportObservationType, @@ -1209,6 +1211,7 @@ impl RadrootsOutbox { Ok(changed.rows_affected()) } + #[cfg(feature = "event-store-adapter")] pub async fn ingest_signed_event_local( &self, event_store: &RadrootsEventStore, @@ -1605,6 +1608,7 @@ impl RadrootsOutbox { Ok(()) } + #[cfg(feature = "event-store-adapter")] async fn claimed_event( &self, outbox_event_id: i64, @@ -3447,6 +3451,7 @@ mod tests { .expect("generic draft") } + #[cfg(feature = "event-store-adapter")] fn durable_draft(expected_pubkey: &str, label: &str) -> RadrootsEventDraft { RadrootsEventDraft::new( "radroots.social.follow_list.v1", @@ -8062,6 +8067,7 @@ mod tests { } } + #[cfg(feature = "event-store-adapter")] #[tokio::test] async fn local_signed_event_ingest_records_one_idempotent_local_import_observation() { let outbox = RadrootsOutbox::open_memory().await.expect("open"); @@ -8133,6 +8139,7 @@ mod tests { ); } + #[cfg(feature = "event-store-adapter")] #[tokio::test] async fn local_signed_event_ingest_rejects_negative_observation_time_without_mutation() { let outbox = RadrootsOutbox::open_memory().await.expect("open"); @@ -8194,6 +8201,7 @@ mod tests { ); } + #[cfg(feature = "event-store-adapter")] #[tokio::test] async fn local_ingest_rejects_an_invalid_signature_without_marking_the_outbox_or_store() { let outbox = RadrootsOutbox::open_memory().await.expect("open");