A session represents an active connection to an urbit ship.
url : Session -> String
Get a Session's url.
ship : Session -> Encoding.Atom.Atom
Get a Session's ship.
uid : Session -> String
Get a Session's uid.
lastEventId : Session -> Basics.Int
Get a Session's lastEventId.
{ lastEventId : Basics.Int
, data : InMsgData
}
Represents an incoming message.
An incoming message may be one of the following:
Poke
represents a response for a previous pokeSubscribe
represents a response for a subscription requestsDiff
represents a new incoming diff for a subscriptionQuit
means you have been kicked from a subscription and should likely
attempt to resubscribeIn all cases the first Int
value represents the Id of the message it is
relevant to.
Represents an outgoing message.
These are required in order to maintain an active connection to an urbit ship and to perform poke/subscription requests.
connect : { ship : Encoding.Atom.Atom, url : String, channelId : String, code : String } -> (Result Http.Error Session -> msg) -> Platform.Cmd.Cmd msg
Connect to an urbit ship and return a Session
on success. Should be
followed by setupEventSource (this must be done as a
separate step due to the nature of Elm ports).
You can generate a unique channelId
any way you wish, however the provided
genChannelId function is recommended.
connectUnauth : { ship : Encoding.Atom.Atom, url : String, channelId : String } -> (Result Http.Error Session -> msg) -> Platform.Cmd.Cmd msg
Alternative to connect that does not require a code
.
Note: Ensure the correct cookie is set through some other means beforehand or else this will not work. Hosting from within an urbit using the :file-server app with public set to false should work, for example.
setupEventSource : (String -> Platform.Cmd.Cmd msg) -> Session -> Platform.Cmd.Cmd msg
This will set up the realtime communication channel with urbit. Because Elm does not support the EventSource API required, this must be done using ports. Elm does not allow ports to be published as part of a package, but luckily the setup for this is fairly straightforward.
First, copy/paste the following into your js file and replace any references to
app
with the variable name of your running Elm app:
app.ports.setupUrbitEventSource.subscribe((url) => {
const eventSource = new EventSource(url, { withCredentials: true });
eventSource.onmessage = function (event) {
app.ports.onUrbitMessage.send({ message: event });
};
eventSource.onerror = function (event) {
app.ports.onUrbitMessage.send({ error: event });
};
});
Next, declare a port module and the following ports to handle the initial setup and incoming messages:
port setupUrbitEventSource : String -> Cmd msg
port onUrbitMessage : (JE.Value -> msg) -> Sub msg
Now, the newly created setupUrbitEventSource
can be passed as the first
argument to our setupEventSource function and used to
perform the necessary setup. Similarly, the onUrbitMessage
function can be
passed as the first argument to messages below to set up the
subscription to incoming events.
setupCommand =
Urbit.setupEventSource setupUrbitEventSource session
messagesSubscription =
Urbit.messages onUrbitMessage GotUrbitMessage
See the Elm guide for further information regarding ports.
messages : ((Json.Encode.Value -> msg) -> Platform.Sub.Sub msg) -> (Result Json.Decode.Error InMsg -> msg) -> Platform.Sub.Sub msg
Subscribe to incoming messages from urbit. See setupEventSource above for instructions on how to use this. Every message received must be acknowledged by using the related ack function, otherwise urbit will stop accepting any further messages.
ack : Basics.Int -> OutMsg
Acknowledge an incoming message by its Id. Must be performed for every incoming message received.
poke : { ship : Encoding.Atom.Atom, app : String, mark : String, json : Json.Encode.Value } -> OutMsg
Poke an app on a ship.
subscribe : { ship : Encoding.Atom.Atom, app : String, path : String } -> OutMsg
Subscribe to ship events on some path.
unsubscribe : Basics.Int -> OutMsg
Unsubscribe from an existing subscription by its Id.
disconnect : OutMsg
Safely deletes a channel.
send : Session -> (Result Http.Error () -> msg) -> OutMsg -> ( Session, Platform.Cmd.Cmd msg )
Sends an outgoing message to urbit. Returns a tuple of a new session and the command.
sendBatch : Session -> (Result Http.Error () -> msg) -> List OutMsg -> ( Session, Platform.Cmd.Cmd msg )
Sends multiple outgoing messages to urbit in one request. Returns a tuple of a new session and the command.
sendTask : Session -> OutMsg -> ( Session, Task Http.Error () )
Sends an outgoing message to urbit as a task. Returns a tuple of a new session and the task.
sendBatchTask : Session -> List OutMsg -> ( Session, Task Http.Error () )
Sends multiple outgoing messages to urbit in one request as a task. Returns a tuple of a new session and the task.
These do not require an active connection, however they do at least require you to be authenticated.
login : { url : String, code : String } -> (Result Http.Error () -> msg) -> Platform.Cmd.Cmd msg
Login to an urbit without maintaining an active connection. This will allow for stateless scry and spider requests that require authentication, but not others.
Note: This is not required if you have already used connect to authenticate.
scry : { url : String, app : String, path : String, mark : String, decoder : Json.Decode.Decoder a } -> (Result Http.Error a -> msg) -> Platform.Cmd.Cmd msg
Make a scry request.
spider : { url : String, desk : String, inputMark : String, outputMark : String, threadName : String, body : Json.Encode.Value, decoder : Json.Decode.Decoder output } -> (Result Http.Error output -> msg) -> Platform.Cmd.Cmd msg
Start a thread and get the response.
genChannelId : Time.Posix -> Random.Generator String
Recommended way to create a unique id for a session's channel. Takes the current time and returns a random generator which can then be used to generate the full ID.
genUid : Random.Generator String
Helper for generating random urbit UIDs.
Based off of https://github.com/urbit/urbit/blob/137e4428f617c13f28ed31e520eff98d251ed3e9/pkg/interface/src/lib/util.js#L3