Socket.IO event frames
Encode and decode text packets shaped like 42["event", ...args].
windsock.encode("submitOp", [json.string("client-1")]) Gleam primitives for text-frame boundaries
windsock encodes and decodes the text packets your higher-level protocol already knows how to name. It handles the frame shape; you keep ownership of schemas, sessions, transports, and application vocabulary.
Scope
windsock is intentionally narrow. It does not implement namespaces, binary attachments, ACK packet ids, Engine.IO transport negotiation, reconnection, or a full Socket.IO client/server. Those choices stay above this layer.
Primitives
Encode and decode text packets shaped like 42["event", ...args].
windsock.encode("submitOp", [json.string("client-1")]) Keep event arguments dynamic so callers decode with their own schema.
Incoming(event: String, args: List(Dynamic)) Expose ping and pong packets without owning transport negotiation.
windsock.ping == "2" && windsock.pong == "3" Quick start
import gleam/json
import windsock
pub fn frame() {
windsock.encode("submitOp", [
json.string("client-1"),
json.preprocessed_array([]),
])
} case windsock.decode("42[\"op\",\"c1\"]") {
Ok(incoming) -> incoming.event
Error(windsock.InvalidFormat(reason)) -> reason
Error(windsock.InvalidJson(reason)) -> reason
} API semantics
encode(event, args) returns a 42[...] event packet.encode_heartbeat() returns the Engine.IO ping packet.decode(text) returns Result(Incoming, DecodeError).InvalidJsonInvalidFormat