Browser runtime
chops-search.js runs in one of two modes, chosen automatically at load.
Mode selection
Page contains #chops-input? | Mode |
|---|---|
| No | Overlay: a dialog is mounted as a direct child of <body> |
| Yes | Inline: the existing markup is driven in place |
Element contract (inline mode)
| Element | Requirement |
|---|---|
#chops-input | The query input |
#chops-results | Must be a <ul>; results are appended as <li> |
#chops-mode | A <span>; receives the status line (aria-live recommended) |
In inline mode, showing/hiding the container, clearing behaviour, and stacking context are your responsibility.
Data attributes (both modes)
| Attribute | Effect |
|---|---|
data-chops-open | Opens the overlay on click, Enter, or Space |
data-chops-clear | Wired as a clear button; an empty element gets the icon injected |
Programmatic clearing must dispatch the event, since setting .value fires
nothing: input.dispatchEvent(new Event('input')).
Keyboard
| Key | Action |
|---|---|
Ctrl/Cmd-K or / | Open (overlay mode; / only outside text fields) |
↓ ↑ | Move through results (↑ from no selection goes to the last) |
Ctrl-N / Ctrl-P | Same, readline-style (some browsers reserve Ctrl-N) |
Enter | Open the selected result |
Esc or Ctrl-[ | Clear the query; close if already empty |
Results and status line
Each result renders as its document title with a snippet underneath: the
text of the chunk that earned the document its rank, fetched after ranking
and streamed in as it arrives, with the query's matched words highlighted.
The results list carries data-mode="hybrid" or data-mode="keyword",
which the stylesheet and your own CSS can key off.
#chops-mode reports the states a user needs to know about: the result
count with the mode it was ranked under ("keyword only" when semantic rows
can't load), and unavailability when the engine can't boot. See
Designed degradation for when each
occurs.
Theming
Every colour in the built-in overlay derives from currentColor; the custom
properties on .chops are the theming surface, so the dialog inherits your
site's palette and a handful of property overrides tune the rest. The
stylesheet is search/chops-search.css, regenerated by every build, so
put overrides in your own stylesheet rather than editing it.
Network behaviour
The page script spawns search-worker.js, which loads the wasm engine (from
search/pkg/, version-queried), plans byte ranges per query, and persists
fetched rows in a Cache API row cache keyed to the build hash. Queries are
debounced, and a superseded in-flight query is dropped rather than raced.
Snippet fetches are memoized by chunk id for the session, and the snippet
offset table is fetched once at boot as a single small range. A host that
answers a range request with a 200 is remembered as range-hostile for the
session: the file is ingested whole once, and later queries skip ranges
rather than re-paying the fallback. The
artifact reference lists what loads when.