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. * Get the full FediDB server list (up to 40, the API max).
* Returns a flat array of { domain, software, description, mau, openRegistration }. * 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
* Results are cached per normalized query for 24 hours. * and filter client-side in searchInstances().
* *
* @param {object} kvCollection - MongoDB ap_kv collection * @param {object} kvCollection - MongoDB ap_kv collection
* @param {string} query - Search term (e.g. "mast")
* @param {number} [limit=10] - Max results
* @returns {Promise<Array>} * @returns {Promise<Array>}
*/ */
export async function searchInstances(kvCollection, query, limit = 10) { async function getAllServers(kvCollection) {
const q = (query || "").trim().toLowerCase(); const cacheKey = "fedidb:servers-all";
if (!q) return [];
const cacheKey = `fedidb:instances:${q}:${limit}`;
const cached = await getFromCache(kvCollection, cacheKey); const cached = await getFromCache(kvCollection, cacheKey);
if (cached) return cached; if (cached) return cached;
try { try {
const url = `${API_BASE}/servers?q=${encodeURIComponent(q)}&limit=${limit}`; const url = `${API_BASE}/servers?limit=40`;
const res = await fetchWithTimeout(url); const res = await fetchWithTimeout(url);
if (!res.ok) return []; 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. * Check if a remote instance supports unauthenticated public timeline access.
* Makes a lightweight HEAD-like request (limit=1) to the Mastodon public timeline API. * Makes a lightweight HEAD-like request (limit=1) to the Mastodon public timeline API.