Skip to content
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

cljs compilation fixes #724

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ dhi
dhi.build_artifacts.txt
trace.edn
tmp.edn
.shadow-cljs
1 change: 1 addition & 0 deletions bb/resources/native-image-tests/run-bb-pod-tests.clj
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
[?e :age ?a]]
(d/db conn)))))
(let [timestamp (Date.)]
(Thread/sleep 1)
(d/transact conn {:tx-data [{:db/id 3 :age 25}]})
(d/transact conn [{:name "FOO" :age "BAR"}])
(testing "pull"
Expand Down
8 changes: 7 additions & 1 deletion bb/src/tools/test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,17 @@
(defn specs []
(kaocha "--focus" "specs" "--plugin" "kaocha.plugin/orchestra"))

(defn cljs-compile-test []
(p/shell "clj -M:cljs -m shadow.cljs.devtools.cli compile :comptest")
(p/shell "node target/out/comptest.js"))

(defn all [config]
(kaocha "--skip" "specs")
(specs)
(back-compat config)
(native-image)
(bb-pod))
(bb-pod)
(cljs-compile-test))

(defn -main [config & args]
(if (seq args)
Expand All @@ -72,5 +77,6 @@
"bb-pod" (bb-pod)
"back-compat" (back-compat config)
"specs" (specs)
"cljs" (cljs-compile-test)
(apply kaocha "--focus" args))
(all config)))
12 changes: 8 additions & 4 deletions deps.edn
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
io.replikativ/hitchhiker-tree {:mvn/version "0.2.222"
:exclusions [org.clojure/clojurescript]}
io.replikativ/konserve {:mvn/version "0.7.319"
:exclusions [org.clojure/clojurescript]}
:exclusions [org.clojure/clojurescript
org.clojars.mmb90/cljs-cache]}
io.replikativ/superv.async {:mvn/version "0.3.48"
:exclusions [org.clojure/clojurescript]}
io.replikativ/datalog-parser {:mvn/version "0.2.29"}
io.replikativ/datalog-parser {:mvn/version "0.2.30"}
io.replikativ/zufall {:mvn/version "0.2.9"}
persistent-sorted-set/persistent-sorted-set {:mvn/version "0.3.0"}
environ/environ {:mvn/version "1.2.0"}
Expand All @@ -18,7 +19,8 @@
metosin/spec-tools {:mvn/version "0.10.6"}
mvxcvi/clj-cbor {:mvn/version "1.1.1"}
org.babashka/http-client {:mvn/version "0.3.11"}
metosin/jsonista {:mvn/version "0.3.7"}}
metosin/jsonista {:mvn/version "0.3.7"}
com.github.pkpkpk/cljs-cache {:mvn/version "1.0.21"}}

:paths ["src" "target/classes" "resources"]

Expand All @@ -32,7 +34,9 @@

:1.10 {:override-deps {org.clojure/clojure {:mvn/version "1.10.0"}}}

:cljs {:extra-deps {org.clojure/clojurescript {:mvn/version "1.11.121"}}}
:cljs {:extra-deps {org.clojure/clojurescript {:mvn/version "1.11.132"}
thheller/shadow-cljs {:mvn/version "2.28.20"}}
:extra-paths ["test"]}

