# `nupp.host.spi`
The interface a `nupp.host` implementation provides.
The facade selects one implementation when it loads: a provider discovered
through `nupp.spi`, otherwise the embedding host natively and the page in a
browser. Every function is receiver-free and takes its arguments as a flat list,
so an argument list is never wrapped in a table on its way through.
The facade has already checked the kind's spelling. A provider checks the
values themselves against the channel's value model -- `nil`, booleans, finite
numbers, UTF-8 strings and byte spans -- because only the provider knows what it
is about to encode, and it reports a refusal with the argument's position.
`call` suspends through `nupp.suspension` until the host answers. Should the
waiting task be cancelled after the request reached the host, a later answer is
handed to `late` rather than dropped, so a result naming a host resource is
always released by someone. `post` never suspends and discards the answer.
## Types
### `Late` _type_
```nupp
type Late = function(...: any): nil
```
Called with the results of a call whose caller stopped waiting.
### `Policy` _type_
```nupp
type Policy = "block" | "latest" | "dropOldest"
```
What a full stream does with one more message: suspend the sender until
the stream ships (`block`, outbound only), keep only the newest (`latest`),
or drop the oldest past the limit (`dropOldest`).
### `Provider` _interface_
```nupp
interface Provider ...
```
#### Members
| Name | Kind | Description |
| --- | --- | --- |
| [`priority`](#nupp.host.spi.Provider.priority) | field | Ranks a discovered implementation; the highest unique priority wins. |
| [`attached`](#nupp.host.spi.Provider.attached) | method | Reports whether something is attached to answer requests at all. |
| [`call`](#nupp.host.spi.Provider.call) | method | Sends a request and suspends until the host answers it. |
| [`post`](#nupp.host.spi.Provider.post) | method | Queues a request for the host without waiting for its answer. |
| [`send`](#nupp.host.spi.Provider.send) | method | Appends a message to the kind's outbound stream, applying policy with limit when the stream already holds that many... |
| [`route`](#nupp.host.spi.Provider.route) | method | Delivers the kind's inbound messages to deliver at each turn boundary, keeping at most limit per turn as policy says. |
#### `priority` _field_
```nupp
priority: integer?
```
`@readonly`
Ranks a discovered implementation; the highest unique priority wins.
#### `attached` _method_
```nupp
attached: function(): boolean
```
`@readonly`
Reports whether something is attached to answer requests at all.
##### Returns
| Type | Description |
| --- | --- |
| `boolean` | |
#### `call` _method_
```nupp
call: function(kind: string, late: Late?, ...: any): ...any
```
`@readonly`
Sends a request and suspends until the host answers it.
Raises the host's failure as an error in the caller.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `kind` | `string` | |
| `late` | `Late?` | |
| `...` | `any` | |
##### Returns
| Type | Description |
| --- | --- |
| `...any` | |
#### `post` _method_
```nupp
post: function(kind: string, ...: any): nil
```
`@readonly`
Queues a request for the host without waiting for its answer.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `kind` | `string` | |
| `...` | `any` | |
##### Returns
| Type | Description |
| --- | --- |
| `nil` | |
#### `send` _method_
```nupp
send: function(kind: string, policy: Policy, limit: integer, ...: any): nil
```
`@readonly`
Appends a message to the kind's outbound stream, applying `policy` with
`limit` when the stream already holds that many unshipped messages.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `kind` | `string` | |
| `policy` | `Policy` | |
| `limit` | `integer` | |
| `...` | `any` | |
##### Returns
| Type | Description |
| --- | --- |
| `nil` | |
#### `route` _method_
```nupp
route: function(
kind: string,
policy: Policy,
limit: integer,
deliver: function(...: any): nil
): (function(): nil, function(): integer)
```
`@readonly`
Delivers the kind's inbound messages to `deliver` at each turn boundary,
keeping at most `limit` per turn as `policy` says. Returns two
functions: one stops the route when called; the other returns how many
messages it has dropped.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `kind` | `string` | |
| `policy` | `Policy` | |
| `limit` | `integer` | |
| `deliver` | `function(...: any): nil` | |
##### Returns
| Type | Description |
| --- | --- |
| `function(): nil` | |
| `function(): integer` | |