# `WardrikStore`

A durable key-value store. Wardrik packages keep their data in it, each under its own scope.

    store = WardrikStore.ETS.new(name: MyApp.Store)
    children = [{WardrikStore, store}]

    vault = WardrikStore.scope(store, "wardrik_vault")
    {:ok, vsn} = WardrikStore.put(vault, "github/jon", grant, if_vsn: nil)

An adapter decides where the keys are kept. See `WardrikStore.ETS`, `WardrikStore.EKV` and
`WardrikStore.Ecto`.

# `key`

```elixir
@type key() :: String.t()
```

A key within a scope.

# `t`

```elixir
@type t() :: %WardrikStore{
  adapter: module(),
  config: WardrikStore.Adapter.config(),
  scope: String.t()
}
```

A store, scoped or not.

# `vsn`

```elixir
@type vsn() :: term()
```

The version an adapter stamps a write with.

# `child_spec`

```elixir
@spec child_spec(t()) :: Supervisor.child_spec()
```

Returns the child spec that runs the store.

Starts nothing if the store is already running. So each thing that uses the store can list it
among its own children.

    children = [{WardrikStore, store}, {MyApp.Uses, store: store}]

# `delete`

```elixir
@spec delete(t(), key(), [{:if_vsn, vsn()}]) :: :ok | {:error, :conflict | term()}
```

Removes `key`. Returns `:ok`, also when `key` isn't there.

## Options

  * `:if_vsn` - removes only this version. Returns `{:error, :conflict}` otherwise.

# `entries`

```elixir
@spec entries(t(), String.t()) :: [{key(), term(), vsn()}]
```

Returns `{key, value, vsn}` for each of the scope's keys that starts with `prefix`, sorted by key.

# `get`

```elixir
@spec get(t(), key()) :: term() | nil
```

Returns the value under `key`, or `nil`.

# `keys`

```elixir
@spec keys(t(), String.t()) :: [key()]
```

Returns the scope's keys that start with `prefix`, sorted.

# `lookup`

```elixir
@spec lookup(t(), key()) :: {term(), vsn()} | nil
```

Returns `{value, vsn}` for `key`, or `nil`.

# `lookup_many`

```elixir
@spec lookup_many(t(), [key()]) :: %{required(key()) =&gt; {term(), vsn()}}
```

Returns `%{key => {value, vsn}}` for `keys`. Keys that aren't there are left out.

# `new`

```elixir
@spec new(module(), WardrikStore.Adapter.config()) :: t()
```

Builds a store over `adapter`. Adapters call this from their own `new/1`.

# `put`

```elixir
@spec put(t(), key(), term(), [{:if_vsn, vsn() | nil}]) ::
  {:ok, vsn() | nil} | {:error, :conflict | term()}
```

Writes `value` under `key`. Returns `{:ok, vsn}`.

    {:ok, vsn} = WardrikStore.put(store, "settings/theme", "dark", if_vsn: nil)
    {:ok, _vsn} = WardrikStore.put(store, "settings/theme", "light", if_vsn: vsn)
    {:error, :conflict} = WardrikStore.put(store, "settings/theme", "blue", if_vsn: vsn)

## Options

  * `:if_vsn` - writes only over this version, or only where `key` is empty when `nil`.
    Returns `{:error, :conflict}` otherwise. Without it, the write always lands, and some
    adapters return `{:ok, nil}`.

# `scope`

```elixir
@spec scope(t(), String.t()) :: t()
```

Returns the store nested under the scope `name`.

Keys in one scope never match keys in another.

    mine = WardrikStore.scope(store, "my_app")

`name` starts with a lowercase letter, followed by lowercase letters, digits and underscores.
Raises `ArgumentError` otherwise.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
