Skip to content

Clerk in Babashka #232

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 58 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
ff2ef75
First sketch of Clerk in Babashka
zampino Oct 18, 2022
36ba59c
Fix bb task
zampino Oct 18, 2022
066161f
Require latest babashka
zampino Oct 18, 2022
ed9b560
clean bb deps
zampino Oct 19, 2022
baa9660
Rely on latest bb for namespace instance check
zampino Oct 19, 2022
4fc3526
Move stubs to bb files
zampino Oct 19, 2022
1493d7b
Pass cli args to bb task
zampino Oct 19, 2022
8406591
Fix add-viewers! and auto-resolve of ::alias keywords
zampino Oct 19, 2022
e5ce7ab
Extract var from def
zampino Oct 19, 2022
a4b3738
Fix static builder in bb runtime
zampino Oct 19, 2022
a642887
Fix markdown viewer for cljs consumption
zampino Oct 19, 2022
b6bd4c4
Add build bb task
zampino Oct 19, 2022
7c95f89
Implement no-cache?
zampino Oct 20, 2022
995e264
Parse markdown via quickjs
zampino Oct 20, 2022
865c088
Check quickjs is available
zampino Oct 20, 2022
38997c8
Lazily copy markdown js module
zampino Oct 20, 2022
10e95c4
More escapes
zampino Oct 20, 2022
a5312a1
Merge branch 'main' into bb-clerk
borkdude May 6, 2025
ef77ecc
bypass editscript
borkdude May 6, 2025
b39c34b
dejavu
borkdude May 6, 2025
6ce1ddb
bypass nippy
borkdude May 6, 2025
9b711cd
wip [skip ci]
borkdude May 6, 2025
b219f09
more stuff
borkdude May 6, 2025
86e0d5d
more
borkdude May 6, 2025
e34c6bd
more
borkdude May 6, 2025
1fe803b
wip
borkdude May 6, 2025
6cc60fc
always-array-map is challenge
borkdude May 6, 2025
48dd946
wip
borkdude May 6, 2025
92c6676
kondo
borkdude May 6, 2025
e1f15d2
wip [skip ci]
borkdude May 12, 2025
0a907a0
wip
borkdude May 12, 2025
142f873
web server starts
borkdude May 29, 2025
e180a18
wip
borkdude May 29, 2025
9587c6d
fix macro
borkdude May 29, 2025
83d4d7f
wip
borkdude May 29, 2025
329c08f
fix build
borkdude May 29, 2025
9c6ee05
kondo
borkdude May 29, 2025
8bdc2b0
wip
borkdude May 29, 2025
4d29767
wip
borkdude May 29, 2025
e7f26d6
caching works
borkdude May 30, 2025
aeee8cd
wip
borkdude May 30, 2025
876b963
debug [skip ci]
borkdude May 30, 2025
61ba530
remove dbg
borkdude Jun 2, 2025
3fc5c6b
parse bb reader conditionals
borkdude Jun 2, 2025
69b5b8d
wip
borkdude Jun 2, 2025
673be31
reduce diff
borkdude Jun 3, 2025
2383705
wip
borkdude Jun 3, 2025
33f1481
fix tests
borkdude Jun 3, 2025
285eff7
fix lint warning
borkdude Jun 3, 2025
9d6a91f
Remove redundant clj-kondo warnings
mk Jun 3, 2025
fb5d2c4
Revert "Remove redundant clj-kondo warnings"
borkdude Jun 3, 2025
2e5f437
wip
borkdude Jun 3, 2025
aec2fc9
wip
borkdude Jun 16, 2025
77fccb7
multiformats upgrade
borkdude Jun 16, 2025
eeb7878
wip
borkdude Jun 16, 2025
1a58c86
wip
borkdude Jun 16, 2025
920baff
wip
borkdude Jun 16, 2025
c933c96
tests
borkdude Jun 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .clj-kondo/config.edn
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
taoensso.encore/defonce clojure.core/defonce
taoensso.encore/defalias clojure.core/def
promesa.core/let clojure.core/let
shadow.cljs.modern/defclass clojure.core/defprotocol}
shadow.cljs.modern/defclass clojure.core/defprotocol
nextjournal.clerk.utils/if-bb clojure.core/if}
:linters {:clojure-lsp/unused-public-var {:level :off}
:consistent-alias {:aliases {datomic.api datomic
clojure.string str
Expand Down
25 changes: 25 additions & 0 deletions bb-runtime.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{:min-bb-version "1.12.202"
:paths ["notebooks" "resources" "test"]
:deps {io.github.nextjournal/clerk {:local/root "."}
mvxcvi/multiformats {:mvn/version "1.0.125"}}
:tasks
{:init (do (require '[babashka.fs :as fs])
(System/setProperty "clerk.resource_manifest" (str {"/js/viewer.js" "/js/viewer.js"})))
dev
{:requires ([babashka.nrepl.server :as srv]
[nextjournal.clerk :as clerk]
[babashka.cli :as cli])
:task (do (srv/start-server! {:host "localhost" :port 1339})
(spit ".nrepl-port" "1339")
(nextjournal.clerk/serve! (cli/parse-opts *command-line-args*))
(-> (Runtime/getRuntime)
(.addShutdownHook (Thread. (fn []
(nextjournal.clerk/halt!)
(fs/delete ".nrepl-port")))))
(deref (promise)))}

build
{:requires ([nextjournal.clerk :as clerk]
[babashka.cli :as cli])
:task (let [spec (-> (resolve 'nextjournal.clerk/build!) meta :org.babashka/cli)]
(clerk/build! (cli/parse-opts *command-line-args* spec)))}}}
8 changes: 8 additions & 0 deletions bb.edn
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@
clojure (str ":" clojure-version))
*command-line-args*))}

test:bb {:doc "Run babashka tests"
:extra-paths ["test"]
:extra-deps {io.github.nextjournal/clerk {:local/root "."}
nubank/matcher-combinators {:mvn/version "3.5.1"}
org.clojure/test.check {:mvn/version "1.1.1"}
io.github.cognitect-labs/test-runner {:git/tag "v0.5.1" :git/sha "dfb30dd"}}
:task cognitect.test-runner/-main}

playwright:version {:doc "Print used playwright version from ui_tests/yarn.json"
:task (print (->> (babashka.process/shell {:out :string} "grep -E 'playwright-core \"(.*)\"' ui_tests/yarn.lock")
:out
Expand Down
7 changes: 4 additions & 3 deletions deps.edn
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
{:paths ["src" "resources" "bb"]
:deps {org.clojure/clojure {:mvn/version "1.10.3"}
:deps {org.clojure/clojure {:mvn/version "1.11.1"}
org.clojure/java.classpath {:mvn/version "1.0.0"}
babashka/fs {:mvn/version "0.5.22"}
borkdude/edamame {:mvn/version "1.4.28"}
weavejester/dependency {:mvn/version "0.2.1"}
com.nextjournal/beholder {:mvn/version "1.0.2"}
org.flatland/ordered {:mvn/version "1.15.12"}
io.github.nextjournal/markdown {:mvn/version "0.7.184"}
io.github.nextjournal/markdown {:mvn/version "0.7.186"}
babashka/process {:mvn/version "0.4.16"}
io.github.nextjournal/dejavu {:git/sha "4980e0cc18c9b09fb220874ace94ba6b57a749ca"}
io.github.babashka/sci.nrepl {:mvn/version "0.0.2"}

com.taoensso/nippy {:mvn/version "3.4.2"}

mvxcvi/multiformats {:mvn/version "0.3.107"}
mvxcvi/multiformats {:mvn/version "1.0.125"}
mvxcvi/alphabase {:mvn/version "3.0.185"}
com.pngencoder/pngencoder {:mvn/version "0.13.1"}

http-kit/http-kit {:mvn/version "2.8.0"}
Expand Down
31 changes: 31 additions & 0 deletions notebooks/babashka.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
(ns babashka
; {:nextjournal.clerk/no-cache true}
(:require [babashka.fs :as fs]
[nextjournal.clerk :as clerk]))

(System/getProperty "babashka.version")

*file*

(fs/exists? *file*)

;;;;

;;;; dude

(+ 1 2 3)

(prn :dude)

java.io.File

(def x 2)

(prn x)

(clerk/with-viewer
{
:render-fn '(fn [_]
[:div {:style {:color "green"}}
"Hello"])}
nil)
5 changes: 5 additions & 0 deletions src/nextjournal/beholder.bb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
(ns nextjournal.beholder
"Babashka runtime no-op stubs")

(defn watch [cb & args] nil)
(defn stop [w] nil)
4 changes: 4 additions & 0 deletions src/nextjournal/clerk.clj
Original file line number Diff line number Diff line change
Expand Up @@ -662,3 +662,7 @@
(clear-cache!)
(halt!)
)

(comment
(with-cache 1)
)
162 changes: 102 additions & 60 deletions src/nextjournal/clerk/always_array_map.clj
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
(ns nextjournal.clerk.always-array-map
"A persistent data structure that is based on array-map, but doesn't turn into a hash-map by using assoc etc.
Prints like a normal Clojure map in the order of insertion.")
Prints like a normal Clojure map in the order of insertion."
(:require [nextjournal.clerk.utils :as utils]))

(set! *warn-on-reflection* true)

Expand All @@ -9,72 +10,113 @@

(declare ->AlwaysArrayMap)

(deftype AlwaysArrayMap [^clojure.lang.PersistentArrayMap the-map]
clojure.lang.ILookup
(valAt [_ k]
(get the-map k))

clojure.lang.Seqable
(seq [_]
(seq the-map))

clojure.lang.IPersistentMap
(assoc [_ k v]
(if (< (count the-map) 8)
(->AlwaysArrayMap (assoc the-map k v))
(->AlwaysArrayMap (assoc-after the-map k v))))

(assocEx [_ _k _v]
(throw (ex-info "Not implemented" {})))

(without [_ k]
(->AlwaysArrayMap (dissoc the-map k)))

clojure.lang.Associative
(containsKey [_ k]
(contains? the-map k))

clojure.lang.IPersistentCollection
(equiv [_ other]
(= the-map other))
(count [_]
(count the-map))

java.lang.Iterable
(iterator [_]
(.iterator the-map))

clojure.lang.IMeta
(meta [_]
(meta the-map))

clojure.lang.IObj
(withMeta [_ meta]
(->AlwaysArrayMap (with-meta the-map meta)))

Object
(toString [_]
"<always-array-map>"))
;; (defn ->LazyMapEntry
;; [key_ val_]
;; (proxy [clojure.lang.AMapEntry] []
;; (key [] key_)
;; (val [] (force val_))
;; (getKey [] key_)
;; (getValue [] (force val_))))

;; (defn ->LazyMap [m]
;; (proxy [clojure.lang.APersistentMap clojure.lang.IMeta clojure.lang.IObj]
;; []
;; (valAt
;; ([k]
;; (auto-deref (get m k)))
;; ([k default-value]
;; (auto-deref (get m k default-value))))
;; (iterator []
;; (.iterator ^java.lang.Iterable
;; (eduction
;; (map #(->LazyMapEntry % (delay (get this %))))
;; (keys m))))

;; (containsKey [k] (contains? m k))
;; (entryAt [k] (if (contains? m k)
;; (->LazyMapEntry k (delay (get this k)))))
;; (equiv [other] (= m other))
;; (empty [] (->LazyMap (empty m)))
;; (count [] (count m))
;; (assoc [k v] (->LazyMap (assoc m k v)))
;; (without [k] (->LazyMap (dissoc m k)))
;; (seq [] (some->> (keys m)
;; (map #(->LazyMapEntry % (delay (get this %))))))
;; ; a lot of map users expect meta to work
;; (meta [] (meta m))
;; (withMeta [meta] (->LazyMap (with-meta m meta)))))


(utils/if-bb
nil
(deftype AlwaysArrayMap [^clojure.lang.PersistentArrayMap the-map]
clojure.lang.ILookup
(valAt [_ k]
(get the-map k))

clojure.lang.Seqable
(seq [_]
(seq the-map))

clojure.lang.IPersistentMap
(assoc [_ k v]
(if (< (count the-map) 8)
(->AlwaysArrayMap (assoc the-map k v))
(->AlwaysArrayMap (assoc-after the-map k v))))

(assocEx [_ _k _v]
(throw (ex-info "Not implemented" {})))

(without [_ k]
(->AlwaysArrayMap (dissoc the-map k)))

clojure.lang.Associative
(containsKey [_ k]
(contains? the-map k))

clojure.lang.IPersistentCollection
(equiv [_ other]
(= the-map other))
(count [_]
(count the-map))

java.lang.Iterable
(iterator [_]
(.iterator the-map))

clojure.lang.IMeta
(meta [_]
(meta the-map))

clojure.lang.IObj
(withMeta [_ meta]
(->AlwaysArrayMap (with-meta the-map meta)))

Object
(toString [_]
"<always-array-map>")))

(defn assoc-before [aam k v]
(->AlwaysArrayMap (apply array-map (list* k v (interleave (keys aam) (vals aam))))))

(defn always-array-map [& kvs]
(->AlwaysArrayMap (apply array-map kvs)))

(defmethod print-method AlwaysArrayMap
[v ^java.io.Writer writer]
(.write writer "{")
(let [write-kv! (fn [k v]
(.write writer (pr-str k))
(.write writer " ")
(.write writer (pr-str v)))]
(doseq [[k v] (butlast v)]
(write-kv! k v)
(.write writer ", "))
(let [[k v] (last v)]
(write-kv! k v)))
(.write writer "}"))
(utils/if-bb
nil
(defmethod print-method AlwaysArrayMap
[v ^java.io.Writer writer]
(.write writer "{")
(let [write-kv! (fn [k v]
(.write writer (pr-str k))
(.write writer " ")
(.write writer (pr-str v)))]
(doseq [[k v] (butlast v)]
(write-kv! k v)
(.write writer ", "))
(let [[k v] (last v)]
(write-kv! k v)))
(.write writer "}")))

(comment
(pr-str (always-array-map 1 2))
Expand Down
27 changes: 16 additions & 11 deletions src/nextjournal/clerk/analyzer.clj
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@
[clojure.java.io :as io]
[clojure.set :as set]
[clojure.string :as str]
[multiformats.base.b58 :as b58]
[multiformats.hash :as hash]
[nextjournal.clerk.analyzer.impl :as ana :refer [analyze*]]
[nextjournal.clerk.classpath :as cp]
[nextjournal.clerk.config :as config]
[nextjournal.clerk.parser :as parser]
[nextjournal.clerk.utils :as utils]
[nextjournal.clerk.walk :as walk]
[taoensso.nippy :as nippy]
[weavejester.dependency :as dep]))

(when-not utils/bb?
(require '[taoensso.nippy :as nippy]))

(set! *warn-on-reflection* true)

(defn deref? [form]
Expand All @@ -42,10 +44,10 @@
#_(no-cache? '^{:nextjournal.clerk/no-cache false} (def ^:nextjournal.clerk/no-cache my-rand (rand-int 10)))

(defn sha1-base58 [s]
(->> s hash/sha1 hash/encode b58/format-btc))
(->> s hash/sha1 hash/encode (utils/->base58)))

(defn sha2-base58 [s]
(->> s hash/sha2-512 hash/encode b58/format-btc))
(->> s hash/sha2-512 hash/encode (utils/->base58)))

#_(sha1-base58 "hello")

Expand Down Expand Up @@ -80,7 +82,9 @@
e)))))))

(defn analyze-form [form]
(with-bindings {clojure.lang.Compiler/LOADER (clojure.lang.RT/makeClassLoader)}
(with-bindings (utils/if-bb
{}
{clojure.lang.Compiler/LOADER (clojure.lang.RT/makeClassLoader)})
(binding [ana/*deps* (or ana/*deps* (atom #{}))]
(analyze-form* (rewrite-defcached form)))))

Expand Down Expand Up @@ -453,7 +457,7 @@
(if-let [ns (and (qualified-symbol? sym) (-> sym namespace symbol find-ns))]
(or (ns->file ns)
(ns->jar ns))
(symbol->jar sym)))))
(utils/if-bb nil (symbol->jar sym))))))

#_(find-location `inc)
#_(find-location `*print-dup*)
Expand Down Expand Up @@ -646,10 +650,12 @@
(let [digest-fn (case hash-type
:sha1 sha1-base58
:sha512 sha2-base58)]
(binding [nippy/*incl-metadata?* false]
(-> value
nippy/fast-freeze
digest-fn)))))
(utils/if-bb (-> value pr-str digest-fn)
#_{:clj-kondo/ignore [:unresolved-namespace]}
(binding [nippy/*incl-metadata?* false]
(-> value
nippy/fast-freeze
digest-fn))))))

#_(valuehash (range 100))
#_(valuehash :sha1 (range 100))
Expand All @@ -674,7 +680,6 @@
(assoc-in state [:->hash deref-dep] (->hash-str (eval deref-dep))))
analyzed-doc
(sort topo-comp deref-deps-to-eval))]
#_(prn :hash-deref-deps/form form :deref-deps deref-deps-to-eval)
(hash doc-with-deref-dep-hashes (sort topo-comp (dep/transitive-dependents-set graph deref-deps-to-eval))))
analyzed-doc))

Expand Down
Loading
Loading