-module(wist). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/wist.gleam"). -export([raw_codec/0, handler/2, get_init_state/1, get_update/1]). -export_type([context/0, close_frame/0, close_reason/0, decode_error/0, encode_error/0, socket_error/0, frame/0, event/1, effect/1, codec/2, handler/3]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC( " Wist provides a transport-neutral, stateful WebSocket programming model for Gleam.\n" "\n" " This module contains the core data structures, codecs, events, effects, and handler\n" " constructors. It represents the \"port\" in Wist's ports-and-adapters architecture,\n" " defining the API interface that developers use to write WebSocket connection logic.\n" "\n" " Transports (like the Mist web server) consume the `Handler` defined here and run it\n" " using a specific transport adapter (e.g. `wist/adapters/mist`).\n" ). -type context() :: {context, binary(), list({binary(), binary()}), gleam@option:option(binary())}. -type close_frame() :: {close_frame, integer(), binary()}. -type close_reason() :: normal | {abnormal, binary()} | unknown. -type decode_error() :: {decode_error, binary()}. -type encode_error() :: {encode_error, binary()}. -type socket_error() :: {socket_error, binary()}. -type frame() :: {text, binary()} | {binary, bitstring()} | {ping, bitstring()} | {pong, bitstring()} | {close, gleam@option:option(close_frame())}. -type event(MZX) :: opened | {message, MZX} | {closed, close_reason()} | {failed, socket_error()}. -type effect(MZY) :: {send, MZY} | {send_frame, frame()} | {close_connection, gleam@option:option(close_frame())}. -type codec(MZZ, NAA) :: {codec, fun((frame()) -> {ok, MZZ} | {error, decode_error()}), fun((NAA) -> {ok, frame()} | {error, encode_error()})}. -opaque handler(NAB, NAC, NAD) :: {handler, fun((context()) -> NAB), fun((NAB, event(NAC)) -> {NAB, list(effect(NAD))})}. -file("src/wist.gleam", 127). ?DOC( " A no-op codec that maps raw `Frame`s directly to and from themselves.\n" "\n" " Useful for handlers that process raw text or binary frames directly.\n" "\n" " ### Example\n" " ```gleam\n" " import wist\n" "\n" " let codec = wist.raw_codec()\n" " ```\n" ). -spec raw_codec() -> codec(frame(), frame()). raw_codec() -> {codec, fun(Frame) -> {ok, Frame} end, fun(Frame@1) -> {ok, Frame@1} end}. -file("src/wist.gleam", 162). ?DOC( " Constructor to create a stateful WebSocket handler.\n" "\n" " The handler defines:\n" " 1. `init_state`: How to construct the connection state from the `Context`.\n" " 2. `update`: A pure reducer mapping state and events to state transitions and effects.\n" "\n" " ### Example\n" " ```gleam\n" " import wist\n" "\n" " let echo = wist.handler(\n" " init_state: fn(_ctx) { Nil },\n" " update: fn(state, event) {\n" " case event {\n" " wist.Message(frame) -> #(state, [wist.SendFrame(frame)])\n" " _ -> #(state, [])\n" " }\n" " }\n" " )\n" " ```\n" ). -spec handler( fun((context()) -> NAG), fun((NAG, event(NAH)) -> {NAG, list(effect(NAJ))}) ) -> handler(NAG, NAH, NAJ). handler(Init_state, Update) -> {handler, Init_state, Update}. -file("src/wist.gleam", 172). ?DOC(false). -spec get_init_state(handler(NAP, any(), any())) -> fun((context()) -> NAP). get_init_state(Handler) -> erlang:element(2, Handler). -file("src/wist.gleam", 181). ?DOC(false). -spec get_update(handler(NAV, NAW, NAX)) -> fun((NAV, event(NAW)) -> {NAV, list(effect(NAX))}). get_update(Handler) -> erlang:element(3, Handler).