HTTP client, WebSocket, signal bus
HTTP client, WebSocket, signal bus, in the reference of the Soma programming language (soma 3.2.4). A block marked ✓ is a whole program that soma check accepts; the others are excerpts.
let resp = http_get(url, map("timeout", 2000)) // GET; JSON bodies auto-parse to Map/List
let resp = http_post(url, body, map("timeout", 2000)) // a Map/List body goes as JSON
// also http_put / http_patch (url, body, opts?) and http_delete(url, opts?)
// opts: timeout (ms, default 30000), max_bytes, headers: map("Authorization", "Bearer …")
let ws = ws_connect("ws://host:9001") // open WebSocket (send-only) → {status, url}
ws_send(message) // send text on the open WebSocket
subscribe("ws://host:9001/stream") // read-only WS: incoming {"event", "data"} → on event(data) when the program emits that event or soma.toml [bus] accept lists it; other text → on ws(msg); a dropped stream is reconnected (1 s, backing off to 30 s)
link("host:8082") // TCP signal-bus link: emits reach peer, peer EVENTs → handlers
publish("stream-name", data) // push to SSE subscribers on a runtime-chosen streamThe http builtins never raise. A 2xx answer is its body; anything else is {error, kind, status, body}: kind http_status (with the upstream status and its body, parsed when JSON), timeout, refused or network. Branch on resp.kind / resp.status, not on the text. Under soma serve the call holds the handler lock for its whole duration (handlers are serialized): keep timeouts short. In tests, mock http_post map(...) scripts the next call, mock http_get error "timeout: slow" a failure (status_404: … gives status 404); an unscripted real call prints a note. A List scripts several calls in order (mock http_get [1, 2] answers 1 then 2): to answer ONE call with a JSON array, nest it (mock http_get [[1, 2]]).