strata_client
strata_client — sans-IO client state machine for Strata.
This package is transport-agnostic. It provides:
Connection— opaque state holding which documents are joined and whether the serverwelcomeframe has been received.outbound/2— given aCommand, produces the JSON bytes the caller must send over the WebSocket.inbound/2— feeds a received text frame in; returns the updatedConnectionand a typedEvent(or aStepErrorif the frame could not be decoded).frames_for_resume/1— after a reconnect, returns the list of bytes needed to re-join every previously joined document.
The caller wires this state machine to a real WebSocket — browser
WebSocket, gun, mist, or any other transport. There is no
FFI inside this package, so it compiles unchanged on both the
Erlang/BEAM and JavaScript targets.
Command
Section titled “Command”Things the caller can ask the connection to do.
pub type Command { Join(document_id: String) Leave(document_id: String) SendDelta(document_id: String, state: json.Json) SendPresence(document_id: String, payload: json.Json) Create(parent: String, child: String, child_state: json.Json, parent_state: json.Json) Delete(parent: String, child: String, parent_state: json.Json) SendPing}Join(document_id: String)
Section titled “Join(document_id: String)”Subscribe to a document.
Leave(document_id: String)
Section titled “Leave(document_id: String)”Unsubscribe from a document.
SendDelta(document_id: String, state: json.Json)
Section titled “SendDelta(document_id: String, state: json.Json)”Push a new CRDT state for a document. state is opaque JSON
produced by the caller's CRDT layer.
SendPresence(document_id: String, payload: json.Json)
Section titled “SendPresence(document_id: String, payload: json.Json)”Push a presence update for a document.
Create(parent: String, child: String, child_state: json.Json, parent_state: json.Json)
Section titled “Create(parent: String, child: String, child_state: json.Json, parent_state: json.Json)”Create child under parent, merging parent_state into the
parent document in the same server-side operation. child_state
and parent_state are opaque JSON produced by the caller's CRDT
layer.
Delete(parent: String, child: String, parent_state: json.Json)
Section titled “Delete(parent: String, child: String, parent_state: json.Json)”Delete child (and its descendants) from parent, merging
parent_state into the parent document in the same server-side
operation.
SendPing
Section titled “SendPing”Liveness probe.
Connection
Section titled “Connection”Opaque connection state.
pub type ConnectionThings the server tells the client about.
pub type Event { Welcomed(session_id: String, server: String) Snapshot(document_id: String, state: dynamic.Dynamic) Deleted(document_id: String) RemoteDelta(document_id: String, state: dynamic.Dynamic, from: String) PresenceState(document_id: String, presences: List(presence.Presence)) PresenceDiff(document_id: String, joins: List(presence.Presence), leaves: List(presence.Presence)) ServerError(code: String, message: String) Pong}Deleted(document_id: String)
Section titled “Deleted(document_id: String)”document_id (and its descendants) was deleted server-side. The
document id is
removed from joined so a subsequent reconnect does not rejoin it.
StepError
Section titled “StepError”Anything that can go wrong while feeding bytes in.
pub type StepError { ProtocolError(error: error.DecodeError)}Functions
Section titled “Functions”frames_for_resume
Section titled “frames_for_resume”After a reconnect, returns the bytes needed to re-join every
document that was joined before the disconnect. The joined set is
preserved in the returned Connection so the caller can keep using
the same instance.
pub fn frames_for_resume(Connection) -> #(Connection, List(String))inbound
Section titled “inbound”Feed a received text frame in. Returns the updated connection plus
the decoded event, or a StepError if the frame is malformed.
pub fn inbound( Connection, String) -> Result(#(Connection, Event), StepError)is_welcomed
Section titled “is_welcomed”True once the server has sent its welcome frame.
pub fn is_welcomed(Connection) -> Booljoined_documents
Section titled “joined_documents”The set of documents this connection has joined (and not yet left).
pub fn joined_documents(Connection) -> List(String)Build a fresh connection state. Call once per WebSocket session;
after a reconnect, call new() again or use the existing instance
with frames_for_resume to resubscribe.
pub fn new() -> Connectionoutbound
Section titled “outbound”Apply a command: returns the updated Connection plus the bytes
the caller must send over the WebSocket.
pub fn outbound( Connection, Command) -> #(Connection, String)protocol_version
Section titled “protocol_version”The wire protocol version this client speaks.
pub fn protocol_version() -> Intserver_id
Section titled “server_id”Server identification string from the welcome frame, or None.
pub fn server_id(Connection) -> option.Option(String)session_id
Section titled “session_id”The server-assigned session id for this connection, or None if the
welcome frame has not arrived yet.
pub fn session_id(Connection) -> option.Option(String)