Browser runtime

chops-search.js runs in one of two modes, chosen automatically at load.

Mode selection

Page contains #chops-input?Mode
NoOverlay: a dialog is mounted as a direct child of <body>
YesInline: the existing markup is driven in place

Element contract (inline mode)

ElementRequirement
#chops-inputThe query input
#chops-resultsMust be a <ul>; results are appended as <li>
#chops-modeA <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)

AttributeEffect
data-chops-openOpens the overlay on click, Enter, or Space
data-chops-clearWired 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

KeyAction
Ctrl/Cmd-K or /Open (overlay mode; / only outside text fields)
↓ ↑Move through results (↑ from no selection goes to the last)
Ctrl-N / Ctrl-PSame, readline-style (some browsers reserve Ctrl-N)
EnterOpen 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.