diff --git a/examples/hello-httpkit/README.md b/examples/hello-httpkit/README.md new file mode 100644 index 0000000..cb1cdb8 --- /dev/null +++ b/examples/hello-httpkit/README.md @@ -0,0 +1,15 @@ +# A Datastar + http-kit starter + +## Running the example + +- repl: + +``` +clojure -M:repl -m nrepl.cmdline --middleware "[cider.nrepl/cider-middleware]" +``` + +- main: + +``` +clojure -M -m hello-httpkit +``` diff --git a/examples/hello-httpkit/deps.edn b/examples/hello-httpkit/deps.edn new file mode 100644 index 0000000..04873e1 --- /dev/null +++ b/examples/hello-httpkit/deps.edn @@ -0,0 +1,11 @@ +{:paths ["src" "resources"] + :deps {com.cnuernber/charred {:mvn/version "1.034"} + dev.data-star.clojure/http-kit {:local/root "../../sdk-adapter-http-kit"} + dev.data-star.clojure/sdk {:local/root "../../sdk"} + dev.onionpancakes/chassis {:mvn/version "1.0.365"} + http-kit/http-kit {:mvn/version "2.8.1"} + metosin/reitit {:mvn/version "0.7.2"}} + :aliases + {:repl {:extra-deps {org.clojure/clojure {:mvn/version "1.12.0"} + nrepl/nrepl {:mvn/version "1.3.0"} + cider/cider-nrepl {:mvn/version "0.50.2"}}}}} diff --git a/examples/hello-httpkit/resources/hello-world.html b/examples/hello-httpkit/resources/hello-world.html new file mode 100644 index 0000000..9aa2d8e --- /dev/null +++ b/examples/hello-httpkit/resources/hello-world.html @@ -0,0 +1,33 @@ + + + + Datastar SDK Demo + + + + +
+
+

+ Datastar SDK Demo +

+ Rocket +
+

+ SSE events will be streamed from the backend to the frontend. +

+
+ + +
+ +
+
+
Hello, world!
+
+ + diff --git a/examples/hello-httpkit/src/hello_httpkit.clj b/examples/hello-httpkit/src/hello_httpkit.clj new file mode 100644 index 0000000..3b4c68c --- /dev/null +++ b/examples/hello-httpkit/src/hello_httpkit.clj @@ -0,0 +1,86 @@ +(ns hello-httpkit + (:require + [charred.api] + [clojure.java.io :as io] + [dev.onionpancakes.chassis.compiler :as hc] + [dev.onionpancakes.chassis.core :as h] + [org.httpkit.server] + [reitit.ring.middleware.parameters] + [reitit.ring] + [ring.util.response] + [starfederation.datastar.clojure.adapter.http-kit :refer [->sse-response on-open]] + [starfederation.datastar.clojure.api :as d*])) + +(def read-json (charred.api/parse-json-fn {:async? false :bufsize 1024})) + +(defn get-signals [req] + (-> req d*/get-signals read-json)) + +(def home-page + (slurp (io/resource "hello-world.html"))) + +(defn home [_] + (-> home-page + (ring.util.response/response) + (ring.util.response/content-type "text/html"))) + +(def message "Hello, world!") + +(defn ->frag [i] + (h/html + (hc/compile + [:div {:id "message"} + (subs message 0 (inc i))]))) + +(defn hello-world [request] + (let [d (-> request get-signals (get "delay") int)] + (->sse-response request + {on-open + (fn [sse] + (d*/with-open-sse sse + (dotimes [i (count message)] + (d*/patch-elements! sse (->frag i)) + (Thread/sleep d))))}))) + +(def routes + [["/" {:handler home}] + ["/hello-world" {:handler hello-world + :middleware [reitit.ring.middleware.parameters/parameters-middleware]}]]) + +(def router (reitit.ring/router routes)) + +(def handler (reitit.ring/ring-handler router)) + +;; ------------------------------------------------------------ +;; Server +;; ------------------------------------------------------------ +(defonce !server (atom nil)) + +(defn stop! [] + (if-let [s @!server] + (do (org.httpkit.server/server-stop! s) + (reset! !server nil)) + (throw (ex-info "Server not running" {})))) + +(defn start! [handler opts] + (when-not (nil? @!server) + (stop!)) + (reset! !server + (org.httpkit.server/run-server + handler + (merge {:port 8080} + opts + {:legacy-return-value? false})))) + +(comment + (stop!) + (start! #'handler {}) + ) + +;; ------------------------------------------------------------ +;; Main +;; ------------------------------------------------------------ +(defn -main [& _] + (start! #'handler {:port 8080}) + (.addShutdownHook (Runtime/getRuntime) + (Thread. #(do (stop!) (shutdown-agents)))))