:dev {:extra-paths ["dev" "benchmark/src"]
:extra-deps {org.clojure/tools.namespace {:mvn/version "1.4.4"}
Expand Down
9 changes: 9 additions & 0 deletions shadow-cljs.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{:deps true
:src-paths ["src" "test"]
:builds {:comptest
{:target :node-script
:output-to "target/out/comptest.js"
:main datahike.cljs-compilation-test/-main
:compiler-options {:infer-externs true
:warnings {:fn-deprecated false
:protocol-multiple-impls false}}}}}
27 changes: 17 additions & 10 deletions src/datahike/api.cljc
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
(ns datahike.api
"Public API for datahike. Expanded from api.specification."
(:refer-clojure :exclude [filter])
#?(:cljs (:require-macros [datahike.api :refer [emit-api]]))
(:require [datahike.connector :as dc]
[datahike.config :as config]
[datahike.api.specification :refer [api-specification spec-args->argslist]]
[datahike.api.impl]
[clojure.spec.alpha :as s]
[datahike.writer :as dw]
[datahike.http.writer]
#?(:clj [datahike.http.writer])
[datahike.writing :as writing]
[datahike.constants :as const]
[datahike.core :as dcore]
Expand All @@ -25,12 +26,18 @@
[datahike.db HistoricalDB AsOfDB SinceDB FilteredDB]
[datahike.impl.entity Entity])))

(doseq [[n {:keys [args ret fn doc impl]}] api-specification]
(eval
`(s/fdef ~n :args ~args :ret ~ret ~@(when fn [:fn fn])))
(eval
`(def
~(with-meta n
{:arglists `(spec-args->argslist (quote ~args))
:doc doc})
~impl)))
(defmacro ^:private emit-api []
`(do
~@(reduce
(fn [acc [n {:keys [args ret fn doc impl]}]]
(conj acc
`(s/fdef ~n :args ~args :ret ~ret ~@(when fn [:fn fn]))
`(def
~(with-meta n
{:arglists `(spec-args->argslist (quote ~args))
:doc doc})
~impl)))
()
(into (sorted-map) api-specification))))

(emit-api)
2 changes: 1 addition & 1 deletion src/datahike/api/specification.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -857,7 +857,7 @@ Returns the key under which this listener is registered. See also [[unlisten]]."
gc-storage
{:args (s/alt :with-date (s/cat :conn spec/SConnection :remove-before spec/time-point?)
:no-date (s/cat :conn spec/SConnection))
:ret set?
:ret any?
:doc "Invokes garbage collection on the store of connection by whitelisting currently known branches.
All db snapshots on these branches before remove-before date will also be
erased (defaults to beginning of time [no erasure]). The branch heads will
Expand Down
51 changes: 31 additions & 20 deletions src/datahike/array.cljc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
(ns ^:no-doc datahike.array
#?(:clj (:require [hitchhiker.tree.node :as n]))
#?(:cljs (:require [goog.array]))
#?(:clj (:import [java.util Arrays])))

#?(:clj
Expand Down Expand Up @@ -36,26 +37,35 @@
(recur (inc i#)))))))
`(array-compare ~a ~b))))

#?(:clj (defn compare-arrays
"Compare two arrays a and b element-wise in ascending order. If one array is a
prefix of another then it comes first."
[a b]
(if (not (and (bytes? a) (bytes? b)))
(try
(compare a b)
(catch ClassCastException _
(- (n/-order-on-edn-types a)
(n/-order-on-edn-types b))))
(raw-array-compare a b))))
#?(:cljs
(defn bytes? [x]
(and (instance? js/ArrayBuffer (.-buffer x))
(number? (.-byteLength x)))))

#?(:clj (defn string-from-bytes
"Represents a byte array as a string. Two byte arrays are said to be equal iff their corresponding values after applying this function are equal. That way, we rely on the equality and hash code implementations of the String class to compare byte arrays."
[x]
(let [n (alength x)
dst (char-array n)]
(dotimes [i n]
(aset dst i (char (aget x i))))
(String. dst))))
(defn compare-arrays
"Compare two arrays a and b element-wise in ascending order. If one array is a
prefix of another then it comes first."
[a b]
#?(:cljs (goog.array/compare3 a b)
:clj
(if (not (and (bytes? a) (bytes? b)))
(try
(compare a b)
(catch ClassCastException _
(- (n/-order-on-edn-types a)
(n/-order-on-edn-types b))))
(raw-array-compare a b))))

(defn string-from-bytes
"Represents a byte array as a string. Two byte arrays are said to be equal iff their corresponding values after applying this function are equal. That way, we rely on the equality and hash code implementations of the String class to compare byte arrays."
[x]
#?(:cljs (.decode (js/TextDecoder. "utf8") x)
:clj
(let [n (alength x)
dst (char-array n)]
(dotimes [i n]
(aset dst i (char (aget x i))))
(String. dst))))

(defrecord WrappedBytes [string-repr])

Expand All @@ -75,4 +85,5 @@
#?(:clj (and (bytes? a)
(bytes? b)
(zero? (compare-arrays a b)))
:cljs (zero? (compare-arrays a b)))))
:cljs (or (identical? a b)
(zero? (compare-arrays a b))))))
26 changes: 15 additions & 11 deletions src/datahike/config.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
[datahike.tools :as dt]
[datahike.store :as ds]
[datahike.index :as di])
(:import [java.net URI]))
(:import #?(:clj [java.net URI]
:cljs [goog.Uri])))

