Constellation, Spacedust, Slingshot, UFOs: atproto crates and services for microcosm

bucket sums, more samples, export json

Changed files
+181 -38
constellation
links
+3 -2
Cargo.lock
··· 534 534 "ratelimit", 535 535 "rocksdb", 536 536 "serde", 537 + "serde_json", 537 538 "serde_with", 538 539 "tempfile", 539 540 "tinyjson", ··· 1848 1849 1849 1850 [[package]] 1850 1851 name = "serde_json" 1851 - version = "1.0.138" 1852 + version = "1.0.139" 1852 1853 source = "registry+https://github.com/rust-lang/crates.io-index" 1853 - checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" 1854 + checksum = "44f86c3acccc9c65b153fe1b85a3be07fe5515274ec9f0653b4a0875731c72a6" 1854 1855 dependencies = [ 1855 1856 "itoa", 1856 1857 "memchr",
+1
constellation/Cargo.toml
··· 25 25 ratelimit = "0.10.0" 26 26 rocksdb = { version = "0.23.0", optional = true } 27 27 serde = { version = "1.0.215", features = ["derive"] } 28 + serde_json = "1.0.139" 28 29 serde_with = { version = "3.12.0", features = ["hex"] } 29 30 tinyjson = "2.5.1" 30 31 tokio-util = "0.7.13"
+3 -1
constellation/readme.md
··· 153 153 - [ ] read ops (api) 154 154 - [ ] expose internal stats? 155 155 - [ ] figure out what's the right thing to do if merge op fails. happened on startup after an unclean reboot. 156 - 156 + - [x] backups! 157 + - [x] manual backup on startup 158 + - [x] background task to create backups on an interval 157 159 158 160 cache 159 161 - [ ] set api response headers
+1 -1
constellation/src/storage/rocks_store.rs
··· 49 49 } 50 50 fn get_db_read_opts() -> Options { 51 51 let mut opts = Options::default(); 52 - opts.optimize_for_point_lookup(128); // mb 52 + opts.optimize_for_point_lookup(16_384); // mb (run this on big machines) 53 53 opts 54 54 } 55 55
+67
links/src/at_uri.rs
··· 137 137 // there's a more normalization to do still. ugh. 138 138 } 139 139 140 + pub fn at_uri_collection(at_uri: &str) -> Option<String> { 141 + let (proto, rest) = at_uri.split_at_checked(5)?; 142 + if !proto.eq_ignore_ascii_case("at://") { 143 + return None; 144 + } 145 + let (_did, rest) = rest.split_once('/')?; 146 + if let Some((collection, _path_rest)) = rest.split_once('/') { 147 + return Some(collection.to_string()); 148 + } 149 + if let Some((collection, _query_rest)) = rest.split_once('?') { 150 + return Some(collection.to_string()); 151 + } 152 + if let Some((collection, _hash_rest)) = rest.split_once('#') { 153 + return Some(collection.to_string()); 154 + } 155 + Some(rest.to_string()) 156 + } 157 + 140 158 #[cfg(test)] 141 159 mod tests { 142 160 use super::*; ··· 231 249 ] { 232 250 assert_eq!( 233 251 parse_at_uri(case), 252 + expected.map(|s| s.to_string()), 253 + "{detail}" 254 + ); 255 + } 256 + } 257 + 258 + #[test] 259 + fn test_at_uri_collection() { 260 + for (case, expected, detail) in vec![ 261 + ("", None, "empty"), 262 + ("at://did:plc:vc7f4oafdgxsihk4cry2xpze", None, "did only"), 263 + ( 264 + "at://did:plc:vc7f4oafdgxsihk4cry2xpze/collec.tion", 265 + Some("collec.tion"), 266 + "no path (weird)", 267 + ), 268 + ( 269 + "at://did:plc:vc7f4oafdgxsihk4cry2xpze/collec.tion/path", 270 + Some("collec.tion"), 271 + "normal at-uri", 272 + ), 273 + ( 274 + "at://did:plc:vc7f4oafdgxsihk4cry2xpze/collec.tion?query", 275 + Some("collec.tion"), 276 + "colleciton with query", 277 + ), 278 + ( 279 + "at://did:plc:vc7f4oafdgxsihk4cry2xpze/collec.tion#hash", 280 + Some("collec.tion"), 281 + "colleciton with hash", 282 + ), 283 + ( 284 + "at://did:plc:vc7f4oafdgxsihk4cry2xpze/collec.tion/path?query#hash", 285 + Some("collec.tion"), 286 + "colleciton with everything", 287 + ), 288 + ( 289 + "at://did:web:example.com/collec.tion/path", 290 + Some("collec.tion"), 291 + "did:web", 292 + ), 293 + ( 294 + "at://did:web:example.com/col.lec.tio.ns.so.long.going.on.and.on", 295 + Some("col.lec.tio.ns.so.long.going.on.and.on"), 296 + "long collection", 297 + ), 298 + ] { 299 + assert_eq!( 300 + at_uri_collection(case), 234 301 expected.map(|s| s.to_string()), 235 302 "{detail}" 236 303 );
+29
links/src/lib.rs
··· 35 35 Link::Did(_) => "did", 36 36 } 37 37 } 38 + pub fn at_uri_collection(&self) -> Option<String> { 39 + if let Link::AtUri(at_uri) = self { 40 + at_uri::at_uri_collection(at_uri) 41 + } else { 42 + None 43 + } 44 + } 38 45 } 39 46 40 47 #[derive(Debug, PartialEq)] ··· 99 106 parse_any_link("did:plc:44ybard66vv44zksje25o7dz"), 100 107 Some(Link::Did("did:plc:44ybard66vv44zksje25o7dz".into())) 101 108 ) 109 + } 110 + 111 + #[test] 112 + fn test_at_uri_collection() { 113 + assert_eq!( 114 + parse_any_link("https://example.com") 115 + .unwrap() 116 + .at_uri_collection(), 117 + None 118 + ); 119 + assert_eq!( 120 + parse_any_link("did:web:bad-example.com") 121 + .unwrap() 122 + .at_uri_collection(), 123 + None 124 + ); 125 + assert_eq!( 126 + parse_any_link("at://did:web:bad-example.com/my.collection/3jwdwj2ctlk26") 127 + .unwrap() 128 + .at_uri_collection(), 129 + Some("my.collection".into()) 130 + ); 102 131 } 103 132 }