omnimessage_server
Types
pub opaque type ComposedApp(
flags,
model,
msg,
encoding,
decode_error,
)
Holds decode and encode functions for omnimessage messages. Decode errors will be called back for you to handle, while Encode errors are interpreted as “skip this message” – no error will be raised for them and they won’t be sent over.
Since an EncoderDecoder
is expected to receive the whole message type of
an application, but usually will ignore messages that aren’t shared, it’s
best to define it as a thin wrapper around shared encoders/decoders:
// Holds shared message types, encoders and decoders
import shared
let encoder_decoder =
EncoderDecoder(
fn(msg) {
case msg {
// Messages must be encodable
ClientMessage(message) -> Ok(shared.encode_client_message(message))
// Return Error(Nil) for messages you don't want to send out
_ -> Error(Nil)
}
},
fn(encoded_msg) {
// Unsupported messages will cause TransportError(DecodeError(error))
shared.decode_server_message(encoded_msg)
|> result.map(ServerMessage)
},
)
pub type EncoderDecoder(msg, encoding, decode_error) {
EncoderDecoder(
encode: fn(msg) -> Result(encoding, Nil),
decode: fn(encoding) -> Result(msg, decode_error),
)
}
Constructors
-
EncoderDecoder( encode: fn(msg) -> Result(encoding, Nil), decode: fn(encoding) -> Result(msg, decode_error), )
Functions
pub fn application(
init: fn(a) -> #(b, Effect(c)),
update: fn(b, c) -> #(b, Effect(c)),
encoder_decoder: EncoderDecoder(c, d, e),
) -> ComposedApp(a, b, c, d, e)
This creates a version of a Lustre application that can be used in
omnimessage_server.start_actor
(see below). A view is not necessary, as
this application will never render anything.
pub fn dispatch(message: a) -> Action(a, b)
Dispatch a message to a running application’s update
function.
pub fn mist_websocket_application(
req: Request(Connection),
app: ComposedApp(a, b, c, String, d),
flags: a,
on_error: fn(d) -> Nil,
) -> Response(ResponseData)
A mist websocket handler to automatically responsd to omnimessage messages
via a Lustre server component. The server component can then be used
similarly to one created by an omnimessage_lustre
and handle the messages
via update, dispatch, and effects.
Return this as a response to the websocket init request.
req
The mist requestapp
An application created withomnimessage_server.application
flags
Flags to hand to the application’sinit
on_error
For handling decode errors
See a full example using this in the Readme or in the examples folder.
pub fn mist_websocket_pipe(
req: Request(Connection),
encoder_decoder: EncoderDecoder(a, String, b),
handler: fn(a) -> a,
on_error: fn(b) -> Nil,
) -> Response(ResponseData)
A mist websocket handler to automatically responsd to omnimessage messages.
Return this as a response to the websocket init request.
req
The mist requestencoder_decoder
For encoding and decoding messageshandler
For handling the incoming messageson_error
For handling decode errors
See a full example using this in the Readme or in the examples folder.
pub fn pipe(
msg: a,
encoder_decoder: EncoderDecoder(b, a, c),
handler: fn(b) -> b,
) -> Result(Option(a), c)
A utility function for easily handling messages:
let out_msg = pipe(in_msg, encoder_decoder, handler)
pub fn start_actor(
app: ComposedApp(a, b, c, d, e),
with flags: a,
) -> Result(Subject(Action(c, ServerComponent)), Error)
This is a beefed up version of lustre.start_actor
that allows subscribing
to messages dispatched inside the runtime.
This is what enables using a Lustre server component for communication,
powering mist_websocket_application()
below.
pub fn subscribe(
id: String,
dispatch: fn(a) -> Nil,
) -> Action(a, b)
This action subscribes to updates in a running application.
pub fn wisp_http_middleware(
req: Request(Connection),
path: String,
encoder_decoder: EncoderDecoder(a, String, b),
handler: fn(a) -> a,
fun: fn() -> Response(Body),
) -> Response(Body)
A wisp middleware to automatically handle HTTP POST omnimessage messages.
req
The wisp requestpath
The path to which messages are POSTedencoder_decoder
For encoding and decoding messageshandler
For handling the incoming messages
See a full example using this in the Readme or in the examples folder.