atproto_tap/lib.rs
1//! TAP (Trusted Attestation Protocol) service consumer for AT Protocol.
2//!
3//! This crate provides a client for consuming events from a TAP service,
4//! which delivers filtered, verified AT Protocol repository events.
5//!
6//! # Overview
7//!
8//! TAP is a single-tenant service that subscribes to an AT Protocol Relay and
9//! outputs filtered, verified events. Key features include:
10//!
11//! - **Verified Events**: MST integrity checks and signature verification
12//! - **Automatic Backfill**: Historical events delivered with `live: false`
13//! - **Repository Filtering**: Track specific DIDs or collections
14//! - **Acknowledgment Protocol**: At-least-once delivery semantics
15//!
16//! # Quick Start
17//!
18//! ```ignore
19//! use atproto_tap::{connect_to, TapEvent};
20//! use tokio_stream::StreamExt;
21//!
22//! #[tokio::main]
23//! async fn main() {
24//! let mut stream = connect_to("localhost:2480");
25//!
26//! while let Some(result) = stream.next().await {
27//! match result {
28//! Ok(event) => match event.as_ref() {
29//! TapEvent::Record { record, .. } => {
30//! println!("{} {} {}", record.action, record.collection, record.did);
31//! }
32//! TapEvent::Identity { identity, .. } => {
33//! println!("Identity: {} = {}", identity.did, identity.handle);
34//! }
35//! },
36//! Err(e) => eprintln!("Error: {}", e),
37//! }
38//! }
39//! }
40//! ```
41//!
42//! # Using with `tokio::select!`
43//!
44//! The stream integrates naturally with Tokio's select macro:
45//!
46//! ```ignore
47//! use atproto_tap::{connect, TapConfig};
48//! use tokio_stream::StreamExt;
49//! use tokio::signal;
50//!
51//! #[tokio::main]
52//! async fn main() {
53//! let config = TapConfig::builder()
54//! .hostname("localhost:2480")
55//! .admin_password("secret")
56//! .build();
57//!
58//! let mut stream = connect(config);
59//!
60//! loop {
61//! tokio::select! {
62//! Some(result) = stream.next() => {
63//! // Process event
64//! }
65//! _ = signal::ctrl_c() => {
66//! break;
67//! }
68//! }
69//! }
70//! }
71//! ```
72//!
73//! # Management API
74//!
75//! Use [`TapClient`] to manage tracked repositories:
76//!
77//! ```ignore
78//! use atproto_tap::TapClient;
79//!
80//! let client = TapClient::new("localhost:2480", Some("password".to_string()));
81//!
82//! // Add repositories to track
83//! client.add_repos(&["did:plc:xyz123"]).await?;
84//!
85//! // Check service health
86//! if client.health().await? {
87//! println!("TAP service is healthy");
88//! }
89//! ```
90//!
91//! # Memory Efficiency
92//!
93//! This crate is optimized for high-throughput event processing:
94//!
95//! - **Arc-wrapped events**: Events are shared via `Arc` for zero-cost sharing
96//! - **CompactString**: Small strings use inline storage (no heap allocation)
97//! - **`Box<str>`**: Immutable strings without capacity overhead
98//! - **RawValue**: Record payloads are lazily parsed on demand
99//! - **Pre-allocated buffers**: Ack messages avoid per-message allocations
100
101#![forbid(unsafe_code)]
102#![warn(missing_docs)]
103
104mod client;
105mod config;
106mod connection;
107mod errors;
108mod events;
109mod stream;
110
111// Re-export public types
112pub use atproto_identity::model::{Document, Service, VerificationMethod};
113#[allow(deprecated)]
114pub use client::RepoStatus;
115pub use client::{RepoInfo, RepoState, TapClient};
116pub use config::{TapConfig, TapConfigBuilder};
117pub use errors::TapError;
118pub use events::{
119 IdentityEvent, IdentityStatus, RecordAction, RecordEvent, TapEvent, extract_event_id,
120};
121pub use stream::{TapStream, connect, connect_to};