;; global
(def ^:dynamic *schema-meta-cache-size* (env :schema-meta-cache-size 1024))
Expand Down Expand Up @@ -83,7 +84,7 @@
:path path
:host host
:port port
:id (str (java.util.UUID/randomUUID))}
:id (str #?(:clj (java.util.UUID/randomUUID) :cljs (random-uuid)))}
:level {:path path}
:file {:path path}))
:index index
Expand All @@ -101,19 +102,20 @@
(defn int-from-env
[key default]
(try
(Integer/parseInt (get env key (str default)))
(catch Exception _ default)))
(#?(:clj Integer/parseInt :cljs js/parseInt) (get env key (str default)))
(catch #?(:clj Exception :cljs js/Error) _ default)))

(defn bool-from-env
[key default]
(try
(Boolean/parseBoolean (get env key default))
(catch Exception _ default)))
#?(:clj (Boolean/parseBoolean (get env key default))
:cljs (= "true" (get env key default)))
(catch #?(:clj Exception :cljs js/Error) _ default)))

(defn map-from-env [key default]
(try
(edn/read-string (get env key (str default)))
(catch Exception _ default)))
(catch #?(:clj Exception :cljs js/Error) _ default)))

(defn validate-config-attribute [attribute value config]
(when-not (s/valid? attribute value)
Expand Down Expand Up @@ -167,7 +169,7 @@
(keyword "datahike.index" (:datahike-index env))
*default-index*)
config {:store store-config
:initial-tx (:datahike-intial-tx env)
:initial-tx (:datahike-initial-tx env)
:keep-history? (bool-from-env :datahike-keep-history *default-keep-history?*)
:attribute-refs? (bool-from-env :datahike-attribute-refs *default-attribute-refs?*)
:schema-flexibility (keyword (:datahike-schema-flexibility env *default-schema-flexibility*))
Expand All @@ -191,7 +193,8 @@
(when (and attribute-refs? (= :read schema-flexibility))
(throw (ex-info "Attribute references cannot be used with schema-flexibility ':read'." config)))
(if (string? initial-tx)
(update merged-config :initial-tx (fn [path] (-> path slurp read-string)))
#?(:clj (update merged-config :initial-tx (fn [path] (-> path slurp read-string)))
:cljs (throw (ex-info ":initial-tx from path is not supported in cljs at this time" merged-config)))
merged-config))))

;; deprecation begin
Expand All @@ -207,10 +210,11 @@
:opt-un [::username ::password ::path ::host ::port]))

