init commit
This commit is contained in:
commit
8a3f9fee9a
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
.nrepl-port
|
||||||
|
.cpcache
|
15
README.md
Normal file
15
README.md
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# Hello world example
|
||||||
|
|
||||||
|
## Running the example
|
||||||
|
|
||||||
|
- repl:
|
||||||
|
|
||||||
|
```
|
||||||
|
clj -A:repl
|
||||||
|
```
|
||||||
|
|
||||||
|
- main:
|
||||||
|
|
||||||
|
```
|
||||||
|
clojure -M -m example.main
|
||||||
|
```
|
22
deps.edn
Normal file
22
deps.edn
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{:paths ["src/main" "resources"]
|
||||||
|
|
||||||
|
:deps {
|
||||||
|
starfederation.datastar/sdk {:git/url "https://github.com/starfederation/datastar/"
|
||||||
|
:git/sha "376c4e2411706b942ea0ab937e4c6218d24fb30f"
|
||||||
|
:deps/root "sdk/clojure/sdk"}
|
||||||
|
starfederation.datastar/ring {:git/url "https://github.com/starfederation/datastar/"
|
||||||
|
:git/sha "376c4e2411706b942ea0ab937e4c6218d24fb30f"
|
||||||
|
:deps/root "sdk/clojure/adapter-ring"}
|
||||||
|
ring/ring-jetty-adapter {:mvn/version "1.13.0"}
|
||||||
|
metosin/reitit {:mvn/version "0.7.2"}
|
||||||
|
dev.onionpancakes/chassis {:mvn/version "1.0.365"}
|
||||||
|
com.cnuernber/charred {:mvn/version "1.034"}
|
||||||
|
org.clojure/data.json {:mvn/version "2.5.1"}}
|
||||||
|
|
||||||
|
:aliases
|
||||||
|
{:repl {:extra-paths ["src/dev"]
|
||||||
|
:extra-deps {org.clojure/clojure {:mvn/version "1.12.1"}
|
||||||
|
nrepl/nrepl {:mvn/version "1.3.0"}
|
||||||
|
cider/cider-nrepl {:mvn/version "0.50.2"}
|
||||||
|
io.github.tonsky/clj-reload {:mvn/version "0.7.1"}}
|
||||||
|
:main-opts ["-m" "nrepl.cmdline" "--middleware" "[cider.nrepl/cider-middleware]"]}}}
|
14
resources/public/index.html
Normal file
14
resources/public/index.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<!-- This is auto-generated by Datastar. DO NOT EDIT. -->
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>hello world d*</title>
|
||||||
|
<script src="https://unpkg.com/@tailwindcss/browser@4"></script>
|
||||||
|
<script type="module" src="https://cdn.jsdelivr.net/gh/starfederation/datastar@main/bundles/datastar.js"></script>
|
||||||
|
<!-- put css here -->
|
||||||
|
</head>
|
||||||
|
<body style="outline: solid; 1px; red">
|
||||||
|
%%content%%
|
||||||
|
</body>
|
||||||
|
</html>
|
21
src/dev/user.clj
Normal file
21
src/dev/user.clj
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
(ns user
|
||||||
|
(:require
|
||||||
|
[clj-reload.core :as reload]))
|
||||||
|
|
||||||
|
|
||||||
|
(alter-var-root #'*warn-on-reflection* (constantly true))
|
||||||
|
|
||||||
|
|
||||||
|
(reload/init
|
||||||
|
{:no-reload ['user]})
|
||||||
|
|
||||||
|
|
||||||
|
(defn reload! []
|
||||||
|
(reload/reload))
|
||||||
|
|
||||||
|
|
||||||
|
(comment
|
||||||
|
(reload!)
|
||||||
|
*e)
|
||||||
|
|
||||||
|
|
144
src/main/example/core.clj
Normal file
144
src/main/example/core.clj
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
(ns example.core
|
||||||
|
(:require
|
||||||
|
[clojure.java.io :as io]
|
||||||
|
[clojure.string :as string]
|
||||||
|
[dev.onionpancakes.chassis.compiler :as hc]
|
||||||
|
[dev.onionpancakes.chassis.core :as h]
|
||||||
|
[example.utils :as u]
|
||||||
|
[reitit.ring.middleware.parameters :as rmparams]
|
||||||
|
[reitit.ring :as rr]
|
||||||
|
[ring.util.response :as ruresp]
|
||||||
|
[starfederation.datastar.clojure.api :as d*]
|
||||||
|
[starfederation.datastar.clojure.adapter.ring :refer [->sse-response on-open on-close] :as dr]
|
||||||
|
[clojure.data.json :as json]))
|
||||||
|
|
||||||
|
(declare conns) ;; for broadcasts
|
||||||
|
|
||||||
|
;; html utils
|
||||||
|
(defn html->str [hiccup-forms]
|
||||||
|
(h/html
|
||||||
|
(hc/compile
|
||||||
|
hiccup-forms)))
|
||||||
|
|
||||||
|
(defn page-template [content]
|
||||||
|
(-> (io/resource "public/index.html")
|
||||||
|
slurp
|
||||||
|
(string/split-lines)
|
||||||
|
(->> (drop 3)
|
||||||
|
(apply str))
|
||||||
|
(string/replace "%%content%%" content)))
|
||||||
|
|
||||||
|
|
||||||
|
;; home page
|
||||||
|
(def home-frag
|
||||||
|
(html->str
|
||||||
|
[:main {:id "main"
|
||||||
|
:data-on-load "@get('/connect')"}
|
||||||
|
[:input {:data-bind "msg"}]
|
||||||
|
[:div {:data-text "$msg"}]
|
||||||
|
[:button {:data-on-click "@get('/hello-world')"} "click for text animation"]]))
|
||||||
|
|
||||||
|
(def home-page
|
||||||
|
(page-template home-frag))
|
||||||
|
|
||||||
|
(defn home [request respond _]
|
||||||
|
(respond
|
||||||
|
(-> home-page
|
||||||
|
ruresp/response
|
||||||
|
(ruresp/content-type "text/html"))))
|
||||||
|
|
||||||
|
|
||||||
|
;; d* api utils
|
||||||
|
(defn patch-signals-edn! [sse edn]
|
||||||
|
(d*/patch-signals! sse (json/write-str edn)))
|
||||||
|
|
||||||
|
(defn add-elements! [sse elems]
|
||||||
|
(d*/patch-elements! sse elems #:d*.elements{:patch-mode "append"
|
||||||
|
:selector "body"}))
|
||||||
|
(defn try!
|
||||||
|
[d*-f! sse & args]
|
||||||
|
(try (apply d*-f! sse args)
|
||||||
|
(catch Exception _
|
||||||
|
(println "exception occured. dropping connection")
|
||||||
|
(d*/close-sse! sse)
|
||||||
|
(swap! conns disj sse))))
|
||||||
|
|
||||||
|
|
||||||
|
;; broadcast utils
|
||||||
|
(def conns (atom #{}))
|
||||||
|
|
||||||
|
(defn broadcast!
|
||||||
|
([f]
|
||||||
|
(doseq [conn @conns]
|
||||||
|
(try! f conn)))
|
||||||
|
([f arg & args]
|
||||||
|
(doseq [conn @conns]
|
||||||
|
(apply try! f conn arg args))))
|
||||||
|
|
||||||
|
(defn broadcast-signals! [data]
|
||||||
|
(broadcast! patch-signals-edn! data))
|
||||||
|
|
||||||
|
(defn broadcast-js! [js-src]
|
||||||
|
(broadcast! add-elements! (html->str [:script js-src])))
|
||||||
|
|
||||||
|
(defn broadcast-reload! []
|
||||||
|
(broadcast-js! "location.reload()"))
|
||||||
|
|
||||||
|
(defn kill-broadcast! []
|
||||||
|
(doseq [conn @conns]
|
||||||
|
(try! d*/close-sse! conn)
|
||||||
|
(swap! conns disj conn)))
|
||||||
|
|
||||||
|
(defn connect [request respond _raise]
|
||||||
|
(respond
|
||||||
|
(->sse-response request
|
||||||
|
{on-open
|
||||||
|
(fn [sse] (swap! conns conj sse)
|
||||||
|
(println "adding connection"))
|
||||||
|
on-close
|
||||||
|
(fn [sse]
|
||||||
|
(swap! conns disj sse)
|
||||||
|
(println "dropping connection"))})))
|
||||||
|
|
||||||
|
|
||||||
|
;; hello world animation
|
||||||
|
(def message "Hello, world!")
|
||||||
|
|
||||||
|
(def msg-count (count message))
|
||||||
|
|
||||||
|
(defn hello-world [request respond _raise]
|
||||||
|
(respond
|
||||||
|
(->sse-response request
|
||||||
|
{on-open
|
||||||
|
(fn [sse]
|
||||||
|
(d*/with-open-sse sse
|
||||||
|
(dotimes [i msg-count]
|
||||||
|
(patch-signals-edn! sse {:msg (subs message 0 (inc i))})
|
||||||
|
(Thread/sleep 500))))})))
|
||||||
|
|
||||||
|
|
||||||
|
;; http stuffs
|
||||||
|
(def routes
|
||||||
|
[["/" {:handler home}]
|
||||||
|
["/connect" {:handler connect}]
|
||||||
|
["/hello-world" {:handler hello-world}]])
|
||||||
|
|
||||||
|
(def router (rr/router routes))
|
||||||
|
|
||||||
|
(def handler (rr/ring-handler router))
|
||||||
|
|
||||||
|
|
||||||
|
;; repl it up ;P
|
||||||
|
(comment
|
||||||
|
(broadcast-signals! {:msg "hi franz"})
|
||||||
|
(broadcast-signals! {:msg "hi ty"})
|
||||||
|
(broadcast! d*/console-log! "hi franz")
|
||||||
|
(broadcast-js! "console.log('test')")
|
||||||
|
(broadcast-reload!)
|
||||||
|
|
||||||
|
(kill-broadcast!)
|
||||||
|
|
||||||
|
|
||||||
|
(clojure.repl/dir d*)
|
||||||
|
(clojure.repl/doc d*/patch-signals!))
|
||||||
|
|
12
src/main/example/main.clj
Normal file
12
src/main/example/main.clj
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
(ns example.main
|
||||||
|
(:require
|
||||||
|
[example.core :as c]
|
||||||
|
[example.server :as server]))
|
||||||
|
|
||||||
|
|
||||||
|
(defn -main [& _]
|
||||||
|
(let [server (server/start! c/handler)]
|
||||||
|
(.addShutdownHook (Runtime/getRuntime)
|
||||||
|
(Thread. (fn []
|
||||||
|
(server/stop! server)
|
||||||
|
(shutdown-agents))))))
|
33
src/main/example/server.clj
Normal file
33
src/main/example/server.clj
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
(ns example.server
|
||||||
|
(:require
|
||||||
|
[example.core :as c]
|
||||||
|
[ring.adapter.jetty :as jetty])
|
||||||
|
(:import
|
||||||
|
org.eclipse.jetty.server.Server))
|
||||||
|
|
||||||
|
|
||||||
|
(defonce !jetty-server (atom nil))
|
||||||
|
|
||||||
|
|
||||||
|
(defn start! [handler & {:as opts}]
|
||||||
|
(let [opts (merge {:port 80 :join? false}
|
||||||
|
opts)]
|
||||||
|
(println "Starting server on port:" (:port opts))
|
||||||
|
(jetty/run-jetty handler opts)))
|
||||||
|
|
||||||
|
|
||||||
|
(defn stop! [server]
|
||||||
|
(println "Stopping server")
|
||||||
|
(println server)
|
||||||
|
(.stop ^Server server))
|
||||||
|
|
||||||
|
|
||||||
|
(defn reboot-jetty-server! [handler & {:as opts}]
|
||||||
|
(swap! !jetty-server
|
||||||
|
(fn [server]
|
||||||
|
(when server
|
||||||
|
(stop! server))
|
||||||
|
(start! handler opts))))
|
||||||
|
|
||||||
|
(comment
|
||||||
|
(reboot-jetty-server! #'c/handler {:async? true}))
|
13
src/main/example/utils.clj
Normal file
13
src/main/example/utils.clj
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
(ns example.utils
|
||||||
|
(:require
|
||||||
|
[charred.api :as charred]
|
||||||
|
[starfederation.datastar.clojure.api :as d*]))
|
||||||
|
|
||||||
|
|
||||||
|
(def ^:private bufSize 1024)
|
||||||
|
(def read-json (charred/parse-json-fn {:async? false :bufsize bufSize}))
|
||||||
|
|
||||||
|
(defn get-signals [req]
|
||||||
|
(-> req d*/get-signals read-json))
|
||||||
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user