Skip to content

Commit e2d8a6c

Browse files
committed
feat: adds basic template
1 parent 5dc2cb6 commit e2d8a6c

File tree

23 files changed

+5492
-11
lines changed

23 files changed

+5492
-11
lines changed

.clj-kondo/config.edn

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{:hooks {:analyze-call {codes.clj.docs.frontend.infra.helix/defnc clj-kondo.lilactown.helix/defnc}}}

.clj-kondo/funcool/promesa/config.edn

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{:lint-as {promesa.core/-> clojure.core/->
2+
promesa.core/->> clojure.core/->>
3+
promesa.core/as-> clojure.core/as->
4+
promesa.core/let clojure.core/let
5+
promesa.core/plet clojure.core/let
6+
promesa.core/loop clojure.core/loop
7+
promesa.core/recur clojure.core/recur
8+
promesa.core/with-redefs clojure.core/with-redefs
9+
promesa.core/doseq clojure.core/doseq}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
(ns clj-kondo.lilactown.helix
2+
(:require
3+
[clj-kondo.hooks-api :as api]))
4+
5+
6+
(defn $
7+
"Macro analysis for `helix.core/$` & `helix.dom/$d`."
8+
[{:keys [node]}]
9+
(let [[fn-sym & body] (-> node :children)
10+
[component-sym body] [(first body) (next body)]
11+
[old-props body] (if (api/map-node? (first body))
12+
[(-> body first :children) (next body)]
13+
[nil body])
14+
children body
15+
new-props (when old-props
16+
(->> old-props
17+
(map
18+
#(if (cond-> (api/sexpr %) symbol? (= '&))
19+
(api/keyword-node :&)
20+
%))
21+
api/map-node))
22+
expanded (api/list-node
23+
(list* fn-sym component-sym new-props children))]
24+
{:node (with-meta expanded (meta node))}))
25+
26+
27+
(defn dom
28+
"Macro analysis for `helix.dom/*`."
29+
[{:keys [node]}]
30+
(let [[fn-sym & body] (-> node :children)
31+
[old-props body] (if (api/map-node? (first body))
32+
[(-> body first :children) (next body)]
33+
[nil body])
34+
children body
35+
new-props (when old-props
36+
(->> old-props
37+
(map
38+
#(if (cond-> (api/sexpr %) symbol? (= '&))
39+
(api/keyword-node :&)
40+
%))
41+
api/map-node))
42+
expanded (api/list-node
43+
(list* fn-sym new-props children))]
44+
{:node (with-meta expanded (meta node))}))
45+
46+
47+
(defn analyze-definition
48+
"Macro analysis for `helix.core/defnc` and `helix.core/defnc-`."
49+
[{:keys [node]} definer]
50+
(let [[_ component-name & body] (-> node :children)
51+
render-children (last body)
52+
the-rest (butlast body)
53+
[docstring the-rest] (if (api/string-node? (first the-rest))
54+
[(first the-rest) (rest the-rest)]
55+
[nil the-rest])
56+
[metadata-map the-rest] (if (api/map-node? (first the-rest))
57+
[(first the-rest) (rest the-rest)]
58+
[nil the-rest])
59+
[argvec the-rest] (if (api/vector-node? (first the-rest))
60+
[(-> the-rest first) (rest the-rest)]
61+
[nil the-rest])
62+
opts-node (when (api/map-node? (first the-rest))
63+
(first the-rest))
64+
metadata-map (when metadata-map
65+
(-> (api/sexpr metadata-map)
66+
(assoc :wrap
67+
(api/sexpr
68+
(api/list-node
69+
(list*
70+
(api/token-node '->)
71+
(api/token-node '(helix.core/fnc [] ""))
72+
(-> (api/sexpr metadata-map)
73+
:wrap
74+
(api/coerce)
75+
:children)))))))
76+
new-opts (if opts-node
77+
(-> (api/sexpr opts-node)
78+
(assoc :wrap
79+
(api/sexpr
80+
(api/list-node
81+
(list* (api/token-node '->)
82+
(api/token-node
83+
'(helix.core/fnc [] ""))
84+
(-> (api/sexpr opts-node)
85+
:wrap
86+
(api/coerce)
87+
:children)))))
88+
api/coerce
89+
(with-meta (meta opts-node)))
90+
opts-node)]
91+
(when (and opts-node (contains? (api/sexpr opts-node) :wrap))
92+
(prn :opts-node)
93+
(api/reg-finding! (assoc (meta new-opts)
94+
:message ":wrap should be passed to metadata map before args"
95+
:type :helix/wrap-after-args)))
96+
{:node (with-meta
97+
(api/list-node
98+
(list*
99+
(api/token-node definer)
100+
component-name
101+
(filter some?
102+
[docstring metadata-map
103+
(if (and opts-node (get-in (api/sexpr opts-node) [:helix/features :define-factory]))
104+
(api/vector-node
105+
(concat (:children argvec)
106+
[(api/token-node '&)
107+
(api/token-node '_children)]))
108+
argvec)
109+
new-opts render-children])))
110+
(meta node))}))
111+
112+
(defn defnc
113+
[{:keys [node] :as form}]
114+
(analyze-definition form 'defn))
115+
116+
(defn defnc-
117+
[{:keys [node] :as form}]
118+
(analyze-definition form 'defn-))

.clj-kondo/lilactown/helix/config.edn

+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
{:hooks {:analyze-call {helix.core/$ clj-kondo.lilactown.helix/$
2+
helix.core/defnc clj-kondo.lilactown.helix/defnc
3+
helix.core/defnc- clj-kondo.lilactown.helix/defnc-
4+
helix.dom/$d clj-kondo.lilactown.helix/dom
5+
helix.dom/a clj-kondo.lilactown.helix/dom
6+
helix.dom/abbr clj-kondo.lilactown.helix/dom
7+
helix.dom/address clj-kondo.lilactown.helix/dom
8+
helix.dom/area clj-kondo.lilactown.helix/dom
9+
helix.dom/article clj-kondo.lilactown.helix/dom
10+
helix.dom/aside clj-kondo.lilactown.helix/dom
11+
helix.dom/audio clj-kondo.lilactown.helix/dom
12+
helix.dom/b clj-kondo.lilactown.helix/dom
13+
helix.dom/base clj-kondo.lilactown.helix/dom
14+
helix.dom/bdi clj-kondo.lilactown.helix/dom
15+
helix.dom/bdo clj-kondo.lilactown.helix/dom
16+
helix.dom/big clj-kondo.lilactown.helix/dom
17+
helix.dom/blockquote clj-kondo.lilactown.helix/dom
18+
helix.dom/body clj-kondo.lilactown.helix/dom
19+
helix.dom/br clj-kondo.lilactown.helix/dom
20+
helix.dom/button clj-kondo.lilactown.helix/dom
21+
helix.dom/canvas clj-kondo.lilactown.helix/dom
22+
helix.dom/caption clj-kondo.lilactown.helix/dom
23+
helix.dom/circle clj-kondo.lilactown.helix/dom
24+
helix.dom/cite clj-kondo.lilactown.helix/dom
25+
helix.dom/clipPath clj-kondo.lilactown.helix/dom
26+
helix.dom/code clj-kondo.lilactown.helix/dom
27+
helix.dom/col clj-kondo.lilactown.helix/dom
28+
helix.dom/colgroup clj-kondo.lilactown.helix/dom
29+
helix.dom/data clj-kondo.lilactown.helix/dom
30+
helix.dom/datalist clj-kondo.lilactown.helix/dom
31+
helix.dom/dd clj-kondo.lilactown.helix/dom
32+
helix.dom/defs clj-kondo.lilactown.helix/dom
33+
helix.dom/del clj-kondo.lilactown.helix/dom
34+
helix.dom/details clj-kondo.lilactown.helix/dom
35+
helix.dom/dfn clj-kondo.lilactown.helix/dom
36+
helix.dom/dialog clj-kondo.lilactown.helix/dom
37+
helix.dom/div clj-kondo.lilactown.helix/dom
38+
helix.dom/dl clj-kondo.lilactown.helix/dom
39+
helix.dom/dt clj-kondo.lilactown.helix/dom
40+
helix.dom/ellipse clj-kondo.lilactown.helix/dom
41+
helix.dom/em clj-kondo.lilactown.helix/dom
42+
helix.dom/embed clj-kondo.lilactown.helix/dom
43+
helix.dom/fieldset clj-kondo.lilactown.helix/dom
44+
helix.dom/figcaption clj-kondo.lilactown.helix/dom
45+
helix.dom/figure clj-kondo.lilactown.helix/dom
46+
helix.dom/footer clj-kondo.lilactown.helix/dom
47+
helix.dom/form clj-kondo.lilactown.helix/dom
48+
helix.dom/g clj-kondo.lilactown.helix/dom
49+
helix.dom/h1 clj-kondo.lilactown.helix/dom
50+
helix.dom/h2 clj-kondo.lilactown.helix/dom
51+
helix.dom/h3 clj-kondo.lilactown.helix/dom
52+
helix.dom/h4 clj-kondo.lilactown.helix/dom
53+
helix.dom/h5 clj-kondo.lilactown.helix/dom
54+
helix.dom/h6 clj-kondo.lilactown.helix/dom
55+
helix.dom/head clj-kondo.lilactown.helix/dom
56+
helix.dom/header clj-kondo.lilactown.helix/dom
57+
helix.dom/hr clj-kondo.lilactown.helix/dom
58+
helix.dom/html clj-kondo.lilactown.helix/dom
59+
helix.dom/i clj-kondo.lilactown.helix/dom
60+
helix.dom/iframe clj-kondo.lilactown.helix/dom
61+
helix.dom/img clj-kondo.lilactown.helix/dom
62+
helix.dom/input clj-kondo.lilactown.helix/dom
63+
helix.dom/ins clj-kondo.lilactown.helix/dom
64+
helix.dom/kbd clj-kondo.lilactown.helix/dom
65+
helix.dom/keygen clj-kondo.lilactown.helix/dom
66+
helix.dom/label clj-kondo.lilactown.helix/dom
67+
helix.dom/legend clj-kondo.lilactown.helix/dom
68+
helix.dom/li clj-kondo.lilactown.helix/dom
69+
helix.dom/line clj-kondo.lilactown.helix/dom
70+
helix.dom/linearGradient clj-kondo.lilactown.helix/dom
71+
helix.dom/link clj-kondo.lilactown.helix/dom
72+
helix.dom/main clj-kondo.lilactown.helix/dom
73+
helix.dom/map clj-kondo.lilactown.helix/dom
74+
helix.dom/mark clj-kondo.lilactown.helix/dom
75+
helix.dom/mask clj-kondo.lilactown.helix/dom
76+
helix.dom/menu clj-kondo.lilactown.helix/dom
77+
helix.dom/menuitem clj-kondo.lilactown.helix/dom
78+
helix.dom/meta clj-kondo.lilactown.helix/dom
79+
helix.dom/meter clj-kondo.lilactown.helix/dom
80+
helix.dom/nav clj-kondo.lilactown.helix/dom
81+
helix.dom/noscript clj-kondo.lilactown.helix/dom
82+
helix.dom/object clj-kondo.lilactown.helix/dom
83+
helix.dom/ol clj-kondo.lilactown.helix/dom
84+
helix.dom/optgroup clj-kondo.lilactown.helix/dom
85+
helix.dom/option clj-kondo.lilactown.helix/dom
86+
helix.dom/output clj-kondo.lilactown.helix/dom
87+
helix.dom/p clj-kondo.lilactown.helix/dom
88+
helix.dom/param clj-kondo.lilactown.helix/dom
89+
helix.dom/path clj-kondo.lilactown.helix/dom
90+
helix.dom/pattern clj-kondo.lilactown.helix/dom
91+
helix.dom/picture clj-kondo.lilactown.helix/dom
92+
helix.dom/polygon clj-kondo.lilactown.helix/dom
93+
helix.dom/polyline clj-kondo.lilactown.helix/dom
94+
helix.dom/pre clj-kondo.lilactown.helix/dom
95+
helix.dom/progress clj-kondo.lilactown.helix/dom
96+
helix.dom/q clj-kondo.lilactown.helix/dom
97+
helix.dom/radialGradient clj-kondo.lilactown.helix/dom
98+
helix.dom/rect clj-kondo.lilactown.helix/dom
99+
helix.dom/rp clj-kondo.lilactown.helix/dom
100+
helix.dom/rt clj-kondo.lilactown.helix/dom
101+
helix.dom/ruby clj-kondo.lilactown.helix/dom
102+
helix.dom/s clj-kondo.lilactown.helix/dom
103+
helix.dom/samp clj-kondo.lilactown.helix/dom
104+
helix.dom/script clj-kondo.lilactown.helix/dom
105+
helix.dom/section clj-kondo.lilactown.helix/dom
106+
helix.dom/select clj-kondo.lilactown.helix/dom
107+
helix.dom/small clj-kondo.lilactown.helix/dom
108+
helix.dom/source clj-kondo.lilactown.helix/dom
109+
helix.dom/span clj-kondo.lilactown.helix/dom
110+
helix.dom/stop clj-kondo.lilactown.helix/dom
111+
helix.dom/strong clj-kondo.lilactown.helix/dom
112+
helix.dom/style clj-kondo.lilactown.helix/dom
113+
helix.dom/sub clj-kondo.lilactown.helix/dom
114+
helix.dom/summary clj-kondo.lilactown.helix/dom
115+
helix.dom/sup clj-kondo.lilactown.helix/dom
116+
helix.dom/svg clj-kondo.lilactown.helix/dom
117+
helix.dom/table clj-kondo.lilactown.helix/dom
118+
helix.dom/tbody clj-kondo.lilactown.helix/dom
119+
helix.dom/td clj-kondo.lilactown.helix/dom
120+
helix.dom/text clj-kondo.lilactown.helix/dom
121+
helix.dom/textarea clj-kondo.lilactown.helix/dom
122+
helix.dom/tfoot clj-kondo.lilactown.helix/dom
123+
helix.dom/th clj-kondo.lilactown.helix/dom
124+
helix.dom/thead clj-kondo.lilactown.helix/dom
125+
helix.dom/time clj-kondo.lilactown.helix/dom
126+
helix.dom/title clj-kondo.lilactown.helix/dom
127+
helix.dom/tr clj-kondo.lilactown.helix/dom
128+
helix.dom/track clj-kondo.lilactown.helix/dom
129+
helix.dom/tspan clj-kondo.lilactown.helix/dom
130+
helix.dom/u clj-kondo.lilactown.helix/dom
131+
helix.dom/ul clj-kondo.lilactown.helix/dom
132+
helix.dom/var clj-kondo.lilactown.helix/dom
133+
helix.dom/video clj-kondo.lilactown.helix/dom
134+
helix.dom/wbr clj-kondo.lilactown.helix/dom}}
135+
:lint-as {helix.core/defhook clojure.core/defn
136+
helix.core/fnc clojure.core/fn}
137+
:linters {:helix/invalid-children {:level :error}
138+
:helix/wrap-after-args {:level :warning}}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{:lint-as
2+
{rewrite-clj.zip/subedit-> clojure.core/->
3+
rewrite-clj.zip/subedit->> clojure.core/->>
4+
rewrite-clj.zip/edit-> clojure.core/->
5+
rewrite-clj.zip/edit->> clojure.core/->>}}

.gitignore

+23-11
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,26 @@
1+
node_modules/
2+
resources/public/js
3+
resources/public/css
4+
resources/tests
5+
6+
/out
7+
/checkouts
8+
/src/gen
9+
10+
.clj-kondo/.cache
11+
.lsp/.cache
12+
.cpcache
13+
114
pom.xml
215
pom.xml.asc
16+
*.iml
317
*.jar
4-
*.class
5-
/lib/
6-
/classes/
7-
/target/
8-
/checkouts/
9-
.lein-deps-sum
10-
.lein-repl-history
11-
.lein-plugins/
12-
.lein-failures
13-
.nrepl-port
14-
.cpcache/
18+
*.log
19+
.shadow-cljs
20+
.idea
21+
.lein-*
22+
.nrepl-*
23+
.DS_Store
24+
25+
.hgignore
26+
.hg/

README.md

+22
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,24 @@
11
# docs.frontend
22
Frontend SPA for docs.clj.codes
3+
4+
## Commands
5+
6+
### Watch
7+
Start shadow-cljs watching and serving app and tests
8+
```bash
9+
npm start
10+
```
11+
> Main App available at http://localhost:5000
12+
> Tests available at http://localhost:5002
13+
14+
### Tests
15+
Compile with shadow-cljs and run tests in node with jsdom
16+
```bash
17+
npm test
18+
```
19+
20+
### Release
21+
Build the release package to production deploy
22+
```bash
23+
npm run release
24+
```

deps.edn

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{:paths ["src" "resources"]
2+
:deps {com.fbeyer/refx {:mvn/version "0.0.49"}
3+
lilactown/helix {:mvn/version "0.2.0"}
4+
metosin/reitit-schema {:mvn/version "0.6.0"}
5+
metosin/reitit-frontend {:mvn/version "0.6.0"}
6+
funcool/promesa {:mvn/version "11.0.678"}
7+
lambdaisland/fetch {:mvn/version "1.5.83"}}
8+
:aliases {:dev {:extra-paths ["dev" "test"]
9+
:extra-deps {thheller/shadow-cljs {:mvn/version "2.27.1"}
10+
cider/cider-nrepl {:mvn/version "0.45.0"}}}}}
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
(ns codes.clj.docs.frontend.dev.core
2+
(:require [codes.clj.docs.frontend.core :as app]
3+
[promesa.core :as p]))
4+
5+
(def debug? ^boolean goog.DEBUG)
6+
7+
(defn dev-setup []
8+
(when debug?
9+
(enable-console-print!)
10+
(println "dev mode")))
11+
12+
(defn ^:export init []
13+
(p/do (dev-setup)
14+
(app/init)))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
(ns codes.clj.docs.frontend.dev.refresh
2+
"A place to add preloads for developer tools!"
3+
(:require [codes.clj.docs.frontend.core :as app]
4+
[helix.experimental.refresh :as r]
5+
[refx.alpha :as refx]))
6+
7+
;; inject-hook! needs to run on application start.
8+
;; For ease, we run it at the top level.
9+
;; This function adds the react-refresh runtime to the page
10+
(r/inject-hook!)
11+
12+
;; shadow-cljs allows us to annotate a function name with `:dev/after-load`
13+
;; to signal that it should be run after any code reload. We call the `refresh!`
14+
;; function, which will tell react to refresh any components which have a
15+
;; signature created by turning on the `:fast-refresh` feature flag.
16+
(defn ^:dev/after-load refresh []
17+
(r/refresh!))
18+
19+
(defn ^:dev/after-load clear-cache-and-render! []
20+
;; The `:dev/after-load` metadata causes this function to be called
21+
;; after shadow-cljs hot-reloads code. We force a UI update by clearing
22+
;; the Refx subscription cache.
23+
(refx/clear-subscription-cache!)
24+
(app/render))

0 commit comments

Comments
 (0)