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

A LiveView in a room: the same session as a browser's channel or an
agent's process, in the LiveView's own process. Presence, awareness,
the room's documents and the policy work the same; the room's events
reach the LiveView's components with `send_update/2`, or the LiveView
itself.

    live_session :default, on_mount: [Issho.Live] do

    # In a LiveView or one of its components, once connected:
    {:ok, _session} = Issho.Live.join(MyApp.Issho, current_user, "board:42")
    {:ok, snapshot} = Issho.Live.open("board:42", "board:42", notify: {MyComponent, "board"})

A component named in `notify` gets `update/2` with an `:issho` assign
for each event, `{event, key, payload}`:

  * `{"tx", document_id, accepted_transaction}`: a transaction accepted
    in a document it opened;
  * `{"aware", room, frame}`: the others' awareness;
  * `{"presence_diff", room, diff}`: people who came and went;
  * `{"bye", room, reason}`: the session ended (revoked, refused).

`notify: :self` sends them to the LiveView as
`{Issho.Live, event, key, payload}` messages instead.

The components of a LiveView share one session per room: joining a
room the LiveView is in already gives the same session.

Join only in a connected LiveView (`connected?(socket)`): the static
render has no process that lasts.

# `target`

```elixir
@type target() :: {module(), term()} | :self
```

# `aware`

```elixir
@spec aware(String.t(), map() | nil) :: :ok | {:error, term()}
```

Sets this session's awareness state (`nil` clears it).

# `join`

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

Joins a room as an actor, from this LiveView, or gives the session the
LiveView already has there. Options: `:can` (`:write`), `:claims`,
`:on_behalf_of`.

# `open`

```elixir
@spec open(String.t(), String.t(), keyword()) :: {:ok, map()} | {:error, term()}
```

Opens a document of the room. Options: `:notify`, a component
(`{module, id}`) or `:self`, for its transactions and the room's events;
and `:spec`, what the document is if this opens it first (see
`Issho.Documents.open/4`).

# `people`

```elixir
@spec people(String.t()) :: map()
```

The people of the room now: `Phoenix.Presence`'s list, by actor key.

# `read`

```elixir
@spec read(String.t(), String.t()) :: {:ok, map()} | {:error, term()}
```

The document's current snapshot, from its authority.

# `session_id`

```elixir
@spec session_id(String.t()) :: String.t() | nil
```

The session id of this LiveView in the room, or `nil`.

# `subscribe`

```elixir
@spec subscribe(String.t(), target()) :: true
```

Sends the room's events to a component, or the LiveView, without opening a document.

# `transact`

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

Commits to an open document: a list of operations (on the document's
latest revision) or a whole transaction.

---

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