(defn uri->config [uri]
(let [base-uri (URI. uri)
(let [base-uri (#?(:clj URI. :cljs goog.Uri.) uri)
_ (when-not (= (.getScheme base-uri) "datahike")
(throw (ex-info "URI scheme is not datahike conform." {:uri uri})))
sub-uri (URI. (.getSchemeSpecificPart base-uri))
sub-uri #?(:clj (URI. (.getSchemeSpecificPart base-uri))
:cljs (goog.Uri. (.getScheme base-uri)))
backend (keyword (.getScheme sub-uri))
[username password] (when-let [user-info (.getUserInfo sub-uri)]
(str/split user-info #":"))
Expand Down
36 changes: 18 additions & 18 deletions src/datahike/connector.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
[taoensso.timbre :as log]
[clojure.spec.alpha :as s]
[clojure.data :refer [diff]])
(:import [clojure.lang IDeref IAtom IMeta ILookup IRef]))
#?(:clj (:import [clojure.lang IDeref IAtom IMeta ILookup IRef])))

;; connection

Expand All @@ -22,25 +22,25 @@

(deftype Connection [wrapped-atom]
IDeref
(deref [conn] (deref-conn conn))
(#?(:clj deref :cljs -deref) [conn] (deref-conn conn))
;; These interfaces should not be used from the outside, they are here to keep
;; the internal interfaces lean and working.
ILookup
(valAt [c k] (if (= k :wrapped-atom) wrapped-atom nil))
IAtom
(swap [_ f] (swap! wrapped-atom f))
(swap [_ f arg] (swap! wrapped-atom f arg))
(swap [_ f arg1 arg2] (swap! wrapped-atom f arg1 arg2))
(swap [_ f arg1 arg2 args] (apply swap! wrapped-atom f arg1 arg2 args))
(compareAndSet [_ oldv newv] (compare-and-set! wrapped-atom oldv newv))
(reset [_ newval] (reset! wrapped-atom newval))

(#?(:clj valAt :cljs -lookup) [c k] (if (= k :wrapped-atom) wrapped-atom nil))
IMeta
(meta [_] (meta wrapped-atom))

IRef ;; TODO This is unoffically supported, it triggers watches on each update, not on commits. For proper listeners use the API.
(addWatch [_ key f] (add-watch wrapped-atom key f))
(removeWatch [_ key] (remove-watch wrapped-atom key)))
(#?(:clj meta :cljs -meta) [_] (meta wrapped-atom))
#?(:cljs IAtom)
#?@(:clj
[IAtom
(swap [_ f] (swap! wrapped-atom f))
(swap [_ f arg] (swap! wrapped-atom f arg))
(swap [_ f arg1 arg2] (swap! wrapped-atom f arg1 arg2))
(swap [_ f arg1 arg2 args] (apply swap! wrapped-atom f arg1 arg2 args))
(compareAndSet [_ oldv newv] (compare-and-set! wrapped-atom oldv newv))
(reset [_ newval] (reset! wrapped-atom newval))
IRef ;; TODO This is unofficially supported, it triggers watches on each update, not on commits. For proper listeners use the API.
(addWatch [_ key f] (add-watch wrapped-atom key f))
(removeWatch [_ key] (remove-watch wrapped-atom key))]))

(defn connection? [x]
(instance? Connection x))
Expand Down Expand Up @@ -139,11 +139,11 @@
(dissoc :writer :store-cache-size :search-cache-size)))

(extend-protocol PConnector
String
#?(:clj String :cljs string)
(-connect [uri]
(-connect (dc/uri->config uri)))

clojure.lang.IPersistentMap
#?(:clj clojure.lang.IPersistentMap :cljs PersistentArrayMap)
(-connect [raw-config]
(let [config (dissoc (dc/load-config raw-config) :initial-tx :remote-peer :name)
_ (log/debug "Using config " (update-in config [:store] dissoc :password))
Expand Down
13 changes: 8 additions & 5 deletions src/datahike/datom.cljc
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
(ns ^:no-doc datahike.datom
#?(:cljs (:require-macros [datahike.datom :refer [combine-cmp]]))
(:require [clojure.walk]
[clojure.data]
[datahike.constants :refer [tx0]]
[datahike.tools :refer [combine-hashes]]
[datahike.constants :refer [tx0]]))
#?(:cljs [goog.array :as garray])))

(declare hash-datom equiv-datom seq-datom nth-datom assoc-datom val-at-datom)

Expand Down Expand Up @@ -147,7 +149,8 @@
:v (datom (.-e d) (.-a d) v (datom-tx d) (datom-added d))
:tx (datom (.-e d) (.-a d) (.-v d) v (datom-added d))
:added (datom (.-e d) (.-a d) (.-v d) (datom-tx d) v)
(throw (IllegalArgumentException. (str "invalid key for #datahike/Datom: " k)))))
(throw (#?(:clj IllegalArgumentException. :cljs js/Error.)
(str "invalid key for #datahike/Datom: " k)))))

;; printing and reading
;; #datomic/DB {:schema <map>, :datoms <vector of [e a v tx]>}
Expand Down Expand Up @@ -243,13 +246,13 @@
(.compareTo ^Comparable a1 a2)))

(defn- class-name [x]
(let [c (class x)]
(.getName ^Class c)))
#?(:clj (.getName (class x))
:cljs (type x)))

(defn- safe-compare [a b]
(try
(compare a b)
(catch Exception _e
(catch #?(:clj Exception :cljs js/Error) _e
(compare (class-name a)
(class-name b)))))

Expand Down
Loading