// Related-note scoring, shared by the Eleventy build and the browser. Keep it import-free. const LINK_WEIGHT = 3; /** @type {(a: string, b: string) => number} */ const desc = (a, b) => (a < b ? 1 : a > b ? -1 : 0); /** * Rank notes connected to a set of notes: +3 per link (either direction) and * +1 per shared tag, summed over every note in the set. * @template {{slug: string, title: string, tended: string, tags: string[], links: string[]}} T * @param {T[]} entries * @param {string[]} setSlugs notes already on the page * @param {number} [limit] * @returns {T[]} */ export function scoreCandidates(entries, setSlugs, limit = 5) { const inSet = new Set(setSlugs); const set = entries.filter((x) => inSet.has(x.slug)); return entries .filter((c) => !inSet.has(c.slug)) .map((c) => { let score = 0; for (const s of set) { if (c.links.includes(s.slug) || s.links.includes(c.slug)) score += LINK_WEIGHT; score += c.tags.filter((t) => s.tags.includes(t)).length; } return { c, score }; }) .filter((x) => x.score > 0) .sort((a, b) => b.score - a.score || desc(a.c.tended, b.c.tended) || -desc(a.c.title, b.c.title)) .slice(0, limit) .map((x) => x.c); }