JavaScript · Platform Notes

Platform Notes

3.0.0-rc.1 · 4c3e5023

§ What This Binding Does Not Expose

A JavaScript callback runs only on the thread owning the JavaScript context, and an executor’s threads never are. A thread-safe function would queue onto a loop that sits blocked inside the verb, so the callback could never run. That is why attend runs on the calling thread alone, where its rowOf can, and no executor receiver offers it. It is also why a search predicate, a per-candidate callback the engine calls from the threads it fanned out over, is not exposed at all; pull through searchStream instead and filter in JavaScript. The same reasoning excludes the progress handlers every long verb takes.

§ Design

  • A thin layer over the C ABI. Every name follows include/usearch/: a C verb usearch_dense_<verb> is a camel-cased <verb> here, every type is its C name without usearch_ and _t, and a verb’s argument structure becomes its Dense*Config. Enums mirror C enums through the C name tables, so a misspelling is refused rather than read as a default.
  • The receiver chooses, the verb stays. The index runs a verb on the calling thread, on(executor) blocks on an executor, and deferred(executor) submits it, all with the same arguments.
  • Deferred calls use the language’s own idioms. status polls through usearch_outcome_status, wait() blocks through usearch_outcome_wait, and await hands that same wait to the libuv pool through napi_async_work, since the library has no wake-up to register.
  • No life of its own. The binding starts no threads and keeps no queues; releasing a Deferred rides using and Symbol.dispose, which waits for the call first.
  • Arenas are lent and reused, never shared. Every output whose length scales with the call lands in an arena the caller passes; a rewind detaches the buffers under the previous call’s views, so a stale one throws rather than reading another call’s memory.
  • Nothing costs anything until it is used. Submitting a call allocates nothing, and an arena allocates only when a call writes into it.
  • Every wrapper names its C symbol. Each wrapper’s documentation names the C function it calls, or says it is binding-only, as contains, keyAt and RowsView.of are.