From 77fb997785daf7510fe50a5b79c3fa0a0ae85eea Mon Sep 17 00:00:00 2001 From: Richard Newman Date: Thu, 22 Sep 2016 10:38:45 -0700 Subject: [PATCH 01/14] Fix source paths. --- README.md | 18 ++++++++++++++++++ project.clj | 19 +++++++++++++------ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d9db9546..77f90f5a 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,24 @@ brew install rlwrap Run `lein cljsbuild auto advanced` to generate JavaScript into `target/`. +To build for a browser, into `release-browser`: + +``` +lein cljsbuild once release-browser +``` + +To build for node, into `release-node`: + +``` +lein cljsbuild once release-node +``` + +To package or install a JAR for node, modifying the source path appropriately (make sure you clean up swap or temp files in `src`!): + +``` +lein with-profile node jar +``` + ### Starting a ClojureScript REPL from the terminal ``` diff --git a/project.clj b/project.clj index bf0b92a6..07fdaa65 100644 --- a/project.clj +++ b/project.clj @@ -12,13 +12,19 @@ [jamesmacaulay/cljs-promises "0.1.0"]] ;; The browser will never require from the .JAR anyway. - :source-paths ["src/common" "src/node"] + :source-paths [ + "src/common" + ;; Can't be enabled by default: layers on top of cljsbuild! + ;; Instead, add the :node profile: + ;; lein with-profile node install + ;"src/node" + ] :cljsbuild {:builds { :release-node { - :source-paths ["src/node" "src/common"] + :source-paths ["src/node"] :assert false :compiler { @@ -46,7 +52,7 @@ ;; There's no point in generating a source map -- it'll be wrong ;; due to wrapping. { - :source-paths ["src/browser" "src/common"] + :source-paths ["src/common" "src/browser"] :assert false :compiler { @@ -67,7 +73,7 @@ :notify-command ["release-browser/wrap_bare.sh"]} :advanced - {:source-paths ["src/node" "src/common"] + {:source-paths ["src/node"] :compiler { :language-in :ecmascript5 @@ -83,7 +89,7 @@ :test { - :source-paths ["src/node" "src/common" "test"] + :source-paths ["src/node" "test"] :compiler { :language-in :ecmascript5 @@ -98,7 +104,8 @@ }} }} - :profiles {:dev {:dependencies [[cljsbuild "1.1.3"] + :profiles {:node {:source-paths ["src/common" "src/node"]} + :dev {:dependencies [[cljsbuild "1.1.3"] [tempfile "0.2.0"] [com.cemerick/piggieback "0.2.1"] [org.clojure/tools.nrepl "0.2.10"] From d178c53dcb07f7cbfffc182246dcbf6d466de89e Mon Sep 17 00:00:00 2001 From: Richard Newman Date: Wed, 14 Sep 2016 16:05:14 -0700 Subject: [PATCH 02/14] Use normal sqlite3 and promise_sqlite. --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 9e2570e9..d20d47ea 100644 --- a/package.json +++ b/package.json @@ -7,9 +7,9 @@ "version": "0.1.0-SNAPSHOT", "description": "A persistent, embedded knowledge base inspired by Datomic and DataScript.", "dependencies": { - "promise-sqlite": "1.2.1", + "promise-sqlite": "1.3.0", "source-map-support": "ncalexan/node-source-map-support#fileUrls-plus", - "sqlite3": "mossop/node-sqlite3#v3.1.4.1", + "sqlite3": "3.1.4", "thenify-all": "^1.6.0", "ws": "1.1.1" }, From 330433a45c146486dd3a518de64b8dec93b329ca Mon Sep 17 00:00:00 2001 From: Richard Newman Date: Wed, 14 Sep 2016 16:05:42 -0700 Subject: [PATCH 03/14] Add externs file for Node's use of promise_sqlite. --- project.clj | 2 ++ src/node/externs.js | 13 +++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 src/node/externs.js diff --git a/project.clj b/project.clj index 07fdaa65..e80272f1 100644 --- a/project.clj +++ b/project.clj @@ -29,6 +29,7 @@ :compiler { :elide-asserts true + :externs ["src/node/externs.js"] :hashbang false :language-in :ecmascript5 :language-out :ecmascript5 @@ -76,6 +77,7 @@ {:source-paths ["src/node"] :compiler { + :externs ["src/node/externs.js"] :language-in :ecmascript5 :language-out :ecmascript5 :output-dir "target/advanced" diff --git a/src/node/externs.js b/src/node/externs.js new file mode 100644 index 00000000..5bfb1525 --- /dev/null +++ b/src/node/externs.js @@ -0,0 +1,13 @@ +var sqlite = {}; + +sqlite.DB = {}; + +/** + * @return {Promise} + */ +sqlite.DB.open = function (path, options) {}; + +var DBVal = {}; +DBVal.run = function (sql, bindings) {}; +DBVal.close = function () {}; +DBVal.each = function (sql, bindings, cb) {}; From 1d53d547b86c4ca115abdba8dc7664a94d05d6f8 Mon Sep 17 00:00:00 2001 From: Richard Newman Date: Wed, 21 Sep 2016 14:05:12 -0700 Subject: [PATCH 04/14] Externs. --- src/browser/externs.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/browser/externs.js b/src/browser/externs.js index a39b1a03..f6356568 100644 --- a/src/browser/externs.js +++ b/src/browser/externs.js @@ -1,3 +1,11 @@ +var Object = {}; +Object.keys = function (object) {}; +Object.__proto__ = {}; +Object.hasOwnProperty = function () {}; +var Array = {}; +Array.length = 0; +Array.isArray = function () {}; + var SqliteStatic = {}; /** From ea027e8cea9e90a56135546979a81479d38f210e Mon Sep 17 00:00:00 2001 From: Richard Newman Date: Wed, 21 Sep 2016 14:07:19 -0700 Subject: [PATCH 05/14] Implement cljify. --- src/browser/datomish/cljify.cljs | 47 ++++++++++++++++++++++++++++++++ src/node/datomish/cljify.cljs | 7 +++++ 2 files changed, 54 insertions(+) create mode 100644 src/browser/datomish/cljify.cljs create mode 100644 src/node/datomish/cljify.cljs diff --git a/src/browser/datomish/cljify.cljs b/src/browser/datomish/cljify.cljs new file mode 100644 index 00000000..7c02f5bb --- /dev/null +++ b/src/browser/datomish/cljify.cljs @@ -0,0 +1,47 @@ +(ns datomish.cljify) + +(defn cljify + "Does what `(js->clj o :keywordize-keys true) is supposed to do, but works + in environments with more than one context (e.g., web browsers). + + See . + + Note that Date instances are passed through." + [o] + (cond + (nil? o) + nil + + ;; Primitives. + (or + (true? o) + (false? o) + (number? o) + (string? o) + ;; Dates are passed through. + (not (nil? (aget (aget o "__proto__") "getUTCMilliseconds")))) + o + + ;; Array. + (.isArray js/Array o) + (let [n (.-length o)] + (loop [i 0 + acc (transient [])] + (if (< i n) + (recur (inc i) (conj! acc (cljify (aget o i)))) + (persistent! acc)))) + + ;; Object. + (not (nil? (aget (aget o "__proto__") "hasOwnProperty"))) + (let [a (.keys js/Object o) + n (.-length a)] + (loop [i 0 + acc (transient {})] + (if (< i n) + (let [key (aget a i)] + (recur (inc i) (assoc! acc + (keyword key) + (cljify (aget o key))))) + (persistent! acc)))) + + :else o)) diff --git a/src/node/datomish/cljify.cljs b/src/node/datomish/cljify.cljs new file mode 100644 index 00000000..3ef64a3f --- /dev/null +++ b/src/node/datomish/cljify.cljs @@ -0,0 +1,7 @@ +(ns datomish.cljify) + +(defn cljify + "In node, equivalent to `(js->clj o :keywordize-keys true). + See ." + [o] + (js->clj o :keywordize-keys true)) From 4f37a860392655285455268446bea5ff3ad0ac48 Mon Sep 17 00:00:00 2001 From: Richard Newman Date: Wed, 21 Sep 2016 17:31:36 -0700 Subject: [PATCH 06/14] Use cljify in promise-sqlite. --- src/node/datomish/promise_sqlite.cljs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/node/datomish/promise_sqlite.cljs b/src/node/datomish/promise_sqlite.cljs index 539fd5da..ddf6c1c3 100644 --- a/src/node/datomish/promise_sqlite.cljs +++ b/src/node/datomish/promise_sqlite.cljs @@ -5,6 +5,7 @@ (ns datomish.promise-sqlite (:require [datomish.sqlite :as s] + [datomish.cljify :refer [cljify]] [cljs-promises.async] [cljs.nodejs :as nodejs])) @@ -20,7 +21,7 @@ (-each [db sql bindings row-cb] (let [cb (fn [row] - (row-cb (js->clj row :keywordize-keys true)))] + (row-cb (cljify row)))] (cljs-promises.async/pair-port (.each (.-db db) sql (or (clj->js bindings) #js []) (when row-cb cb))))) From bae1cfdc77ae921de17bb5aa1547e04da1308ea1 Mon Sep 17 00:00:00 2001 From: Richard Newman Date: Thu, 15 Sep 2016 15:11:58 -0700 Subject: [PATCH 07/14] Alter release node config to be a bit more human-readable. --- project.clj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/project.clj b/project.clj index e80272f1..3089b31b 100644 --- a/project.clj +++ b/project.clj @@ -38,7 +38,9 @@ :output-to "release-node/datomish.bare.js" :output-wrapper false :parallel-build true - :pretty-print false + :pretty-print true + :pseudo-names true + :static-fns true :target :nodejs } :notify-command ["release-node/wrap_bare.sh"]} From 360f7622e8cc07cce05497895eaf7959b0c7093d Mon Sep 17 00:00:00 2001 From: Richard Newman Date: Wed, 14 Sep 2016 16:08:13 -0700 Subject: [PATCH 08/14] Add handling of simple schemas. Fixes #53. --- src/common/datomish/db.cljc | 4 ++ src/common/datomish/js.cljs | 40 ++++++++++++++-- src/common/datomish/schema.cljc | 1 + src/common/datomish/simple_schema.cljc | 66 ++++++++++++++++++++++++++ src/node/datomish/core.cljs | 7 +-- test/datomish/db_test.cljc | 34 +++++++++++++ 6 files changed, 143 insertions(+), 9 deletions(-) create mode 100644 src/common/datomish/simple_schema.cljc diff --git a/src/common/datomish/db.cljc b/src/common/datomish/db.cljc index 16b74700..5fd28115 100644 --- a/src/common/datomish/db.cljc +++ b/src/common/datomish/db.cljc @@ -713,6 +713,10 @@ Returns a transduced channel of [result err] pairs. Closes the channel when fully consumed." [db find options] + (let [unexpected (seq (clojure.set/difference (set (keys options)) #{:limit :order-by :inputs}))] + (when unexpected + (raise "Unexpected options: " unexpected {:bad-options unexpected}))) + (let [{:keys [limit order-by inputs]} options parsed (query/parse find) context (-> db diff --git a/src/common/datomish/js.cljs b/src/common/datomish/js.cljs index c67f7854..0fd7aa5a 100644 --- a/src/common/datomish/js.cljs +++ b/src/common/datomish/js.cljs @@ -14,6 +14,7 @@ [datomish.db-factory :as db-factory] [datomish.pair-chan] [datomish.sqlite :as sqlite] + [datomish.simple-schema :as simple-schema] [datomish.js-sqlite :as js-sqlite] [datomish.transact :as transact])) @@ -29,6 +30,38 @@ ;; Public API. +(defn ^:export db [conn] + (transact/db conn)) + +(defn ^:export q [db find options] + (let [find (cljs.reader/read-string find) + options (js->clj options)] + (take-pair-as-promise! + (db/clj simple-schema)] + (println "simple-schema: " (pr-str simple-schema)) + (take-pair-as-promise! + (transact/schema simple-schema))))) + +(defn js->tx-data [tx-data] + ;; Objects to maps. + ;; Arrays to arrays. + ;; RHS stringsā€¦ well, some of them will be richer types. + ;; TODO + (println "Converting" (pr-str tx-data) "to" (pr-str (js->clj tx-data :keywordize-keys true))) + (println "Converting" (pr-str tx-data) "to" (pr-str (js->clj tx-data :keywordize-keys true))) + (js->clj tx-data)) + +(defn ^:export transact [conn tx-data] + ;; Expects a JS array as input. + (let [tx-data (js->tx-data tx-data)] + (take-pair-as-promise! + (transact/js {:conn c + :ensureSchema (fn [simple-schema] (ensure-schema c simple-schema)) + :transact (fn [tx-data] (transact c tx-data)) + :q (fn [find options] (q (transact/db c) find options)) :close (fn [] (db/close-db db)) :toString (fn [] (str "#")) :path path})))))) - -(defn ^:export q [query & sources] - (let [query (cljs.reader/read-string query)] - (clj->js query))) diff --git a/src/common/datomish/schema.cljc b/src/common/datomish/schema.cljc index b4524d7a..664a34b6 100644 --- a/src/common/datomish/schema.cljc +++ b/src/common/datomish/schema.cljc @@ -208,3 +208,4 @@ {:pre [(or (nil? schema) (map? schema))]} (map->Schema {:schema (validate-schema schema) :rschema (rschema schema)})) + diff --git a/src/common/datomish/simple_schema.cljc b/src/common/datomish/simple_schema.cljc new file mode 100644 index 00000000..2bba32d7 --- /dev/null +++ b/src/common/datomish/simple_schema.cljc @@ -0,0 +1,66 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. + +(ns datomish.simple-schema + #?(:cljs + (:require-macros + [datomish.pair-chan :refer [go-pair !]]]) + #?@(:cljs [[datomish.pair-chan] + [cljs.core.async :as a :refer [chan !]]]))) + +(defn- name->ident [name] + (when-not (and (string? name) + (not (empty? name))) + (raise "Invalid name " name {:error :invalid-name :name name})) + (keyword name)) + +(defn simple-schema-attributes->schema-parts [attrs] + (let [{:keys [cardinality type name unique doc fulltext]} attrs + value-type (when type (keyword (str "db.type/" type)))] + + (when-not (and value-type + (contains? ds/value-type-map value-type)) + (raise "Invalid type " type {:error :invalid-type :type type})) + + (let [unique + (case unique + "identity" :db.unique/identity + "value" :db.unique/value + nil nil + (raise "Invalid unique " unique + {:error :invalid-unique :unique unique})) + + cardinality + (case cardinality + "one" :db.cardinality/one + "many" :db.cardinality/many + nil nil + (raise "Invalid cardinality " cardinality + {:error :invalid-cardinality :cardinality cardinality}))] + + (util/assoc-if + {:db/valueType value-type + :db/ident (name->ident name) + :db/id (db/id-literal :db.part/user) + :db.install/_attribute :db.part/db} + :db/doc doc + :db/unique unique + :db/fulltext fulltext + :db/cardinality cardinality)))) + +(defn simple-schema->schema [simple-schema] + (let [{:keys [name attributes]} simple-schema] + (map simple-schema-attributes->schema-parts attributes))) + diff --git a/src/node/datomish/core.cljs b/src/node/datomish/core.cljs index 61e7b573..7b77da5a 100644 --- a/src/node/datomish/core.cljs +++ b/src/node/datomish/core.cljs @@ -5,9 +5,6 @@ (ns datomish.core (:require [cljs.nodejs :as nodejs])) -(nodejs/enable-util-print!) - -(defn -main [& args] - (println "Hello world!")) - +(defn -main [& args]) (set! *main-cli-fn* -main) +(nodejs/enable-util-print!) diff --git a/test/datomish/db_test.cljc b/test/datomish/db_test.cljc index 2d972461..1dea8c66 100644 --- a/test/datomish/db_test.cljc +++ b/test/datomish/db_test.cljc @@ -13,6 +13,7 @@ [datomish.db.debug :refer [schema in)) + expected))))) + + #_ (time (t/run-tests)) From 17d7eaec7bcecbe34012153afe1bf2ca8513cef3 Mon Sep 17 00:00:00 2001 From: Richard Newman Date: Wed, 21 Sep 2016 14:07:04 -0700 Subject: [PATCH 09/14] Add a babelified test file, Webpack the add-on, and make the JS API work. We concatenate a simple setTimeout monkeypatch onto the add-on itself. --- .babelrc | 27 ++++++++ .gitignore | 7 +- addon/.babelrc | 6 ++ addon/build.sh | 2 + addon/index.js | 15 ----- addon/package.json | 28 +++++--- addon/{ => release}/README.md | 0 addon/release/data/datomish-48.png | Bin 0 -> 1082 bytes addon/release/package.json | 15 +++++ addon/release/run.sh | 1 + addon/src/index.js | 101 +++++++++++++++++++++++++++++ addon/src/wrapper.prefix | 4 ++ addon/webpack.config.js | 21 ++++++ package.json | 23 ++++++- src/common/datomish/js.cljs | 76 ++++++++++++++-------- test/js/tests.js | 46 +++++++++++++ 16 files changed, 317 insertions(+), 55 deletions(-) create mode 100644 .babelrc create mode 100644 addon/.babelrc create mode 100755 addon/build.sh delete mode 100644 addon/index.js rename addon/{ => release}/README.md (100%) create mode 100644 addon/release/data/datomish-48.png create mode 100644 addon/release/package.json create mode 100755 addon/release/run.sh create mode 100644 addon/src/index.js create mode 100644 addon/src/wrapper.prefix create mode 100644 addon/webpack.config.js create mode 100644 test/js/tests.js diff --git a/.babelrc b/.babelrc new file mode 100644 index 00000000..d707934a --- /dev/null +++ b/.babelrc @@ -0,0 +1,27 @@ +{ + "env": { + "production": { + "presets": ["react", "react-optimize"] + }, + "development": { + "presets": ["react"] + }, + "test": { + "presets": ["react"] + } + }, + "only": [ + "test/js/**" + ], + "plugins": [ + "transform-es2015-destructuring", + "transform-es2015-parameters", + "transform-es2015-modules-commonjs", + "transform-async-to-generator", + "transform-object-rest-spread", + "transform-class-properties", + "transform-runtime" + ], + "sourceMaps": "inline", + "retainLines": true +} diff --git a/.gitignore b/.gitignore index 76f17ade..bb6ab5a9 100644 --- a/.gitignore +++ b/.gitignore @@ -28,5 +28,8 @@ pom.xml.asc /release-node /release-node/datomish.js /release-node/datomish.bare.js -/addon/datomish-test.xpi -/addon/datomish.js +/addon/built/index.js +/addon/node_modules/ +/addon/release/datomish-test.xpi +/addon/release/datomish.js +/addon/release/index.js diff --git a/addon/.babelrc b/addon/.babelrc new file mode 100644 index 00000000..a0dc53f5 --- /dev/null +++ b/addon/.babelrc @@ -0,0 +1,6 @@ +{ + "presets": ["es2015"], + "plugins": [ + "transform-async-to-generator" + ] +} diff --git a/addon/build.sh b/addon/build.sh new file mode 100755 index 00000000..493c055d --- /dev/null +++ b/addon/build.sh @@ -0,0 +1,2 @@ +node_modules/.bin/webpack -p +cat src/wrapper.prefix built/index.js > release/index.js diff --git a/addon/index.js b/addon/index.js deleted file mode 100644 index 765cb243..00000000 --- a/addon/index.js +++ /dev/null @@ -1,15 +0,0 @@ -var self = require("sdk/self"); - -console.log("Datomish Test"); -console.log("This: " + this); - -var datomish = require("datomish.js"); -datomish.open("/tmp/foobar.db").then(function (db) { - console.log("Got " + db); - try { - db.close(); - console.log("Closed."); - } catch (e) { - console.log("Couldn't close: " + e); - } -}); diff --git a/addon/package.json b/addon/package.json index 6a190546..c2e4d9f0 100644 --- a/addon/package.json +++ b/addon/package.json @@ -1,15 +1,23 @@ { - "title": "Datomish Test", - "name": "datomish-test", - "version": "0.0.1", - "description": "An example add-on that loads Datomish on top of Sqlite.jsm.", + "name": "datomish-example", + "version": "1.0.0", + "description": "A test add-on for Datomish and Firefox.", "main": "index.js", - "author": "Richard Newman ", - "engines": { - "firefox": ">=48.0a1" + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" }, + "author": "", "license": "MPL-2.0", - "keywords": [ - "jetpack" - ] + "devDependencies": { + "babel": "^6.5.2", + "babel-cli": "^6.14.0", + "babel-core": "^6.14.0", + "babel-loader": "^6.2.5", + "babel-plugin-transform-async-to-generator": "^6.8.0", + "babel-preset-es2015": "^6.14.0", + "webpack": "^1.13.2" + }, + "dependencies": { + "babel-polyfill": "^6.13.0" + } } diff --git a/addon/README.md b/addon/release/README.md similarity index 100% rename from addon/README.md rename to addon/release/README.md diff --git a/addon/release/data/datomish-48.png b/addon/release/data/datomish-48.png new file mode 100644 index 0000000000000000000000000000000000000000..42b9cb678787a5dd3a81dd86bebd51c225fc3447 GIT binary patch literal 1082 zcmeAS@N?(olHy`uVBq!ia0vp^20*OG!2%?YTn~BNn{1`6_P!I zd>I(3)EF2VS{N990fib~Fffz?HNHwHx@oI*`2amCO38HbXa+=a^?Od zuz0ZMqN)1HO>;NZrWl>vHD~kHXHR`5s3&Tra853Ik~U4jd*a(| z+EH6x*Gx>0H)irP1Vb!|n#=IvQ50jN=s@+Ii>~!5NhimFC z!`4rJwAcFq<*v%Jq!Dt;(-iz$1ROMK*Nd#mVQIYJML|wahgLeY~_ztej>ulIvgW8r#D@5?;qnVm~!@J%mqIO_EBezdUo z8S6uzKJHpPQNO}&*VSJ}mU7<~3g0W^e7h@{eaemnr=O{4e`zh;t=l)lpQTM^Qg==@ zZ`P#ge*d;e&fguqQ%n8m-u&LB8;r{K#*2qGz?7V1?Qt zdEf=*?4!Azac&33yd<+RV=8vjpz z#$l)3Kb}TEog^V#exNoi`aR=$&CvD6k6-j`@R}Rf*wT{MzpUzaebvviWqYkfcCT=L zFS_S1SJ;N8|04gG7`AFGkO-LQ0L)9OC9V-ADTyViR>?)FK#IZ0z|c(Bz*5)1EX2^< v%EZhH#5K1vFt8E*Jr_koZhlH;S|t_@rVtG^3nKRbH86O(`njxgN@xNAGvwj5 literal 0 HcmV?d00001 diff --git a/addon/release/package.json b/addon/release/package.json new file mode 100644 index 00000000..6a190546 --- /dev/null +++ b/addon/release/package.json @@ -0,0 +1,15 @@ +{ + "title": "Datomish Test", + "name": "datomish-test", + "version": "0.0.1", + "description": "An example add-on that loads Datomish on top of Sqlite.jsm.", + "main": "index.js", + "author": "Richard Newman ", + "engines": { + "firefox": ">=48.0a1" + }, + "license": "MPL-2.0", + "keywords": [ + "jetpack" + ] +} diff --git a/addon/release/run.sh b/addon/release/run.sh new file mode 100755 index 00000000..40114394 --- /dev/null +++ b/addon/release/run.sh @@ -0,0 +1 @@ +jpm run -b /Applications/FirefoxNightly.app/ diff --git a/addon/src/index.js b/addon/src/index.js new file mode 100644 index 00000000..9b8817da --- /dev/null +++ b/addon/src/index.js @@ -0,0 +1,101 @@ +var self = require("sdk/self"); +var buttons = require('sdk/ui/button/action'); +var tabs = require('sdk/tabs'); + +var datomish = require("datomish.js"); + +var schema = { + "name": "pages", + "attributes": [ + {"name": "page/url", + "type": "string", + "cardinality": "one", + "unique": "identity", + "doc": "A page's URL."}, + {"name": "page/title", + "type": "string", + "cardinality": "one", + "fulltext": true, + "doc": "A page's title."}, + {"name": "page/content", + "type": "string", + "cardinality": "one", // Simple for now. + "fulltext": true, + "doc": "A snapshot of the page's content. Should be plain text."}, + ] +}; + +async function initDB(path) { + let db = await datomish.open(path); + await db.ensureSchema(schema); + return db; +} + +async function findURLs(db) { + let query = `[:find ?page ?url ?title :in $ :where [?page :page/url ?url][(get-else $ ?page :page/title "") ?title]]`; + let options = new Object(); + options["limit"] = 10; + return datomish.q(db.db(), query, options); +} + +async function findPagesMatching(db, string) { + let query = + `[:find ?url ?title + :in $ ?str + :where + [(fulltext $ :any ?str) [[?page]]] + [?page :page/url ?url] + [(get-else $ ?page :page/title "") ?title]]`; + return datomish.q(db.db(), query, {"limit": 10, "inputs": {"str": string}}); +} + +async function savePage(db, url, title, content) { + let txResult = await db.transact([{"db/id": 55, + "page/title": title, + "page/url": url + // "page/starred": true + }]); + return txResult; +} + +async function handleClick(state) { + let db = await datomish.open("/tmp/testing.db"); + await db.ensureSchema(schema); + let txResult = await savePage(db, tabs.activeTab.url, tabs.activeTab.title, "Content goes here"); + console.log("Transaction returned " + JSON.stringify(txResult)); + console.log("Transaction instant: " + txResult.txInstant); + let results = await findURLs(db); //datomish.q(db.db(), "[:find ?url :in $ :where [?e :page/url ?url]]"); + results = results.map(r => r[1]); + console.log("Query results: " + JSON.stringify(results)); + let pages = await findPagesMatching(db, "goes"); + console.log("Pages: " + JSON.stringify(pages)); + await db.close(); +} + +/* +async function handleClick(state) { + console.log("Handling click: " + state); + let tab = tabs.activeTab; + console.log("Active tab: " + tab); + console.log("Active tab: " + tab.url); + console.log("Active tab: " + tab.title); + let db = await initDB("/tmp/datomish.db"); + console.log("Opened DB: " + db); + await savePage(db, tab.url, tab.title, "Content goes here."); + console.log("Saved page."); + + let urls = await findURLs(db); + console.log("URLs: " + JSON.stringify(urls)); + + let results = await findPagesMatching(db, "goes"); + console.log("Pages: " + JSON.stringify(results)); + await db.close(); +} +*/ + +var button = buttons.ActionButton({ + id: "datomish-save", + label: "Save Page", + icon: "./datomish-48.png", + onClick: handleClick +}); diff --git a/addon/src/wrapper.prefix b/addon/src/wrapper.prefix new file mode 100644 index 00000000..f69c8236 --- /dev/null +++ b/addon/src/wrapper.prefix @@ -0,0 +1,4 @@ +// Monkeypatch. +var { setTimeout } = require("sdk/timers"); +this.setTimeout = setTimeout; + diff --git a/addon/webpack.config.js b/addon/webpack.config.js new file mode 100644 index 00000000..f82bede4 --- /dev/null +++ b/addon/webpack.config.js @@ -0,0 +1,21 @@ + +module.exports = { + entry: ['babel-polyfill', './src/index.js'], + output: { + filename: 'built/index.js' + }, + target: 'webworker', + externals: { + 'datomish.js': 'commonjs datomish.js', + 'sdk/self': 'commonjs sdk/self', + 'sdk/ui/button/action': 'commonjs sdk/ui/button/action', + 'sdk/tabs': 'commonjs sdk/tabs' + }, + module: { + loaders: [{ + test: /\.js?$/, + exclude: /(node_modules)|(wrapper.prefix)/, + loader: 'babel' + }] + } +} diff --git a/package.json b/package.json index d20d47ea..696f3d89 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,26 @@ "thenify-all": "^1.6.0", "ws": "1.1.1" }, + "scripts": { + "test": "babel-node test/js/tests.js" + }, "devDependencies": { + "babel-cli": "^6.14.0", + "babel-core": "6.14.0", + "babel-eslint": "6.1.2", + "babel-loader": "6.2.5", + "babel-plugin-transform-async-to-generator": "6.8.0", + "babel-plugin-transform-class-properties": "6.11.5", + "babel-plugin-transform-es2015-destructuring": "6.9.0", + "babel-plugin-transform-es2015-modules-commonjs": "6.11.5", + "babel-plugin-transform-es2015-parameters": "6.11.4", + "babel-plugin-transform-object-rest-spread": "6.8.0", + "babel-plugin-transform-runtime": "6.12.0", + "babel-polyfill": "6.13.0", + "babel-preset-react": "6.11.1", + "babel-preset-react-optimize": "1.0.1", + "babel-register": "6.14.0", + "babel-runtime": "6.11.6", "tmp": "0.0.28" }, "repository": { @@ -27,5 +46,7 @@ }, "homepage": "https://github.com/mozilla/datomish#readme", "main": "./datomish.js", - "files": ["datomish.js"] + "files": [ + "datomish.js" + ] } diff --git a/src/common/datomish/js.cljs b/src/common/datomish/js.cljs index 0fd7aa5a..fc7a39cb 100644 --- a/src/common/datomish/js.cljs +++ b/src/common/datomish/js.cljs @@ -10,6 +10,7 @@ [cljs.core.async :as a :refer [take! !]] [cljs.reader] [cljs-promises.core :refer [promise]] + [datomish.cljify :refer [cljify]] [datomish.db :as db] [datomish.db-factory :as db-factory] [datomish.pair-chan] @@ -18,14 +19,17 @@ [datomish.js-sqlite :as js-sqlite] [datomish.transact :as transact])) -(defn- take-pair-as-promise! [ch] +(defn- take-pair-as-promise! [ch f] ;; Just like take-as-promise!, but aware that it's handling a pair channel. + ;; Also converts values, if desired. (promise (fn [resolve reject] (letfn [(split-pair [[v e]] (if e - (reject e) - (resolve v)))] + (do + (println "Got error:" e) + (reject e)) + (resolve (f v))))] (cljs.core.async/take! ch split-pair))))) ;; Public API. @@ -35,32 +39,46 @@ (defn ^:export q [db find options] (let [find (cljs.reader/read-string find) - options (js->clj options)] + opts (cljify options)] + (println "Running query " (pr-str find) (pr-str {:foo find}) (pr-str opts)) (take-pair-as-promise! - (db/js res))) + identity))) (defn ^:export ensure-schema [conn simple-schema] - (let [simple-schema (js->clj simple-schema)] - (println "simple-schema: " (pr-str simple-schema)) + (let [simple-schema (cljify simple-schema) + datoms (simple-schema/simple-schema->schema simple-schema)] + (println "Transacting schema datoms" (pr-str datoms)) (take-pair-as-promise! (transact/schema simple-schema))))) + datoms) + clj->js))) -(defn js->tx-data [tx-data] - ;; Objects to maps. - ;; Arrays to arrays. - ;; RHS stringsā€¦ well, some of them will be richer types. - ;; TODO - (println "Converting" (pr-str tx-data) "to" (pr-str (js->clj tx-data :keywordize-keys true))) - (println "Converting" (pr-str tx-data) "to" (pr-str (js->clj tx-data :keywordize-keys true))) - (js->clj tx-data)) +(def js->tx-data cljify) + +(def ^:export tempid (partial db/id-literal :db.part/user)) (defn ^:export transact [conn tx-data] ;; Expects a JS array as input. - (let [tx-data (js->tx-data tx-data)] - (take-pair-as-promise! - (transact/tx-data tx-data)] + (println "Transacting:" (pr-str tx-data)) + (take-pair-as-promise! + (go-pair + (let [tx-result (js)) + (catch js/Error e + (println "Error in transact:" e)))) (defn ^:export open [path] ;; Eventually, URI. For now, just a plain path (no file://). @@ -69,11 +87,15 @@ (let [conn (js - {:conn c - :ensureSchema (fn [simple-schema] (ensure-schema c simple-schema)) - :transact (fn [tx-data] (transact c tx-data)) - :q (fn [find options] (q (transact/db c) find options)) - :close (fn [] (db/close-db db)) - :toString (fn [] (str "#")) - :path path})))))) + (clj->js + ;; We pickle the connection as a thunk here so it roundtrips through JS + ;; without incident. + {:conn (fn [] c) + :roundtrip (fn [x] (clj->js (cljify x))) + :db (fn [] (transact/db c)) + :ensureSchema (fn [simple-schema] (ensure-schema c simple-schema)) + :transact (fn [tx-data] (transact c tx-data)) + :close (fn [] (db/close-db db)) + :toString (fn [] (str "#")) + :path path})))) + identity)) diff --git a/test/js/tests.js b/test/js/tests.js new file mode 100644 index 00000000..e9e20a44 --- /dev/null +++ b/test/js/tests.js @@ -0,0 +1,46 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +var datomish = require("../../release-node/datomish.js"); + +var schema = { + "name": "pages", + "attributes": [ + {"name": "page/url", + "type": "string", + "cardinality": "one", + "unique": "identity", + "doc": "A page's URL."}, + {"name": "page/title", + "type": "string", + "cardinality": "one", + "doc": "A page's title."}, + {"name": "page/starred", + "type": "boolean", + "cardinality": "one", + "doc": "Whether the page is starred."}, + {"name": "page/visit", + "type": "ref", + "cardinality": "many", + "doc": "A visit to the page."} + ] +}; + +async function testOpen() { + let db = await datomish.open("/tmp/testing.db"); + await db.ensureSchema(schema); + let txResult = await db.transact([{"db/id": 55, + "page/url": "http://foo.com/bar", + "page/starred": true}]); + console.log("Transaction returned " + JSON.stringify(txResult)); + console.log("Transaction instant: " + txResult.txInstant); + let results = await datomish.q(db.db(), "[:find ?url :in $ :where [?e :page/url ?url]]") + results = results.map(r => r[0]); + console.log("Query results: " + JSON.stringify(results)); + await db.close(); +} + +testOpen() +.then((r) => console.log("Done.")) +.catch((e) => console.log("Failure: " + e.stack)); From 548340c655369a21b9fbac6e68c07d05700d99bf Mon Sep 17 00:00:00 2001 From: Richard Newman Date: Thu, 22 Sep 2016 15:46:16 -0700 Subject: [PATCH 10/14] Copy the built datomish.js when building the add-on. --- addon/build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/addon/build.sh b/addon/build.sh index 493c055d..925bc6c3 100755 --- a/addon/build.sh +++ b/addon/build.sh @@ -1,2 +1,3 @@ +cp ../target/release-browser/datomish.js release/ node_modules/.bin/webpack -p cat src/wrapper.prefix built/index.js > release/index.js From 155f9b6d988034f5592ec6873f0e8693245a8c02 Mon Sep 17 00:00:00 2001 From: Richard Newman Date: Thu, 22 Sep 2016 15:49:35 -0700 Subject: [PATCH 11/14] Add Public Domain license to addon code. --- addon/src/index.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/addon/src/index.js b/addon/src/index.js index 9b8817da..5a6c3868 100644 --- a/addon/src/index.js +++ b/addon/src/index.js @@ -1,3 +1,6 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + var self = require("sdk/self"); var buttons = require('sdk/ui/button/action'); var tabs = require('sdk/tabs'); From 03d8d178fbd1243951fd7168dd2cde050fe9a3ab Mon Sep 17 00:00:00 2001 From: Richard Newman Date: Wed, 21 Sep 2016 17:34:04 -0700 Subject: [PATCH 12/14] Add CREDITS file for the icon the add-on uses. --- addon/CREDITS | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 addon/CREDITS diff --git a/addon/CREDITS b/addon/CREDITS new file mode 100644 index 00000000..359a4f89 --- /dev/null +++ b/addon/CREDITS @@ -0,0 +1,3 @@ +Icon file is "Line Graph" by Cris Dobbins, from The Noun Project. + +https://thenounproject.com/term/line-graph/145324/ From d0a04a5e56ea2abaf3da5be5a714e7411724d7c3 Mon Sep 17 00:00:00 2001 From: Richard Newman Date: Wed, 21 Sep 2016 18:07:34 -0700 Subject: [PATCH 13/14] Review comment: extracted shared go-promise. --- addon/src/index.js | 42 +++++++----------- src/common/datomish/js.cljs | 73 ++++++++++++------------------- src/common/datomish/promises.cljc | 30 +++++++++++++ 3 files changed, 72 insertions(+), 73 deletions(-) create mode 100644 src/common/datomish/promises.cljc diff --git a/addon/src/index.js b/addon/src/index.js index 5a6c3868..d0cb6142 100644 --- a/addon/src/index.js +++ b/addon/src/index.js @@ -53,49 +53,37 @@ async function findPagesMatching(db, string) { } async function savePage(db, url, title, content) { - let txResult = await db.transact([{"db/id": 55, - "page/title": title, - "page/url": url - // "page/starred": true - }]); + let datom = {"db/id": 55, "page/url": url}; + if (title) { + datom["page/title"] = title; + } + if (content) { + datom["page/content"] = content; + } + let txResult = await db.transact([datom]); return txResult; } async function handleClick(state) { let db = await datomish.open("/tmp/testing.db"); await db.ensureSchema(schema); + let txResult = await savePage(db, tabs.activeTab.url, tabs.activeTab.title, "Content goes here"); + console.log("Transaction returned " + JSON.stringify(txResult)); console.log("Transaction instant: " + txResult.txInstant); - let results = await findURLs(db); //datomish.q(db.db(), "[:find ?url :in $ :where [?e :page/url ?url]]"); + + let results = await findURLs(db); results = results.map(r => r[1]); + console.log("Query results: " + JSON.stringify(results)); + let pages = await findPagesMatching(db, "goes"); + console.log("Pages: " + JSON.stringify(pages)); await db.close(); } -/* -async function handleClick(state) { - console.log("Handling click: " + state); - let tab = tabs.activeTab; - console.log("Active tab: " + tab); - console.log("Active tab: " + tab.url); - console.log("Active tab: " + tab.title); - let db = await initDB("/tmp/datomish.db"); - console.log("Opened DB: " + db); - await savePage(db, tab.url, tab.title, "Content goes here."); - console.log("Saved page."); - - let urls = await findURLs(db); - console.log("URLs: " + JSON.stringify(urls)); - - let results = await findPagesMatching(db, "goes"); - console.log("Pages: " + JSON.stringify(results)); - await db.close(); -} -*/ - var button = buttons.ActionButton({ id: "datomish-save", label: "Save Page", diff --git a/src/common/datomish/js.cljs b/src/common/datomish/js.cljs index fc7a39cb..0c7ab46b 100644 --- a/src/common/datomish/js.cljs +++ b/src/common/datomish/js.cljs @@ -5,7 +5,8 @@ (ns datomish.js (:refer-clojure :exclude []) (:require-macros - [datomish.pair-chan :refer [go-pair !]] [cljs.reader] @@ -14,23 +15,12 @@ [datomish.db :as db] [datomish.db-factory :as db-factory] [datomish.pair-chan] + [datomish.promises :refer [take-pair-as-promise!]] [datomish.sqlite :as sqlite] [datomish.simple-schema :as simple-schema] [datomish.js-sqlite :as js-sqlite] [datomish.transact :as transact])) -(defn- take-pair-as-promise! [ch f] - ;; Just like take-as-promise!, but aware that it's handling a pair channel. - ;; Also converts values, if desired. - (promise - (fn [resolve reject] - (letfn [(split-pair [[v e]] - (if e - (do - (println "Got error:" e) - (reject e)) - (resolve (f v))))] - (cljs.core.async/take! ch split-pair))))) ;; Public API. @@ -40,13 +30,9 @@ (defn ^:export q [db find options] (let [find (cljs.reader/read-string find) opts (cljify options)] - (println "Running query " (pr-str find) (pr-str {:foo find}) (pr-str opts)) (take-pair-as-promise! - (go-pair - (let [res (js res))) - identity))) + (db/js))) (defn ^:export ensure-schema [conn simple-schema] (let [simple-schema (cljify simple-schema) @@ -67,35 +53,30 @@ (try (let [tx-data (js->tx-data tx-data)] (println "Transacting:" (pr-str tx-data)) - (take-pair-as-promise! - (go-pair - (let [tx-result (js)) + (go-promise clj->js + (let [tx-result (js - ;; We pickle the connection as a thunk here so it roundtrips through JS - ;; without incident. - {:conn (fn [] c) - :roundtrip (fn [x] (clj->js (cljify x))) - :db (fn [] (transact/db c)) - :ensureSchema (fn [simple-schema] (ensure-schema c simple-schema)) - :transact (fn [tx-data] (transact c tx-data)) - :close (fn [] (db/close-db db)) - :toString (fn [] (str "#")) - :path path})))) - identity)) + (go-promise clj->js + (let [conn (js (cljify x))) + :db (fn [] (transact/db c)) + :ensureSchema (fn [simple-schema] (ensure-schema c simple-schema)) + :transact (fn [tx-data] (transact c tx-data)) + :close (fn [] (db/close-db db)) + :toString (fn [] (str "#")) + :path path})))) diff --git a/src/common/datomish/promises.cljc b/src/common/datomish/promises.cljc new file mode 100644 index 00000000..feee3d27 --- /dev/null +++ b/src/common/datomish/promises.cljc @@ -0,0 +1,30 @@ +(ns datomish.promises + #?(:cljs + (:require-macros + [datomish.pair-chan :refer [go-pair Date: Thu, 22 Sep 2016 15:56:20 -0700 Subject: [PATCH 14/14] Include deps.cljs giving externs for Node.js consumers; normalize build output. cljsbuild using leiningen projects that depend on Datomish will automatically include the externs. --- .gitignore | 6 -- project.clj | 57 ++++--------------- release-browser/test_include_node.js | 2 - release-browser/wrap_bare.sh | 4 +- release-node/test_include_node.js | 2 +- release-node/wrap_bare.sh | 4 +- .../{externs.js => externs/datomish.js} | 0 src/node/deps.cljs | 1 + src/node/{externs.js => externs/datomish.js} | 0 test/js/tests.js | 2 +- 10 files changed, 17 insertions(+), 61 deletions(-) delete mode 100644 release-browser/test_include_node.js rename src/browser/{externs.js => externs/datomish.js} (100%) create mode 100644 src/node/deps.cljs rename src/node/{externs.js => externs/datomish.js} (100%) diff --git a/.gitignore b/.gitignore index bb6ab5a9..d7fe2318 100644 --- a/.gitignore +++ b/.gitignore @@ -22,12 +22,6 @@ pom.xml pom.xml.asc /.cljs_node_repl/ /.cljs_rhino_repl/ -/release-browser -/release-browser/datomish.js -/release-browser/datomish.bare.js -/release-node -/release-node/datomish.js -/release-node/datomish.bare.js /addon/built/index.js /addon/node_modules/ /addon/release/datomish-test.xpi diff --git a/project.clj b/project.clj index 3089b31b..e1f2b6f5 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject datomish "0.1.0-SNAPSHOT" +(defproject datomish "0.1.1-SNAPSHOT" :description "A persistent, embedded knowledge base inspired by Datomic and DataScript." :url "https://github.com/mozilla/datomish" :license {:name "Mozilla Public License Version 2.0" @@ -24,18 +24,18 @@ { :release-node { - :source-paths ["src/node"] + :source-paths ["src/common" "src/node"] :assert false :compiler { + ;; :externs specified in deps.cljs. :elide-asserts true - :externs ["src/node/externs.js"] :hashbang false :language-in :ecmascript5 :language-out :ecmascript5 :optimizations :advanced - :output-dir "release-node" - :output-to "release-node/datomish.bare.js" + :output-dir "target/release-node" + :output-to "target/release-node/datomish.bare.js" :output-wrapper false :parallel-build true :pretty-print true @@ -60,12 +60,12 @@ :compiler { :elide-asserts true - :externs ["src/browser/externs.js"] + :externs ["src/browser/externs/datomish.js"] :language-in :ecmascript5 :language-out :ecmascript5 :optimizations :advanced - :output-dir "release-browser" - :output-to "release-browser/datomish.bare.js" + :output-dir "target/release-browser" + :output-to "target/release-browser/datomish.bare.js" :output-wrapper false :parallel-build true :preloads [datomish.preload] @@ -75,25 +75,9 @@ } :notify-command ["release-browser/wrap_bare.sh"]} - :advanced - {:source-paths ["src/node"] - :compiler - { - :externs ["src/node/externs.js"] - :language-in :ecmascript5 - :language-out :ecmascript5 - :output-dir "target/advanced" - :output-to "target/advanced/datomish.js" - :optimizations :advanced - :parallel-build true - :pretty-print true - :source-map "target/advanced/datomish.js.map" - :target :nodejs - }} - :test { - :source-paths ["src/node" "test"] + :source-paths ["src/common" "src/node" "test"] :compiler { :language-in :ecmascript5 @@ -125,26 +109,5 @@ :doo {:build "test"} - :clean-targets ^{:protect false} - [ - "target" - "release-node/cljs/" - "release-node/cljs_promises/" - "release-node/clojure/" - "release-node/datascript/" - "release-node/datomish/" - "release-node/honeysql/" - "release-node/taoensso/" - "release-node/datomish.bare.js" - "release-node/datomish.js" - "release-browser/cljs/" - "release-browser/cljs_promises/" - "release-browser/clojure/" - "release-browser/datascript/" - "release-browser/datomish/" - "release-browser/honeysql/" - "release-browser/taoensso/" - "release-browser/datomish.bare.js" - "release-browser/datomish.js" - ] + :clean-targets ^{:protect false} ["target"] ) diff --git a/release-browser/test_include_node.js b/release-browser/test_include_node.js deleted file mode 100644 index 683261cd..00000000 --- a/release-browser/test_include_node.js +++ /dev/null @@ -1,2 +0,0 @@ -var d = require('./datomish'); -console.log(d.q("[:find ?e ?v :where [?e \"name\" ?v] {:x :y}]")); diff --git a/release-browser/wrap_bare.sh b/release-browser/wrap_bare.sh index 6d5ae26a..ff03a0d4 100755 --- a/release-browser/wrap_bare.sh +++ b/release-browser/wrap_bare.sh @@ -2,6 +2,6 @@ set -e -(cat release-browser/wrapper.prefix; cat release-browser/datomish.bare.js; cat release-browser/wrapper.suffix) > release-browser/datomish.js +(cat release-browser/wrapper.prefix; cat target/release-browser/datomish.bare.js; cat release-browser/wrapper.suffix) > target/release-browser/datomish.js -echo "Packed release-browser/datomish.js" +echo "Packed target/release-browser/datomish.js" diff --git a/release-node/test_include_node.js b/release-node/test_include_node.js index 683261cd..2abc19d9 100644 --- a/release-node/test_include_node.js +++ b/release-node/test_include_node.js @@ -1,2 +1,2 @@ -var d = require('./datomish'); +var d = require('../target/release-node/datomish'); console.log(d.q("[:find ?e ?v :where [?e \"name\" ?v] {:x :y}]")); diff --git a/release-node/wrap_bare.sh b/release-node/wrap_bare.sh index 13707e8f..50e0916e 100755 --- a/release-node/wrap_bare.sh +++ b/release-node/wrap_bare.sh @@ -2,6 +2,6 @@ set -e -(cat release-node/wrapper.prefix && cat release-node/datomish.bare.js && cat release-node/wrapper.suffix) > release-node/datomish.js +(cat release-node/wrapper.prefix && cat target/release-node/datomish.bare.js && cat release-node/wrapper.suffix) > target/release-node/datomish.js -echo "Packed release-node/datomish.js" +echo "Packed target/release-node/datomish.js" diff --git a/src/browser/externs.js b/src/browser/externs/datomish.js similarity index 100% rename from src/browser/externs.js rename to src/browser/externs/datomish.js diff --git a/src/node/deps.cljs b/src/node/deps.cljs new file mode 100644 index 00000000..c41ac085 --- /dev/null +++ b/src/node/deps.cljs @@ -0,0 +1 @@ +{:externs ["externs/datomish.js"]} diff --git a/src/node/externs.js b/src/node/externs/datomish.js similarity index 100% rename from src/node/externs.js rename to src/node/externs/datomish.js diff --git a/test/js/tests.js b/test/js/tests.js index e9e20a44..e69b55c5 100644 --- a/test/js/tests.js +++ b/test/js/tests.js @@ -2,7 +2,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -var datomish = require("../../release-node/datomish.js"); +var datomish = require("../../target/release-node/datomish.js"); var schema = { "name": "pages",