Split search_index.js into pure JS logic and Liquid data template#637
Split search_index.js into pure JS logic and Liquid data template#637khemarato merged 4 commits intobuddhist-uni:mainfrom
Conversation
Extract pure JavaScript functions (getPositions, resultMatched, addMatchHighlights, getBlurbForResult, categoryName, displaySearchResult) into a separate search_functions.js file. This separates testable logic from the Jekyll/Liquid template, enabling direct unit testing without needing to parse the Liquid template or run a Jekyll build first. search_index.js now imports search_functions.js via importScripts and retains only the Liquid-generated data (store), lunr index building, and the web worker message handler. No functional changes — same behavior, just file reorganization. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
✅ Deploy Preview for obu ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
khemarato
left a comment
There was a problem hiding this comment.
Let's also pull out the message handling code as well so we can test that too. I want the search_index file as js-lean as possible.
Per review feedback, also extract the message handling code and displaySearchResults so search_index.js is as JS-lean as possible. search_index.js now contains only the Liquid data template, lunr pipeline setup, and index building. The moved functions reference globals (store, idx) that are defined at runtime by search_index.js — this works because importScripts runs synchronously and the onmessage handler is only called after the worker finishes initialization. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
|
Done — moved
All testable JS logic is now in |
khemarato
left a comment
There was a problem hiding this comment.
Two small nits and then this is good to go.
assets/js/search_functions.js
Outdated
| @@ -0,0 +1,228 @@ | |||
| // Pure JavaScript functions for the search worker. | |||
| // Split from search_index.js so they can be tested independently | |||
There was a problem hiding this comment.
no need for the history lesson 😊
There was a problem hiding this comment.
Done — removed the header comments.
assets/js/search_functions.js
Outdated
| }); | ||
| }); | ||
| } | ||
| self.postMessage({ |
There was a problem hiding this comment.
Make this a pure function returning the message. _index can hook up the self. business.
There was a problem hiding this comment.
Done — converted to a pure handleSearchMessage(data, searchFn) function that returns the message object. search_index.js now just wires it up:
self.onmessage = function(e) {
self.postMessage(handleSearchMessage(e.data, idx.search.bind(idx)));
}- Remove file header comments per review feedback - Convert self.onmessage into a pure handleSearchMessage function that returns the message object; search_index.js wires up self Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
| } | ||
|
|
||
| // Parameters | ||
| var BMAX = 250; // Max blurb size in characters |
There was a problem hiding this comment.
Turns out these Parameters were load bearing. Can you see the bug?
There was a problem hiding this comment.
Good catch — found it. The // Parameters and var BMAX lines were providing newlines between the OBU_STEMMER closing brace and the Liquid {%- ... -%} tags. Without them, the Liquid whitespace stripping concatenates } and var store onto the same line, which breaks ASI (automatic semicolon insertion).
Fixed by adding a semicolon after the OBU_STEMMER function definition. Should have tested on the deploy preview — lesson learned.
There was a problem hiding this comment.
Welcome to the joys of Liquid! 😅
The removed BMAX/RMAX lines previously provided newlines between the
OBU_STEMMER closing brace and the Liquid {%- tags. Without them, the
Liquid whitespace stripping concatenates '}' and 'var store' on the
same line, preventing automatic semicolon insertion.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
…tests Address review feedback: - Remove extractFunction parser since search_functions.js now exists as a standalone file (after buddhist-uni#637 merged) - Load search_functions.js directly via vm sandbox - Add handleSearchMessage tests covering: stop word handling, +prefix logic, fallback search, filterquery filtering, and result structure validation Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* Added Node.js unit tests for core JavaScript utilities Added tests for utils.js (unaccented, UpdateQueryString, locationOf, sortedInsert, Ranges) and buggytrack.js (cyrb53) using Node's built-in test runner. Zero new dependencies. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> * Address review feedback: relocate tests, improve assertions, add coverage - Moved test files from test/ to assets/js/tests/ (closer to source) - Added assets/js/tests/ to _config.yml exclude list - Updated categoryName tests to validate HTML structure instead of specific names - Added tests for addMatchHighlights and getBlurbForResult - Added inline comments explaining why vm.createContext needs explicit globals Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> * refactor: load search_functions.js directly, add handleSearchMessage tests Address review feedback: - Remove extractFunction parser since search_functions.js now exists as a standalone file (after #637 merged) - Load search_functions.js directly via vm sandbox - Add handleSearchMessage tests covering: stop word handling, +prefix logic, fallback search, filterquery filtering, and result structure validation Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> * test: add +-, --, -+ prefix combination tests for handleSearchMessage Address review feedback from khemarato: add test cases covering all prefix combinations to verify existing +/- prefixes are preserved. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> * test: address review feedback — add html-validate and missing test cases * fix(test): add HTML validation in categoryName loop + flip assertion order Address review nits: - Add assertValidHtml() for every category in the knownCategories loop - Flip assertion order in "finds the section with the most matches" to catch incorrect greedy implementations by checking the negative first Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> * fix(search): use numeric for-loop instead of for-in on positions array for (var i in positions) yields string keys ("0", "1", ...), causing j = i + 1 to produce "01" (string concatenation) instead of 1 (numeric addition). This made the inner while-loop skip positions[1] for i=0 and exit immediately for all other starting indices, so the algorithm always selected the first match's window regardless of where the densest cluster was. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> * test(search): flip test data to catch greedy blurb selection Place the lone IGNORE match before the cluster (MATCH, ME, INSTEAD) so that a greedy algorithm picking the first match would fail. Also add assertValidHtml() in the categoryName loop per review. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> --------- Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
Summary
search_index.jsinto a newsearch_functions.jsfilegetPositions,resultMatched,addMatchHighlights,getBlurbForResult,categoryName,displaySearchResult, and theBMAXconstantsearch_index.jsnow importssearch_functions.jsviaimportScriptsand retains only: Liquid-generated data (store), lunr index building,displaySearchResults, and the web worker message handlerMotivation
This is a prerequisite for PR #636 (unit tests). By separating testable logic from the Liquid template, tests can import
search_functions.jsdirectly without needing a custom parser or a Jekyll build step. Discussed and agreed upon in PR #636 review.Test plan
Co-Authored-By: Claude Opus 4.6 (1M context) [email protected]
🤖 Generated with Claude Code