frameworkify 2/x
This commit is contained in:
parent
b1d8a207ce
commit
7af519c788
2
deps.edn
2
deps.edn
@ -7,6 +7,8 @@
|
|||||||
starfederation.datastar/ring {:git/url "https://github.com/starfederation/datastar/"
|
starfederation.datastar/ring {:git/url "https://github.com/starfederation/datastar/"
|
||||||
:git/sha "376c4e2411706b942ea0ab937e4c6218d24fb30f"
|
:git/sha "376c4e2411706b942ea0ab937e4c6218d24fb30f"
|
||||||
:deps/root "sdk/clojure/adapter-ring"}
|
:deps/root "sdk/clojure/adapter-ring"}
|
||||||
|
datastar/expressions {:git/url "https://github.com/ramblurr/datastar-expressions/"
|
||||||
|
:git/sha "8db9d4bf5a178912ca173f67671fd9dba6b14f90"}
|
||||||
ring/ring-jetty-adapter {:mvn/version "1.13.0"}
|
ring/ring-jetty-adapter {:mvn/version "1.13.0"}
|
||||||
metosin/reitit {:mvn/version "0.7.2"}
|
metosin/reitit {:mvn/version "0.7.2"}
|
||||||
dev.onionpancakes/chassis {:mvn/version "1.0.365"}
|
dev.onionpancakes/chassis {:mvn/version "1.0.365"}
|
||||||
|
@ -1,57 +1,47 @@
|
|||||||
(ns example.core
|
(ns example.core
|
||||||
(:require
|
(:require
|
||||||
[example.utils :refer [html->str defpage defaction defaction-async] :as u]
|
[example.utils :refer [html->str defpage defaction defaction-async keep-open] :as u]
|
||||||
|
[starfederation.datastar.clojure.expressions :refer [->expr]]
|
||||||
[reitit.ring :as rr]
|
[reitit.ring :as rr]
|
||||||
[ring.util.response :as ruresp]))
|
[ring.util.response :as ruresp]))
|
||||||
|
|
||||||
(declare home-page page-2 hello-world)
|
(declare home-page page-2 hello-world)
|
||||||
|
|
||||||
;; views
|
|
||||||
(def home-page
|
|
||||||
{:url "/"
|
|
||||||
:view
|
|
||||||
(fn home-view [_]
|
|
||||||
(html->str
|
|
||||||
[:main
|
|
||||||
[:div
|
|
||||||
[:input {:data-bind "msg"}]
|
|
||||||
[:div {:data-text "$msg"}]
|
|
||||||
[:button {:data-on-click (u/at-get hello-world)}
|
|
||||||
"click for text animation"]]
|
|
||||||
[:button {:data-on-click (u/at-get page-2)} "go to page 2"]]))})
|
|
||||||
|
|
||||||
(def page-2
|
|
||||||
{:url "/page2"
|
|
||||||
:view
|
|
||||||
(fn page2-view [_]
|
|
||||||
(html->str
|
|
||||||
[:main
|
|
||||||
[:p "this is page2"]
|
|
||||||
[:button {:data-on-click (u/at-get home-page)}
|
|
||||||
"go back to home"]]))})
|
|
||||||
|
|
||||||
;; hello world animation
|
|
||||||
(def message "Hello, world!")
|
(def message "Hello, world!")
|
||||||
|
|
||||||
(def msg-count (count message))
|
(def msg-count (count message))
|
||||||
|
|
||||||
(def hello-world
|
;; actions
|
||||||
{:url "/hello-world"
|
(defaction hello-world [sse]
|
||||||
:fn (fn hello-world [sse]
|
(dotimes [i msg-count]
|
||||||
(dotimes [i msg-count]
|
(u/patch-signals-edn! sse {:msg (subs message 0 (inc i))})
|
||||||
(u/patch-signals-edn! sse {:msg (subs message 0 (inc i))})
|
(Thread/sleep 500)))
|
||||||
(Thread/sleep 500)))})
|
|
||||||
|
|
||||||
;; http stuff
|
;; pages
|
||||||
|
(defpage home-page
|
||||||
|
(html->str
|
||||||
|
[:main
|
||||||
|
[:div
|
||||||
|
[:input {:data-bind "msg"}]
|
||||||
|
[:div {:data-text "$msg"}]
|
||||||
|
[:button {:data-on-click (->expr (@post ~hello-world ~keep-open))}
|
||||||
|
"click for text animation"]]
|
||||||
|
[:button {:data-on-click (->expr (@post ~page-2))}
|
||||||
|
"go to page 2"]]))
|
||||||
|
|
||||||
|
(defpage page-2
|
||||||
|
(html->str
|
||||||
|
[:main
|
||||||
|
[:p "this is page2"]
|
||||||
|
[:button {:data-on-click (->expr (@post ~home-page))}
|
||||||
|
"go back to home"]]))
|
||||||
|
|
||||||
|
;; http app server
|
||||||
(def routes
|
(def routes
|
||||||
(concat
|
(concat
|
||||||
(defpage home-page)
|
(u/app-routes home-page)
|
||||||
(defpage page-2)
|
;; todo frameworkify the aysnc & broadcast stuffs then all the http things
|
||||||
(defaction hello-world)
|
|
||||||
(defaction-async "/connect" u/connect-sse! u/disconnect-sse!)))
|
(defaction-async "/connect" u/connect-sse! u/disconnect-sse!)))
|
||||||
|
|
||||||
(def router (rr/router routes))
|
(def router (rr/router routes))
|
||||||
|
|
||||||
(def handler (rr/ring-handler router))
|
(def handler (rr/ring-handler router))
|
||||||
|
|
||||||
;; repl it up ;P
|
;; repl it up ;P
|
||||||
|
@ -25,5 +25,8 @@
|
|||||||
(stop! server))
|
(stop! server))
|
||||||
(start! handler opts))))
|
(start! handler opts))))
|
||||||
|
|
||||||
|
(defn -main [& _args]
|
||||||
|
(reboot-jetty-server! #'c/handler {:async? true}))
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
(reboot-jetty-server! #'c/handler {:async? true}))
|
(reboot-jetty-server! #'c/handler {:async? true}))
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
[starfederation.datastar.clojure.adapter.ring :refer [->sse-response on-open on-close] :as dr]
|
[starfederation.datastar.clojure.adapter.ring :refer [->sse-response on-open on-close] :as dr]
|
||||||
[clojure.data.json :as json]))
|
[clojure.data.json :as json]))
|
||||||
|
|
||||||
(declare conns add-elements! sse-navigate!)
|
(declare conns add-elements! sse-navigate! disconnect-sse!)
|
||||||
|
|
||||||
;; global utils
|
;; global utils
|
||||||
(defn tap! [x]
|
(defn tap! [x]
|
||||||
@ -30,12 +30,14 @@
|
|||||||
(string/split-lines)
|
(string/split-lines)
|
||||||
(->> (drop 3)
|
(->> (drop 3)
|
||||||
(apply str))
|
(apply str))
|
||||||
(str "<div data-on-load=\"@get('connect')\"></div>")
|
(str "<div data-on-load=\"@get('/connect')\"></div>")
|
||||||
(string/replace "%%content%%" content)))
|
(string/replace "%%content%%" content)))
|
||||||
|
|
||||||
(defn at-get [page-or-action]
|
(defn at-get [page-or-action]
|
||||||
(format "@get('%s')" (:url page-or-action)))
|
(format "@get('%s')" (:url page-or-action)))
|
||||||
|
|
||||||
|
(def keep-open {:openWhenHidden true})
|
||||||
|
|
||||||
;; fix. use replaceState api? or push some real state? back button doesn't work yet
|
;; fix. use replaceState api? or push some real state? back button doesn't work yet
|
||||||
(defn update-url-frag [url]
|
(defn update-url-frag [url]
|
||||||
(html->str [:script (format "history.pushState({page:1}, 'Title', '%s')"
|
(html->str [:script (format "history.pushState({page:1}, 'Title', '%s')"
|
||||||
@ -117,29 +119,46 @@
|
|||||||
(swap! conns disj conn)))
|
(swap! conns disj conn)))
|
||||||
|
|
||||||
;; http stuffs
|
;; http stuffs
|
||||||
(defn defpage
|
(defonce !ma-routes (atom {}))
|
||||||
([page]
|
|
||||||
(defpage (:url page) (:view page)))
|
|
||||||
([endpoint view]
|
|
||||||
[[endpoint
|
|
||||||
{:handler (fn [request respond _]
|
|
||||||
(page request respond endpoint view))}]
|
|
||||||
[(str "/sse" endpoint)
|
|
||||||
{:handler (fn [request respond _]
|
|
||||||
(page request respond endpoint view))}]]))
|
|
||||||
|
|
||||||
(defn defaction
|
(defn add-route! [url f]
|
||||||
([action]
|
(swap! !ma-routes assoc url f))
|
||||||
(defaction (:url action) (:fn action)))
|
|
||||||
([url f]
|
;; todo, custom url support
|
||||||
(let [sse-handler
|
(defmacro defpage
|
||||||
(fn [request respond raise_]
|
[name-sym & body]
|
||||||
(respond
|
(let [route-str (str "/" name-sym)
|
||||||
(->sse-response
|
route-str-sse (str "/sse" route-str)]
|
||||||
request
|
`(let [view# (fn [_#]
|
||||||
{on-open #(d*/with-open-sse % (f %))})))]
|
~@body)]
|
||||||
[[url sse-handler]
|
|
||||||
[(str "/sse" url) sse-handler]])))
|
(add-route! ~route-str
|
||||||
|
(fn [request# respond# _#]
|
||||||
|
(page request# respond# ~route-str view#)))
|
||||||
|
(add-route! ~route-str-sse
|
||||||
|
(fn [request# respond# _#]
|
||||||
|
(sse-page request# respond# view# ~route-str-sse)))
|
||||||
|
(def ~name-sym ~route-str))))
|
||||||
|
|
||||||
|
(defn app-routes
|
||||||
|
([]
|
||||||
|
(->> @!ma-routes
|
||||||
|
vec))
|
||||||
|
([index-route]
|
||||||
|
(concat (app-routes)
|
||||||
|
[["/" (@!ma-routes index-route)]])))
|
||||||
|
|
||||||
|
(defmacro defaction [action-sym args & body]
|
||||||
|
(let [url (str "/sse/" action-sym)]
|
||||||
|
`(let [sse-handler#
|
||||||
|
(fn [request# respond# raise_#]
|
||||||
|
(respond#
|
||||||
|
(->sse-response
|
||||||
|
request#
|
||||||
|
{on-open (fn ~args (d*/with-open-sse ~(get args 0)
|
||||||
|
~@body))})))]
|
||||||
|
(add-route! ~url sse-handler#)
|
||||||
|
(def ~action-sym ~url))))
|
||||||
|
|
||||||
(defn defaction-async [url on-open-f on-close-f]
|
(defn defaction-async [url on-open-f on-close-f]
|
||||||
(let [sse-handler
|
(let [sse-handler
|
||||||
|
Loading…
x
Reference in New Issue
Block a user