commit e7817600be65afe420b9346ba2f8dfcd601b8131
parent 74d6515696249db9d51b61293c6f8832a543ed67
Author: triesap <tyson@radroots.org>
Date: Fri, 12 Jun 2026 22:50:21 -0700
nostr_runtime: rename event callback sink
- rename the runtime event callback trait and in-memory helper from store to sink
- move the runtime module surface from store to sink without preserving old aliases
- update the nostrdb runtime adapter and tests to expose event-sink semantics
- verify the focused runtime lanes and workspace check under the new names
Diffstat:
8 files changed, 97 insertions(+), 101 deletions(-)
diff --git a/crates/nostr_ndb/README b/crates/nostr_ndb/README
@@ -7,7 +7,7 @@ primitives for the `radroots` core libraries.
* configuration, filter, ingest, query, and subscription types for
nostrdb-backed workflows;
- * runtime-adapter hooks that let higher layers drive a nostrdb event store;
+ * runtime-adapter hooks that let higher layers drive nostrdb as an event sink;
* feature-gated support for the `nostrdb` crate, runtime glue, and gift-wrap
handling;
* a `std`-based integration crate with optional async runtime support.
diff --git a/crates/nostr_ndb/src/lib.rs b/crates/nostr_ndb/src/lib.rs
@@ -40,7 +40,7 @@ pub mod prelude {
RadrootsNostrNdbNote, RadrootsNostrNdbProfile, RadrootsNostrNdbQuerySpec,
};
#[cfg(all(feature = "ndb", feature = "runtime-adapter"))]
- pub use crate::runtime_adapter::RadrootsNostrNdbEventStoreAdapter;
+ pub use crate::runtime_adapter::RadrootsNostrNdbEventSinkAdapter;
#[cfg(all(feature = "ndb", feature = "rt"))]
pub use crate::subscription::RadrootsNostrNdbSubscriptionStream;
#[cfg(feature = "ndb")]
diff --git a/crates/nostr_ndb/src/runtime_adapter.rs b/crates/nostr_ndb/src/runtime_adapter.rs
@@ -1,11 +1,11 @@
use crate::ingest::RadrootsNostrNdbIngestSource;
use crate::ndb::RadrootsNostrNdb;
use radroots_nostr::prelude::RadrootsNostrEvent;
-use radroots_nostr_runtime::prelude::RadrootsNostrEventStore;
+use radroots_nostr_runtime::prelude::RadrootsNostrEventSink;
use std::sync::Arc;
#[derive(Clone)]
-pub struct RadrootsNostrNdbEventStoreAdapter {
+pub struct RadrootsNostrNdbEventSinkAdapter {
ndb: RadrootsNostrNdb,
source: RadrootsNostrNdbIngestSource,
}
@@ -14,7 +14,7 @@ fn ndb_error_to_string(source: crate::error::RadrootsNostrNdbError) -> String {
source.to_string()
}
-impl RadrootsNostrNdbEventStoreAdapter {
+impl RadrootsNostrNdbEventSinkAdapter {
pub fn new(ndb: RadrootsNostrNdb) -> Self {
Self {
ndb,
@@ -27,19 +27,19 @@ impl RadrootsNostrNdbEventStoreAdapter {
self
}
- pub fn into_event_store(self) -> Arc<dyn RadrootsNostrEventStore> {
+ pub fn into_event_sink(self) -> Arc<dyn RadrootsNostrEventSink> {
Arc::new(self)
}
}
-impl RadrootsNostrEventStore for RadrootsNostrNdb {
+impl RadrootsNostrEventSink for RadrootsNostrNdb {
fn ingest_event(&self, event: &RadrootsNostrEvent) -> Result<(), String> {
RadrootsNostrNdb::ingest_event(self, event, RadrootsNostrNdbIngestSource::client())
.map_err(ndb_error_to_string)
}
}
-impl RadrootsNostrEventStore for RadrootsNostrNdbEventStoreAdapter {
+impl RadrootsNostrEventSink for RadrootsNostrNdbEventSinkAdapter {
fn ingest_event(&self, event: &RadrootsNostrEvent) -> Result<(), String> {
self.ndb
.ingest_event(event, self.source.clone())
@@ -60,7 +60,7 @@ mod tests {
let db_dir = tmp_dir.path().join("ndb");
let config = RadrootsNostrNdbConfig::new(&db_dir);
let ndb = RadrootsNostrNdb::open(config).expect("database should open");
- let adapter = RadrootsNostrNdbEventStoreAdapter::new(ndb);
+ let adapter = RadrootsNostrNdbEventSinkAdapter::new(ndb);
let keys = RadrootsNostrKeys::generate();
let event = RadrootsNostrEventBuilder::text_note("hello from runtime adapter")
@@ -73,40 +73,38 @@ mod tests {
}
#[test]
- fn runtime_adapter_can_be_boxed_as_store_trait() {
+ fn runtime_adapter_can_be_boxed_as_sink_trait() {
let tmp_dir = TempDir::new().expect("tempdir should open");
let db_dir = tmp_dir.path().join("ndb");
let config = RadrootsNostrNdbConfig::new(&db_dir);
let ndb = RadrootsNostrNdb::open(config).expect("database should open");
- let store = RadrootsNostrNdbEventStoreAdapter::new(ndb)
+ let sink = RadrootsNostrNdbEventSinkAdapter::new(ndb)
.with_source(RadrootsNostrNdbIngestSource::relay("wss://radroots.org"))
- .into_event_store();
+ .into_event_sink();
let keys = RadrootsNostrKeys::generate();
let event = RadrootsNostrEventBuilder::text_note("hello trait object")
.sign_with_keys(&keys)
.expect("event should sign");
- store
- .ingest_event(&event)
- .expect("boxed store should ingest event");
+ sink.ingest_event(&event)
+ .expect("boxed sink should ingest event");
}
#[test]
- fn ndb_can_be_boxed_as_store_trait() {
+ fn ndb_can_be_boxed_as_sink_trait() {
let tmp_dir = TempDir::new().expect("tempdir should open");
let db_dir = tmp_dir.path().join("ndb");
let config = RadrootsNostrNdbConfig::new(&db_dir);
let ndb = RadrootsNostrNdb::open(config).expect("database should open");
- let store: Arc<dyn RadrootsNostrEventStore> = Arc::new(ndb.clone());
+ let sink: Arc<dyn RadrootsNostrEventSink> = Arc::new(ndb.clone());
let keys = RadrootsNostrKeys::generate();
let event = RadrootsNostrEventBuilder::text_note("hello ndb trait object")
.sign_with_keys(&keys)
.expect("event should sign");
- store
- .ingest_event(&event)
+ sink.ingest_event(&event)
.expect("ndb trait object should ingest event");
}
diff --git a/crates/nostr_runtime/README b/crates/nostr_runtime/README
@@ -8,7 +8,7 @@ coordination for the `radroots` core libraries.
* runtime builder, runtime events, and long-lived connection state types;
* subscription specifications, policies, handles, and traffic-light status
models;
- * store abstractions and snapshot types used by higher-level network
+ * sink abstractions and snapshot types used by higher-level network
orchestration;
* feature-gated integration with client, runtime, and nostrdb adapter crates.
diff --git a/crates/nostr_runtime/src/lib.rs b/crates/nostr_runtime/src/lib.rs
@@ -9,14 +9,14 @@ pub mod types;
#[cfg(all(feature = "nostr-client", feature = "rt"))]
pub mod runtime;
#[cfg(all(feature = "nostr-client", feature = "rt"))]
-pub mod store;
+pub mod sink;
pub mod prelude {
pub use crate::error::RadrootsNostrRuntimeError;
#[cfg(all(feature = "nostr-client", feature = "rt"))]
pub use crate::runtime::{RadrootsNostrRuntime, RadrootsNostrRuntimeBuilder};
#[cfg(all(feature = "nostr-client", feature = "rt"))]
- pub use crate::store::{RadrootsNostrEventStore, RadrootsNostrInMemoryEventStore};
+ pub use crate::sink::{RadrootsNostrEventSink, RadrootsNostrInMemoryEventSink};
pub use crate::types::{
RadrootsNostrConnectionSnapshot, RadrootsNostrRuntimeEvent,
RadrootsNostrSubscriptionHandle, RadrootsNostrSubscriptionPolicy,
diff --git a/crates/nostr_runtime/src/runtime.rs b/crates/nostr_runtime/src/runtime.rs
@@ -1,5 +1,5 @@
use crate::error::RadrootsNostrRuntimeError;
-use crate::store::RadrootsNostrEventStore;
+use crate::sink::RadrootsNostrEventSink;
use crate::types::{
RadrootsNostrConnectionSnapshot, RadrootsNostrRuntimeEvent, RadrootsNostrSubscriptionHandle,
RadrootsNostrSubscriptionPolicy, RadrootsNostrSubscriptionSpec, RadrootsNostrTrafficLight,
@@ -25,7 +25,7 @@ pub struct RadrootsNostrRuntimeBuilder {
relays: Vec<String>,
queue_capacity: usize,
monitor_capacity: usize,
- event_store: Option<Arc<dyn RadrootsNostrEventStore>>,
+ event_sink: Option<Arc<dyn RadrootsNostrEventSink>>,
}
impl RadrootsNostrRuntimeBuilder {
@@ -38,7 +38,7 @@ impl RadrootsNostrRuntimeBuilder {
relays: Vec::new(),
queue_capacity: Self::DEFAULT_QUEUE_CAPACITY,
monitor_capacity: Self::DEFAULT_MONITOR_CAPACITY,
- event_store: None,
+ event_sink: None,
}
}
@@ -67,8 +67,8 @@ impl RadrootsNostrRuntimeBuilder {
self
}
- pub fn event_store(mut self, store: Arc<dyn RadrootsNostrEventStore>) -> Self {
- self.event_store = Some(store);
+ pub fn event_sink(mut self, sink: Arc<dyn RadrootsNostrEventSink>) -> Self {
+ self.event_sink = Some(sink);
self
}
@@ -102,7 +102,7 @@ impl RadrootsNostrRuntimeBuilder {
started: AtomicBool::new(false),
shutting_down: AtomicBool::new(false),
next_subscription_id: AtomicU64::new(1),
- event_store: self.event_store,
+ event_sink: self.event_sink,
});
Ok(RadrootsNostrRuntime { inner })
@@ -132,7 +132,7 @@ struct RadrootsNostrRuntimeInner {
started: AtomicBool,
shutting_down: AtomicBool,
next_subscription_id: AtomicU64,
- event_store: Option<Arc<dyn RadrootsNostrEventStore>>,
+ event_sink: Option<Arc<dyn RadrootsNostrEventSink>>,
}
impl RadrootsNostrRuntime {
@@ -413,8 +413,8 @@ fn spawn_subscription_worker(
let kind = event.kind.as_u16();
since_unix = Some(event.created_at.as_secs().saturating_add(1));
- if let Some(store) = inner.event_store.as_ref() {
- if let Err(message) = store.ingest_event(&event) {
+ if let Some(sink) = inner.event_sink.as_ref() {
+ if let Err(message) = sink.ingest_event(&event) {
if let Ok(mut guard) = inner.last_error.lock() {
*guard = Some(message.clone());
}
@@ -458,7 +458,7 @@ fn spawn_subscription_worker(
#[cfg(test)]
mod tests {
use super::*;
- use crate::store::RadrootsNostrInMemoryEventStore;
+ use crate::sink::RadrootsNostrInMemoryEventSink;
use alloc::sync::Arc;
use radroots_nostr::prelude::RadrootsNostrFilter;
@@ -519,12 +519,12 @@ mod tests {
}
#[test]
- fn build_accepts_event_store() {
- let store = Arc::new(RadrootsNostrInMemoryEventStore::new());
+ fn build_accepts_event_sink() {
+ let sink = Arc::new(RadrootsNostrInMemoryEventSink::new());
let result = RadrootsNostrRuntimeBuilder::new()
.keys(RadrootsNostrKeys::generate())
.add_relay("wss://relay.example.com")
- .event_store(store)
+ .event_sink(sink)
.build();
assert!(result.is_ok());
}
diff --git a/crates/nostr_runtime/src/sink.rs b/crates/nostr_runtime/src/sink.rs
@@ -0,0 +1,64 @@
+use alloc::string::ToString;
+use alloc::vec::Vec;
+use radroots_nostr::prelude::RadrootsNostrEvent;
+use std::sync::Mutex;
+
+pub trait RadrootsNostrEventSink: Send + Sync {
+ fn ingest_event(&self, event: &RadrootsNostrEvent) -> Result<(), String>;
+}
+
+#[derive(Default)]
+pub struct RadrootsNostrInMemoryEventSink {
+ events: Mutex<Vec<RadrootsNostrEvent>>,
+}
+
+impl RadrootsNostrInMemoryEventSink {
+ pub fn new() -> Self {
+ Self::default()
+ }
+
+ pub fn events(&self) -> Vec<RadrootsNostrEvent> {
+ self.events
+ .lock()
+ .map(|guard| guard.clone())
+ .unwrap_or_default()
+ }
+
+ pub fn len(&self) -> usize {
+ self.events.lock().map(|guard| guard.len()).unwrap_or(0)
+ }
+
+ pub fn is_empty(&self) -> bool {
+ self.len() == 0
+ }
+}
+
+impl RadrootsNostrEventSink for RadrootsNostrInMemoryEventSink {
+ fn ingest_event(&self, event: &RadrootsNostrEvent) -> Result<(), String> {
+ self.events
+ .lock()
+ .map_err(|_| "in-memory sink lock poisoned".to_string())
+ .map(|mut guard| {
+ guard.push(event.clone());
+ })
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use radroots_nostr::prelude::{RadrootsNostrEventBuilder, RadrootsNostrKeys};
+
+ #[test]
+ fn in_memory_sink_tracks_events() {
+ let sink = RadrootsNostrInMemoryEventSink::new();
+ let keys = RadrootsNostrKeys::generate();
+ let event = RadrootsNostrEventBuilder::text_note("hello")
+ .sign_with_keys(&keys)
+ .expect("event should sign");
+
+ sink.ingest_event(&event).expect("event should be accepted");
+ assert_eq!(sink.len(), 1);
+ assert!(!sink.is_empty());
+ }
+}
diff --git a/crates/nostr_runtime/src/store.rs b/crates/nostr_runtime/src/store.rs
@@ -1,66 +0,0 @@
-use alloc::string::ToString;
-use alloc::vec::Vec;
-use radroots_nostr::prelude::RadrootsNostrEvent;
-use std::sync::Mutex;
-
-pub trait RadrootsNostrEventStore: Send + Sync {
- fn ingest_event(&self, event: &RadrootsNostrEvent) -> Result<(), String>;
-}
-
-#[derive(Default)]
-pub struct RadrootsNostrInMemoryEventStore {
- events: Mutex<Vec<RadrootsNostrEvent>>,
-}
-
-impl RadrootsNostrInMemoryEventStore {
- pub fn new() -> Self {
- Self::default()
- }
-
- pub fn events(&self) -> Vec<RadrootsNostrEvent> {
- self.events
- .lock()
- .map(|guard| guard.clone())
- .unwrap_or_default()
- }
-
- pub fn len(&self) -> usize {
- self.events.lock().map(|guard| guard.len()).unwrap_or(0)
- }
-
- pub fn is_empty(&self) -> bool {
- self.len() == 0
- }
-}
-
-impl RadrootsNostrEventStore for RadrootsNostrInMemoryEventStore {
- fn ingest_event(&self, event: &RadrootsNostrEvent) -> Result<(), String> {
- self.events
- .lock()
- .map_err(|_| "in-memory store lock poisoned".to_string())
- .map(|mut guard| {
- guard.push(event.clone());
- })
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use radroots_nostr::prelude::{RadrootsNostrEventBuilder, RadrootsNostrKeys};
-
- #[test]
- fn in_memory_store_tracks_events() {
- let store = RadrootsNostrInMemoryEventStore::new();
- let keys = RadrootsNostrKeys::generate();
- let event = RadrootsNostrEventBuilder::text_note("hello")
- .sign_with_keys(&keys)
- .expect("event should sign");
-
- store
- .ingest_event(&event)
- .expect("event should be accepted");
- assert_eq!(store.len(), 1);
- assert!(!store.is_empty());
- }
-}