···1414| :--- | :--- | :--- |
1515| `subject` | yes | AT URI or DID to look up backlinks for. |
1616| `source` | no | filter by source collection, e.g. `app.bsky.feed.like`. also accepts `collection:path` form to further filter by field path, e.g. `app.bsky.feed.like:subject.uri`. the path is matched against the dotted field path within the record (`.` is prepended automatically). |
1717+| `did` | no | filter links to those from specific users. |
1718| `limit` | no | max results to return (default 50, max 100). |
1819| `cursor` | no | opaque pagination cursor from a previous response. |
1920| `reverse` | no | if `true`, return results in reverse order (default `false`). |
···11pub mod links;
22pub mod store;
3344-pub(crate) mod api;
44+pub mod api;
5566use std::ops::Bound;
77use std::sync::Arc;
···3535 subject: subject.into(),
3636 collection: None,
3737 path: None,
3838+ dids: Vec::new(),
3839 limit: 50,
3940 reverse: false,
4041 cursor: None,
···4849 subject: subject.into(),
4950 collection: None,
5051 path: None,
5252+ dids: Vec::new(),
5153 }
5254 }
5355}
···6062 subject: String,
6163 collection: Option<String>,
6264 path: Option<String>,
6565+ dids: Vec<String>,
6366 limit: usize,
6467 reverse: bool,
6568 cursor: Option<Vec<u8>>,
···6972 /// filter results to the given source collection NSID.
7073 pub fn collection(mut self, collection: impl Into<String>) -> Self {
7174 self.collection = Some(collection.into());
7575+ self
7676+ }
7777+7878+ /// filter results to specific source author DIDs.
7979+ pub fn dids(mut self, dids: Vec<String>) -> Self {
8080+ self.dids = dids;
7281 self
7382 }
7483···161170 warn!("backlinks: could not extract source from reverse key");
162171 continue;
163172 };
173173+174174+ if !self.dids.is_empty() {
175175+ if !self.dids.iter().any(|d| d == did) {
176176+ continue;
177177+ }
178178+ }
179179+164180 let Some(cid) = store::lookup_cid_from_ks(&db.records, did, col, rkey) else {
165181 // record deleted after backlink was written
166182 continue;
···190206 subject: String,
191207 collection: Option<String>,
192208 path: Option<String>,
209209+ dids: Vec<String>,
193210}
194211195212impl BacklinksCount {
···199216 self
200217 }
201218219219+ /// filter results to specific source author DIDs.
220220+ pub fn dids(mut self, dids: Vec<String>) -> Self {
221221+ self.dids = dids;
222222+ self
223223+ }
224224+202225 /// filter to a specific dotted field path within the record (e.g. `.subject.uri`).
203226 /// has no effect unless a collection is also set.
204227 pub fn path(mut self, path: impl Into<String>) -> Self {
···224247 self.collection.as_deref(),
225248 self.path.as_deref(),
226249 );
227227- Ok(db.backlinks.prefix(&scan_prefix).count() as u64)
250250+251251+ if !self.dids.is_empty() {
252252+ let mut count = 0;
253253+ for item in db.backlinks.prefix(&scan_prefix) {
254254+ let key = item.key().into_diagnostic()?;
255255+ let Some((_col, _path, did, _rkey)) = store::source_from_reverse_key(&key)
256256+ else {
257257+ continue;
258258+ };
259259+ if self.dids.iter().any(|d| d == did) {
260260+ count += 1;
261261+ }
262262+ }
263263+ Ok(count)
264264+ } else {
265265+ Ok(db.backlinks.prefix(&scan_prefix).count() as u64)
266266+ }
228267 })
229268 .await
230269 .into_diagnostic()?
+5
src/control/mod.rs
···122122}
123123124124impl Hydrant {
125125+ /// Returns a reference to the internal DID resolver.
126126+ pub fn resolver(&self) -> &crate::resolver::Resolver {
127127+ &self.state.resolver
128128+ }
129129+125130 /// open the database and configure hydrant from `config`.
126131 ///
127132 /// this sets up the database, applies any filter configuration from `config`, and
+2-2
src/lib.rs
···3131#[cfg(feature = "indexer")]
3232pub(crate) mod backfill;
3333#[cfg(feature = "backlinks")]
3434-pub(crate) mod backlinks;
3434+pub mod backlinks;
3535#[cfg(feature = "indexer")]
3636pub(crate) mod crawler;
3737pub(crate) mod db;
···3939#[cfg(feature = "indexer")]
4040pub(crate) mod ops;
4141pub(crate) mod patch;
4242-pub(crate) mod resolver;
4242+pub mod resolver;
4343pub(crate) mod state;
4444pub(crate) mod util;
4545