Integrations
A FormScript document can reach out. It can declare a source to fetch data
from and an action to submit to, and §11 makes one rule about both:
An action or a source is data, not code (Spec-11.1). The runtime owns transport, auth and serialisation; the document contributes values.
That is the whole integration model. A document says what to call and with what; it never says how. The host owns how.
What a document may declare
§8.7 is the complete list. There is no headers, no auth, no target and
no body format — and there is deliberately no place to put them.
| Property | Applies to | Meaning |
|---|---|---|
url |
action, source |
Required. The request URL expression |
method |
action, source |
HTTP method. "GET" for a source, "POST" for an action |
when |
action, source |
The guard expression |
params |
source |
An object expression of query parameters |
body |
action |
The request body expression |
timeout |
action, source |
Milliseconds |
retry |
action |
The retry count |
cache |
source |
The cache lifetime |
type |
source |
The declared result type |
conflict |
action |
The replay conflict policy. skip by default |
A document that declares params on an action is rejected by the analyzer:
params belongs to a source.
The body of an action is $form.output — the projected output document — unless
the action declares its own body (Spec-11.4).
What the host must supply
The runtime never opens a socket and never reads a clock by itself. These are the interfaces a host provides.
| The host supplies | It is | Where it is used |
|---|---|---|
Transport |
send(request) → response. The network the runtime does not own |
every source and action |
Clock |
now() and sleep(ms). The time, and the wait a backoff needs |
timeouts, retry, the transaction timestamp |
| A durable store | somewhere to keep unsent submissions | the offline queue (Spec-11.9) |
| The source's status and value | idle | pending | ready | error, and the value when it is ready |
a field whose options come from a source (Spec-11.7) |
| The action's status | idle | pending | success | error |
so a form can branch on it |
$env and $user |
the environment and the person | $env.locale, $env.user.* |
| A locale and a text catalogue | the locale, and a function that resolves a message key | §12 internationalisation |
Because a host supplies the transport and the clock, a test can supply its own and nothing in the runtime package ever touches the network.
How a value becomes a parameter
The mapping is what makes a source or an action well-behaved when a field has not been answered.
| The value | What is sent |
|---|---|
| a value | bound — the parameter is sent |
absent (null or unknown) |
bound to an empty value: asked, not answered (Spec-4.35) |
| inapplicable | omitted: not asked (Spec-8.3) |
| the error value | the mapping fails and the request is not built (E-EVAL-07) |
An array is sent as repeated fields of the same name.
What the specification deliberately leaves out
No transport beyond HTTP verbs, no authentication scheme, no serialisation format for a body other than the output document, no database, no API convention, no message broker, no vendor. §1.4 says the language does not specify a layout system, and §11 says the same about the network: a FormScript document is not tied to any of it.
That is what makes an integration cheap. The host already has a transport, a store and a session; the document only has to name a URL and a guard.
What is wired up today
| Integration | What it is |
|---|---|
| The command line | npm run formscript -- lint | run | ast | conformance | errors | level | spec-lint. It runs a document, a transaction script and the suites |
| The playground | the reference implementation compiled to the browser. It runs a form in the page and shows the output document |
| Server-side rendering | a form rendered to HTML and read back from a POST, with no JavaScript at all — see server rendering |
| The corpus | 232 real forms from FHIR and XForms, converted and run — see the corpus |
| The CI gates | the specification lint, the colour gate, the contrast gate, the tutorial gate, the documents gate, the property suite and the conformance suite |
See also
- Runtimes — the three runtimes and how each is judged
- Renderers — what a runtime hands a renderer
- Remote data and actions — the runtime package, with its API
- The language — the whole language, as the reference states it