# `nupp.spi` Discover implementations, then choose with ordinary module initialization code. `load(Interface)` returns a lazy iterator in dependency order. Iteration order does not choose a winner: the caller may compare priorities, check capabilities, or combine implementations. `select` is the common rule, the unique highest `priority`, with the caller's fallback where nothing is advertised: ```nupp:fragment local spi = require("nupp.spi") local {type Codec} = require("example.codec.spi") local impl: Codec = spi.select(spi.load(Codec)) ?? require("example.defaultcodec") ``` Keep the selected functions when the module loads. Packages advertise their implementation modules in `nupp/spi.json`. ## Functions ### `load` _function_ ```nupp load(Interface): function(): Interface? ``` Iterates implementations of an exported interface without choosing one. Call as `nupp.spi.load(Interface)`, passing the interface declaration. Each iteration loads one module; ordinary require caching retains its identity. #### Arguments | Name | Type | Description | | --- | --- | --- | | `Interface` | `interface declaration` | The exported interface whose implementations to discover. | #### Returns | Type | Description | | --- | --- | | `function(): Interface?` | A lazy iterator of implementations, returning nil at exhaustion. | #### Raises | Type | Condition | | --- | --- | | `any` | whatever an implementation raised while loading, which is that module's business rather than this one's; the next call retries it | ### `select` _function_ ```nupp function select(candidates: function(): I?): I? ``` Chooses the implementation with the unique highest `priority`. Call as `nupp.spi.select(nupp.spi.load(Interface)) ?? fallback`: nil where nothing is advertised, so the fallback is loaded only when it is used. An implementation that states no priority counts as 0, and a higher priority supersedes a tie below it. Discovery order never breaks a tie for the highest. #### Type parameters | Name | Description | | --- | --- | | `I` | | #### Arguments | Name | Type | Description | | --- | --- | --- | | `candidates` | `function(): I?` | The implementations to choose among, usually what `load` answered. | #### Returns | Type | Description | | --- | --- | | `I?` | The implementation with the highest priority, or nil where there is none. | #### Raises | Type | Condition | | --- | --- | | `string` | where two implementations share the highest priority | | `any` | whatever an implementation raised while loading |