diff --git a/CHANGELOG.md b/CHANGELOG.md index eebe784b..fbd9c25a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Fixed handling of false values in entity cache (PR #198, thx [Brandon Bloom](https://github.com/brandonbloom)) - Fixed issue when string values were interpreted as lookup refs (#214) - Speed up rschema calculation (#192, thx [Andre R.](https://github.com/rauhs)) +- Optimize generated JS code by declaring fn arities (#197) # 0.15.5 diff --git a/src/datascript/arrays.cljc b/src/datascript/arrays.cljc index 3f93997f..480a9bc4 100644 --- a/src/datascript/arrays.cljc +++ b/src/datascript/arrays.cljc @@ -8,12 +8,13 @@ (defn- if-cljs [env then else] (if (:ns env) then else)) -#?(:cljs (def make-array cljs.core/make-array) +#?(:cljs (defn ^array make-array [size] (js/Array. size)) :clj (defn make-array ^{:tag "[[Ljava.lang.Object;"} [size] (clojure.core/make-array java.lang.Object size))) -#?(:cljs (def into-array cljs.core/into-array) +#?(:cljs (defn ^array into-array [aseq] + (reduce (fn [a x] (.push a x) a) (js/Array.) aseq)) :clj (defn into-array ^{:tag "[[Ljava.lang.Object;"} [aseq] (clojure.core/into-array java.lang.Object aseq))) @@ -80,6 +81,8 @@ #?(:cljs (.sort arr cmp) :clj (doto arr (java.util.Arrays/sort cmp)))) -(def array? - #?(:cljs cljs.core/array? - :clj (fn array? [^Object x] (-> x .getClass .isArray)))) +#?(:cljs (defn ^boolean array? [x] + (if (identical? *target* "nodejs") + (.isArray js/Array x) + (instance? js/Array x))) + :clj (defn array? [^Object x] (-> x .getClass .isArray))) \ No newline at end of file diff --git a/src/datascript/btset.cljc b/src/datascript/btset.cljc index cbd7331d..81cd8507 100644 --- a/src/datascript/btset.cljc +++ b/src/datascript/btset.cljc @@ -413,7 +413,11 @@ ;; BTSet -(declare btset-conj btset-disj btset-iter) +;; using defn instead of declare because of http://dev.clojure.org/jira/browse/CLJS-1871 +(defn ^:declared btset-conj [set key cmp]) +(defn ^:declared btset-disj [set key cmp]) +(defn ^:declared btset-iter [set]) + (def ^:const uninitialized-hash #?(:cljs nil :clj -1)) (deftype BTSet [root shift cnt comparator meta #?(:cljs ^:mutable __hash @@ -687,9 +691,18 @@ ^long [^BTSet set ^long path] (-prev-path (.-root set) path (.-shift set))) - - -(declare iter riter iter-first iter-next iter-chunk iter-chunked-next iter-rseq iter-reduce) +;; using defn instead of declare because of http://dev.clojure.org/jira/browse/CLJS-1871 +(defn ^:declared iter [set left right]) +(defn ^:declared iter-first [iter]) +(defn ^:declared iter-next [iter]) +(defn ^:declared iter-chunk [iter]) +(defn ^:declared iter-chunked-next [iter]) +(defn ^:declared iter-rseq [iter]) +(defn ^:declared iter-reduce ([iter f]) ([iter f start])) +(defn ^:declared riter [set left right]) +(defn ^:declared riter-first [riter]) +(defn ^:declared riter-next [ri]) +(defn ^:declared riter-rseq [riter]) (defn btset-iter "Iterator that represents whole set" @@ -837,8 +850,6 @@ ;; reverse iteration -(declare riter-first riter-next riter-rseq) - (deftype ReverseIter [set ^long left ^long right keys ^long idx] #?@(:cljs [ ISeqable diff --git a/src/datascript/core.cljc b/src/datascript/core.cljc index 31907fad..baf6475f 100644 --- a/src/datascript/core.cljc +++ b/src/datascript/core.cljc @@ -14,22 +14,38 @@ ;; SUMMING UP +(defn ^:declared q [q & inputs]) (def ^:export q dq/q) + +(defn ^:declared entity [db eid]) (def ^:export entity de/entity) + (defn ^:export entity-db [^Entity entity] {:pre [(de/entity? entity)]} (.-db entity)) +(defn ^:declared datom ([e a v]) ([e a v tx]) ([e a v tx added])) (def ^:export datom db/datom) +(defn ^:declared pull [db selector eid]) (def ^:export pull dp/pull) + +(defn ^:declared pull-many [db selector eids]) (def ^:export pull-many dp/pull-many) + +(defn ^:declared touch [e]) (def ^:export touch de/touch) +(defn ^:declared empty-db ([]) ([schema])) (def ^:export empty-db db/empty-db) + +(defn ^:declared init-db ([datoms]) ([datoms schema])) (def ^:export init-db db/init-db) +(defn ^:declared datom? [x]) (def ^:export datom? db/datom?) + +(defn ^:declared db? [x]) (def ^:export db? db/db?) (def ^:export ^:const tx0 db/tx0) @@ -81,6 +97,7 @@ {:pre [(db/db? db)]} (db/-index-range db attr start end)) +(defn ^:declared entid [db eid]) (def ^:export entid db/entid) ;; Conn diff --git a/src/datascript/db.cljc b/src/datascript/db.cljc index aa849c52..20485e54 100644 --- a/src/datascript/db.cljc +++ b/src/datascript/db.cljc @@ -26,7 +26,9 @@ data (last fragments)] `(throw (ex-info (str ~@(map (fn [m#] (if (string? m#) m# (list 'pr-str m#))) msgs)) ~data))))) -(defn seqable? [x] +(defn #?@(:clj [^Boolean seqable?] + :cljs [^boolean seqable?]) + [x] (and (not (string? x)) #?(:cljs (or (cljs.core/seqable? x) (da/array? x)) @@ -115,7 +117,13 @@ ;; ---------------------------------------------------------------------------- -(declare hash-datom equiv-datom seq-datom val-at-datom nth-datom assoc-datom) +;; using defn instead of declare because of http://dev.clojure.org/jira/browse/CLJS-1871 +(defn- ^:declared hash-datom [d]) +(defn- ^:declared equiv-datom [a b]) +(defn- ^:declared seq-datom [d]) +(defn- ^:declared nth-datom ([d i]) ([d i nf])) +(defn- ^:declared assoc-datom [d k v]) +(defn- ^:declared val-at-datom [d k nf]) (deftype Datom [e a v tx added] #?@(:cljs @@ -368,7 +376,16 @@ ;; ---------------------------------------------------------------------------- -(declare hash-db hash-fdb equiv-db empty-db pr-db resolve-datom validate-attr components->pattern indexing?) +;; using defn instead of declare because of http://dev.clojure.org/jira/browse/CLJS-1871 +(defn- ^:declared hash-db [db]) +(defn- ^:declared hash-fdb [db]) +(defn- ^:declared equiv-db [a b]) +(defn- ^:declared empty-db ([]) ([schema])) +#?(:cljs (defn ^:declared pr-db [db w opts])) +(defn- ^:declared resolve-datom [db e a v t]) +(defn- ^:declared validate-attr [attr at]) +(defn- ^:declared components->pattern [db index cs]) +(defn ^:declared indexing? [db attr]) (defrecord-updatable DB [schema eavt aevt avet max-eid max-tx rschema hash] #?@(:cljs @@ -681,7 +698,10 @@ ;; ---------------------------------------------------------------------------- -(declare entid-strict entid-some ref?) +;; using defn instead of declare because of http://dev.clojure.org/jira/browse/CLJS-1871 +(defn ^:declared entid-strict [db eid]) +(defn ^:declared entid-some [db eid]) +(defn ^:declared ref? [db attr]) (defn- resolve-datom [db e a v t] (when a (validate-attr a (list 'resolve-datom 'db e a v t))) @@ -985,7 +1005,8 @@ ~expr (cond-let ~@rest))))) -(declare transact-tx-data) +;; using defn instead of declare because of http://dev.clojure.org/jira/browse/CLJS-1871 +(defn ^:declared transact-tx-data [report es]) (defn retry-with-tempid [report es tempid upserted-eid] (if (contains? (:tempids report) tempid) diff --git a/src/datascript/impl/entity.cljc b/src/datascript/impl/entity.cljc index 7de87e5b..1c1ca33f 100644 --- a/src/datascript/impl/entity.cljc +++ b/src/datascript/impl/entity.cljc @@ -3,7 +3,12 @@ (:require [#?(:cljs cljs.core :clj clojure.core) :as c] [datascript.db :as db])) -(declare entity ->Entity equiv-entity lookup-entity touch) +;; using defn instead of declare because of http://dev.clojure.org/jira/browse/CLJS-1871 +(defn ^:declared entity [db eid]) +(defn ^:declared ->Entity [db eid touched cache]) +(defn- ^:declared equiv-entity [this that]) +(defn- ^:declared lookup-entity ([this attr]) ([this attr not-found])) +(defn ^:declared touch [e]) (defn- entid [db eid] (when (or (number? eid) diff --git a/src/datascript/js.cljs b/src/datascript/js.cljs index 9e8fa4c5..9216a3a5 100644 --- a/src/datascript/js.cljs +++ b/src/datascript/js.cljs @@ -17,7 +17,7 @@ (reduce-kv (fn [m k v] (assoc m k (walk/postwalk keywordize v))) {}))) -(declare entities->clj) +(defn- ^:declared entities->clj [entities]) (defn- entity->clj [e] (cond (map? e) @@ -90,15 +90,23 @@ (defn ^:export entity [db eid] (d/entity db (js->clj eid))) -(def ^:export touch d/touch) -(def ^:export entity_db d/entity-db) -(def ^:export filter d/filter) -(def ^:export is_filtered d/is-filtered) +(defn ^:export ^:declared touch [e]) +(def ^:export touch d/touch) + +(defn ^:export ^:declared entity_db [entity]) +(def ^:export entity_db d/entity-db) + +(defn ^:export ^:declared filter [db pred]) +(def ^:export filter d/filter) + +(defn ^:export ^:declared is-filtered [x]) +(def ^:export is_filtered d/is-filtered) (defn ^:export create_conn [& [schema]] (d/create-conn (schema->clj schema))) -(def ^:export conn_from_db d/conn-from-db) +(defn ^:export ^:declared conn-from-db [db]) +(def ^:export conn_from_db d/conn-from-db) (defn ^:export conn_from_datoms ([datoms] (conn_from_db (init_db datoms))) @@ -128,9 +136,11 @@ (callback report)) db)) -(def ^:export listen d/listen!) +(defn ^:export ^:declared listen ([conn callback]) ([conn key callback])) +(def ^:export listen d/listen!) -(def ^:export unlisten d/unlisten!) +(defn ^:export ^:declared unlisten [conn key]) +(def ^:export unlisten d/unlisten!) (defn ^:export resolve_tempid [tempids tempid] (aget tempids (str tempid))) diff --git a/src/datascript/lru.cljc b/src/datascript/lru.cljc index a290268b..ef670adb 100644 --- a/src/datascript/lru.cljc +++ b/src/datascript/lru.cljc @@ -1,6 +1,8 @@ (ns datascript.lru) -(declare assoc-lru cleanup-lru) +;; using defn instead of declare because of http://dev.clojure.org/jira/browse/CLJS-1871 +(defn ^:declared assoc-lru [lru k v]) +(defn ^:declared cleanup-lru [lru]) #?(:cljs (deftype LRU [key-value gen-key key-gen gen limit] diff --git a/src/datascript/parser.cljc b/src/datascript/parser.cljc index c0716041..ec99130b 100644 --- a/src/datascript/parser.cljc +++ b/src/datascript/parser.cljc @@ -7,7 +7,11 @@ ;; utils -(declare collect-vars-acc) +;; using defn instead of declare because of http://dev.clojure.org/jira/browse/CLJS-1871 +(defn- ^:declared collect-vars-acc [acc form]) +(defn ^:declared parse-clause [form]) +(defn ^:declared parse-clauses [clauses]) +(defn ^:declared parse-binding [form]) (defprotocol ITraversable (-collect [_ pred acc]) @@ -178,8 +182,6 @@ (deftrecord BindTuple [bindings]) (deftrecord BindColl [binding]) -(declare parse-binding) - (defn parse-bind-ignore [form] (when (= '_ form) (with-source (BindIgnore.) form))) @@ -406,7 +408,6 @@ (deftrecord Or [source rule-vars clauses]) (deftrecord And [clauses]) -(declare parse-clause parse-clauses) (defn parse-pattern-el [form] (or (parse-placeholder form) diff --git a/src/datascript/pull_api.cljc b/src/datascript/pull_api.cljc index 92d3a06f..20056f7c 100644 --- a/src/datascript/pull_api.cljc +++ b/src/datascript/pull_api.cljc @@ -62,8 +62,8 @@ [key frame] (some-> (:kvps frame) persistent! (get key))) -(def ^:private recursion-result - (partial single-frame-result ::recursion)) +(defn- recursion-result [frame] + (single-frame-result ::recursion frame)) (defn- recursion-frame [parent eid] diff --git a/src/datascript/pull_parser.cljc b/src/datascript/pull_parser.cljc index 1cd6a373..295eaf74 100644 --- a/src/datascript/pull_parser.cljc +++ b/src/datascript/pull_parser.cljc @@ -55,7 +55,8 @@ spec (reduce aggregate-specs init specs)] [:subpattern (update spec :attrs persistent!)]))) -(declare parse-pattern) +;; using defn instead of declare because of http://dev.clojure.org/jira/browse/CLJS-1871 +(defn ^:declared parse-pattern [pattern]) (def ^:private wildcard? #{'* :* "*"}) diff --git a/src/datascript/query.cljc b/src/datascript/query.cljc index 74d7ffe8..d7e5534b 100644 --- a/src/datascript/query.cljc +++ b/src/datascript/query.cljc @@ -19,7 +19,10 @@ ;; ---------------------------------------------------------------------------- (def ^:const lru-cache-size 100) -(declare built-ins) + +;; using defn instead of declare because of http://dev.clojure.org/jira/browse/CLJS-1871 +(defn ^:declared -collect ([context symbols]) ([acc rels symbols])) +(defn ^:declared -resolve-clause [context clause]) ;; Records @@ -234,8 +237,6 @@ (let [rules (if (string? rules) (edn/read-string rules) rules)] ;; for datascript.js interop (group-by ffirst rules))) -(def bindable-to-seq? db/seqable?) - (defn empty-rel [binding] (let [vars (->> (dp/collect-vars-distinct binding) (map :symbol))] @@ -256,7 +257,7 @@ BindColl (in->rel [binding coll] (cond - (not (bindable-to-seq? coll)) + (not (db/seqable? coll)) (raise "Cannot bind value " coll " to collection " (dp/source binding) {:error :query/binding, :value coll, :binding (dp/source binding)}) (empty? coll) @@ -268,7 +269,7 @@ BindTuple (in->rel [binding coll] (cond - (not (bindable-to-seq? coll)) + (not (db/seqable? coll)) (raise "Cannot bind value " coll " to tuple " (dp/source binding) {:error :query/binding, :value coll, :binding (dp/source binding)}) (< (count coll) (count (:bindings binding))) @@ -494,9 +495,6 @@ (second clause) (first clause))))) -(declare -collect) -(declare -resolve-clause) - (def rule-seqid (atom 0)) (defn expand-rule [clause context used-args] diff --git a/src/datascript/query_v3.cljc b/src/datascript/query_v3.cljc index 88f7159c..b94bcfbb 100644 --- a/src/datascript/query_v3.cljc +++ b/src/datascript/query_v3.cljc @@ -21,7 +21,13 @@ [datascript.db Datom] [datascript.btset Iter]))) -(declare resolve-clauses collect-rel-xf collect-to) +;; using defn instead of declare because of http://dev.clojure.org/jira/browse/CLJS-1871 +(defn ^:declared resolve-clauses [context clauses]) +(defn ^:declared collect-rel-xf [syms-indexed rel]) +(defn ^:declared collect-to + ([context syms acc]) + ([context syms acc xfs]) + ([context syms acc xfs specimen])) (def ^:const lru-cache-size 100) @@ -468,10 +474,6 @@ ;; Bindings - -(def bindable-to-seq? db/seqable?) - - (defn- bind! [tuples binding source indexes] (condp instance? binding @@ -485,7 +487,7 @@ tuples) BindColl - (if (not (bindable-to-seq? source)) + (if (not (db/seqable? source)) (db/raise "Cannot bind value " source " to collection " (dp/source binding) {:error :query/binding, :value source, :binding (dp/source binding)}) (let [inner-binding (:binding binding)] @@ -500,7 +502,7 @@ BindTuple (let [bindings (:bindings binding)] - (when-not (bindable-to-seq? source) + (when-not (db/seqable? source) (db/raise "Cannot bind value " source " to tuple " (dp/source binding) {:error :query/binding, :value source, :binding (dp/source binding)})) (when (< (count source) (count bindings)) @@ -579,7 +581,7 @@ (defn- matches-pattern? [idxs tuple] ;; TODO handle repeated vars -;; (when-not (bindable-to-seq? tuple) +;; (when-not (db/seqable? tuple) ;; (db/raise "Cannot match pattern " (dp/source clause) " because tuple is not a collection: " tuple ;; {:error :query/where, :value tuple, :binding (dp/source clause)})) ;; (when (< (count tuple) (count (:pattern clause))) @@ -595,7 +597,7 @@ (defn resolve-pattern-coll [coll clause] - (when-not (bindable-to-seq? coll) + (when-not (db/seqable? coll) (db/raise "Cannot match by pattern " (dp/source clause) " because source is not a collection: " coll {:error :query/where, :value coll, :binding (dp/source clause)})) (let [pattern (:pattern clause)