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.
|
* 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.
|
||||||
|
|||||||
Reference in New Issue
Block a user