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

Collaboration for Phoenix: one engine for people and agents working
together live, under every component on a page.

Start an instance in your supervision tree, after your PubSub:

    {Issho,
     name: MyApp.Issho,
     pubsub: MyApp.PubSub,
     endpoint: MyAppWeb.Endpoint,
     policy: MyApp.Collaboration,
     store: {MyApp.CollabStore, MyApp.Repo}}

## Options

  * `:name` (required): the instance's name, given to every call.
  * `:pubsub` (required): your app's `Phoenix.PubSub`.
  * `:policy` (required): your `Issho.Policy`, which authorizes every
    action and says what each document is.
  * `:endpoint` or `:secret_key_base`: to sign join tokens.
  * `:store`: `{module, context}`, an `Issho.Store` for documents.
  * `:registry`: `:global` (the default) or a module with
    `name(instance, document_id)`, for the documents' authorities.
  * `:presence`: whether this instance starts `Issho.Presence` (`true`).
  * `:ttl`: how long, in milliseconds, an unused document stays open
    (30 seconds).
  * `:awareness_interval`: milliseconds between awareness frames (50).
  * `:awareness_max_bytes`: the largest awareness state of a session, as
    JSON (64 KB).
  * `:max_document_bytes` (16 MB), `:max_message_bytes` (1 MB) and
    `:token_max_age` (300 seconds).

See the architecture guide for how the parts fit together.

# `content`

```elixir
@spec content(atom(), String.t(), String.t(), non_neg_integer()) ::
  {:ok, term()} | {:error, term()}
```

The content of a document's revision, for a form that publishes exactly
what a person saw: the `epoch` and `revision` the browser posts.

# `join_as`

```elixir
@spec join_as(atom(), Issho.Actor.t(), String.t(), keyword()) ::
  {:ok, pid()} | {:error, term()}
```

Joins a room as an actor from Elixir (an agent, a job), as a browser
would. Gives an `Issho.Participant`. Options: `:can` (`:write`),
`:on_behalf_of`, `:claims` and `:notify` (the process that receives the
room's events, the caller unless given).

# `revoke`

```elixir
@spec revoke(atom(), String.t(), Issho.Actor.t() | String.t()) :: :ok
```

Takes an actor out of a room now, on every node: its sessions end, and
it receives nothing more. Your app calls it when it takes access away;
the policy refuses the actor from then on.

# `start_link`

```elixir
@spec start_link(keyword()) :: Supervisor.on_start()
```

Starts an instance. See the options above.

# `transact`

```elixir
@spec transact(atom(), String.t(), [map()], keyword()) ::
  {:ok, map()} | {:error, term()}
```

Commits operations to a document from your server (a job, an import),
through the same checks and authority as everyone else's. `author` is
the key it is recorded under (`"server"` unless given).

---

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