# `Issho.Authority`
[🔗](https://github.com/hattoriai/issho/blob/v0.1.0/lib/issho/authority.ex#L1)

The one process that orders a document's changes, across every node of
a cluster.

It loads the document from the store (or builds it from the initial
content your policy gives), and for each transaction:

  1. checks the envelope (`Issho.Transaction`) and its receipt: a retry
     of an accepted transaction gets its revision again, and changes
     nothing;
  2. applies the operations with the document's engine, all or none;
  3. validates the result (`c:Issho.Engine.validate/2`);
  4. saves the document and its content, comparing the stored version;
  5. only then answers the author and broadcasts the transaction.

The stored document is the engine's state with Issho's envelope: the
engine's name and version, an epoch, a revision, the state the epoch
began with, a journal of the accepted transactions, and their receipts.
The journal can rebuild any revision of the epoch (`content_at/3`), so a
form can publish exactly the revision a person saw.

A store that answers `{:error, :conflict}` means another process saved
meanwhile (a node that lost touch with the cluster): this one stops, and
the next open loads the newer document.

When no session has used the document for the instance's `:ttl` (30
seconds), the authority stops; the document stays in the store.

Start an authority with `Issho.Documents.open/3`, not directly.

# `accepted`

```elixir
@spec accepted(GenServer.server(), [String.t()], String.t()) :: [String.t()]
```

Which of these transaction ids the author already has accepted, after a reconnect.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `commit`

```elixir
@spec commit(GenServer.server(), Issho.Transaction.t(), String.t()) ::
  {:ok, map()} | {:error, term()}
```

Commits a transaction of the actor `author` (its key). Gives
`{:ok, %{"id" => id, "revision" => revision}}`, with `"duplicate" =>
true` for a retry, or `{:error, reason}`.

# `content`

```elixir
@spec content(GenServer.server()) :: {:ok, map()} | {:error, term()}
```

The content of the current revision, with its epoch and revision.

# `content_at`

```elixir
@spec content_at(GenServer.server(), String.t(), non_neg_integer()) ::
  {:ok, term()} | {:error, term()}
```

The content of an accepted revision of the epoch.

# `join`

```elixir
@spec join(GenServer.server(), pid()) :: {:ok, map(), module()}
```

Adds a session (a channel, an agent) that uses the document; the
authority stays while one does. Returns the document as a browser
receives it, and the document's engine.

# `snapshot`

```elixir
@spec snapshot(GenServer.server()) :: {:ok, map()}
```

The document as a browser receives it: epoch, revision and the engine's snapshot.

---

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