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);{"event", room, %Issho.Event{}}: an event of the room, for a component subscribed to its name (subscribe/3's:events).
notify: :self sends them to the LiveView as
{Issho.Live, event, key, payload} messages instead.
Grants: rooms the browser joins
A component whose browser half joins the room itself (a text editor,
which applies its own changes in the browser) needs a grant: a short
token for the room, signed by the LiveView for the actor it
authenticated. grant/4 signs it and remembers it, and the hook
renews it when the browser asks (the "issho:grant" event, with the
room), after asking the policy again, so that a person whose access
went away gets no new grant. One grant serves every component of the
page in that room.
grant = Issho.Live.grant(MyApp.Issho, current_user, "notebook:7", can: :write)The components of a LiveView share one session per room: joining a
room the LiveView is in already gives the same session. A LiveView may
be in several rooms (a document, and a canvas of another room in it).
A component that goes while the LiveView stays releases its room
(release/2): the LiveView leaves it with its last component.
Join only in a connected LiveView (connected?(socket)): the static
render has no process that lasts.
Summary
Functions
Sets this session's awareness state (nil clears it).
This session's own awareness state (an empty map for none).
Closes a stream of the room, for the person of this LiveView (Accept,
Reject): when they may see it (Issho.Streams.visible?/2).
A grant for the browser to join the room as the actor: %{"room", "token", "can", "self", "socket", "max_channels"}, for a component's
browser half. The LiveView renews it when the browser asks. Options:
:can (:write or :read), :claims, :on_behalf_of, :socket
(the Issho socket's path, "/issho/socket") and :max_channels
(that socket's :max_channels_per_transport, 100).
Who this LiveView is in the room (Issho.Identity), or nil.
Pauses, resumes or stops an agent at work in the room (Issho.Work),
as this LiveView's person: the person it acts for may, and anyone the
policy allows :interrupt.
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.
Leaves a room while the LiveView goes on: its people see the actor go (unless a tab of theirs is still there), its awareness of them clears, and the documents it opened are closed for it. Joining again later is a new session. A room the LiveView is not in is left already.
Merges keys into this session's awareness state: for the components of a LiveView that share its session in a room, each setting its own keys (a grid its place, another component its own key).
Merges a component's own keys into this session's state, under its
document ("blocks", see Issho.Awareness), so that the LiveView's
components, and Issho's own keys, never write over each other's; a
key set to nil goes.
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 and your
policy's document/2 does not say (see Issho.Documents.open/4).
The people of the room now: Phoenix.Presence's list, by actor key.
The document's current snapshot, from its authority.
Stops sending the room's events, and its documents', to a component
(or the LiveView, :self); when none is left in the room, leaves it
(leave/1). For a component that goes from the page while the
LiveView stays: a canvas deleted from a document, a panel closed.
The session id of this LiveView in the room, or nil.
The awareness states of the room's sessions, from every node:
%{session_id => %{"key" => actor_key, "state" => state}}, for a
component that draws the others itself.
The streams of the room this LiveView may see (Issho.Streams), as
they are now, with what they hold so far; from then on, the LiveView
gets what comes as messages, and the room's new streams it may see
Sends the room's messages to a component, or the LiveView, without opening a document. Options
Commits to an open document: a list of operations (on the document's latest revision) or a whole transaction.
Types
Functions
Sets this session's awareness state (nil clears it).
This session's own awareness state (an empty map for none).
Closes a stream of the room, for the person of this LiveView (Accept,
Reject): when they may see it (Issho.Streams.visible?/2).
@spec grant(atom(), Issho.Actor.t(), String.t(), keyword()) :: map()
A grant for the browser to join the room as the actor: %{"room", "token", "can", "self", "socket", "max_channels"}, for a component's
browser half. The LiveView renews it when the browser asks. Options:
:can (:write or :read), :claims, :on_behalf_of, :socket
(the Issho socket's path, "/issho/socket") and :max_channels
(that socket's :max_channels_per_transport, 100).
@spec identity(String.t()) :: Issho.Identity.t() | nil
Who this LiveView is in the room (Issho.Identity), or nil.
Pauses, resumes or stops an agent at work in the room (Issho.Work),
as this LiveView's person: the person it acts for may, and anyone the
policy allows :interrupt.
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.
@spec leave(String.t()) :: :ok
Leaves a room while the LiveView goes on: its people see the actor go (unless a tab of theirs is still there), its awareness of them clears, and the documents it opened are closed for it. Joining again later is a new session. A room the LiveView is not in is left already.
Merges keys into this session's awareness state: for the components of a LiveView that share its session in a room, each setting its own keys (a grid its place, another component its own key).
Merges a component's own keys into this session's state, under its
document ("blocks", see Issho.Awareness), so that the LiveView's
components, and Issho's own keys, never write over each other's; a
key set to nil goes.
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 and your
policy's document/2 does not say (see Issho.Documents.open/4).
The people of the room now: Phoenix.Presence's list, by actor key.
The document's current snapshot, from its authority.
Stops sending the room's events, and its documents', to a component
(or the LiveView, :self); when none is left in the room, leaves it
(leave/1). For a component that goes from the page while the
LiveView stays: a canvas deleted from a document, a panel closed.
A LiveComponent hears nothing when it goes, so its browser half says
it, from its hook's destroyed, and Issho's hook releases the room for
the component of that id:
destroyed() {
this.pushEvent("issho:release", { room: "board:42", component: "board" })
}
The session id of this LiveView in the room, or nil.
The awareness states of the room's sessions, from every node:
%{session_id => %{"key" => actor_key, "state" => state}}, for a
component that draws the others itself.
@spec streams(String.t()) :: {:ok, [Issho.Stream.t()]} | {:error, term()}
The streams of the room this LiveView may see (Issho.Streams), as
they are now, with what they hold so far; from then on, the LiveView
gets what comes as messages, and the room's new streams it may see:
def mount(_params, _session, socket) do
{:ok, outputs} = if connected?(socket), do: Issho.Live.streams(room), else: {:ok, []}
{:ok, assign(socket, :outputs, Map.new(outputs, &{&1.id, &1}))}
end
def handle_info({Issho, :stream, id, {:started, stream}}, socket), do: ...
def handle_info({Issho, :stream, id, {:chunk, text}}, socket), do: ...
def handle_info({Issho, :stream, id, :finished}, socket), do: ...and {:failed, reason}, {:closed, outcome} and :gone. A page that
mounts while a stream is written picks it up where it got to. The
LiveView is in the room (join/4). (Not LiveView's own streams of a
list, stream/4, and not their assign: :streams is LiveView's.)
Sends the room's messages to a component, or the LiveView, without opening a document. Options:
:events, the names of the room's events (Issho.Event) the component gets as{"event", room, event}: a list of names, a name ending in".*"for all of a kind ("comment.*"), or:all. Without it, none.:on_release, a function of no argument, runs when the component is released (release/2), before the LiveView leaves the room if it was the last: for what the component put in the session's awareness, which stays while the LiveView is in the room.
Commits to an open document: a list of operations (on the document's latest revision) or a whole transaction.