Skip to content

beryl/wire

Phoenix wire protocol: encoding and decoding helpers and the canonical phoenix_codec() for beryl/wire/codec.

Phoenix uses a JSON array format: [join_ref, ref, topic, event, payload]. This module parses and emits that format, and exposes a Codec value that plugs the Phoenix framing into the runtime.

Phoenix framing must be selected explicitly when constructing beryl:

beryl.config(wire.phoenix_codec())
pub type BinaryEncodeError {
MetadataTooLong(
component: String,
byte_size: Int
)
}

An error returned when encoding a Phoenix binary frame.

MetadataTooLong(
component: String,
byte_size: Int
)

A metadata component is too large for the protocol's one-byte length.

pub fn binary_broadcast(
topic: String,
event: String,
payload: BitArray
) -> Result(codec.Frame, BinaryEncodeError)

Encode a Phoenix V2 binary broadcast: (topic, event, payload).

Returns Error(MetadataTooLong(component, byte_size)) when a metadata component exceeds the framing's 255-byte limit.

pub fn binary_push(
join_ref: option.Option(String),
topic: String,
event: String,
payload: BitArray
) -> Result(codec.Frame, BinaryEncodeError)

Encode a Phoenix V2 binary server push: (join_ref, topic, event, payload).

Returns Error(MetadataTooLong(component, byte_size)) when a metadata component exceeds the framing's 255-byte limit.

pub fn binary_reply(
join_ref: option.Option(String),
ref: option.Option(String),
topic: String,
status: codec.ReplyStatus,
payload: BitArray
) -> Result(codec.Frame, BinaryEncodeError)

Encode a Phoenix V2 binary reply: (join_ref, ref, topic, status, payload).

Returns Error(MetadataTooLong(component, byte_size)) when a metadata component exceeds the framing's 255-byte limit.

pub fn channel_close(
option.Option(String),
String
) -> codec.Frame

Create a Phoenix phx_close frame for a normal channel termination.

Phoenix copies the channel's join_ref to the ref slot.

pub fn channel_error(
option.Option(String),
String
) -> codec.Frame

Create a Phoenix phx_error frame for an abnormal channel termination.

Phoenix clients respond by scheduling an automatic rejoin.

pub fn decode_binary_message(BitArray) -> Result(codec.Inbound, codec.DecodeError)

Decode a Phoenix V2 binary push frame from a client into an Inbound.

The payload remains a BitArray wrapped in Dynamic. The decoded frame follows normal event classification and reaches the app as a Join or Message event rather than Binary. Decode the payload with gleam/dynamic/decode.bit_array if needed. Zero-length join_ref and ref components decode as None. Reserved protocol events use the same classification as text frames.

pub fn decode_message(String) -> Result(codec.Inbound, codec.DecodeError)

Parse a JSON string into an Inbound.

Expected format: [join_ref, ref, topic, event, payload]. The join_ref and ref values can be null.

pub fn dynamic_to_json(dynamic.Dynamic) -> Result(json.Json, Nil)

Convert a Dynamic value decoded from JSON back to json.Json.

Returns Error(Nil) when the value exceeds the wire protocol's maximum JSON depth or contains a value that JSON cannot represent.

pub fn encode(codec.Inbound) -> Result(String, Nil)

Encode an Inbound as a Phoenix wire JSON string.

Returns Error(Nil) when the payload contains a value JSON cannot represent or exceeds the wire protocol's maximum JSON nesting depth. Conversion failures are not replaced with JSON null: a successful encoding preserves the payload.

pub fn format_decode_error(codec.DecodeError) -> String

Format a DecodeError as a human-readable string.

pub fn heartbeat_reply(option.Option(String)) -> codec.Frame

Create a Phoenix heartbeat reply.

pub fn phoenix_codec() -> codec.Codec

Return the canonical Phoenix wire codec.

Pass this codec to beryl.config.

The codec handles JSON array framing on text frames and Phoenix V2 binary framing on binary frames (see decode_binary_message). Decoded binary frames follow the normal inbound path, producing Join or Message events according to their event name. The app receives a Binary event only for an undecoded frame from a codec without a binary decoder.

pub fn push(
String,
String,
json.Json
) -> codec.Frame

Create a server-initiated push message.

pub fn reply_json(
option.Option(String),
option.Option(String),
String,
codec.ReplyStatus,
json.Json
) -> codec.Frame

Create a Phoenix phx_reply JSON string.