Connection checks
Validate tenant, document, expiration, and scope, then negotiate protocol versions and feature flags.

Typed protocol logic for Gleam and the BEAM
You keep your server. Spillway decides how Fluid protocol messages are ordered, accepted, rejected, and validated.

Your server owns sockets, storage, token issuance, and document lifetime.
Pure Gleam functions for sequencing, feature negotiation, signal routing, summaries, nacks, and JWT claim validation.
Clients receive ordered protocol messages while your server keeps its own runtime shape.
Connection rules, ordered operations, and protocol responses stay testable as pure Gleam functions.
Validate tenant, document, expiration, and scope, then negotiate protocol versions and feature flags.
Track connected clients, client sequence numbers, reference sequence numbers, and minimum sequence progression.
Build nacks, summary acks, summary nacks, sequenced ops, and routed signals from typed constructors.
Spillway keeps protocol decisions explicit: clients join, ops receive sequence numbers, claims are checked, and invalid operations become protocol nacks.
import spillwayimport spillway/sequencing
let state = spillway.new_sequence_state() |> spillway.client_join("client-7", 0)
let assert sequencing.SequenceOk(next_state, assigned_sn, minimum_sn) = spillway.assign_sequence_number(state, "client-7", 1, 0)
#(next_state, assigned_sn, minimum_sn)Spillway is intentionally small: Gleam stdlib plus JSON, ready to sit under a server layer that owns sockets, persistence, and deployment policy. Install it where protocol decisions need to stay explicit.
gleam add spillway