# `nupp.store`
Typed keys and the stores they index.
A key is a phantom-typed identity: Nupp remembers `T`, the runtime holds an id
and an optional name. A store is one table indexed by id behind generic methods,
so `store:get(key)` reads `T?` and `store:set(key, value)` accepts `T`.
Names are opaque strings registered once per runtime state. Ids are allocated
in declaration order and identify a key inside this state only; the name is the
identity that persists.
## Constructors
### `newKey` _constructor_
```nupp
function newKey(name: string?): Key
```
Creates a key.
The type argument comes from the annotation at the declaration. A named key
is registered for the runtime state's lifetime; an anonymous key is
retained by nothing but its holders.
#### Type parameters
| Name | Description |
| --- | --- |
| `T` | |
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `name` | `string?` | the opaque name to register, or nil for an anonymous key |
#### Returns
| Type | Description |
| --- | --- |
| `Key\` | the key |
#### Raises
- when the name is empty or already registered, before an id is used
### `newStore` _constructor_
```nupp
function newStore(): Store
```
Creates an empty store.
#### Returns
| Type | Description |
| --- | --- |
| `Store` | the store |
## Types
### `Key` _interface_
```nupp
interface Key
readonly id: integer
readonly name: string?
end
```
A typed identity for one value in a [`nupp.store.Store`](#nupp.store.Store).
`id` and `name` are all a key holds at runtime. `_valueType` is never
present: it mentions `T` in both positions so that keys are invariant, which
is what makes a wrong write through one a checker error rather than a
silent widening.
#### Type parameters
| Name | Description |
| --- | --- |
| `T` | |
#### Fields
##### `id`
```nupp
id: integer
```
##### `name`
```nupp
name: string?
```
### `KeyStep` _type_
```nupp
type KeyStep = function(any, integer): (integer, string)
```
The step of [`nupp.store.registeredKeys`](#nupp.store.registeredKeys).
Terminating on nil is the generic for's business, so the surface type
promises what the loop delivers rather than what the last call returns.
### `Store` _record_
```nupp
record Store
get: function(self: Store, key: Key): T?
set: function(self: Store, key: Key, value: T): nil
remove: function(self: Store, key: Key): nil
clear: function(self: Store): nil
entries: function(
borrows self: Store
): (function(Store, integer): (integer, string?, string), Store borrows (self), integer)
end
```
An independent typed bag indexed by keys.
#### Methods
##### `get`
```nupp
get: function(self: Store, key: Key): T?
```
Answers the value held under a key.
###### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `Store` | |
| `key` | `Key\` | |
###### Returns
| Type | Description |
| --- | --- |
| `T?` | |
##### `set`
```nupp
set: function(self: Store, key: Key, value: T): nil
```
Stores a non-nil value under a key.
###### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `Store` | |
| `key` | `Key\` | |
| `value` | `T` | |
###### Returns
| Type | Description |
| --- | --- |
| `nil` | |
###### Raises
- when value is nil; use `remove` to delete an entry
##### `remove`
```nupp
remove: function(self: Store, key: Key): nil
```
Removes the value held under a key.
###### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `Store` | |
| `key` | `Key\` | |
###### Returns
| Type | Description |
| --- | --- |
| `nil` | |
##### `clear`
```nupp
clear: function(self: Store): nil
```
Removes every value without touching key registration.
###### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `Store` | |
###### Returns
| Type | Description |
| --- | --- |
| `nil` | |
##### `entries`
```nupp
entries: function(
borrows self: Store
): (function(Store, integer): (integer, string?, string), Store borrows (self), integer)
```
Walks every occupied key ascending by id, without its value.
###### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `borrows self` | `Store` | |
###### Returns
| Type | Description |
| --- | --- |
| `function(Store, integer): (integer, string?, string)` | |
| `Store borrows (self)` | |
| `integer` | |
### `StoreStep` _type_
```nupp
type StoreStep = function(Store, integer): (integer, string?, string)
```
The step of [`Store.entries`](#nupp.store.Store.entries).
Terminating on nil is the generic for's business, so the surface type
promises what the loop delivers rather than what the last call returns.
## Functions
### `findKey` _function_
```nupp
function findKey(name: string): unknown
```
Finds a registered key by name.
The registry knows the name's id and nothing about its type, so the result
is `unknown` and the caller casts to the `Key` it claims.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `name` | `string` | the registered name |
#### Returns
| Type | Description |
| --- | --- |
| `unknown` | the key, or nil when the name is not registered |
### `registeredKeys` _function_
```nupp
function registeredKeys(): KeyStep, any, integer
```
Walks every registered name, ascending by id.
The walk allocates nothing: the step is one shared function and the control
variable is the id it last reported. The registry itself is never handed
out, so nothing the loop is given can be used to reach or change it. An
anonymous key registers no name and is not walked.
#### Returns
| Type | Description |
| --- | --- |
| `KeyStep` | the step the loop calls |
| `any` | nothing to carry, since the ids are the whole state |
| `integer` | the id to resume after, 0 to start |