# Design

> UForm for JavaScript

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.

