JavaScript · Design

Design

4.0.0-rc.1 · 3ee5e534

The SDK is a thin layer over the C interface, one module per header: types, model, encode and train.

  • One method per exported verb, spelled as in C: textEncode calls uform_text_encode.
  • The receiver chooses and the verb stays: model.textEncode runs on the calling thread, model.on(executor).textEncode blocks on an executor, and model.deferred(executor).textEncode answers a Deferred.
  • A Deferred is PromiseLike and Disposable: await waits on the libuv pool, wait blocks the calling thread, status polls, and disposing one waits until it is final.
  • Every output verb takes an arena and answers views borrowing it, detached when the arena rewinds or is freed.
  • Statuses, scalars, moods, modalities, objectives, negatives and multimem tiers are string enums spelled as the C name tables spell them.
  • CPU and GPU classes cross as the strings the C name tables spell, and pair-loss forms, late-interaction sides and GPU vendors as numeric enums of the C numbers.
  • The SDK starts no threads and keeps no queues or caches; the only thread it borrows is the libuv worker an await runs its wait on.
  • A progress handler runs only on the calling thread, so only a model’s own verbs take one.
  • Blocking calls look as they would without asynchrony, deferred calls reach the same verbs through the language’s own idioms, and neither costs anything until used.
  • The browser build lays every argument structure into the module’s heap at offsets computed once from the C headers, runs it with a NULL executor, and copies its outputs out before the next call can grow the heap.
  • The suite runs against the stand-in library, and against the real library with the tiny checkpoint.