Skip to content

Instantly share code, notes, and snippets.

@Ramblurr
Created May 20, 2025 14:14
Show Gist options
  • Save Ramblurr/3cd94cae77b8a984d738f5f3a75dacc7 to your computer and use it in GitHub Desktop.
Save Ramblurr/3cd94cae77b8a984d738f5f3a75dacc7 to your computer and use it in GitHub Desktop.
(defn render-handler
"A default http-kit ring handler for rendering views over a long-lived SSE connection with datastar.
- `render-fn` is an arity-1 function of req that returns a string of HTML sent to the client with D*'s merge-fragment
Opts are:
- `init-tab-state-fn` is an arity-1 pure-function of state and returns the initialized state.
On a first-connect/refresh the state will be nil, but on an SSE reconnect the state will be whatever
the state was before the disconnect.
This handler is a basic implementation, if you outgrow it, copy and paste it into your codebase to extend it."
([render-fn]
(render-handler render-fn nil))
([render-fn {:keys [init-tab-state-fn]}]
(let [init-tab-state-fn (or init-tab-state-fn #(identity %2))]
(fn [req]
(let [ctx (datastar/long-lived-render-setup req render-fn)
first-tab-state (tab-state/init-tab-state! req (:hifi.datastar/<render ctx) #(init-tab-state-fn req %))
req (assoc req :hifi.datastar/tab-state first-tab-state)]
(hk-gen/->sse-response req
{:headers {}
hk-gen/on-open (fn [sse-gen]
(datastar/long-lived-render-on-open ctx req sse-gen))
hk-gen/on-close (fn [_ _]
(datastar/long-lived-render-on-close ctx))
d*com/write-profile (datastar/brotli-write-profile)}))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment