nx_search_handler_flow.nx
buildroot/runtime/hub/nx_search_handler_flow.nx
about
nx_search_handler_flow.nx -- HUB primitive; site-agnostic search
HTTP handler flow. Operator cardinal 2026-05-27: "make sure you
make the onsite and offsite search reusable and not just tied to the
wiki but with capabilities to be used on other sites".
COMPOSES (HUB / runtime-level primitives only -- ZERO site imports):
hub/nx_search_query_parser (query string -> NxSearchQuery)
hub/nx_search_render_html (HTML render with per-site theme)
nx_search_onsite_engine (NxSearchResults)
nx_search_inverted (NxInvIndex)
COMPOSED BY:
wiki/nx_wiki_search_wiring (next commit)
(future) obd-config search wiring
(future) sprinkler-config search wiring
(future) Nishi-hosted third-party site search per charter §3.5 V4
SEPARATION OF CONCERNS (per operator cardinal):
This module owns the FLOW: parse -> execute -> render -> HTTP wrap.
The SITE owns:
1. Building the index (when content changes)
2. The doc-store callback: given rowid, return title/url/body
3. The theme literals (per-site CSS class prefixes)
4. The HTTP route prefix matching ("/wiki/search" vs "/obd/search")
The site never re-implements query parsing, AND-intersection,
snippet extraction, or HTML emission -- those are HUB primitives.
HOW SITES INTEGRATE (~50-line per-site wiring):
1. Allocate one NxSearchFlow at startup (large buffers reused)
2. Define site doc-store walker: given results.rowids[], fill
the inputs.title_ptrs/url_ptrs/body_ptrs arrays
3. Build NxSearchRenderTheme with site CSS class prefixes
4. On HTTP request: extract query string, call
nx_search_flow_run(flow, query_str, q_n, walker_fn, theme,
resp_buf, resp_cap, resp_n)
V1 SCOPE per NISHI_SEARCH_CHARTER.md §6:
- End-to-end onsite query -> HTML response bytes
- Site doc-store integration via pre-resolved inputs
- QoS elapsed_us observable
dependencies 5 imports · 6 importers
imports: nx_syscalls.nxnx_search_query_parser.nxnx_search_onsite_engine.nxnx_search_render_html.nxnx_search_inverted.nx
imported by: nx_wiki_https_daemon.nxnx_wiki_https_daemon_mv.nxnx_wiki_main.nxnx_wiki_routes.nxnx_wiki_search_wiring.nxnx_wiki_vhost_table.nx
structs
| 83 | struct NxSearchFlow |
consts
| 56 | const NX_SHF_OK: i64 = 0 |
| 57 | const NX_SHF_BAD_INPUT: i64 = 2100 |
| 58 | const NX_SHF_PARSE_FAIL: i64 = 2101 |
| 59 | const NX_SHF_ENGINE_FAIL: i64 = 2102 |
| 60 | const NX_SHF_RESOLVER_FAIL: i64 = 2103 |
| 61 | const NX_SHF_RENDER_FAIL: i64 = 2104 |
| 62 | const NX_SHF_HTTP_OVERFLOW: i64 = 2105 |
| 63 | const NX_SHF_NOT_IMPLEMENTED: i64 = 2106 |
| 66 | const NX_SHF_DEFAULT_RESP_CAP: i64 = 65536 // 64 KB response cap |
| 67 | const NX_SHF_DEFAULT_BODY_CAP: i64 = 49152 // 48 KB body cap (header ~16 KB headroom) |
| 68 | const NX_SHF_DEFAULT_RESULTS: i64 = 100 |
| 69 | const NX_SHF_DEFAULT_TERM_BUF: i64 = 128 |
| 70 | const NX_SHF_DEFAULT_POSTINGS: i64 = 100000 |
| 71 | const NX_SHF_DEFAULT_COUNTER: i64 = 4000000 // 4 MB; ~4M docs |
| 72 | const NX_SHF_QUERY_STR_CAP: i64 = 2048 |
| 73 | const NX_SHF_TERMS_BUF_CAP: i64 = 1024 |
| 74 | const NX_SHF_HEADER_BUF_CAP: i64 = 512 |
| 75 | const NX_SHF_INT_BUF_CAP: i64 = 32 |
functions
| 117 | func nx_search_flow_init(flow: *NxSearchFlow, |
| 181 | func nx_search_flow_parse(flow: *NxSearchFlow, |
| 199 | func nx_search_flow_execute_onsite(flow: *NxSearchFlow, |
| 225 | func nx_search_flow_finalize_inputs(flow: *NxSearchFlow) -> i64 |
| 240 | func nx_search_flow_render(flow: *NxSearchFlow, |
| 259 | func nx_shf_int_to_dec(v: i64, out: *u8, cap: i64) -> i64 |
| 290 | func nx_search_flow_wrap_http(flow: *NxSearchFlow, |
| 351 | func nx_search_flow_results(flow: *NxSearchFlow) -> *NxSearchResults |
| 356 | func nx_search_flow_query(flow: *NxSearchFlow) -> *NxSearchQuery |