From 7e8f6b2cdfb45d6e8576d332fdd4583540a03b03 Mon Sep 17 00:00:00 2001 From: ashish <69289857+ashishbhateja@users.noreply.github.com> Date: Wed, 3 Jun 2026 09:20:27 +0530 Subject: [PATCH] Search: index author names + friendly empty state (#3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - search.js: index the article author field (weight 2), so a query matches authors as well as titles/themes/text — issue #3 explicitly asks to find authors - reader.js: friendly message when a search returns no results - smoke.mjs: author-match test -> 19 total --- scripts/smoke.mjs | 9 +++++++++ src/reader/reader.js | 4 ++++ src/search.js | 3 ++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/scripts/smoke.mjs b/scripts/smoke.mjs index 9a9fe04..02f90be 100644 --- a/scripts/smoke.mjs +++ b/scripts/smoke.mjs @@ -145,4 +145,13 @@ check('snippet falls back to the start of the text when nothing matches', () => assert.ok(s.startsWith('Gratitude')); }); +check('search matches an author name', () => { + const idx = new SearchIndex().build([ + { title: 'On stillness', themes: ['Silence'], author: 'Nirodbaran', summary: 'x', body: 'y' }, + ]); + const hits = idx.search('Nirodbaran'); + assert.equal(hits.length, 1); + assert.ok(hits[0].matched.includes('nirodbaran')); +}); + console.log(`\n${passed} checks passed.`); diff --git a/src/reader/reader.js b/src/reader/reader.js index 2a492c4..c3ee722 100644 --- a/src/reader/reader.js +++ b/src/reader/reader.js @@ -250,6 +250,10 @@ function renderList(items) { /** Render search hits with a highlighted contextual snippet (issue #3). */ function renderSearchResults(hits) { els.results.replaceChildren(); + if (!hits.length) { + els.results.append(tag('li', 'card', 'No articles match that search. Try a broader word or a theme.')); + return; + } for (const { article, matched } of hits) { const li = document.createElement('li'); li.className = 'card'; diff --git a/src/search.js b/src/search.js index 7174433..73ab647 100644 --- a/src/search.js +++ b/src/search.js @@ -2,7 +2,7 @@ * search.js — small, dependency-free full-text search for an edition. * * Builds an in-memory inverted index over each article's title, themes, - * summary, and body, then ranks matches with TF-IDF plus light field + * author, summary, and body, then ranks matches with TF-IDF plus light field * weighting (a hit in the title counts for more than one in the body). It is * meant for a single edition's worth of articles — hundreds, not millions — * which is exactly the scale of a monthly magazine, and it keeps the whole @@ -15,6 +15,7 @@ const FIELD_WEIGHTS = Object.freeze({ title: 3, themes: 2, + author: 2, summary: 1.5, body: 1, });