use std::{collections::HashMap, sync::Arc}; use crate::database::Database; use tokio::sync::{broadcast, RwLock}; const CHANNEL_CAPACITY: usize = 256; #[derive(Debug, Clone)] pub struct NoteUpdate { pub content: String, pub revision_id: i64, pub updated_at: String, pub author: Option, pub owner_map: String, } #[derive(Debug)] pub struct AppState { pub db: Database, pub asset_version: String, pub files_dir: String, pub upload_max_size_bytes: usize, channels: RwLock>>, } impl AppState { pub fn new(db: Database, asset_version: String, files_dir: String, upload_max_size_bytes: usize) -> Self { Self { db, asset_version, files_dir, upload_max_size_bytes, channels: RwLock::new(HashMap::new()) } } async fn channel_for_key(&self, key: String) -> broadcast::Sender { if let Some(sender) = self.channels.read().await.get(&key) { return sender.clone(); } let mut channels = self.channels.write().await; channels.entry(key).or_insert_with(|| broadcast::channel(CHANNEL_CAPACITY).0).clone() } pub async fn note_channel(&self, workspace_slug: &str, note_slug: &str) -> broadcast::Sender { self.channel_for_key(format!("workspace:{workspace_slug}/{note_slug}")).await } pub async fn pad_channel(&self, slug: &str) -> broadcast::Sender { self.channel_for_key(format!("pad:{slug}")).await } } pub type SharedState = Arc;