Public API for Supabase Realtime: WebSocket-based postgres_changes, broadcast, and presence subscriptions.
(require '[supabase.core.client :as sc]
'[supabase.realtime :as rt])
(def client (sc/make-client "https://abc.supabase.co" "anon-key"))
(def conn (rt/connect client {:on-error println}))
(def ch (rt/channel conn "room:lobby"
{:config {:broadcast {:self false}}}))
(rt/on ch :postgres-changes
{:event :insert :schema "public" :table "users"}
(fn [payload] (println "row" payload)))
(rt/on ch :broadcast {:event "typing"}
(fn [payload] (println "typing" payload)))
(rt/subscribe ch)
(rt/broadcast ch "typing" {:user "alice"})
(rt/track ch {:online_at (System/currentTimeMillis)})
(rt/unsubscribe ch)
(rt/disconnect conn)
In: postgres_changes, broadcast send/receive, basic presence,
manual set-auth, heartbeat, multi-channel per connection.
Out (deferred): auto-reconnect, broadcast ack/wait_for_ack, HTTP fallback, binary v2 protocol, exponential backoff, auto token refresh.
Public API for Supabase Realtime: WebSocket-based postgres_changes,
broadcast, and presence subscriptions.
## Quick start
(require '[supabase.core.client :as sc]
'[supabase.realtime :as rt])
(def client (sc/make-client "https://abc.supabase.co" "anon-key"))
(def conn (rt/connect client {:on-error println}))
(def ch (rt/channel conn "room:lobby"
{:config {:broadcast {:self false}}}))
(rt/on ch :postgres-changes
{:event :insert :schema "public" :table "users"}
(fn [payload] (println "row" payload)))
(rt/on ch :broadcast {:event "typing"}
(fn [payload] (println "typing" payload)))
(rt/subscribe ch)
(rt/broadcast ch "typing" {:user "alice"})
(rt/track ch {:online_at (System/currentTimeMillis)})
(rt/unsubscribe ch)
(rt/disconnect conn)
## v0.1.0 scope
In: postgres_changes, broadcast send/receive, basic presence,
manual `set-auth`, heartbeat, multi-channel per connection.
Out (deferred): auto-reconnect, broadcast ack/wait_for_ack, HTTP fallback,
binary v2 protocol, exponential backoff, auto token refresh.WebSocket connection lifecycle for Supabase Realtime.
Holds a single hato-backed WebSocket per connect call. State lives in
one atom; mutation goes through swap!; user callbacks run outside the
swap to avoid running user code under contention.
The Transport protocol is the test seam — tests substitute a recording
transport (see realtime_test) without redefining hato internals.
WebSocket connection lifecycle for Supabase Realtime. Holds a single hato-backed WebSocket per `connect` call. State lives in one atom; mutation goes through `swap!`; user callbacks run outside the swap to avoid running user code under contention. The `Transport` protocol is the test seam — tests substitute a recording transport (see `realtime_test`) without redefining hato internals.
Phoenix Channel v1.0.0 JSON wire protocol for Supabase Realtime.
Pure builders + parser. No I/O, no state. The connection module composes these into a transport-bound conversation.
{:topic "realtime:room:lobby"
:event "phx_join"
:payload {...}
:ref "1"
:join_ref "1"} ; only on channel-bound messages
event-kind returns one of:
:phx-reply :phx-close :phx-error
:postgres-changes :broadcast
:presence-state :presence-diff
:system :heartbeat-reply :unknown
Phoenix Channel v1.0.0 JSON wire protocol for Supabase Realtime.
Pure builders + parser. No I/O, no state. The connection module composes
these into a transport-bound conversation.
## Frame shape
{:topic "realtime:room:lobby"
:event "phx_join"
:payload {...}
:ref "1"
:join_ref "1"} ; only on channel-bound messages
## Event kinds
`event-kind` returns one of:
:phx-reply :phx-close :phx-error
:postgres-changes :broadcast
:presence-state :presence-diff
:system :heartbeat-reply :unknownMalli schemas for Supabase Realtime API inputs.
Validates caller arguments only. Server payloads pass through unchecked — postgres column data is user-defined and shouldn't be gated.
Malli schemas for Supabase Realtime API inputs. Validates caller arguments only. Server payloads pass through unchecked — postgres column data is user-defined and shouldn't be gated.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |