diff --git a/lib/fedidb.js b/lib/fedidb.js index 83f69b9..9ba8b74 100644 --- a/lib/fedidb.js +++ b/lib/fedidb.js @@ -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} */ -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} + */ +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.