···136136- [x] either count or estimate the total number of links added (distinct from link targets)
137137- [x] jetstream: don't crash on connection refused (retry * backoff)
138138- [x] allow cors requests (ie. atproto-browser. (but it's really meant for backends))
139139-- [~] api: get distinct linking dids (https://bsky.app/profile/bnewbold.net/post/3lhhzejv7zc2h)
140140- - [~] endpoint for count
141141- - [~] endpoint for listing them
142142- - [ ] add to exploratory /all endpoint
139139+- [x] api: get distinct linking dids (https://bsky.app/profile/bnewbold.net/post/3lhhzejv7zc2h)
140140+ - [x] endpoint for count
141141+ - [x] endpoint for listing them
142142+ - [x] add to exploratory /all endpoint
143143144144cache
145145- [ ] set api response headers
+7
constellation/src/lib.rs
···4545 self.rkey.clone()
4646 }
4747}
4848+4949+/// maybe the worst type in this repo, and there are some bad types
5050+#[derive(Debug, Serialize, PartialEq)]
5151+pub struct CountsByCount {
5252+ pub records: u64,
5353+ pub distinct_dids: u64,
5454+}
···4949 </style>
5050 </head>
5151 <body class="{% block body_classes %}{% endblock %}">
5252- <h1><a href="/">This</a> is an <a href="https://github.com/at-ucosm/links/tree/main/constellation">atproto link aggregator</a> server from <a href="https://github.com/at-ucosm">microcosm</a>!</h1>
5252+ <h1><a href="/">This</a> is a <a href="https://github.com/at-ucosm/links/tree/main/constellation">constellation 🌌</a> server from <a href="https://github.com/at-ucosm">microcosm</a> ✨</h1>
5353 {% block content %}{% endblock %}
54545555 <footer>
5656- <p>To get this API to return JSON, set request header <code>Accept: application/json</code>.</p>
5757- <p><a href="/">API docs main</a></p>
5656+ <p>To get this response as JSON, set request header <code>Accept: application/json</code>.</p>
5757+ <p><a href="/">Constellation API docs main</a></p>
5858 </footer>
5959 </body>
6060</html>
+3-3
constellation/templates/dids.html.j2
···1717 <p><strong>{{ total }} dids</strong> from <code>{{ query.collection }}</code> at <code>{{ query.path }}</code></p>
18181919 <ul>
2020- <li>See linking records to this target <code>/links</code>: <a href="/links?target={{ query.target|urlencode }}&collection={{ query.collection|urlencode }}&path={{ query.path|urlencode }}">/links?target={{ query.target }}&collection={{ query.collection }}&path={{ query.path }}</a></li>
2121- <li>See all links to this target <code>/links/all/count</code>: <a href="/links/all/count?target={{ query.target|urlencode }}">/links/all/count?target={{ query.target }}</a></li>
2020+ <li>See linking records to this target at <code>/links</code>: <a href="/links?target={{ query.target|urlencode }}&collection={{ query.collection|urlencode }}&path={{ query.path|urlencode }}">/links?target={{ query.target }}&collection={{ query.collection }}&path={{ query.path }}</a></li>
2121+ <li>See all links to this target at <code>/links/all</code>: <a href="/links/all?target={{ query.target|urlencode }}">/links/all?target={{ query.target }}</a></li>
2222 </ul>
23232424 <h3>DIDs, most recent first:</h3>
25252626 {% for did in linking_dids %}
2727 <pre style="display: block; margin: 1em 2em" class="code"><strong>DID</strong>: {{ did.0 }}
2828- -> see <a href="/links/all/count?target={{ did.0|urlencode }}">links to this DID</a>
2828+ -> see <a href="/links/all?target={{ did.0|urlencode }}">links to this DID</a>
2929 -> browse <a href="https://atproto-browser-plus-links.vercel.app/at/{{ did.0|urlencode }}">this DID record</a></pre>
3030 {% endfor %}
3131
···8080 {% call try_it::dids_count("did:plc:vc7f4oafdgxsihk4cry2xpze", "app.bsky.graph.block", ".subject") %}
818182828383- <h3 class="route"><code>GET /links/all/count</code></h3>
8383+ <h3 class="route"><code>GET /links/all</code></h3>
8484+8585+ <p>Show all sources with links to a target, including linking record counts and distinct linking DIDs</p>
8686+8787+ <h4>Query parameters:</h4>
8888+8989+ <ul>
9090+ <li><code>target</code>: required, must url-encode. Example: <code>did:plc:oky5czdrnfjpqslsw2a5iclo</code></li>
9191+ </ul>
9292+9393+ <p style="margin-bottom: 0"><strong>Try it:</strong></p>
9494+ {% call try_it::explore_links("did:plc:oky5czdrnfjpqslsw2a5iclo") %}
9595+9696+9797+ <h3 class="route deprecated"><code>[deprecated] GET /links/all/count</code></h3>
84988599 <p>The total counts of all links pointing at a given target, by collection and path.</p>
100100+101101+ <p>DEPRECATED: Use <code>GET /links/all</code> instead.</p>
8610287103 <h4>Query parameters:</h4>
88104
+5-1
constellation/templates/links-all-count.html.j2
···11{% extends "base.html.j2" %}
22{% import "try-it-macros.html.j2" as try_it %}
3344-{% block title %}All link counts{% endblock %}
44+{% block title %}[deprecated] All link counts{% endblock %}
5566{% block content %}
77···1313 <small style="font-weight: normal; font-size: 1rem"><a href="{{ browseable_uri }}">browse record</a></small>
1414 {% endif %}
1515 </h2>
1616+1717+ <ul>
1818+ <li>This endpoint is deprecated. use <code>/links/all</code> instead: <a href="/links/all?target={{ query.target|urlencode }}">/links/all?target={{ query.target }}</a></li>
1919+ </ul>
16201721 <h3>Links by collection and path:</h3>
1822
+3-3
constellation/templates/links.html.j2
···1717 <p><strong>{{ total }} links</strong> from <code>{{ query.collection }}</code> at <code>{{ query.path }}</code></p>
18181919 <ul>
2020- <li>See distinct DIDs <code>/links/distinct-dids</code>: <a href="/links/distinct-dids?target={{ query.target|urlencode }}&collection={{ query.collection|urlencode }}&path={{ query.path|urlencode }}">/links/distinct-dids?target={{ query.target }}&collection={{ query.collection }}&path={{ query.path }}</a></li>
2121- <li>See all links to this target <code>/links/all/count</code>: <a href="/links/all/count?target={{ query.target|urlencode }}">/links/all/count?target={{ query.target }}</a></li>
2020+ <li>See distinct linking DIDs at <code>/links/distinct-dids</code>: <a href="/links/distinct-dids?target={{ query.target|urlencode }}&collection={{ query.collection|urlencode }}&path={{ query.path|urlencode }}">/links/distinct-dids?target={{ query.target }}&collection={{ query.collection }}&path={{ query.path }}</a></li>
2121+ <li>See all links to this target at <code>/links/all</code>: <a href="/links/all?target={{ query.target|urlencode }}">/links/all?target={{ query.target }}</a></li>
2222 </ul>
23232424 <h3>Links, most recent first:</h3>
25252626 {% for record in linking_records %}
2727- <pre style="display: block; margin: 1em 2em" class="code"><strong>DID</strong>: {{ record.did().0 }} (<a href="/links/all/count?target={{ record.did().0|urlencode }}">DID links</a>)
2727+ <pre style="display: block; margin: 1em 2em" class="code"><strong>DID</strong>: {{ record.did().0 }} (<a href="/links/all?target={{ record.did().0|urlencode }}">DID links</a>)
2828<strong>Collection</strong>: {{ record.collection }}
2929<strong>RKey</strong>: {{ record.rkey }}
3030-> <a href="https://atproto-browser-plus-links.vercel.app/at/{{ record.did().0|urlencode }}/{{ record.collection }}/{{ record.rkey }}">browse record</a></pre>