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:
+35
-12
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user