wist

Wist provides a transport-neutral, stateful WebSocket programming model for Gleam.

This module contains the core data structures, codecs, events, effects, and handler constructors. It represents the “port” in Wist’s ports-and-adapters architecture, defining the API interface that developers use to write WebSocket connection logic.

Transports (like the Mist web server) consume the Handler defined here and run it using a specific transport adapter (e.g. wist/adapters/mist).

Types

Represents the WebSocket close code and close reason payload sent on the wire.

Under the hood, close frames are encoded with a 16-bit status code and an optional UTF-8 string payload.

pub type CloseFrame {
  CloseFrame(code: Int, reason: String)
}

Constructors

  • CloseFrame(code: Int, reason: String)

    Arguments

    code

    The 16-bit WebSocket status code (e.g. 1000 for normal closure).

    reason

    The human-readable reason payload.

Represents the classification of why a WebSocket connection closed.

pub type CloseReason {
  Normal
  Abnormal(String)
  Unknown
}

Constructors

  • Normal

    The connection closed cleanly via a normal close handshake.

  • Abnormal(String)

    The connection closed due to a protocol violation, crash, or transport-level error.

  • Unknown

    The connection closed without a clear code or details.

A Codec specifies how to serialize and deserialize messages.

It translates raw wire Frames to typed inbound messages, and typed outbound messages back to raw Frames.

pub type Codec(inbound, outbound) {
  Codec(
    decode: fn(Frame) -> Result(inbound, DecodeError),
    encode: fn(outbound) -> Result(Frame, EncodeError),
  )
}

Constructors

A transport-neutral representation of the HTTP WebSocket handshake request.

It contains connection-specific metadata that is available before the connection is upgraded.

Use Context to extract authentication tokens from headers, route based on path, or load initial configuration parameters.

pub type Context {
  Context(
    path: String,
    headers: List(#(String, String)),
    query: option.Option(String),
  )
}

Constructors

  • Context(
      path: String,
      headers: List(#(String, String)),
      query: option.Option(String),
    )

    Arguments

    path

    The HTTP path of the WebSocket request (e.g., "/ws").

    headers

    A list of HTTP request headers sent by the client during upgrade.

    query

    The raw query string, if present (e.g., Some("token=xyz")).

Represents an error encountered while decoding a raw WebSocket frame.

pub type DecodeError {
  DecodeError(String)
}

Constructors

  • DecodeError(String)

Represents output actions or side-effects returned by the handler’s reducer.

pub type Effect(message) {
  Send(message)
  SendFrame(Frame)
  CloseConnection(option.Option(CloseFrame))
}

Constructors

  • Send(message)

    Encode and send a typed application message to the client.

  • SendFrame(Frame)

    Send a raw WebSocket data frame directly to the client.

  • CloseConnection(option.Option(CloseFrame))

    Initiate the WebSocket close handshake carrying optional close metadata.

Represents an error encountered while encoding an application message.

pub type EncodeError {
  EncodeError(String)
}

Constructors

  • EncodeError(String)

Represents connection lifecycle and message events dispatched to Handler.update.

pub type Event(message) {
  Opened
  Message(message)
  Closed(CloseReason)
  Failed(SocketError)
}

Constructors

  • Opened

    Dispatched exactly once when the connection has been successfully established. Generate any initial welcome messages or startup pushes here.

  • Message(message)

    Dispatched when a new application message is successfully received and decoded.

  • Closed(CloseReason)

    Dispatched when the connection closes. This is a terminal event; any returned effects will be ignored by the runtime.

  • Failed(SocketError)

    Dispatched when a socket or protocol failure occurs. This is a terminal event.

Represents all standard WebSocket frame types defined by RFC-6455.

pub type Frame {
  Text(String)
  Binary(BitArray)
  Ping(BitArray)
  Pong(BitArray)
  Close(option.Option(CloseFrame))
}

Constructors

  • Text(String)

    A UTF-8 text data frame.

  • Binary(BitArray)

    A binary data frame.

  • Ping(BitArray)

    A control Ping frame carrying a raw payload.

  • Pong(BitArray)

    A control Pong frame carrying a raw payload.

  • A control Close frame indicating connection shutdown.

A stateful WebSocket handler that manages its own state and responds to events.

Handlers are opaque to ensure binary compatibility and prevent external code from directly reading or mutating the handler’s transitions. Create them using handler.

pub opaque type Handler(state, inbound, outbound)

Represents physical socket or TCP/SSL transport failures.

pub type SocketError {
  SocketError(String)
}

Constructors

  • SocketError(String)

Values

pub fn handler(
  init_state init_state: fn(Context) -> state,
  update update: fn(state, Event(inbound)) -> #(
    state,
    List(Effect(outbound)),
  ),
) -> Handler(state, inbound, outbound)

Constructor to create a stateful WebSocket handler.

The handler defines:

  1. init_state: How to construct the connection state from the Context.
  2. update: A pure reducer mapping state and events to state transitions and effects.

Example

import wist

let echo = wist.handler(
  init_state: fn(_ctx) { Nil },
  update: fn(state, event) {
    case event {
      wist.Message(frame) -> #(state, [wist.SendFrame(frame)])
      _ -> #(state, [])
    }
  }
)
pub fn raw_codec() -> Codec(Frame, Frame)

A no-op codec that maps raw Frames directly to and from themselves.

Useful for handlers that process raw text or binary frames directly.

Example

import wist

let codec = wist.raw_codec()
Search Document