fix: FediDB instance search now filters by query

The FediDB /v1/servers API ignores the q parameter and always returns
the same top-10 ranked list. Changed to fetch the full 40-server list
once (cached 24h) and filter server-side by domain/software match.
This commit is contained in:
Ricardo
2026-02-27 11:45:19 +01:00
parent 3bedcac4b7
commit 0a0998cfcc
+35 -12
View File
@@ -71,26 +71,21 @@ async function writeToCache(kvCollection, cacheKey, data) {
}
/**
* Search FediDB for instances matching a query.
* Returns a flat array of { domain, software, description, mau, openRegistration }.
*
* Results are cached per normalized query for 24 hours.
* Get the full FediDB server list (up to 40, the API max).
* Cached for 24 hours as a single entry. The API ignores query params
* and always returns the same ranked-by-MAU list, so we fetch once
* and filter client-side in searchInstances().
*
* @param {object} kvCollection - MongoDB ap_kv collection
* @param {string} query - Search term (e.g. "mast")
* @param {number} [limit=10] - Max results
* @returns {Promise<Array>}
*/
export async function searchInstances(kvCollection, query, limit = 10) {
const q = (query || "").trim().toLowerCase();
if (!q) return [];
const cacheKey = `fedidb:instances:${q}:${limit}`;
async function getAllServers(kvCollection) {
const cacheKey = "fedidb:servers-all";
const cached = await getFromCache(kvCollection, cacheKey);
if (cached) return cached;
try {
const url = `${API_BASE}/servers?q=${encodeURIComponent(q)}&limit=${limit}`;
const url = `${API_BASE}/servers?limit=40`;
const res = await fetchWithTimeout(url);
if (!res.ok) return [];
@@ -113,6 +108,34 @@ export async function searchInstances(kvCollection, query, limit = 10) {
}
}
/**
* Search FediDB for instances matching a query.
* Returns a flat array of { domain, software, description, mau, openRegistration }.
*
* Fetches the full server list once (cached 24h) and filters by domain/software match.
* FediDB's /v1/servers endpoint ignores the `q` param and always returns a static
* ranked list, so server-side filtering is the only way to get relevant results.
*
* @param {object} kvCollection - MongoDB ap_kv collection
* @param {string} query - Search term (e.g. "mast")
* @param {number} [limit=10] - Max results
* @returns {Promise<Array>}
*/
export async function searchInstances(kvCollection, query, limit = 10) {
const q = (query || "").trim().toLowerCase();
if (!q) return [];
const allServers = await getAllServers(kvCollection);
return allServers
.filter(
(s) =>
s.domain.toLowerCase().includes(q) ||
s.software.toLowerCase().includes(q),
)
.slice(0, limit);
}
/**
* Check if a remote instance supports unauthenticated public timeline access.
* Makes a lightweight HEAD-like request (limit=1) to the Mastodon public timeline API.