···396396 ) -> Result<HashMap<String, HashMap<String, CountsByCount>>> {
397397 let data = self.0.lock().unwrap();
398398 let mut out: HashMap<String, HashMap<String, CountsByCount>> = HashMap::new();
399399- if let Some(asdf) = data.targets.get(&Target::new(target)) {
400400- for (Source { collection, path }, linkers) in asdf {
399399+ if let Some(source_linker_pairs) = data.targets.get(&Target::new(target)) {
400400+ for (Source { collection, path }, linkers) in source_linker_pairs {
401401 let records = linkers.iter().flatten().count() as u64;
402402 let distinct_dids = linkers
403403 .iter()
+49
constellation/templates/get-distinct.html.j2
···11+{% extends "base.html.j2" %}
22+{% import "try-it-macros.html.j2" as try_it %}
33+44+{% block title %}DIDs{% endblock %}
55+{% block description %}Distinct DIDs with records in {{ query.source }} linking to {{ query.subject }} {% endblock %}
66+77+{% block content %}
88+99+ {% call try_it::get_distinct(query.subject, query.source) %}
1010+1111+ <h2>
1212+ Distinct DIDs with links to <code>{{ query.subject }}</code> from <code>{{ query.source }}</code>
1313+ {% if let Some(browseable_uri) = query.subject|to_browseable %}
1414+ <small style="font-weight: normal; font-size: 1rem"><a href="{{ browseable_uri }}">browse record</a></small>
1515+ {% endif %}
1616+ </h2>
1717+1818+ <p><strong>{{ total|human_number }} distinct DIDs</strong> with links to <code>{{ query.subject }}</code> from <code>{{ query.source }}</code></p>
1919+2020+ <ul>
2121+ <li>See direct backlinks at <code>/xrpc/blue.microcosm.links.getBacklinks</code>: <a href="/xrpc/blue.microcosm.links.getBacklinks?subject={{ query.subject|urlencode }}&source={{ query.source|urlencode }}">/xrpc/blue.microcosm.links.getBacklinks?subject={{ query.subject }}&source={{ query.source }}</a></li>
2222+ <li>See all links to this target at <code>/links/all</code>: <a href="/links/all?target={{ query.subject|urlencode }}">/links/all?target={{ query.subject }}</a></li>
2323+ </ul>
2424+2525+ <h3>DIDs, most recent first:</h3>
2626+2727+ {% for did in linking_dids %}
2828+ <pre style="display: block; margin: 1em 2em" class="code"><strong>DID</strong>: {{ did.0 }}
2929+ -> see <a href="/links/all?target={{ did.0|urlencode }}">links to this DID</a>
3030+ -> browse <a href="https://pdsls.dev/at://{{ did.0 }}">this DID record</a></pre>
3131+ {% endfor %}
3232+3333+ {% if let Some(c) = cursor %}
3434+ <form method="get" action="/xrpc/blue.microcosm.links.getDistinct">
3535+ <input type="hidden" name="subject" value="{{ query.subject }}" />
3636+ <input type="hidden" name="source" value="{{ query.source }}" />
3737+ <input type="hidden" name="cursor" value={{ c|json|safe }} />
3838+ <button type="submit">next page…</button>
3939+ </form>
4040+ {% else %}
4141+ <button disabled><em>end of results</em></button>
4242+ {% endif %}
4343+4444+ <details>
4545+ <summary>Raw JSON response</summary>
4646+ <pre class="code">{{ self|tojson }}</pre>
4747+ </details>
4848+4949+{% endblock %}
+45
constellation/templates/hello.html.j2
···8383 ) %}
848485858686+ <h3 class="route"><code>GET /xrpc/blue.microcosm.links.getCounts</code></h3>
8787+8888+ <p>The total number of links pointing at a given target.</p>
8989+9090+ <h4>Query parameters:</h4>
9191+9292+ <ul>
9393+ <li><code>subject</code>: required, must url-encode. The target being linked to. Example: <code>did:plc:vc7f4oafdgxsihk4cry2xpze</code> or <code>at://did:plc:vc7f4oafdgxsihk4cry2xpze/app.bsky.feed.post/3lgwdn7vd722r</code></li>
9494+ <li><code>source</code>: required. Collection and path specification for the primary link. Example: <code>app.bsky.feed.like:subject.uri</code></li>
9595+ </ul>
9696+9797+ <p style="margin-bottom: 0"><strong>Try it:</strong></p>
9898+ {% call try_it::get_counts("did:plc:vc7f4oafdgxsihk4cry2xpze", "app.bsky.graph.block:subject.uri") %}
9999+100100+101101+ <h3 class="route"><code>GET /xrpc/blue.microcosm.links.getDistinct</code></h3>
102102+103103+ <p>A list of distinct DIDs (identities) with links to a target.</p>
104104+105105+ <h4>Query parameters:</h4>
106106+107107+ <ul>
108108+ <li><code>subject</code>: required, must url-encode. The target being linked to. Example: <code>did:plc:vc7f4oafdgxsihk4cry2xpze</code> or <code>at://did:plc:vc7f4oafdgxsihk4cry2xpze/app.bsky.feed.post/3lgwdn7vd722r</code></li>
109109+ <li><code>source</code>: required. Collection and path specification for the primary link. Example: <code>app.bsky.feed.like:subject.uri</code></li>
110110+ <li><code>limit</code>: optional. Number of results to return. Default: <code>16</code>. Maximum: <code>100</code></li>
111111+ <li><code>cursor</code>: optional, see Definitions.</li>
112112+ </ul>
113113+114114+ <p style="margin-bottom: 0"><strong>Try it:</strong></p>
115115+ {% call try_it::get_distinct("at://did:plc:vc7f4oafdgxsihk4cry2xpze/app.bsky.feed.post/3lgwdn7vd722r", "app.bsky.feed.like:subject.uri") %}
116116+117117+86118 <h3 class="route"><code>GET /links</code></h3>
8711988120 <p>A list of records linking to a target.</p>
···104136 <p style="margin-bottom: 0"><strong>Try it:</strong></p>
105137 {% call try_it::links("at://did:plc:a4pqq234yw7fqbddawjo7y35/app.bsky.feed.post/3m237ilwc372e", "app.bsky.feed.like", ".subject.uri", [""], 16) %}
106138139139+ <h3 class="route"><code>GET /xrpc/blue.microcosm.links.getBacklinks</code></h3>
140140+141141+ <p>A list of distinct DIDs (identities) with links to a target.</p>
142142+143143+ <h4>Query parameters:</h4>
144144+145145+ <ul>
146146+ <li><code>subject</code>: required, must url-encode. Example: <code>at://did:plc:vc7f4oafdgxsihk4cry2xpze/app.bsky.feed.post/3lgwdn7vd722r</code></li>
147147+ <li><code>source</code>: required, must url-encode. Example: <code>app.bsky.feed.post:.subject.uri</code></li>
148148+ </ul>
149149+150150+ <p style="margin-bottom: 0"><strong>Try it:</strong></p>
151151+ {% call try_it::get_distinct("at://did:plc:vc7f4oafdgxsihk4cry2xpze/app.bsky.feed.post/3lgwdn7vd722r", "app.bsky.feed.like:.subject.uri") %}
107152108153 <h3 class="route"><code>GET /links/distinct-dids</code></h3>
109154