app/lib/search/zero-result.server.ts
38 lines and 3 functions in DrDustinEdwards/dustinedwards-info, at commit 1590ba4 on 2026-10-24. This file on GitHub.
Functions
| Function | Lines | Complexity | Covered | CRAP | Mutation |
|---|---|---|---|---|---|
| recordZeroResult | 13 to 28 | 2 | No data: no coverage report in this map | No data: no coverage report in this map | No data: no mutants in this code |
| purgeZeroResults | 31 to 36 | 2 | No data: no coverage report in this map | No data: no coverage report in this map | No data: no mutants in this code |
| topZeroResults | 38 to 44 | 1 | No data: no coverage report in this map | No data: no coverage report in this map | No data: no mutants in this code |
Imports
It imports app/db/index.ts, app/db/schema.ts, app/lib/search/zero-result.mjs. Imported by app/lib/operator/api.server.ts, app/routes/admin.tools.tsx, app/routes/search.tsx.
Source
import { desc, sql } from "drizzle-orm";
import { getDb } from "~/db";
import { zeroResultQueries } from "~/db/schema";
import {
normaliseZeroResultQuery,
ZERO_RESULT_RETENTION_SECONDS,
} from "./zero-result.mjs";
// Stores the query and counters only, never an IP, user agent or session. The write never fails a search.
/** Upsert on the query, so table size tracks distinct misses rather than traffic. */
export async function recordZeroResult(env: Env, raw: string): Promise<void> {
const query = normaliseZeroResultQuery(raw);
if (query === null) return;
const db = getDb(env);
await db
.insert(zeroResultQueries)
.values({ query })
.onConflictDoUpdate({
target: zeroResultQueries.query,
set: {
count: sql`${zeroResultQueries.count} + 1`,
lastSeen: sql`(unixepoch())`,
},
});
}
/** On last_seen, not first_seen: a long-running gap asked about last week is live demand. */
export async function purgeZeroResults(env: Env, now = new Date()): Promise<number> {
const cutoff = Math.floor(now.getTime() / 1000) - ZERO_RESULT_RETENTION_SECONDS;
const result = await getDb(env)
.run(sql`DELETE FROM zero_result_queries WHERE last_seen < ${cutoff}`);
return result.meta?.changes ?? 0;
}
export async function topZeroResults(env: Env, limit = 50) {
return getDb(env)
.select()
.from(zeroResultQueries)
.orderBy(desc(zeroResultQueries.count), desc(zeroResultQueries.lastSeen))
.limit(limit);
}