strata_server/codec
Strata wire codec for beryl.
Translates strata's flat {"v":0,"kind":"...",...} JSON envelope
into beryl's normalised Inbound shape (topic + structural kind +
payload) and back out as encoded server frames.
The codec is the only place that knows about the kind ↔ event and
doc ↔ topic mappings. Channel handlers in the server see beryl's
usual (event, payload, socket) arguments.
Mapping:
| Client kind | Topic | Inbound kind |
|---|---|---|
| join | doc: | Join |
| leave | doc: | Leave |
| delta | doc: | Event("strata.delta") |
| create | doc: | Event("strata.create") |
| delete | doc: | Event("strata.delete") |
| presence_set | doc: | Event("strata.presence_set") |
| admin_status | admin:status | Join |
| ping | "_strata" | Heartbeat |
For create and delete, <doc> is the parent document id. The
channel handler extracts the child id from the payload.
The payload carried in the Inbound is the whole decoded JSON
frame as a Dynamic; handlers extract the fields they need (for
example state for a delta) using gleam/dynamic/decode.
Server-initiated outbound frames are encoded directly as
strata_protocol/server JSON. The codec's encode_push /
encode_reply ignore beryl's topic + event arguments because the
strata wire shape carries kind (and doc when needed) itself —
channel handlers must hand a fully-formed strata server frame as the
payload argument. The one exception is the presence_diff push
that beryl's runtime emits on its own: its Phoenix-shaped diff is
wrapped verbatim in a strata presence_diff envelope, with doc
derived from the topic. Replies that beryl's runtime generates itself
(for example {"reason": "invalid_topic"} for an unroutable join)
are not strata frames; encode_reply wraps those in a strata
error frame so clients never see a foreign shape.
Legacy frames have no refs and receive pushes. Opt-in mutations use
request_id as beryl's reply ref; handlers resolve it with a correlated
operation receipt. Runtime errors retain that correlation too.
Constants
Section titled “Constants”admin_status_topic
Section titled “admin_status_topic”Dedicated admin status topic.
pub const admin_status_topic: Stringdocument_topic_prefix
Section titled “document_topic_prefix”Topic prefix for per-document channels. Concrete topics look like
doc:abc-123.
pub const document_topic_prefix: Stringevent_create
Section titled “event_create”Event name for client create frames.
pub const event_create: Stringevent_delete
Section titled “event_delete”Event name for client delete frames.
pub const event_delete: Stringevent_delta
Section titled “event_delta”Event name for client delta frames.
pub const event_delta: Stringevent_presence_set
Section titled “event_presence_set”Event name for client presence_set frames.
pub const event_presence_set: Stringmeta_topic
Section titled “meta_topic”Special topic used for connection-level frames (currently just ping).
pub const meta_topic: Stringruntime_presence_diff_event
Section titled “runtime_presence_diff_event”Event name beryl's runtime uses for the presence diffs it broadcasts.
pub const runtime_presence_diff_event: StringFunctions
Section titled “Functions”Build the strata codec value to pass to beryl.config(codec).
pub fn codec() -> codec.Codecdocument_id
Section titled “document_id”Extract the document id from a doc:<id> topic.
pub fn document_id(String) -> Result(String, Nil)document_topic
Section titled “document_topic”Build the topic name for a document id.
pub fn document_topic(String) -> String