IndexedDB search library (1000x100, 15-day copies, Update search), server video metadata for instant local results
This commit is contained in:
@@ -58,3 +58,38 @@ export async function stats() {
|
||||
const t = (await db.execute('SELECT COUNT(*) AS n, COALESCE(SUM(size),0) AS b FROM search_cache')).rows[0];
|
||||
return { queries: Number(t.n), bytes: Number(t.b), maxQueries: MAX_ROWS, maxBytes: MAX_BYTES };
|
||||
}
|
||||
|
||||
// ---- Known-video metadata: instant results while YouTube loads ----
|
||||
export const MAX_VIDEOS = Number(process.env.VIDEO_META_MAX) || 500_000;
|
||||
|
||||
export async function rememberVideos(cards) {
|
||||
const now = Date.now();
|
||||
const rows = (cards || []).filter((c) => c && typeof c.id === 'string' && c.title);
|
||||
if (!rows.length) return;
|
||||
await db.batch(rows.map((c) => ({
|
||||
sql: `INSERT INTO video_meta (id, card, hay, seen, updated_at) VALUES (?,?,?,1,?)
|
||||
ON CONFLICT(id) DO UPDATE SET card=excluded.card, hay=excluded.hay, seen=seen+1, updated_at=excluded.updated_at`,
|
||||
args: [c.id, JSON.stringify(c), `${c.title} ${c.channel || ''}`.toLowerCase(), now],
|
||||
})));
|
||||
if (Math.random() < 0.02) trimVideos().catch(() => {});
|
||||
}
|
||||
|
||||
// Cards whose title/channel contain EVERY word of the query, most-seen first.
|
||||
export async function searchVideos(q, limit = 60) {
|
||||
const words = String(q).toLowerCase().split(/\s+/).filter(Boolean).slice(0, 8);
|
||||
if (!words.length) return [];
|
||||
const like = (w) => '%' + w.replace(/[\\%_]/g, '\\$&') + '%';
|
||||
const r = await db.execute({
|
||||
sql: `SELECT card FROM video_meta WHERE ${words.map(() => "hay LIKE ? ESCAPE '\\'").join(' AND ')}
|
||||
ORDER BY seen DESC, updated_at DESC LIMIT ?`,
|
||||
args: [...words.map(like), limit],
|
||||
});
|
||||
return r.rows.map((x) => { try { return JSON.parse(x.card); } catch { return null; } }).filter(Boolean);
|
||||
}
|
||||
|
||||
export async function trimVideos(max = MAX_VIDEOS) {
|
||||
const n = Number((await db.execute('SELECT COUNT(*) AS n FROM video_meta')).rows[0].n);
|
||||
if (n <= max) return 0;
|
||||
await db.execute({ sql: 'DELETE FROM video_meta WHERE id IN (SELECT id FROM video_meta ORDER BY updated_at ASC LIMIT ?)', args: [n - max] });
|
||||
return n - max;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user