From 428791827ea6c363ce1ff246e24b3008d596e675 Mon Sep 17 00:00:00 2001 From: dnolen Date: Fri, 22 May 2015 16:10:02 -0400 Subject: [PATCH 01/60] bump deps --- contacts/project.clj | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/contacts/project.clj b/contacts/project.clj index 284de73..9719854 100644 --- a/contacts/project.clj +++ b/contacts/project.clj @@ -6,16 +6,16 @@ :jvm-opts ^:replace ["-Xms512m" "-Xmx512m" "-server"] - :dependencies [[org.clojure/clojure "1.5.1"] - [org.clojure/clojurescript "0.0-2173"] - [com.datomic/datomic-free "0.9.4699"] + :dependencies [[org.clojure/clojure "1.7.0-RC1"] + [org.clojure/clojurescript "0.0-3291"] + [com.datomic/datomic-free "0.9.5153"] [bidi "1.10.2"] - [om "0.5.3"] + [org.omcljs/om "0.8.8"] [secretary "1.1.0"] [ring/ring "1.2.2"] [fogus/ring-edn "0.2.0"] [com.stuartsierra/component "0.2.1"] - [org.clojure/core.async "0.1.278.0-76b25b-alpha"]] + [org.clojure/core.async "0.1.346.0-17112a-alpha"]] :source-paths ["src/clj"] From b1d420ae2538088efa69d7042a7b9c11c22a22de Mon Sep 17 00:00:00 2001 From: dnolen Date: Fri, 22 May 2015 16:30:22 -0400 Subject: [PATCH 02/60] wip --- contacts/resources/data/initial.edn | 11 +++++++++-- contacts/src/clj/contacts/system.clj | 12 +++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/contacts/resources/data/initial.edn b/contacts/resources/data/initial.edn index 139597f..ecf2279 100644 --- a/contacts/resources/data/initial.edn +++ b/contacts/resources/data/initial.edn @@ -1,2 +1,9 @@ - - +[{:db/id #db/id[:db.part/user] + :person/first-name "Bob" + :person/last-name "Smith" + :person/email [{:email/address "bob.smith@foo.com"}] + :person/telephone [{:telephone/number "111-111-1111"}] + :person/address [{:address/street "Maple Street" + :address/city "Boston" + :address/state "Massachusetts" + :address/zipcode "11111"}]}] \ No newline at end of file diff --git a/contacts/src/clj/contacts/system.clj b/contacts/src/clj/contacts/system.clj index 3c12347..65e0c64 100644 --- a/contacts/src/clj/contacts/system.clj +++ b/contacts/src/clj/contacts/system.clj @@ -23,6 +23,16 @@ (comment (def s (dev-system {:db-uri "datomic:mem://localhost:4334/contacts" - :web-port 8081})) + :web-port 8081})) (def s1 (component/start s)) + + (def conn (-> s1 :db :connection)) + + (require '[datomic.api :as d]) + + (d/transact conn (read-string (slurp "resources/data/initial.edn"))) + + (let [db (d/db conn)] + (d/pull db [:person/first-name :person/last-name {:person/telephone [:telephone/number]}] + 17592186045423)) ) From fff994e547192a6521d9d4fb130b97426d045432 Mon Sep 17 00:00:00 2001 From: dnolen Date: Fri, 22 May 2015 16:47:00 -0400 Subject: [PATCH 03/60] wip --- contacts/src/clj/contacts/datomic.clj | 35 +++++++++++---------------- contacts/src/clj/contacts/system.clj | 10 +++++--- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/contacts/src/clj/contacts/datomic.clj b/contacts/src/clj/contacts/datomic.clj index 4eb6bd7..b7c22fc 100644 --- a/contacts/src/clj/contacts/datomic.clj +++ b/contacts/src/clj/contacts/datomic.clj @@ -9,6 +9,8 @@ ;; ============================================================================= ;; Helpers +;; TODO: remove this and replace with Transit handler + (defn convert-db-id [x] (cond (instance? datomic.query.EntityMap x) @@ -27,21 +29,19 @@ ;; ============================================================================= ;; Queries -(defn list-contacts [db] - (map - ;; won't roundtrip to conn bc segment already probably cached - #(d/entity db (first %)) - (d/q '[:find ?eid - :where - ;; talk about how we can make it do first OR last name - [?eid :person/first-name]] - db))) +(defn list-contacts [db selector] + (d/q '[:find (pull ?eid selector) + :in $ selector + :where + ;; talk about how we can make it do first OR last name + [?eid :person/first-name]] + db selector)) - (defn display-contacts [db] - (let [contacts (list-contacts db)] - (map - #(select-keys % [:db/id :person/last-name :person/first-name]) - (sort-by :person/last-name (map convert-db-id contacts))))) +(defn display-contacts [db selector] + (let [contacts (list-contacts db selector)] + (map + #(select-keys % [:db/id :person/last-name :person/first-name]) + (sort-by :person/last-name (map convert-db-id contacts))))) (defn get-contact [db id-string] @@ -86,13 +86,6 @@ @(d/transact conn [[:db.fn/retractEntity (edn/read-string id)]]) true) -(defn create-phone [conn data]) - -(defn update-phone [conn data]) - -(defn delete-phone [conn data]) - - ;; return datoms to add (def initial-data diff --git a/contacts/src/clj/contacts/system.clj b/contacts/src/clj/contacts/system.clj index 65e0c64..ab49a6c 100644 --- a/contacts/src/clj/contacts/system.clj +++ b/contacts/src/clj/contacts/system.clj @@ -1,7 +1,7 @@ (ns contacts.system (:require [com.stuartsierra.component :as component] contacts.server - contacts.datomic)) + [contacts.datomic :as contacts])) (defn dev-system [config-options] (let [{:keys [db-uri web-port]} config-options] @@ -26,13 +26,17 @@ :web-port 8081})) (def s1 (component/start s)) - (def conn (-> s1 :db :connection)) - (require '[datomic.api :as d]) + (def conn (-> s1 :db :connection)) + (def db (d/db conn)) + (d/transact conn (read-string (slurp "resources/data/initial.edn"))) (let [db (d/db conn)] (d/pull db [:person/first-name :person/last-name {:person/telephone [:telephone/number]}] 17592186045423)) + + (contacts/list-contacts db + [:person/first-name :person/last-name {:person/telephone [:telephone/number]}]) ) From 72502e0ad2dde4fe295160aa5fa2af3d5bf0ae83 Mon Sep 17 00:00:00 2001 From: dnolen Date: Fri, 22 May 2015 16:57:37 -0400 Subject: [PATCH 04/60] wip --- contacts/project.clj | 2 + contacts/src/clj/contacts/datomic.clj | 81 +++++++-------------------- contacts/src/clj/contacts/system.clj | 2 +- 3 files changed, 22 insertions(+), 63 deletions(-) diff --git a/contacts/project.clj b/contacts/project.clj index 9719854..7f4e091 100644 --- a/contacts/project.clj +++ b/contacts/project.clj @@ -14,6 +14,8 @@ [secretary "1.1.0"] [ring/ring "1.2.2"] [fogus/ring-edn "0.2.0"] + [com.cognitect/transit-clj "0.8.271"] + [com.cognitect/transit-cljs "0.8.215"] [com.stuartsierra/component "0.2.1"] [org.clojure/core.async "0.1.346.0-17112a-alpha"]] diff --git a/contacts/src/clj/contacts/datomic.clj b/contacts/src/clj/contacts/datomic.clj index b7c22fc..1d94bd9 100644 --- a/contacts/src/clj/contacts/datomic.clj +++ b/contacts/src/clj/contacts/datomic.clj @@ -2,51 +2,32 @@ (:require [datomic.api :as d] [com.stuartsierra.component :as component] [clojure.java.io :as io] - [clojure.edn :as edn]) - (:import datomic.Util)) - - -;; ============================================================================= -;; Helpers - -;; TODO: remove this and replace with Transit handler - -(defn convert-db-id [x] - (cond - (instance? datomic.query.EntityMap x) - (assoc (into {} (map convert-db-id x)) - :db/id (str (:db/id x))) - - (instance? clojure.lang.MapEntry x) - [(first x) (convert-db-id (second x))] - - (coll? x) - (into (empty x) (map convert-db-id x)) - - :else x)) - + [clojure.edn :as edn] + [cognitect.transit :as t]) + (:import datomic.Util + [java.io ByteArrayInputStream ByteArrayOutputStream])) ;; ============================================================================= ;; Queries -(defn list-contacts [db selector] - (d/q '[:find (pull ?eid selector) - :in $ selector - :where - ;; talk about how we can make it do first OR last name - [?eid :person/first-name]] - db selector)) - -(defn display-contacts [db selector] - (let [contacts (list-contacts db selector)] - (map - #(select-keys % [:db/id :person/last-name :person/first-name]) - (sort-by :person/last-name (map convert-db-id contacts))))) +(defn contacts + ([db] (contacts db '[*])) + ([db selector] + (d/q '[:find (pull ?eid selector) + :in $ selector + :where + [?eid :person/first-name]] ;; talk about how we can make it do first OR last name + db selector))) +(defn get-contact + ([db id] (get-contact db id '[*])) + ([db id selector] + (d/pull db selector id))) -(defn get-contact [db id-string] - (convert-db-id (d/touch (d/entity db (edn/read-string id-string))))) +;; ============================================================================= +;; CRUD +;; TODO: rewrite this into something generic, client will send transaction (defn create-contact [conn data] (let [tempid (d/tempid :db.part/user) @@ -86,30 +67,6 @@ @(d/transact conn [[:db.fn/retractEntity (edn/read-string id)]]) true) -;; return datoms to add - -(def initial-data - (let [person-id (d/tempid :db.part/user) - address-id (d/tempid :db.part/user) - phone-id (d/tempid :db.part/user) - email-id (d/tempid :db.part/user)] - [{:db/id person-id - :person/first-name "Bob" - :person/last-name "Smith" - :person/email email-id - :person/telephone phone-id - :person/address address-id} - {:db/id email-id - :email/address "bob.smith@gmail.com"} - {:db/id phone-id - :telephone/number "123-456-7890"} - {:db/id address-id - :address/street "111 Main St" - :address/city "Brooklyn" - :address/state "NY" - :address/zipcode "11234"}])) - - (defrecord DatomicDatabase [uri schema initial-data connection] component/Lifecycle (start [component] diff --git a/contacts/src/clj/contacts/system.clj b/contacts/src/clj/contacts/system.clj index ab49a6c..8e6335b 100644 --- a/contacts/src/clj/contacts/system.clj +++ b/contacts/src/clj/contacts/system.clj @@ -38,5 +38,5 @@ 17592186045423)) (contacts/list-contacts db - [:person/first-name :person/last-name {:person/telephone [:telephone/number]}]) + [:db/id :person/first-name :person/last-name {:person/telephone [:telephone/number]}]) ) From fc06f8bc2e93ac7730efbfac0c10206a2c2aeac8 Mon Sep 17 00:00:00 2001 From: dnolen Date: Fri, 22 May 2015 17:15:11 -0400 Subject: [PATCH 05/60] wip --- contacts/src/clj/contacts/datomic.clj | 3 +- contacts/src/clj/contacts/middleware.clj | 36 ++++++++++++++++++++++++ contacts/src/clj/contacts/server.clj | 3 +- 3 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 contacts/src/clj/contacts/middleware.clj diff --git a/contacts/src/clj/contacts/datomic.clj b/contacts/src/clj/contacts/datomic.clj index 1d94bd9..7563a96 100644 --- a/contacts/src/clj/contacts/datomic.clj +++ b/contacts/src/clj/contacts/datomic.clj @@ -4,8 +4,7 @@ [clojure.java.io :as io] [clojure.edn :as edn] [cognitect.transit :as t]) - (:import datomic.Util - [java.io ByteArrayInputStream ByteArrayOutputStream])) + (:import datomic.Util)) ;; ============================================================================= ;; Queries diff --git a/contacts/src/clj/contacts/middleware.clj b/contacts/src/clj/contacts/middleware.clj new file mode 100644 index 0000000..8264532 --- /dev/null +++ b/contacts/src/clj/contacts/middleware.clj @@ -0,0 +1,36 @@ +(ns contacts.middleware + (:require [cognitect.transit :as transit]) + (:import [java.io ByteArrayInputStream ByteArrayOutputStream] + [java.nio.charset StandardCharsets])) + +(defn str->is [str] + (ByteArrayInputStream. (.getBytes str StandardCharsets/UTF_8))) + +(defn transit-request? + [req] + (if-let [^String type (:content-type req)] + (not (empty? (re-find #"^application/transit+json" type))))) + +(defprotocol TransitRead + (transit-read [this])) + +(extend-type String + TransitRead + (transit-edn [s] + (transit/read (transit/reader (str->is s) :json)))) + +(extend-type java.io.InputStream + TransitRead + (transit-read [is] + (transit/read (transit/reader is :json)))) + +(defn wrap-transit-params + [handler] + (fn [req] + (if-let [body (and (transit-request? req) (:body req))] + (let [transit-params (transit-read body) + req* (assoc req + :transit-params transit-params + :params (merge (:params req) transit-params))] + (handler req*)) + (handler req)))) diff --git a/contacts/src/clj/contacts/server.clj b/contacts/src/clj/contacts/server.clj index 9d27dbf..07f0164 100644 --- a/contacts/src/clj/contacts/server.clj +++ b/contacts/src/clj/contacts/server.clj @@ -47,7 +47,7 @@ (defn contacts [req] (generate-response (vec - (contacts.datomic/display-contacts + (contacts.datomic/contact (d/db (:datomic-connection req)))))) @@ -126,7 +126,6 @@ (defn wrap-connection [handler conn] (fn [req] (handler (assoc req :datomic-connection conn)))) - (defn contacts-handler [conn] (wrap-resource (wrap-edn-params (wrap-connection handler conn)) From 8ebf1fc49cd68d925c12c415f35720192407135c Mon Sep 17 00:00:00 2001 From: dnolen Date: Fri, 22 May 2015 17:26:26 -0400 Subject: [PATCH 06/60] wip --- contacts/project.clj | 2 +- contacts/src/clj/contacts/datomic.clj | 2 +- contacts/src/clj/contacts/middleware.clj | 153 ++++++++++++++++++----- contacts/src/clj/contacts/server.clj | 5 +- 4 files changed, 130 insertions(+), 32 deletions(-) diff --git a/contacts/project.clj b/contacts/project.clj index 7f4e091..f9c2f91 100644 --- a/contacts/project.clj +++ b/contacts/project.clj @@ -14,8 +14,8 @@ [secretary "1.1.0"] [ring/ring "1.2.2"] [fogus/ring-edn "0.2.0"] - [com.cognitect/transit-clj "0.8.271"] [com.cognitect/transit-cljs "0.8.215"] + [ring-transit "0.1.3"] [com.stuartsierra/component "0.2.1"] [org.clojure/core.async "0.1.346.0-17112a-alpha"]] diff --git a/contacts/src/clj/contacts/datomic.clj b/contacts/src/clj/contacts/datomic.clj index 7563a96..8ebb51a 100644 --- a/contacts/src/clj/contacts/datomic.clj +++ b/contacts/src/clj/contacts/datomic.clj @@ -79,7 +79,7 @@ (defn new-database [db-uri] (DatomicDatabase. db-uri (first (Util/readAll (io/reader (io/resource "data/schema.edn")))) - initial-data + (first (Util/readAll (io/reader (io/resource "data/initial.edn")))) nil)) ;; ============================================================================= diff --git a/contacts/src/clj/contacts/middleware.clj b/contacts/src/clj/contacts/middleware.clj index 8264532..7ca7ec9 100644 --- a/contacts/src/clj/contacts/middleware.clj +++ b/contacts/src/clj/contacts/middleware.clj @@ -1,36 +1,133 @@ (ns contacts.middleware - (:require [cognitect.transit :as transit]) - (:import [java.io ByteArrayInputStream ByteArrayOutputStream] - [java.nio.charset StandardCharsets])) + (:require [ring.util.response :refer :all] + [cognitect.transit :as transit]) + (:import [java.io ByteArrayOutputStream])) -(defn str->is [str] - (ByteArrayInputStream. (.getBytes str StandardCharsets/UTF_8))) +(defn- write [x t opts] + (let [baos (ByteArrayOutputStream.) + w (transit/writer baos t opts) + _ (transit/write w x) + ret (.toString baos)] + (.reset baos) + ret)) -(defn transit-request? - [req] - (if-let [^String type (:content-type req)] - (not (empty? (re-find #"^application/transit+json" type))))) +(defn- transit-request? [request] + (if-let [type (:content-type request)] + (let [mtch (re-find #"^application/transit\+(json|msgpack)" type)] + [(not (empty? mtch)) (keyword (second mtch))]))) -(defprotocol TransitRead - (transit-read [this])) +(defn- read-transit [request {:keys [opts]}] + (let [[res t] (transit-request? request)] + (if res + (if-let [body (:body request)] + (let [rdr (transit/reader body t opts)] + (try + [true (transit/read rdr)] + (catch Exception ex + [false nil]))))))) -(extend-type String - TransitRead - (transit-edn [s] - (transit/read (transit/reader (str->is s) :json)))) +(def ^{:doc "The default response to return when a Transit request is malformed."} +default-malformed-response + {:status 400 + :headers {"Content-Type" "text/plain"} + :body "Malformed Transit in request body."}) -(extend-type java.io.InputStream - TransitRead - (transit-read [is] - (transit/read (transit/reader is :json)))) +(defn wrap-transit-body + "Middleware that parses the body of Transit request maps, and replaces the :body + key with the parsed data structure. Requests without a Transit content type are + unaffected. + Accepts the following options: + :keywords? - true if the keys of maps should be turned into keywords + :opts - a map of options to be passed to the transit reader + :malformed-response - a response map to return when the JSON is malformed" + {:arglists '([handler] [handler options])} + [handler & [{:keys [malformed-response] + :or {malformed-response default-malformed-response} + :as options}]] + (fn [request] + (if-let [[valid? transit] (read-transit request options)] + (if valid? + (handler (assoc request :body transit)) + malformed-response) + (handler request)))) + +(defn- assoc-transit-params [request transit] + (let [request (assoc request :transit-params transit)] + (if (map? transit) + (update-in request [:params] merge transit) + request))) (defn wrap-transit-params - [handler] - (fn [req] - (if-let [body (and (transit-request? req) (:body req))] - (let [transit-params (transit-read body) - req* (assoc req - :transit-params transit-params - :params (merge (:params req) transit-params))] - (handler req*)) - (handler req)))) + "Middleware that parses the body of Transit requests into a map of parameters, + which are added to the request map on the :transit-params and :params keys. + Accepts the following options: + :malformed-response - a response map to return when the JSON is malformed + :opts - a map of options to be passed to the transit reader + Use the standard Ring middleware, ring.middleware.keyword-params, to + convert the parameters into keywords." + {:arglists '([handler] [handler options])} + [handler & [{:keys [malformed-response] + :or {malformed-response default-malformed-response} + :as options}]] + (fn [request] + (if-let [[valid? transit] (read-transit request options)] + (if valid? + (handler (assoc-transit-params request transit)) + malformed-response) + (handler request)))) + +(defn wrap-transit-response + "Middleware that converts responses with a map or a vector for a body into a + Transit response. + Accepts the following options: + :encoding - one of #{:json :json-verbose :msgpack} + :opts - a map of options to be passed to the transit writer" + {:arglists '([handler] [handler options])} + [handler & [{:as options}]] + (let [{:keys [encoding opts] :or {encoding :json}} options] + (assert (#{:json :json-verbose :msgpack} encoding) "The encoding must be one of #{:json :json-verbose :msgpack}.") + (fn [request] + (let [response (handler request)] + (if (coll? (:body response)) + (let [transit-response (update-in response [:body] write encoding opts)] + (if (contains? (:headers response) "Content-Type") + transit-response + (content-type transit-response (format "application/transit+%s; charset=utf-8" (name encoding))))) + response))))) + +;(ns contacts.middleware +; (:require [cognitect.transit :as transit]) +; (:import [java.io ByteArrayInputStream ByteArrayOutputStream] +; [java.nio.charset StandardCharsets])) +; +;(defn str->is [str] +; (ByteArrayInputStream. (.getBytes str StandardCharsets/UTF_8))) +; +;(defn transit-request? +; [req] +; (if-let [^String type (:content-type req)] +; (not (empty? (re-find #"^application/transit+json" type))))) +; +;(defprotocol TransitRead +; (transit-read [this])) +; +;(extend-type String +; TransitRead +; (transit-edn [s] +; (transit/read (transit/reader (str->is s) :json)))) +; +;(extend-type java.io.InputStream +; TransitRead +; (transit-read [is] +; (transit/read (transit/reader is :json)))) +; +;(defn wrap-transit-params +; [handler] +; (fn [req] +; (if-let [body (and (transit-request? req) (:body req))] +; (let [transit-params (transit-read body) +; req* (assoc req +; :transit-params transit-params +; :params (merge (:params req) transit-params))] +; (handler req*)) +; (handler req)))) diff --git a/contacts/src/clj/contacts/server.clj b/contacts/src/clj/contacts/server.clj index 07f0164..c5f6cfc 100644 --- a/contacts/src/clj/contacts/server.clj +++ b/contacts/src/clj/contacts/server.clj @@ -3,12 +3,13 @@ [ring.util.response :refer [file-response resource-response]] [ring.adapter.jetty :refer [run-jetty]] [ring.middleware.edn :refer [wrap-edn-params]] + [contacts.middleware + :refer [wrap-transit-params wrap-transit-response]] [ring.middleware.resource :refer [wrap-resource]] [bidi.bidi :refer [make-handler] :as bidi] [com.stuartsierra.component :as component] [datomic.api :as d] - [contacts.datomic] - )) + [contacts.datomic])) ;; ============================================================================= ;; Routing From 11858e5bcb2bea14faf60c5d9ea2b49e1b5e544a Mon Sep 17 00:00:00 2001 From: dnolen Date: Fri, 22 May 2015 17:28:28 -0400 Subject: [PATCH 07/60] wip --- contacts/src/clj/contacts/server.clj | 2 +- contacts/src/clj/contacts/system.clj | 8 +------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/contacts/src/clj/contacts/server.clj b/contacts/src/clj/contacts/server.clj index c5f6cfc..43d2bf3 100644 --- a/contacts/src/clj/contacts/server.clj +++ b/contacts/src/clj/contacts/server.clj @@ -48,7 +48,7 @@ (defn contacts [req] (generate-response (vec - (contacts.datomic/contact + (contacts.datomic/contacts (d/db (:datomic-connection req)))))) diff --git a/contacts/src/clj/contacts/system.clj b/contacts/src/clj/contacts/system.clj index 8e6335b..9d6c3c0 100644 --- a/contacts/src/clj/contacts/system.clj +++ b/contacts/src/clj/contacts/system.clj @@ -31,12 +31,6 @@ (def conn (-> s1 :db :connection)) (def db (d/db conn)) - (d/transact conn (read-string (slurp "resources/data/initial.edn"))) - - (let [db (d/db conn)] - (d/pull db [:person/first-name :person/last-name {:person/telephone [:telephone/number]}] - 17592186045423)) - - (contacts/list-contacts db + (contacts/contacts db [:db/id :person/first-name :person/last-name {:person/telephone [:telephone/number]}]) ) From d352ac80f065dfda33039624398c9c6766d2f523 Mon Sep 17 00:00:00 2001 From: dnolen Date: Fri, 22 May 2015 17:31:29 -0400 Subject: [PATCH 08/60] wip --- contacts/src/clj/contacts/server.clj | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/contacts/src/clj/contacts/server.clj b/contacts/src/clj/contacts/server.clj index 43d2bf3..3a01fdc 100644 --- a/contacts/src/clj/contacts/server.clj +++ b/contacts/src/clj/contacts/server.clj @@ -4,7 +4,7 @@ [ring.adapter.jetty :refer [run-jetty]] [ring.middleware.edn :refer [wrap-edn-params]] [contacts.middleware - :refer [wrap-transit-params wrap-transit-response]] + :refer [wrap-transit-body wrap-transit-response]] [ring.middleware.resource :refer [wrap-resource]] [bidi.bidi :refer [make-handler] :as bidi] [com.stuartsierra.component :as component] @@ -39,7 +39,7 @@ (defn generate-response [data & [status]] {:status (or status 200) - :headers {"Content-Type" "application/edn"} + :headers {"Content-Type" "application/transit+json"} :body (pr-str data)}) @@ -127,9 +127,10 @@ (defn wrap-connection [handler conn] (fn [req] (handler (assoc req :datomic-connection conn)))) + (defn contacts-handler [conn] (wrap-resource - (wrap-edn-params (wrap-connection handler conn)) + (wrap-transit-response (wrap-transit-body (wrap-connection handler conn))) "public")) From 72d5895068fb7536c1a881f5bd9476216b350ad9 Mon Sep 17 00:00:00 2001 From: dnolen Date: Fri, 22 May 2015 17:44:17 -0400 Subject: [PATCH 09/60] wip --- contacts/project.clj | 2 +- contacts/resources/public/html/index.html | 5 +---- contacts/script/brepl.clj | 13 +++++++++++++ contacts/src/dev/contacts/dev.cljs | 6 ++++++ 4 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 contacts/script/brepl.clj create mode 100644 contacts/src/dev/contacts/dev.cljs diff --git a/contacts/project.clj b/contacts/project.clj index f9c2f91..7433d78 100644 --- a/contacts/project.clj +++ b/contacts/project.clj @@ -15,7 +15,7 @@ [ring/ring "1.2.2"] [fogus/ring-edn "0.2.0"] [com.cognitect/transit-cljs "0.8.215"] - [ring-transit "0.1.3"] + [cljs-ajax "0.3.11"] [com.stuartsierra/component "0.2.1"] [org.clojure/core.async "0.1.346.0-17112a-alpha"]] diff --git a/contacts/resources/public/html/index.html b/contacts/resources/public/html/index.html index e4a46c2..a8abd16 100644 --- a/contacts/resources/public/html/index.html +++ b/contacts/resources/public/html/index.html @@ -4,9 +4,6 @@
- - - - + diff --git a/contacts/script/brepl.clj b/contacts/script/brepl.clj new file mode 100644 index 0000000..710c4a5 --- /dev/null +++ b/contacts/script/brepl.clj @@ -0,0 +1,13 @@ +(require '[cljs.build.api :as b]) +(require '[cljs.repl :as repl]) +(require '[cljs.repl.browser :as browser]) + +(b/build (b/inputs "src/cljs" "src/dev") + {:main 'contacts.dev + :asset-path "out" + :output-to "resources/public/js/app.js" + :output-dir "resources/public/js"}) + +(repl/repl + (browser/repl-env) + :output-dir "resources/public/js") \ No newline at end of file diff --git a/contacts/src/dev/contacts/dev.cljs b/contacts/src/dev/contacts/dev.cljs new file mode 100644 index 0000000..a8a5f69 --- /dev/null +++ b/contacts/src/dev/contacts/dev.cljs @@ -0,0 +1,6 @@ +(ns contacts.dev + (:require [clojure.browser.repl :as repl] + [ajax.core :refer [GET]])) + +(defonce conn + (repl/connect "http://localhost:9000/repl")) From 66b253f0daba2331ac865fee5cdb338d4e02d90e Mon Sep 17 00:00:00 2001 From: dnolen Date: Fri, 22 May 2015 18:02:14 -0400 Subject: [PATCH 10/60] wip --- contacts/project.clj | 3 ++- contacts/resources/public/html/index.html | 2 +- contacts/script/brepl.clj | 4 ++-- contacts/src/clj/contacts/server.clj | 2 +- contacts/src/dev/contacts/dev.cljs | 12 ++++++++++++ 5 files changed, 18 insertions(+), 5 deletions(-) diff --git a/contacts/project.clj b/contacts/project.clj index 7433d78..5f3b2df 100644 --- a/contacts/project.clj +++ b/contacts/project.clj @@ -11,9 +11,10 @@ [com.datomic/datomic-free "0.9.5153"] [bidi "1.10.2"] [org.omcljs/om "0.8.8"] - [secretary "1.1.0"] + [secretary "1.2.3"] [ring/ring "1.2.2"] [fogus/ring-edn "0.2.0"] + [com.cognitect/transit-clj "0.8.271"] [com.cognitect/transit-cljs "0.8.215"] [cljs-ajax "0.3.11"] [com.stuartsierra/component "0.2.1"] diff --git a/contacts/resources/public/html/index.html b/contacts/resources/public/html/index.html index a8abd16..cbdc61a 100644 --- a/contacts/resources/public/html/index.html +++ b/contacts/resources/public/html/index.html @@ -4,6 +4,6 @@
- + diff --git a/contacts/script/brepl.clj b/contacts/script/brepl.clj index 710c4a5..f091514 100644 --- a/contacts/script/brepl.clj +++ b/contacts/script/brepl.clj @@ -2,9 +2,9 @@ (require '[cljs.repl :as repl]) (require '[cljs.repl.browser :as browser]) -(b/build (b/inputs "src/cljs" "src/dev") +(b/build (b/inputs "src/dev") {:main 'contacts.dev - :asset-path "out" + :asset-path "js" :output-to "resources/public/js/app.js" :output-dir "resources/public/js"}) diff --git a/contacts/src/clj/contacts/server.clj b/contacts/src/clj/contacts/server.clj index 3a01fdc..531fb2d 100644 --- a/contacts/src/clj/contacts/server.clj +++ b/contacts/src/clj/contacts/server.clj @@ -130,7 +130,7 @@ (defn contacts-handler [conn] (wrap-resource - (wrap-transit-response (wrap-transit-body (wrap-connection handler conn))) + (wrap-transit-body (wrap-connection handler conn)) "public")) diff --git a/contacts/src/dev/contacts/dev.cljs b/contacts/src/dev/contacts/dev.cljs index a8a5f69..e27ceda 100644 --- a/contacts/src/dev/contacts/dev.cljs +++ b/contacts/src/dev/contacts/dev.cljs @@ -4,3 +4,15 @@ (defonce conn (repl/connect "http://localhost:9000/repl")) + +(defn get-contacts [contacts] + (println contacts)) + +(defn get-contacts-error [err] + (println err)) + +(comment + (GET "http://localhost:8081/contacts" + {:handler get-contacts + :error-handler get-contacts-error}) + ) \ No newline at end of file From 38379af63283fe23aaf18910396acabb07b0d8e4 Mon Sep 17 00:00:00 2001 From: dnolen Date: Fri, 22 May 2015 18:25:51 -0400 Subject: [PATCH 11/60] first successful request --- contacts/src/clj/contacts/server.clj | 15 +++++++++------ contacts/src/dev/contacts/dev.cljs | 5 +++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/contacts/src/clj/contacts/server.clj b/contacts/src/clj/contacts/server.clj index 531fb2d..dbb6483 100644 --- a/contacts/src/clj/contacts/server.clj +++ b/contacts/src/clj/contacts/server.clj @@ -4,7 +4,8 @@ [ring.adapter.jetty :refer [run-jetty]] [ring.middleware.edn :refer [wrap-edn-params]] [contacts.middleware - :refer [wrap-transit-body wrap-transit-response]] + :refer [wrap-transit-body wrap-transit-response + wrap-transit-params]] [ring.middleware.resource :refer [wrap-resource]] [bidi.bidi :refer [make-handler] :as bidi] [com.stuartsierra.component :as component] @@ -21,7 +22,7 @@ {:get {[""] :contacts ["/" :id] :contact-get} - :post {[""] :contact-create} + :post {[""] :contacts} :put {["/" :id] :contact-update} :delete {["/" :id] :contact-delete}} "/phone" @@ -38,9 +39,9 @@ (defn generate-response [data & [status]] - {:status (or status 200) + {:status (or status 200) :headers {"Content-Type" "application/transit+json"} - :body (pr-str data)}) + :body data}) ;; CONTACT HANDLERS @@ -49,7 +50,8 @@ (generate-response (vec (contacts.datomic/contacts - (d/db (:datomic-connection req)))))) + (d/db (:datomic-connection req)) + (-> req :transit-params :selector))))) (defn contact-get [req id] @@ -130,7 +132,8 @@ (defn contacts-handler [conn] (wrap-resource - (wrap-transit-body (wrap-connection handler conn)) + (wrap-transit-response + (wrap-transit-params (wrap-connection handler conn))) "public")) diff --git a/contacts/src/dev/contacts/dev.cljs b/contacts/src/dev/contacts/dev.cljs index e27ceda..426b9d1 100644 --- a/contacts/src/dev/contacts/dev.cljs +++ b/contacts/src/dev/contacts/dev.cljs @@ -1,6 +1,6 @@ (ns contacts.dev (:require [clojure.browser.repl :as repl] - [ajax.core :refer [GET]])) + [ajax.core :refer [POST]])) (defonce conn (repl/connect "http://localhost:9000/repl")) @@ -12,7 +12,8 @@ (println err)) (comment - (GET "http://localhost:8081/contacts" + (POST "http://localhost:8081/contacts" {:handler get-contacts + :params {:selector [:person/last-name]} :error-handler get-contacts-error}) ) \ No newline at end of file From 0bf3b2c29fc758628af982879b543682187ee4c6 Mon Sep 17 00:00:00 2001 From: dnolen Date: Fri, 22 May 2015 18:30:59 -0400 Subject: [PATCH 12/60] first successful request --- contacts/src/dev/contacts/dev.cljs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contacts/src/dev/contacts/dev.cljs b/contacts/src/dev/contacts/dev.cljs index 426b9d1..3ba3907 100644 --- a/contacts/src/dev/contacts/dev.cljs +++ b/contacts/src/dev/contacts/dev.cljs @@ -14,6 +14,7 @@ (comment (POST "http://localhost:8081/contacts" {:handler get-contacts - :params {:selector [:person/last-name]} + :params {:selector [:person/last-name :person/first-name + {:person/telephone [:telephone/number]}]} :error-handler get-contacts-error}) ) \ No newline at end of file From 2e8fbff6823788d96ed21529e17b0153ffea1ab3 Mon Sep 17 00:00:00 2001 From: David Nolen Date: Sat, 23 May 2015 12:23:46 -0400 Subject: [PATCH 13/60] drop cljs-ajax in favor of cljs-http --- contacts/project.clj | 4 +++- contacts/resources/data/initial.edn | 9 +++++++++ contacts/src/clj/contacts/system.clj | 12 +++++++++++- contacts/src/dev/contacts/dev.cljs | 20 ++++++++------------ 4 files changed, 31 insertions(+), 14 deletions(-) diff --git a/contacts/project.clj b/contacts/project.clj index 5f3b2df..b1eb7bc 100644 --- a/contacts/project.clj +++ b/contacts/project.clj @@ -16,7 +16,9 @@ [fogus/ring-edn "0.2.0"] [com.cognitect/transit-clj "0.8.271"] [com.cognitect/transit-cljs "0.8.215"] - [cljs-ajax "0.3.11"] + [cljs-http "0.1.30" :exclusions + [org.clojure/clojure org.clojure/clojurescript + com.cognitect/transit-cljs]] [com.stuartsierra/component "0.2.1"] [org.clojure/core.async "0.1.346.0-17112a-alpha"]] diff --git a/contacts/resources/data/initial.edn b/contacts/resources/data/initial.edn index ecf2279..7c2303e 100644 --- a/contacts/resources/data/initial.edn +++ b/contacts/resources/data/initial.edn @@ -3,6 +3,15 @@ :person/last-name "Smith" :person/email [{:email/address "bob.smith@foo.com"}] :person/telephone [{:telephone/number "111-111-1111"}] + :person/address [{:address/street "Maple Street" + :address/city "Boston" + :address/state "Massachusetts" + :address/zipcode "11111"}]} + {:db/id #db/id[:db.part/user] + :person/first-name "Martha" + :person/last-name "Smith" + :person/email [{:email/address "martha.smith@bar.com"}] + :person/telephone [{:telephone/number "111-111-1112"}] :person/address [{:address/street "Maple Street" :address/city "Boston" :address/state "Massachusetts" diff --git a/contacts/src/clj/contacts/system.clj b/contacts/src/clj/contacts/system.clj index 9d6c3c0..ef0a722 100644 --- a/contacts/src/clj/contacts/system.clj +++ b/contacts/src/clj/contacts/system.clj @@ -24,6 +24,7 @@ (comment (def s (dev-system {:db-uri "datomic:mem://localhost:4334/contacts" :web-port 8081})) + (def s1 (component/start s)) (require '[datomic.api :as d]) @@ -32,5 +33,14 @@ (def db (d/db conn)) (contacts/contacts db - [:db/id :person/first-name :person/last-name {:person/telephone [:telephone/number]}]) + [:db/id :person/first-name :person/last-name + {:person/telephone [:telephone/number]}]) + + (d/q '[:find (pull ?p sel) + :in $ ?street sel + :where + [?a :address/street ?street] + [?p :person/address ?a]] + db "Maple Street" + [:person/first-name :person/last-name]) ) diff --git a/contacts/src/dev/contacts/dev.cljs b/contacts/src/dev/contacts/dev.cljs index 3ba3907..eea2e19 100644 --- a/contacts/src/dev/contacts/dev.cljs +++ b/contacts/src/dev/contacts/dev.cljs @@ -1,20 +1,16 @@ (ns contacts.dev + (:require-macros [cljs.core.async.macros :refer [go]]) (:require [clojure.browser.repl :as repl] - [ajax.core :refer [POST]])) + [ajax.core :refer [POST]] + [cljs-http.client :as http])) (defonce conn (repl/connect "http://localhost:9000/repl")) -(defn get-contacts [contacts] - (println contacts)) - -(defn get-contacts-error [err] - (println err)) - (comment - (POST "http://localhost:8081/contacts" - {:handler get-contacts - :params {:selector [:person/last-name :person/first-name - {:person/telephone [:telephone/number]}]} - :error-handler get-contacts-error}) + (let [c (http/post "http://localhost:8081/contacts" + {:transit-params + {:selector [:person/last-name :person/first-name + {:person/telephone [:telephone/number]}]}})] + (go (println (:body ( Date: Sat, 23 May 2015 13:37:32 -0400 Subject: [PATCH 14/60] include code mirror as dep, wip --- contacts/project.clj | 1 + contacts/src/dev/contacts/dev.cljs | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/contacts/project.clj b/contacts/project.clj index b1eb7bc..414e9d8 100644 --- a/contacts/project.clj +++ b/contacts/project.clj @@ -19,6 +19,7 @@ [cljs-http "0.1.30" :exclusions [org.clojure/clojure org.clojure/clojurescript com.cognitect/transit-cljs]] + [cljsjs/codemirror "5.1.0-1"] [com.stuartsierra/component "0.2.1"] [org.clojure/core.async "0.1.346.0-17112a-alpha"]] diff --git a/contacts/src/dev/contacts/dev.cljs b/contacts/src/dev/contacts/dev.cljs index eea2e19..568866c 100644 --- a/contacts/src/dev/contacts/dev.cljs +++ b/contacts/src/dev/contacts/dev.cljs @@ -2,15 +2,20 @@ (:require-macros [cljs.core.async.macros :refer [go]]) (:require [clojure.browser.repl :as repl] [ajax.core :refer [POST]] - [cljs-http.client :as http])) + [cljs-http.client :as http] + [cljs.pprint :as pprint :refer [pprint]])) (defonce conn (repl/connect "http://localhost:9000/repl")) +(defn log [x] + (println) ;; flush past prompt + (pprint x)) + (comment (let [c (http/post "http://localhost:8081/contacts" {:transit-params {:selector [:person/last-name :person/first-name {:person/telephone [:telephone/number]}]}})] - (go (println (:body ( Date: Sat, 23 May 2015 13:38:17 -0400 Subject: [PATCH 15/60] drop ring-edn --- contacts/project.clj | 1 - 1 file changed, 1 deletion(-) diff --git a/contacts/project.clj b/contacts/project.clj index 414e9d8..18d5877 100644 --- a/contacts/project.clj +++ b/contacts/project.clj @@ -13,7 +13,6 @@ [org.omcljs/om "0.8.8"] [secretary "1.2.3"] [ring/ring "1.2.2"] - [fogus/ring-edn "0.2.0"] [com.cognitect/transit-clj "0.8.271"] [com.cognitect/transit-cljs "0.8.215"] [cljs-http "0.1.30" :exclusions From a9e3a95aea647fc1837619c4f54159eb9da235c1 Mon Sep 17 00:00:00 2001 From: dnolen Date: Sat, 23 May 2015 15:20:25 -0400 Subject: [PATCH 16/60] fix up requires for changed deps --- contacts/src/clj/contacts/server.clj | 1 - contacts/src/dev/contacts/dev.cljs | 1 - 2 files changed, 2 deletions(-) diff --git a/contacts/src/clj/contacts/server.clj b/contacts/src/clj/contacts/server.clj index dbb6483..5cb035a 100644 --- a/contacts/src/clj/contacts/server.clj +++ b/contacts/src/clj/contacts/server.clj @@ -2,7 +2,6 @@ (:require [contacts.util :as util] [ring.util.response :refer [file-response resource-response]] [ring.adapter.jetty :refer [run-jetty]] - [ring.middleware.edn :refer [wrap-edn-params]] [contacts.middleware :refer [wrap-transit-body wrap-transit-response wrap-transit-params]] diff --git a/contacts/src/dev/contacts/dev.cljs b/contacts/src/dev/contacts/dev.cljs index 568866c..5e82d6a 100644 --- a/contacts/src/dev/contacts/dev.cljs +++ b/contacts/src/dev/contacts/dev.cljs @@ -1,7 +1,6 @@ (ns contacts.dev (:require-macros [cljs.core.async.macros :refer [go]]) (:require [clojure.browser.repl :as repl] - [ajax.core :refer [POST]] [cljs-http.client :as http] [cljs.pprint :as pprint :refer [pprint]])) From 3772dd775526f4e69cbc1873237301ce90429c39 Mon Sep 17 00:00:00 2001 From: dnolen Date: Sat, 23 May 2015 15:27:28 -0400 Subject: [PATCH 17/60] some cleanup --- contacts/src/clj/contacts/server.clj | 33 ++++++++++------------------ 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/contacts/src/clj/contacts/server.clj b/contacts/src/clj/contacts/server.clj index 5cb035a..7858575 100644 --- a/contacts/src/clj/contacts/server.clj +++ b/contacts/src/clj/contacts/server.clj @@ -12,7 +12,7 @@ [contacts.datomic])) ;; ============================================================================= -;; Routing +;; Routes (def routes ["" {"/" :index @@ -36,13 +36,11 @@ (assoc (resource-response "html/index.html" {:root "public"}) :headers {"Content-Type" "text/html"})) - (defn generate-response [data & [status]] {:status (or status 200) :headers {"Content-Type" "application/transit+json"} :body data}) - ;; CONTACT HANDLERS (defn contacts [req] @@ -52,27 +50,23 @@ (d/db (:datomic-connection req)) (-> req :transit-params :selector))))) - (defn contact-get [req id] (generate-response (contacts.datomic/get-contact (d/db (:datomic-connection req)) id))) - (defn contact-create [req] (generate-response (contacts.datomic/create-contact (:datomic-connection req) ;; must have form {:person/first-name "x" :person/last-name "y} - (:edn-params req)))) - + (:transit-params req)))) (defn contact-update [req id] (generate-response (contacts.datomic/update-contact (:datomic-connection req) - (assoc (:edn-params req) :db/id id)))) - + (assoc (:transit-params req) :db/id id)))) (defn contact-delete [req id] (generate-response @@ -80,7 +74,6 @@ (:datomic-connection req) id))) - ;;;; PHONE HANLDERS (defn phone-create [req] @@ -88,13 +81,13 @@ (contacts.datomic/create-phone (:datomic-connection req) ;; must have form {:person/_telephone person-id} - (:edn-params req)))) + (:transit-params req)))) (defn phone-update [req id] (generate-response (contacts.datomic/update-phone (:datomic-connection req) - (assoc (:edn-params req) :db/id id)))) + (assoc (:transit-params req) :db/id id)))) (defn phone-delete [req id] (generate-response @@ -121,25 +114,23 @@ :phone-create (phone-create req) :phone-update (phone-update req (:id (:params match))) :phone-delete (phone-delete req (:id (:params match))) - req))) - (defn wrap-connection [handler conn] (fn [req] (handler (assoc req :datomic-connection conn)))) - (defn contacts-handler [conn] (wrap-resource (wrap-transit-response (wrap-transit-params (wrap-connection handler conn))) "public")) - (defn contacts-handler-dev [conn] (fn [req] ((contacts-handler conn) req))) +;; ============================================================================= +;; WebServer (defrecord WebServer [port handler container datomic-connection] component/Lifecycle @@ -154,8 +145,8 @@ (stop [component] (.stop container))) - (defn dev-server [web-port] (WebServer. web-port contacts-handler-dev true nil)) + (defn prod-server [] (WebServer. nil contacts-handler false nil)) ;; ============================================================================= @@ -171,13 +162,13 @@ ;; create contact (handler {:uri "/contacts" :request-method :post - :edn-params {:person/first-name "Bib" :person/last-name "Bibooo"} + :transit-params {:person/first-name "Bib" :person/last-name "Bibooo"} :datomic-connection (:connection (:db @contacts.core/servlet-system))}) ;; update contact (handler {:uri "/contacts/17592186045434" :request-method :put - :edn-params {:person/first-name "k" :person/last-name "b"} + :transit-params {:person/first-name "k" :person/last-name "b"} :datomic-connection (:connection (:db @contacts.core/servlet-system))}) ;; delete contact @@ -188,14 +179,14 @@ ;; create phone (handler {:uri "/phone" :request-method :post - :edn-params {:telephone/number "000-111-2222" + :transit-params {:telephone/number "000-111-2222" :person/_telephone "17592186045438"} :datomic-connection (:connection (:db @contacts.core/servlet-system))}) ;; update phone (handler {:uri "/phone/17592186045444" :request-method :put - :edn-params {:telephone/number "999-888-7777"} + :transit-params {:telephone/number "999-888-7777"} :datomic-connection (:connection (:db @contacts.core/servlet-system))}) From 73097377cb2f0692e828ef6824011fa982a74274 Mon Sep 17 00:00:00 2001 From: dnolen Date: Sat, 23 May 2015 20:19:48 -0400 Subject: [PATCH 18/60] bleeding edge Om --- contacts/project.clj | 4 +-- contacts/src/dev/contacts/dev.cljs | 43 ++++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/contacts/project.clj b/contacts/project.clj index 18d5877..89e863e 100644 --- a/contacts/project.clj +++ b/contacts/project.clj @@ -7,10 +7,10 @@ :jvm-opts ^:replace ["-Xms512m" "-Xmx512m" "-server"] :dependencies [[org.clojure/clojure "1.7.0-RC1"] - [org.clojure/clojurescript "0.0-3291"] + [org.clojure/clojurescript "0.0-3298"] [com.datomic/datomic-free "0.9.5153"] [bidi "1.10.2"] - [org.omcljs/om "0.8.8"] + [org.omcljs/om "0.9.0-SNAPSHOT"] [secretary "1.2.3"] [ring/ring "1.2.2"] [com.cognitect/transit-clj "0.8.271"] diff --git a/contacts/src/dev/contacts/dev.cljs b/contacts/src/dev/contacts/dev.cljs index 5e82d6a..cd2dcd0 100644 --- a/contacts/src/dev/contacts/dev.cljs +++ b/contacts/src/dev/contacts/dev.cljs @@ -2,7 +2,10 @@ (:require-macros [cljs.core.async.macros :refer [go]]) (:require [clojure.browser.repl :as repl] [cljs-http.client :as http] - [cljs.pprint :as pprint :refer [pprint]])) + [cljs.pprint :as pprint :refer [pprint]] + [goog.dom :as gdom] + [om.next :as om :refer-macros [defui]] + [om.dom :as dom])) (defonce conn (repl/connect "http://localhost:9000/repl")) @@ -11,10 +14,40 @@ (println) ;; flush past prompt (pprint x)) +(defui Contact + static om/IQuery + (queries [this] + '{:self [:person/first-name :person/last-name]}) + Object + (render [this] + (let [{:keys [:person/first-name :person/last-name]} + (:self (om/props this))] + (println (om/props this)) + (dom/div nil + (str last-name ", " first-name))))) + +(def contact (om/create-factory Contact)) + +(defui ContactList + Object + (render [this] + (apply dom/ul nil + (map #(dom/li nil (contact %)) (om/props this))))) + +(def contact-list (om/create-factory ContactList)) + +(defn main [] + (let [c (http/post "http://localhost:8081/contacts" + {:transit-params {:selector (om/complete-query Contact)}})] + (go + (js/React.render + (contact-list (:body ( Date: Sat, 23 May 2015 20:40:17 -0400 Subject: [PATCH 19/60] wip fix source mapping --- contacts/project.clj | 2 +- contacts/script/brepl.clj | 3 ++- contacts/src/dev/contacts/dev.cljs | 16 ++++++++++++++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/contacts/project.clj b/contacts/project.clj index 89e863e..2adbbba 100644 --- a/contacts/project.clj +++ b/contacts/project.clj @@ -7,7 +7,7 @@ :jvm-opts ^:replace ["-Xms512m" "-Xmx512m" "-server"] :dependencies [[org.clojure/clojure "1.7.0-RC1"] - [org.clojure/clojurescript "0.0-3298"] + [org.clojure/clojurescript "0.0-3299"] [com.datomic/datomic-free "0.9.5153"] [bidi "1.10.2"] [org.omcljs/om "0.9.0-SNAPSHOT"] diff --git a/contacts/script/brepl.clj b/contacts/script/brepl.clj index f091514..f4e90e1 100644 --- a/contacts/script/brepl.clj +++ b/contacts/script/brepl.clj @@ -9,5 +9,6 @@ :output-dir "resources/public/js"}) (repl/repl - (browser/repl-env) + (browser/repl-env :host-port 8081) + :asset-path "js" :output-dir "resources/public/js") \ No newline at end of file diff --git a/contacts/src/dev/contacts/dev.cljs b/contacts/src/dev/contacts/dev.cljs index cd2dcd0..cd47eae 100644 --- a/contacts/src/dev/contacts/dev.cljs +++ b/contacts/src/dev/contacts/dev.cljs @@ -22,13 +22,18 @@ (render [this] (let [{:keys [:person/first-name :person/last-name]} (:self (om/props this))] - (println (om/props this)) (dom/div nil (str last-name ", " first-name))))) (def contact (om/create-factory Contact)) (defui ContactList + static om/IQueryParams + (params [this] + {:contacts {:contact (om/complete-query Contact)}}) + static om/IQuery + (queries [this] + '{:contacts ?contact}) Object (render [this] (apply dom/ul nil @@ -38,7 +43,7 @@ (defn main [] (let [c (http/post "http://localhost:8081/contacts" - {:transit-params {:selector (om/complete-query Contact)}})] + {:transit-params {:selector (om/complete-query ContactList)}})] (go (js/React.render (contact-list (:body ( Date: Sat, 23 May 2015 22:11:53 -0400 Subject: [PATCH 20/60] wip --- contacts/src/dev/contacts/dev.cljs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/contacts/src/dev/contacts/dev.cljs b/contacts/src/dev/contacts/dev.cljs index cd47eae..e16b30b 100644 --- a/contacts/src/dev/contacts/dev.cljs +++ b/contacts/src/dev/contacts/dev.cljs @@ -36,8 +36,9 @@ '{:contacts ?contact}) Object (render [this] - (apply dom/ul nil - (map #(dom/li nil (contact %)) (om/props this))))) + (let [{:keys [contacts]} (om/props this)] + (apply dom/ul nil + (map #(dom/li nil (contact %)) contacts))))) (def contact-list (om/create-factory ContactList)) From d8924923b02e75f1603d44aacff9a20562731661 Mon Sep 17 00:00:00 2001 From: David Nolen Date: Sun, 24 May 2015 17:09:30 -0400 Subject: [PATCH 21/60] query routing works --- contacts/src/clj/contacts/server.clj | 152 ++++++++------------------- contacts/src/dev/contacts/dev.cljs | 18 ++-- 2 files changed, 55 insertions(+), 115 deletions(-) diff --git a/contacts/src/clj/contacts/server.clj b/contacts/src/clj/contacts/server.clj index 7858575..9fde812 100644 --- a/contacts/src/clj/contacts/server.clj +++ b/contacts/src/clj/contacts/server.clj @@ -17,17 +17,8 @@ (def routes ["" {"/" :index "/index.html" :index - "/contacts" - {:get - {[""] :contacts - ["/" :id] :contact-get} - :post {[""] :contacts} - :put {["/" :id] :contact-update} - :delete {["/" :id] :contact-delete}} - "/phone" - {:post {[""] :phone-create} - :put {["/" :id] :phone-update} - :delete {["/" :id] :phone-delete}}}]) + "/query" + {:post {[""] :query}}}]) ;; ============================================================================= ;; Handlers @@ -43,77 +34,52 @@ ;; CONTACT HANDLERS -(defn contacts [req] +(defn contacts [conn selector] + (contacts.datomic/contacts (d/db conn) selector)) + +(defn contact-get [conn id] + (contacts.datomic/get-contact (d/db conn) id)) + +(defn fetch + ([conn k] (fetch conn '[*])) + ([conn k selector] + (case k + :contacts (contacts conn selector) + (throw + (ex-info (str "No data route for " k) + {:type :error/invalid-data-route}))))) + +(defn populate + ([conn query-map] (populate conn query-map nil)) + ([conn query-map context] + (letfn [(step [ret k v] + (cond + (map? v) + (assoc ret k (populate conn v k)) + + (vector? v) + (let [fk (if (and context (= :self k)) context k)] + (assoc ret k (fetch conn fk v))) + + :else (throw + (ex-info (str "Invalid query-map value " v) + {:type :error/invalid-query-map-value}))))] + (reduce-kv step {} query-map)))) + +(defn query [req] (generate-response - (vec - (contacts.datomic/contacts - (d/db (:datomic-connection req)) - (-> req :transit-params :selector))))) - -(defn contact-get [req id] - (generate-response - (contacts.datomic/get-contact - (d/db (:datomic-connection req)) id))) - -(defn contact-create [req] - (generate-response - (contacts.datomic/create-contact - (:datomic-connection req) - ;; must have form {:person/first-name "x" :person/last-name "y} - (:transit-params req)))) - -(defn contact-update [req id] - (generate-response - (contacts.datomic/update-contact - (:datomic-connection req) - (assoc (:transit-params req) :db/id id)))) - -(defn contact-delete [req id] - (generate-response - (contacts.datomic/delete-contact - (:datomic-connection req) - id))) - -;;;; PHONE HANLDERS - -(defn phone-create [req] - (generate-response - (contacts.datomic/create-phone - (:datomic-connection req) - ;; must have form {:person/_telephone person-id} - (:transit-params req)))) - -(defn phone-update [req id] - (generate-response - (contacts.datomic/update-phone - (:datomic-connection req) - (assoc (:transit-params req) :db/id id)))) - -(defn phone-delete [req id] - (generate-response - (contacts.datomic/delete-phone - (:datomic-connection req) - id))) + (populate (:datomic-connection req) (:transit-params req)))) ;;;; PRIMARY HANDLER (defn handler [req] - (let [match (bidi/match-route - routes - (:uri req) + (let [match (bidi/match-route routes (:uri req) :request-method (:request-method req))] ;(println match) (case (:handler match) :index (index req) - :contacts (contacts req) + :query (query req) :contact-get (contact-get req (:id (:params match))) - :contact-create (contact-create req) - :contact-update (contact-update req (:id (:params match))) - :contact-delete (contact-delete req (:id (:params match))) - - :phone-create (phone-create req) - :phone-update (phone-update req (:id (:params match))) - :phone-delete (phone-delete req (:id (:params match))) req))) (defn wrap-connection [handler conn] @@ -153,48 +119,20 @@ ;; Route Testing (comment + (require '[contacts.core :as cc]) + (cc/dev-start) ;; get contact - (handler {:uri "/contacts/17592186045438" - :request-method :get - :datomic-connection (:connection (:db @contacts.core/servlet-system))}) + (handler {:uri "/query" + :request-method :post + :transit-params {:contacts {:self [:person/first-name :person/last-name]}} + :datomic-connection (:connection (:db @cc/servlet-system))}) ;; create contact (handler {:uri "/contacts" :request-method :post :transit-params {:person/first-name "Bib" :person/last-name "Bibooo"} - :datomic-connection (:connection (:db @contacts.core/servlet-system))}) - - ;; update contact - (handler {:uri "/contacts/17592186045434" - :request-method :put - :transit-params {:person/first-name "k" :person/last-name "b"} - :datomic-connection (:connection (:db @contacts.core/servlet-system))}) - - ;; delete contact - (handler {:uri "/contacts/17592186045434" - :request-method :delete - :datomic-connection (:connection (:db @contacts.core/servlet-system))}) - - ;; create phone - (handler {:uri "/phone" - :request-method :post - :transit-params {:telephone/number "000-111-2222" - :person/_telephone "17592186045438"} - :datomic-connection (:connection (:db @contacts.core/servlet-system))}) - - ;; update phone - (handler {:uri "/phone/17592186045444" - :request-method :put - :transit-params {:telephone/number "999-888-7777"} - :datomic-connection (:connection (:db @contacts.core/servlet-system))}) - - - ;; delete phone - (handler {:uri "/phone/17592186045444" - :request-method :delete - :datomic-connection (:connection (:db @contacts.core/servlet-system))}) - + :datomic-connection (:connection (:db @cc/servlet-system))}) ) diff --git a/contacts/src/dev/contacts/dev.cljs b/contacts/src/dev/contacts/dev.cljs index e16b30b..9425e65 100644 --- a/contacts/src/dev/contacts/dev.cljs +++ b/contacts/src/dev/contacts/dev.cljs @@ -16,7 +16,7 @@ (defui Contact static om/IQuery - (queries [this] + (-queries [this] '{:self [:person/first-name :person/last-name]}) Object (render [this] @@ -29,16 +29,17 @@ (defui ContactList static om/IQueryParams - (params [this] - {:contacts {:contact (om/complete-query Contact)}}) + (-params [this] + {:contacts {:contact (om/queries Contact)}}) static om/IQuery - (queries [this] + (-queries [this] '{:contacts ?contact}) Object (render [this] (let [{:keys [contacts]} (om/props this)] + (println (om/props this)) (apply dom/ul nil - (map #(dom/li nil (contact %)) contacts))))) + (map #(dom/li nil (contact %)) contacts))))) (def contact-list (om/create-factory ContactList)) @@ -46,9 +47,10 @@ (let [c (http/post "http://localhost:8081/contacts" {:transit-params {:selector (om/complete-query ContactList)}})] (go - (js/React.render - (contact-list (:body ( Date: Sun, 24 May 2015 17:20:15 -0400 Subject: [PATCH 22/60] wip --- contacts/src/clj/contacts/core.clj | 2 +- contacts/src/dev/contacts/dev.cljs | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/contacts/src/clj/contacts/core.clj b/contacts/src/clj/contacts/core.clj index 656a87d..f198b61 100644 --- a/contacts/src/clj/contacts/core.clj +++ b/contacts/src/clj/contacts/core.clj @@ -10,7 +10,7 @@ (defn dev-start [] (let [sys (system/dev-system {:db-uri "datomic:mem://localhost:4334/contacts" - :web-port 8080}) + :web-port 8081}) sys' (component/start sys)] (reset! servlet-system sys') sys')) diff --git a/contacts/src/dev/contacts/dev.cljs b/contacts/src/dev/contacts/dev.cljs index 9425e65..82e6a36 100644 --- a/contacts/src/dev/contacts/dev.cljs +++ b/contacts/src/dev/contacts/dev.cljs @@ -21,9 +21,8 @@ Object (render [this] (let [{:keys [:person/first-name :person/last-name]} - (:self (om/props this))] - (dom/div nil - (str last-name ", " first-name))))) + (first (:self (om/props this)))] + (dom/div nil (str last-name ", " first-name))))) (def contact (om/create-factory Contact)) @@ -45,7 +44,7 @@ (defn main [] (let [c (http/post "http://localhost:8081/contacts" - {:transit-params {:selector (om/complete-query ContactList)}})] + {:transit-params {:selector (om/queries ContactList)}})] (go (let [contacts (vec (map first (:body ( Date: Sun, 24 May 2015 17:51:03 -0400 Subject: [PATCH 23/60] getting warmer but still not quite right --- contacts/src/clj/contacts/server.clj | 4 +++- contacts/src/dev/contacts/dev.cljs | 15 ++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/contacts/src/clj/contacts/server.clj b/contacts/src/clj/contacts/server.clj index 9fde812..4ace994 100644 --- a/contacts/src/clj/contacts/server.clj +++ b/contacts/src/clj/contacts/server.clj @@ -59,7 +59,9 @@ (vector? v) (let [fk (if (and context (= :self k)) context k)] - (assoc ret k (fetch conn fk v))) + (assoc ret + k (vec (cond->> (fetch conn fk v) + (= :self k) (map #(do {:self %})))))) :else (throw (ex-info (str "Invalid query-map value " v) diff --git a/contacts/src/dev/contacts/dev.cljs b/contacts/src/dev/contacts/dev.cljs index 82e6a36..64f1997 100644 --- a/contacts/src/dev/contacts/dev.cljs +++ b/contacts/src/dev/contacts/dev.cljs @@ -43,17 +43,18 @@ (def contact-list (om/create-factory ContactList)) (defn main [] - (let [c (http/post "http://localhost:8081/contacts" - {:transit-params {:selector (om/queries ContactList)}})] + (let [c (http/post "http://localhost:8081/query" + {:transit-params (om/queries ContactList)})] (go - (let [contacts (vec (map first (:body ( Date: Sun, 24 May 2015 18:24:07 -0400 Subject: [PATCH 24/60] tweak populate, this is going to be hardest part in the end, what shape the data should take --- contacts/src/clj/contacts/server.clj | 23 +++++++++++++---------- contacts/src/dev/contacts/dev.cljs | 4 +--- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/contacts/src/clj/contacts/server.clj b/contacts/src/clj/contacts/server.clj index 4ace994..01c3012 100644 --- a/contacts/src/clj/contacts/server.clj +++ b/contacts/src/clj/contacts/server.clj @@ -50,22 +50,25 @@ {:type :error/invalid-data-route}))))) (defn populate - ([conn query-map] (populate conn query-map nil)) - ([conn query-map context] + ([conn query-map] (letfn [(step [ret k v] (cond (map? v) - (assoc ret k (populate conn v k)) + (if (contains? v :self) + (assoc ret + k (->> (fetch conn k (:self v)) + (map #(merge {:self %} + (populate conn (dissoc v :self)))) + vec)) + (assoc ret k (populate conn v))) (vector? v) - (let [fk (if (and context (= :self k)) context k)] - (assoc ret - k (vec (cond->> (fetch conn fk v) - (= :self k) (map #(do {:self %})))))) + (fetch conn k v) - :else (throw - (ex-info (str "Invalid query-map value " v) - {:type :error/invalid-query-map-value}))))] + :else + (throw + (ex-info (str "Invalid query-map value " v) + {:type :error/invalid-query-map-value}))))] (reduce-kv step {} query-map)))) (defn query [req] diff --git a/contacts/src/dev/contacts/dev.cljs b/contacts/src/dev/contacts/dev.cljs index 64f1997..b9d3fbb 100644 --- a/contacts/src/dev/contacts/dev.cljs +++ b/contacts/src/dev/contacts/dev.cljs @@ -36,7 +36,6 @@ Object (render [this] (let [{:keys [contacts]} (om/props this)] - (println (om/props this)) (apply dom/ul nil (map #(dom/li nil (contact %)) contacts))))) @@ -47,8 +46,7 @@ {:transit-params (om/queries ContactList)})] (go (let [contacts (:body ( Date: Mon, 25 May 2015 16:01:50 -0400 Subject: [PATCH 25/60] populate / fetch can take a context --- contacts/src/clj/contacts/server.clj | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/contacts/src/clj/contacts/server.clj b/contacts/src/clj/contacts/server.clj index 01c3012..d26c1f1 100644 --- a/contacts/src/clj/contacts/server.clj +++ b/contacts/src/clj/contacts/server.clj @@ -41,8 +41,9 @@ (contacts.datomic/get-contact (d/db conn) id)) (defn fetch - ([conn k] (fetch conn '[*])) - ([conn k selector] + ([conn k] (fetch conn k '[*])) + ([conn k selector] (fetch conn k selector nil)) + ([conn k selector context] (case k :contacts (contacts conn selector) (throw @@ -50,7 +51,8 @@ {:type :error/invalid-data-route}))))) (defn populate - ([conn query-map] + ([conn query-map] (populate conn query-map nil)) + ([conn query-map context] (letfn [(step [ret k v] (cond (map? v) @@ -58,12 +60,12 @@ (assoc ret k (->> (fetch conn k (:self v)) (map #(merge {:self %} - (populate conn (dissoc v :self)))) + (populate conn (dissoc v :self) %))) vec)) (assoc ret k (populate conn v))) (vector? v) - (fetch conn k v) + (fetch conn k v context) :else (throw From 59f7f4e0fbaa4830965d5e92a0d663b0836ebb57 Mon Sep 17 00:00:00 2001 From: David Nolen Date: Tue, 26 May 2015 10:10:13 -0400 Subject: [PATCH 26/60] wip --- contacts/src/clj/contacts/server.clj | 56 +++++++++++++--------------- contacts/src/dev/contacts/dev.cljs | 34 ++++++++++------- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/contacts/src/clj/contacts/server.clj b/contacts/src/clj/contacts/server.clj index d26c1f1..578b9f6 100644 --- a/contacts/src/clj/contacts/server.clj +++ b/contacts/src/clj/contacts/server.clj @@ -40,38 +40,32 @@ (defn contact-get [conn id] (contacts.datomic/get-contact (d/db conn) id)) +(defmulti -fetch (fn [_ k _] k)) + +(defmethod -fetch :contacts + [conn _ selector] + (contacts conn selector)) + (defn fetch ([conn k] (fetch conn k '[*])) - ([conn k selector] (fetch conn k selector nil)) - ([conn k selector context] - (case k - :contacts (contacts conn selector) - (throw - (ex-info (str "No data route for " k) - {:type :error/invalid-data-route}))))) - -(defn populate - ([conn query-map] (populate conn query-map nil)) - ([conn query-map context] - (letfn [(step [ret k v] - (cond - (map? v) - (if (contains? v :self) - (assoc ret - k (->> (fetch conn k (:self v)) - (map #(merge {:self %} - (populate conn (dissoc v :self) %))) - vec)) - (assoc ret k (populate conn v))) - - (vector? v) - (fetch conn k v context) - - :else - (throw - (ex-info (str "Invalid query-map value " v) - {:type :error/invalid-query-map-value}))))] - (reduce-kv step {} query-map)))) + ([conn k selector] + (-fetch conn k selector))) + +(defn populate [conn query] + (letfn [(step [ret k] + (cond + (map? k) + (let [[k v] (first k)] + (assoc ret k (fetch conn k v))) + + (keyword? k) + (assoc ret k (fetch conn k)) + + :else + (throw + (ex-info (str "Invalid query key " k) + {:type :error/invalid-query-value}))))] + (reduce step {} query))) (defn query [req] (generate-response @@ -132,7 +126,7 @@ ;; get contact (handler {:uri "/query" :request-method :post - :transit-params {:contacts {:self [:person/first-name :person/last-name]}} + :transit-params [{:contacts [:person/first-name :person/last-name]}] :datomic-connection (:connection (:db @cc/servlet-system))}) ;; create contact diff --git a/contacts/src/dev/contacts/dev.cljs b/contacts/src/dev/contacts/dev.cljs index b9d3fbb..bb514e1 100644 --- a/contacts/src/dev/contacts/dev.cljs +++ b/contacts/src/dev/contacts/dev.cljs @@ -16,23 +16,31 @@ (defui Contact static om/IQuery - (-queries [this] - '{:self [:person/first-name :person/last-name]}) + (-query [this] + '[:person/first-name :person/last-name + {:person/telephone [:telephone/number]}]) Object (render [this] - (let [{:keys [:person/first-name :person/last-name]} - (first (:self (om/props this)))] - (dom/div nil (str last-name ", " first-name))))) + (let [{:keys [:person/first-name :person/last-name] :as props} + (first (om/props this))] + (dom/div nil + (dom/div nil + (dom/label nil "Full Name:") + (dom/span nil (str last-name ", " first-name))) + (dom/div nil + (dom/label nil "Number:") + (dom/span nil + (:telephone/number (first (:person/telephone props))))))))) (def contact (om/create-factory Contact)) (defui ContactList static om/IQueryParams (-params [this] - {:contacts {:contact (om/queries Contact)}}) + {:contact (om/query Contact)}) static om/IQuery - (-queries [this] - '{:contacts ?contact}) + (-query [this] + '[{:app/contacts ?contact}]) Object (render [this] (let [{:keys [contacts]} (om/props this)] @@ -43,7 +51,7 @@ (defn main [] (let [c (http/post "http://localhost:8081/query" - {:transit-params (om/queries ContactList)})] + {:transit-params (om/query ContactList)})] (go (let [contacts (:body ( Date: Tue, 26 May 2015 10:14:59 -0400 Subject: [PATCH 27/60] tweak --- contacts/src/clj/contacts/server.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contacts/src/clj/contacts/server.clj b/contacts/src/clj/contacts/server.clj index 578b9f6..0165453 100644 --- a/contacts/src/clj/contacts/server.clj +++ b/contacts/src/clj/contacts/server.clj @@ -42,7 +42,7 @@ (defmulti -fetch (fn [_ k _] k)) -(defmethod -fetch :contacts +(defmethod -fetch :app/contacts [conn _ selector] (contacts conn selector)) From 4b46cc79bcf310354cb30b55b59925a7ba2782b6 Mon Sep 17 00:00:00 2001 From: David Nolen Date: Tue, 26 May 2015 10:36:12 -0400 Subject: [PATCH 28/60] update --- contacts/src/clj/contacts/server.clj | 2 +- contacts/src/dev/contacts/dev.cljs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contacts/src/clj/contacts/server.clj b/contacts/src/clj/contacts/server.clj index 0165453..a12ed54 100644 --- a/contacts/src/clj/contacts/server.clj +++ b/contacts/src/clj/contacts/server.clj @@ -126,7 +126,7 @@ ;; get contact (handler {:uri "/query" :request-method :post - :transit-params [{:contacts [:person/first-name :person/last-name]}] + :transit-params [{:app/contacts [:person/first-name :person/last-name]}] :datomic-connection (:connection (:db @cc/servlet-system))}) ;; create contact diff --git a/contacts/src/dev/contacts/dev.cljs b/contacts/src/dev/contacts/dev.cljs index bb514e1..0d4958f 100644 --- a/contacts/src/dev/contacts/dev.cljs +++ b/contacts/src/dev/contacts/dev.cljs @@ -43,7 +43,7 @@ '[{:app/contacts ?contact}]) Object (render [this] - (let [{:keys [contacts]} (om/props this)] + (let [{:keys [:app/contacts]} (om/props this)] (apply dom/ul nil (map #(dom/li nil (contact %)) contacts))))) From efcc9ddfc2d3c215856383db27950a344c8ea3f5 Mon Sep 17 00:00:00 2001 From: David Nolen Date: Tue, 26 May 2015 11:26:35 -0400 Subject: [PATCH 29/60] more examples --- contacts/src/dev/contacts/dev.cljs | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/contacts/src/dev/contacts/dev.cljs b/contacts/src/dev/contacts/dev.cljs index 0d4958f..9077697 100644 --- a/contacts/src/dev/contacts/dev.cljs +++ b/contacts/src/dev/contacts/dev.cljs @@ -14,6 +14,9 @@ (println) ;; flush past prompt (pprint x)) +(defn fetch [q] + (http/post "http://localhost:8081/query" {:transit-params q})) + (defui Contact static om/IQuery (-query [this] @@ -50,8 +53,7 @@ (def contact-list (om/create-factory ContactList)) (defn main [] - (let [c (http/post "http://localhost:8081/query" - {:transit-params (om/query ContactList)})] + (let [c (fetch (om/query ContactList))] (go (let [contacts (:body ( Date: Fri, 5 Jun 2015 14:06:38 -0400 Subject: [PATCH 30/60] wip, delete all the old stuff, arrange for QCon demos --- contacts/contacts.iml | 86 +++++--- contacts/project.clj | 2 +- contacts/resources/public/html/demo1.html | 9 + .../public/html/{index.html => demo2.html} | 2 +- contacts/script/brepl.clj | 2 +- contacts/src/clj/contacts/server.clj | 17 +- contacts/src/cljs/contacts/components.cljs | 48 ----- contacts/src/cljs/contacts/core.cljs | 193 ------------------ contacts/src/cljs/contacts/demo1.cljs | 1 + contacts/src/cljs/contacts/demo2.cljs | 1 + contacts/src/cljs/contacts/util.cljs | 32 --- 11 files changed, 81 insertions(+), 312 deletions(-) create mode 100644 contacts/resources/public/html/demo1.html rename contacts/resources/public/html/{index.html => demo2.html} (69%) delete mode 100644 contacts/src/cljs/contacts/components.cljs delete mode 100644 contacts/src/cljs/contacts/core.cljs create mode 100644 contacts/src/cljs/contacts/demo1.cljs create mode 100644 contacts/src/cljs/contacts/demo2.cljs delete mode 100644 contacts/src/cljs/contacts/util.cljs diff --git a/contacts/contacts.iml b/contacts/contacts.iml index 1b6b335..b678c63 100644 --- a/contacts/contacts.iml +++ b/contacts/contacts.iml @@ -5,41 +5,61 @@ + + + + + + + - + + + - - - - - + + + + + - + - + + + + + + + + + + + + - + + - - - - + + + + + - - - + @@ -48,19 +68,26 @@ - + - - - - - - - + + + + + + - - - + + + + + + + + + + + @@ -69,7 +96,6 @@ - @@ -81,6 +107,6 @@ + - - + \ No newline at end of file diff --git a/contacts/project.clj b/contacts/project.clj index 2adbbba..3de4e5a 100644 --- a/contacts/project.clj +++ b/contacts/project.clj @@ -7,7 +7,7 @@ :jvm-opts ^:replace ["-Xms512m" "-Xmx512m" "-server"] :dependencies [[org.clojure/clojure "1.7.0-RC1"] - [org.clojure/clojurescript "0.0-3299"] + [org.clojure/clojurescript "0.0-3308"] [com.datomic/datomic-free "0.9.5153"] [bidi "1.10.2"] [org.omcljs/om "0.9.0-SNAPSHOT"] diff --git a/contacts/resources/public/html/demo1.html b/contacts/resources/public/html/demo1.html new file mode 100644 index 0000000..a5e03b3 --- /dev/null +++ b/contacts/resources/public/html/demo1.html @@ -0,0 +1,9 @@ + + + + + +
+ + + \ No newline at end of file diff --git a/contacts/resources/public/html/index.html b/contacts/resources/public/html/demo2.html similarity index 69% rename from contacts/resources/public/html/index.html rename to contacts/resources/public/html/demo2.html index cbdc61a..41f8f8c 100644 --- a/contacts/resources/public/html/index.html +++ b/contacts/resources/public/html/demo2.html @@ -4,6 +4,6 @@
- + diff --git a/contacts/script/brepl.clj b/contacts/script/brepl.clj index f4e90e1..37a83f7 100644 --- a/contacts/script/brepl.clj +++ b/contacts/script/brepl.clj @@ -5,7 +5,7 @@ (b/build (b/inputs "src/dev") {:main 'contacts.dev :asset-path "js" - :output-to "resources/public/js/app.js" + :output-to "resources/public/js/demo.js" :output-dir "resources/public/js"}) (repl/repl diff --git a/contacts/src/clj/contacts/server.clj b/contacts/src/clj/contacts/server.clj index a12ed54..d805f86 100644 --- a/contacts/src/clj/contacts/server.clj +++ b/contacts/src/clj/contacts/server.clj @@ -15,16 +15,17 @@ ;; Routes (def routes - ["" {"/" :index - "/index.html" :index + ["" {"/" :demo1 + "/demo/1" :demo1 + "/demo/2" :demo2 "/query" {:post {[""] :query}}}]) ;; ============================================================================= ;; Handlers -(defn index [req] - (assoc (resource-response "html/index.html" {:root "public"}) +(defn demo [n req] + (assoc (resource-response "html/demo" n ".html" {:root "public"}) :headers {"Content-Type" "text/html"})) (defn generate-response [data & [status]] @@ -78,7 +79,8 @@ :request-method (:request-method req))] ;(println match) (case (:handler match) - :index (index req) + :demo1 (demo 1 req) + :demo2 (demo 2 req) :query (query req) :contact-get (contact-get req (:id (:params match))) req))) @@ -126,9 +128,12 @@ ;; get contact (handler {:uri "/query" :request-method :post - :transit-params [{:app/contacts [:person/first-name :person/last-name]}] + :transit-params [{:app/contacts [:person/first-name :person/last-name + {:person/telephone '[*]}]}] :datomic-connection (:connection (:db @cc/servlet-system))}) + (.basisT (d/db (:connection (:db @cc/servlet-system)))) + ;; create contact (handler {:uri "/contacts" :request-method :post diff --git a/contacts/src/cljs/contacts/components.cljs b/contacts/src/cljs/contacts/components.cljs deleted file mode 100644 index 88c205f..0000000 --- a/contacts/src/cljs/contacts/components.cljs +++ /dev/null @@ -1,48 +0,0 @@ -(ns contacts.components - (:require [om.core :as om :include-macros true] - [om.dom :as dom :include-macros true])) - - -(defn display [show] - (if show - #js {} - #js {:display "none"})) - - -(defn handle-change [e owner] - (om/set-state! owner :edit-text (.. e -target -value))) - - -(defn end-edit [data edit-key owner cb] - (om/set-state! owner :editing false) - (om/update! data edit-key (om/get-state owner :edit-text)) - (cb {:value @data :edit-key edit-key})) - - -(defn editable [data owner {:keys [edit-key on-edit] :as opts}] - (reify - om/IInitState - (init-state [_] - {:editing false - :edit-text ""}) - om/IRenderState - (render-state [_ {:keys [edit-text editing]}] - (let [text (get data edit-key)] - (dom/li nil - (dom/span #js {:style (display (not editing))} text) - (dom/input - #js {:style (display editing) - :value edit-text - :onChange #(handle-change % owner) - :onKeyPress #(when (and (om/get-state owner :editing) - (== (.-keyCode %) 13)) - (end-edit data edit-key owner on-edit)) - :onBlur (fn [e] - (when (om/get-state owner :editing) - (end-edit data edit-key owner on-edit)))}) - (dom/button - #js {:style (display (not editing)) - :onClick (fn [e] - (om/set-state! owner :edit-text text) - (om/set-state! owner :editing true))} - "Edit")))))) diff --git a/contacts/src/cljs/contacts/core.cljs b/contacts/src/cljs/contacts/core.cljs deleted file mode 100644 index df78391..0000000 --- a/contacts/src/cljs/contacts/core.cljs +++ /dev/null @@ -1,193 +0,0 @@ -(ns contacts.core - (:require-macros [cljs.core.async.macros :refer [go]]) - (:require [goog.dom :as gdom] - [goog.events :as events] - [secretary.core :as secretary :include-macros true :refer [defroute]] - [om.core :as om :include-macros true] - [om.dom :as dom :include-macros true] - [cljs.core.async :refer [chan put! >! Date: Fri, 5 Jun 2015 14:10:46 -0400 Subject: [PATCH 31/60] move stuff out of dev to demo2 --- contacts/src/cljs/contacts/demo2.cljs | 81 ++++++++++++++++++++++++++- contacts/src/dev/contacts/dev.cljs | 75 ------------------------- 2 files changed, 80 insertions(+), 76 deletions(-) diff --git a/contacts/src/cljs/contacts/demo2.cljs b/contacts/src/cljs/contacts/demo2.cljs index 49d8d59..ad33f19 100644 --- a/contacts/src/cljs/contacts/demo2.cljs +++ b/contacts/src/cljs/contacts/demo2.cljs @@ -1 +1,80 @@ -(ns contacts.demo2) \ No newline at end of file +(ns contacts.demo2 + (:require [goog.dom :as gdom] + [om.next :as om] + [om.dom :as dom] + [cljs-http.client :as http])) + +(defn log [x] + (println) ;; flush past prompt + (pprint x)) + +(defn fetch [q] + (http/post "http://localhost:8081/query" {:transit-params q})) + +(defui Contact + static om/IQuery + (query [this] + '[:person/first-name :person/last-name + {:person/telephone [:telephone/number]}]) + Object + (render [this] + (let [{:keys [:person/first-name :person/last-name] :as props} + (first (om/props this))] + (dom/div nil + (dom/div nil + (dom/label nil "Full Name:") + (dom/span nil (str last-name ", " first-name))) + (dom/div nil + (dom/label nil "Number:") + (dom/span nil + (:telephone/number (first (:person/telephone props))))))))) + +(def contact (om/create-factory Contact)) + +(defui ContactList + static om/IQueryParams + (params [this] + {:contact (om/query Contact)}) + static om/IQuery + (query [this] + '[{:app/contacts ?contact}]) + Object + (render [this] + (let [{:keys [:app/contacts]} (om/props this)] + (apply dom/ul nil + (map #(dom/li nil (contact %)) contacts))))) + +(def contact-list (om/create-factory ContactList)) + +(defn main [] + (let [c (fetch (om/query ContactList))] + (go + (let [contacts (:body ( Date: Fri, 5 Jun 2015 14:16:44 -0400 Subject: [PATCH 32/60] wip --- contacts/resources/public/html/demo1.html | 5 +++-- contacts/resources/public/html/demo2.html | 5 +++-- contacts/src/cljs/contacts/demo1.cljs | 12 +++++++++++- contacts/src/cljs/contacts/demo2.cljs | 7 ++++++- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/contacts/resources/public/html/demo1.html b/contacts/resources/public/html/demo1.html index a5e03b3..a7f6a26 100644 --- a/contacts/resources/public/html/demo1.html +++ b/contacts/resources/public/html/demo1.html @@ -1,9 +1,10 @@ + Demo 1 -
- +
+ \ No newline at end of file diff --git a/contacts/resources/public/html/demo2.html b/contacts/resources/public/html/demo2.html index 41f8f8c..5b855ae 100644 --- a/contacts/resources/public/html/demo2.html +++ b/contacts/resources/public/html/demo2.html @@ -1,9 +1,10 @@ + Demo 2 -
- +
+ diff --git a/contacts/src/cljs/contacts/demo1.cljs b/contacts/src/cljs/contacts/demo1.cljs index 318a195..d98be00 100644 --- a/contacts/src/cljs/contacts/demo1.cljs +++ b/contacts/src/cljs/contacts/demo1.cljs @@ -1 +1,11 @@ -(ns contacts.demo1) \ No newline at end of file +(ns contacts.demo1 + (:require-macros [cljs.core.async.macros :refer [go]]) + (:require [goog.dom :as gdom] + [cljs-http.client :as http] + [cljs.core.async :refer [! chan]])) + +(defn main [] + ) + +(when (gdom/getElement "demo1") + (main)) \ No newline at end of file diff --git a/contacts/src/cljs/contacts/demo2.cljs b/contacts/src/cljs/contacts/demo2.cljs index ad33f19..378adab 100644 --- a/contacts/src/cljs/contacts/demo2.cljs +++ b/contacts/src/cljs/contacts/demo2.cljs @@ -1,8 +1,10 @@ (ns contacts.demo2 + (:require-macros [cljs.core.async.macros :refer [go]]) (:require [goog.dom :as gdom] [om.next :as om] [om.dom :as dom] - [cljs-http.client :as http])) + [cljs-http.client :as http] + [cljs.core.async :refer [! chan]])) (defn log [x] (println) ;; flush past prompt @@ -54,6 +56,9 @@ (contact-list contacts) (gdom/getElement "contacts")))))) +(when (gdom/getElement "demo2") + (main)) + (comment (require '[cljs.pprint :as pprint]) From 2fe704a719e10b8dc1c5c22304b65f426c53a4bc Mon Sep 17 00:00:00 2001 From: dnolen Date: Fri, 5 Jun 2015 14:29:04 -0400 Subject: [PATCH 33/60] fix demo page loading --- contacts/src/clj/contacts/server.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contacts/src/clj/contacts/server.clj b/contacts/src/clj/contacts/server.clj index d805f86..787c880 100644 --- a/contacts/src/clj/contacts/server.clj +++ b/contacts/src/clj/contacts/server.clj @@ -25,7 +25,7 @@ ;; Handlers (defn demo [n req] - (assoc (resource-response "html/demo" n ".html" {:root "public"}) + (assoc (resource-response (str "html/demo" n ".html") {:root "public"}) :headers {"Content-Type" "text/html"})) (defn generate-response [data & [status]] From a6854e72fbbdac69e6d4e09e27d01c76b7227e55 Mon Sep 17 00:00:00 2001 From: dnolen Date: Fri, 5 Jun 2015 14:39:37 -0400 Subject: [PATCH 34/60] fix the obvious bugs --- contacts/project.clj | 5 ++--- contacts/src/cljs/contacts/demo2.cljs | 3 ++- contacts/src/dev/contacts/dev.cljs | 7 ++----- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/contacts/project.clj b/contacts/project.clj index 3de4e5a..1937d3f 100644 --- a/contacts/project.clj +++ b/contacts/project.clj @@ -10,11 +10,10 @@ [org.clojure/clojurescript "0.0-3308"] [com.datomic/datomic-free "0.9.5153"] [bidi "1.10.2"] - [org.omcljs/om "0.9.0-SNAPSHOT"] - [secretary "1.2.3"] + [org.omcljs/om "0.9.0"] [ring/ring "1.2.2"] [com.cognitect/transit-clj "0.8.271"] - [com.cognitect/transit-cljs "0.8.215"] + [com.cognitect/transit-cljs "0.8.220"] [cljs-http "0.1.30" :exclusions [org.clojure/clojure org.clojure/clojurescript com.cognitect/transit-cljs]] diff --git a/contacts/src/cljs/contacts/demo2.cljs b/contacts/src/cljs/contacts/demo2.cljs index 378adab..cafaad8 100644 --- a/contacts/src/cljs/contacts/demo2.cljs +++ b/contacts/src/cljs/contacts/demo2.cljs @@ -1,7 +1,8 @@ (ns contacts.demo2 (:require-macros [cljs.core.async.macros :refer [go]]) (:require [goog.dom :as gdom] - [om.next :as om] + [cljs.pprint :refer [pprint]] + [om.next :as om :refer-macros [defui]] [om.dom :as dom] [cljs-http.client :as http] [cljs.core.async :refer [! chan]])) diff --git a/contacts/src/dev/contacts/dev.cljs b/contacts/src/dev/contacts/dev.cljs index c6fac4b..5a341dd 100644 --- a/contacts/src/dev/contacts/dev.cljs +++ b/contacts/src/dev/contacts/dev.cljs @@ -1,11 +1,8 @@ (ns contacts.dev (:require-macros [cljs.core.async.macros :refer [go]]) (:require [clojure.browser.repl :as repl] - [cljs-http.client :as http] - [cljs.pprint :as pprint :refer [pprint]] - [goog.dom :as gdom] - [om.next :as om :refer-macros [defui]] - [om.dom :as dom])) + [contacts.demo1] + [contacts.demo2])) (defonce conn (repl/connect "http://localhost:9000/repl")) From 3fd56b68b6e0574257f7fbad00b0d7445b31f80e Mon Sep 17 00:00:00 2001 From: dnolen Date: Fri, 5 Jun 2015 14:47:38 -0400 Subject: [PATCH 35/60] fix paths to demo.js --- contacts/resources/public/html/demo1.html | 2 +- contacts/resources/public/html/demo2.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contacts/resources/public/html/demo1.html b/contacts/resources/public/html/demo1.html index a7f6a26..22cf57f 100644 --- a/contacts/resources/public/html/demo1.html +++ b/contacts/resources/public/html/demo1.html @@ -5,6 +5,6 @@
- + \ No newline at end of file diff --git a/contacts/resources/public/html/demo2.html b/contacts/resources/public/html/demo2.html index 5b855ae..17667f5 100644 --- a/contacts/resources/public/html/demo2.html +++ b/contacts/resources/public/html/demo2.html @@ -5,6 +5,6 @@
- + From a293f8e1a9861164da32c2a981759222dc615b77 Mon Sep 17 00:00:00 2001 From: dnolen Date: Fri, 5 Jun 2015 14:56:01 -0400 Subject: [PATCH 36/60] more fixes --- contacts/project.clj | 2 +- contacts/script/brepl.clj | 2 +- contacts/src/cljs/contacts/demo2.cljs | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/contacts/project.clj b/contacts/project.clj index 1937d3f..218a595 100644 --- a/contacts/project.clj +++ b/contacts/project.clj @@ -10,7 +10,7 @@ [org.clojure/clojurescript "0.0-3308"] [com.datomic/datomic-free "0.9.5153"] [bidi "1.10.2"] - [org.omcljs/om "0.9.0"] + [org.omcljs/om "0.9.0-SNAPSHOT"] [ring/ring "1.2.2"] [com.cognitect/transit-clj "0.8.271"] [com.cognitect/transit-cljs "0.8.220"] diff --git a/contacts/script/brepl.clj b/contacts/script/brepl.clj index 37a83f7..e044e32 100644 --- a/contacts/script/brepl.clj +++ b/contacts/script/brepl.clj @@ -4,7 +4,7 @@ (b/build (b/inputs "src/dev") {:main 'contacts.dev - :asset-path "js" + :asset-path "/js" :output-to "resources/public/js/demo.js" :output-dir "resources/public/js"}) diff --git a/contacts/src/cljs/contacts/demo2.cljs b/contacts/src/cljs/contacts/demo2.cljs index cafaad8..714540a 100644 --- a/contacts/src/cljs/contacts/demo2.cljs +++ b/contacts/src/cljs/contacts/demo2.cljs @@ -1,6 +1,7 @@ (ns contacts.demo2 (:require-macros [cljs.core.async.macros :refer [go]]) (:require [goog.dom :as gdom] + [goog.object :as object] [cljs.pprint :refer [pprint]] [om.next :as om :refer-macros [defui]] [om.dom :as dom] From 896f545ca738ee889cbbea00a6bedff29fc185d2 Mon Sep 17 00:00:00 2001 From: dnolen Date: Fri, 5 Jun 2015 15:34:14 -0400 Subject: [PATCH 37/60] wip --- contacts/resources/public/css/main.css | 63 ++++------------------- contacts/resources/public/html/demo1.html | 13 ++++- contacts/src/clj/contacts/server.clj | 10 +++- contacts/src/cljs/contacts/demo1.cljs | 8 ++- 4 files changed, 36 insertions(+), 58 deletions(-) diff --git a/contacts/resources/public/css/main.css b/contacts/resources/public/css/main.css index c0fab42..c972871 100644 --- a/contacts/resources/public/css/main.css +++ b/contacts/resources/public/css/main.css @@ -1,63 +1,20 @@ body { - margin: 0px; - padding: 0px; - width: 100%; -} - -ul { - margin: 0; - padding: 0 0 0 10px; -} - -li { - list-style: none; - margin: 0; - padding: 10px; -} - -label { - font-size: 11px; - font-weight: bold; - text-transform: uppercase; -} - -.button { - font-family: sans-serif; - padding: 5px 10px; - border: 1px solid #666; - border-radius: 4px; - background-color: white; - text-transform: uppercase; -} -#contacts { - font-family: sans-serif; - position: absolute; - width: 400px; - left: 50%; - margin-left: -200px; - margin-top: 10px; } -#contacts-list, #contact-info { - border: 1px solid #ccc; - min-height: 50px; - padding: 10px; - margin-top: 10px; +#demo1 { + display: -ms-flex; + display: -webkit-flex; + display: flex; } -#contacts-list li { - cursor: pointer; +#demo1 > div { + width: 50%; } -.section { - margin-top: 20px; +#input { } -.list { - font-size: 13px; -} - -.editable button { - margin-left: 10px; -} +#output { + border: 1px solid #ccc; +} \ No newline at end of file diff --git a/contacts/resources/public/html/demo1.html b/contacts/resources/public/html/demo1.html index 22cf57f..316e688 100644 --- a/contacts/resources/public/html/demo1.html +++ b/contacts/resources/public/html/demo1.html @@ -1,10 +1,19 @@ - + + Demo 1 -
+
+
+ + +
+
+
+
+
\ No newline at end of file diff --git a/contacts/src/clj/contacts/server.clj b/contacts/src/clj/contacts/server.clj index 787c880..a459bde 100644 --- a/contacts/src/clj/contacts/server.clj +++ b/contacts/src/clj/contacts/server.clj @@ -1,5 +1,6 @@ (ns contacts.server - (:require [contacts.util :as util] + (:require [clojure.java.io :as io] + [contacts.util :as util] [ring.util.response :refer [file-response resource-response]] [ring.adapter.jetty :refer [run-jetty]] [contacts.middleware @@ -18,6 +19,7 @@ ["" {"/" :demo1 "/demo/1" :demo1 "/demo/2" :demo2 + "/css/codemirror.css" :css.codemirror "/query" {:post {[""] :query}}}]) @@ -28,6 +30,11 @@ (assoc (resource-response (str "html/demo" n ".html") {:root "public"}) :headers {"Content-Type" "text/html"})) +(defn codemirror-css [req] + (let [cm-css (slurp (io/resource "cljsjs/codemirror/production/codemirror.min.css"))] + (assoc (resource-response cm-css {:root "public"}) + :headers {"Content-Type" "text/css"}))) + (defn generate-response [data & [status]] {:status (or status 200) :headers {"Content-Type" "application/transit+json"} @@ -79,6 +86,7 @@ :request-method (:request-method req))] ;(println match) (case (:handler match) + :css.codemirror (codemirror-css req) :demo1 (demo 1 req) :demo2 (demo 2 req) :query (query req) diff --git a/contacts/src/cljs/contacts/demo1.cljs b/contacts/src/cljs/contacts/demo1.cljs index d98be00..c0b571d 100644 --- a/contacts/src/cljs/contacts/demo1.cljs +++ b/contacts/src/cljs/contacts/demo1.cljs @@ -2,10 +2,14 @@ (:require-macros [cljs.core.async.macros :refer [go]]) (:require [goog.dom :as gdom] [cljs-http.client :as http] - [cljs.core.async :refer [! chan]])) + [cljs.core.async :refer [! chan]] + [cljsjs.codemirror])) (defn main [] - ) + (let [ed (js/CodeMirror.fromTextArea (gdom/getElement "input") + #js {:lineNumbers true + :mode "clojure"})] + (.log js/console ed))) (when (gdom/getElement "demo1") (main)) \ No newline at end of file From 9571c414a724707cbaac5dcd47fd5475784e4150 Mon Sep 17 00:00:00 2001 From: dnolen Date: Fri, 5 Jun 2015 16:02:10 -0400 Subject: [PATCH 38/60] fix serving code mirror css --- contacts/src/clj/contacts/server.clj | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/contacts/src/clj/contacts/server.clj b/contacts/src/clj/contacts/server.clj index a459bde..6df2a20 100644 --- a/contacts/src/clj/contacts/server.clj +++ b/contacts/src/clj/contacts/server.clj @@ -1,7 +1,7 @@ (ns contacts.server (:require [clojure.java.io :as io] [contacts.util :as util] - [ring.util.response :refer [file-response resource-response]] + [ring.util.response :refer [response file-response resource-response]] [ring.adapter.jetty :refer [run-jetty]] [contacts.middleware :refer [wrap-transit-body wrap-transit-response @@ -32,8 +32,7 @@ (defn codemirror-css [req] (let [cm-css (slurp (io/resource "cljsjs/codemirror/production/codemirror.min.css"))] - (assoc (resource-response cm-css {:root "public"}) - :headers {"Content-Type" "text/css"}))) + (assoc (response cm-css) :headers {"Content-Type" "text/css"}))) (defn generate-response [data & [status]] {:status (or status 200) From 1f9cec3cc65fc0c28ead3949680dc99de594a225 Mon Sep 17 00:00:00 2001 From: dnolen Date: Fri, 5 Jun 2015 16:29:30 -0400 Subject: [PATCH 39/60] wip --- contacts/project.clj | 2 +- .../public/codemirror/closebrackets.js | 185 ++++++++++++++++++ .../public/codemirror/matchbrackets.js | 120 ++++++++++++ contacts/resources/public/css/main.css | 21 +- contacts/src/clj/contacts/server.clj | 5 +- contacts/src/cljs/contacts/demo1.cljs | 11 +- 6 files changed, 336 insertions(+), 8 deletions(-) create mode 100644 contacts/resources/public/codemirror/closebrackets.js create mode 100644 contacts/resources/public/codemirror/matchbrackets.js diff --git a/contacts/project.clj b/contacts/project.clj index 218a595..fef1d50 100644 --- a/contacts/project.clj +++ b/contacts/project.clj @@ -17,7 +17,7 @@ [cljs-http "0.1.30" :exclusions [org.clojure/clojure org.clojure/clojurescript com.cognitect/transit-cljs]] - [cljsjs/codemirror "5.1.0-1"] + [cljsjs/codemirror "5.1.0-2"] [com.stuartsierra/component "0.2.1"] [org.clojure/core.async "0.1.346.0-17112a-alpha"]] diff --git a/contacts/resources/public/codemirror/closebrackets.js b/contacts/resources/public/codemirror/closebrackets.js new file mode 100644 index 0000000..7030268 --- /dev/null +++ b/contacts/resources/public/codemirror/closebrackets.js @@ -0,0 +1,185 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + var defaults = { + pairs: "()[]{}''\"\"", + triples: "", + explode: "[]{}" + }; + + var Pos = CodeMirror.Pos; + + CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) { + if (old && old != CodeMirror.Init) { + cm.removeKeyMap(keyMap); + cm.state.closeBrackets = null; + } + if (val) { + cm.state.closeBrackets = val; + cm.addKeyMap(keyMap); + } + }); + + function getOption(conf, name) { + if (name == "pairs" && typeof conf == "string") return conf; + if (typeof conf == "object" && conf[name] != null) return conf[name]; + return defaults[name]; + } + + var bind = defaults.pairs + "`"; + var keyMap = {Backspace: handleBackspace, Enter: handleEnter}; + for (var i = 0; i < bind.length; i++) + keyMap["'" + bind.charAt(i) + "'"] = handler(bind.charAt(i)); + + function handler(ch) { + return function(cm) { return handleChar(cm, ch); }; + } + + function getConfig(cm) { + var deflt = cm.state.closeBrackets; + if (!deflt) return null; + var mode = cm.getModeAt(cm.getCursor()); + return mode.closeBrackets || deflt; + } + + function handleBackspace(cm) { + var conf = getConfig(cm); + if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass; + + var pairs = getOption(conf, "pairs"); + var ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + if (!ranges[i].empty()) return CodeMirror.Pass; + var around = charsAround(cm, ranges[i].head); + if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass; + } + for (var i = ranges.length - 1; i >= 0; i--) { + var cur = ranges[i].head; + cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1)); + } + } + + function handleEnter(cm) { + var conf = getConfig(cm); + var explode = conf && getOption(conf, "explode"); + if (!explode || cm.getOption("disableInput")) return CodeMirror.Pass; + + var ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + if (!ranges[i].empty()) return CodeMirror.Pass; + var around = charsAround(cm, ranges[i].head); + if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass; + } + cm.operation(function() { + cm.replaceSelection("\n\n", null); + cm.execCommand("goCharLeft"); + ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + var line = ranges[i].head.line; + cm.indentLine(line, null, true); + cm.indentLine(line + 1, null, true); + } + }); + } + + function handleChar(cm, ch) { + var conf = getConfig(cm); + if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass; + + var pairs = getOption(conf, "pairs"); + var pos = pairs.indexOf(ch); + if (pos == -1) return CodeMirror.Pass; + var triples = getOption(conf, "triples"); + + var identical = pairs.charAt(pos + 1) == ch; + var ranges = cm.listSelections(); + var opening = pos % 2 == 0; + + var type, next; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i], cur = range.head, curType; + var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1)); + if (opening && !range.empty()) { + curType = "surround"; + } else if ((identical || !opening) && next == ch) { + if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch) + curType = "skipThree"; + else + curType = "skip"; + } else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 && + cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch && + (cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur.line, cur.ch - 2)) != ch)) { + curType = "addFour"; + } else if (identical) { + if (!CodeMirror.isWordChar(next) && enteringString(cm, cur, ch)) curType = "both"; + else return CodeMirror.Pass; + } else if (opening && (cm.getLine(cur.line).length == cur.ch || + isClosingBracket(next, pairs) || + /\s/.test(next))) { + curType = "both"; + } else { + return CodeMirror.Pass; + } + if (!type) type = curType; + else if (type != curType) return CodeMirror.Pass; + } + + var left = pos % 2 ? pairs.charAt(pos - 1) : ch; + var right = pos % 2 ? ch : pairs.charAt(pos + 1); + cm.operation(function() { + if (type == "skip") { + cm.execCommand("goCharRight"); + } else if (type == "skipThree") { + for (var i = 0; i < 3; i++) + cm.execCommand("goCharRight"); + } else if (type == "surround") { + var sels = cm.getSelections(); + for (var i = 0; i < sels.length; i++) + sels[i] = left + sels[i] + right; + cm.replaceSelections(sels, "around"); + } else if (type == "both") { + cm.replaceSelection(left + right, null); + cm.triggerElectric(left + right); + cm.execCommand("goCharLeft"); + } else if (type == "addFour") { + cm.replaceSelection(left + left + left + left, "before"); + cm.execCommand("goCharRight"); + } + }); + } + + function isClosingBracket(ch, pairs) { + var pos = pairs.lastIndexOf(ch); + return pos > -1 && pos % 2 == 1; + } + + function charsAround(cm, pos) { + var str = cm.getRange(Pos(pos.line, pos.ch - 1), + Pos(pos.line, pos.ch + 1)); + return str.length == 2 ? str : null; + } + + // Project the token type that will exists after the given char is + // typed, and use it to determine whether it would cause the start + // of a string token. + function enteringString(cm, pos, ch) { + var line = cm.getLine(pos.line); + var token = cm.getTokenAt(pos); + if (/\bstring2?\b/.test(token.type)) return false; + var stream = new CodeMirror.StringStream(line.slice(0, pos.ch) + ch + line.slice(pos.ch), 4); + stream.pos = stream.start = token.start; + for (;;) { + var type1 = cm.getMode().token(stream, token.state); + if (stream.pos >= pos.ch + 1) return /\bstring2?\b/.test(type1); + stream.start = stream.pos; + } + } +}); diff --git a/contacts/resources/public/codemirror/matchbrackets.js b/contacts/resources/public/codemirror/matchbrackets.js new file mode 100644 index 0000000..70e1ae1 --- /dev/null +++ b/contacts/resources/public/codemirror/matchbrackets.js @@ -0,0 +1,120 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + var ie_lt8 = /MSIE \d/.test(navigator.userAgent) && + (document.documentMode == null || document.documentMode < 8); + + var Pos = CodeMirror.Pos; + + var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"}; + + function findMatchingBracket(cm, where, strict, config) { + var line = cm.getLineHandle(where.line), pos = where.ch - 1; + var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)]; + if (!match) return null; + var dir = match.charAt(1) == ">" ? 1 : -1; + if (strict && (dir > 0) != (pos == where.ch)) return null; + var style = cm.getTokenTypeAt(Pos(where.line, pos + 1)); + + var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config); + if (found == null) return null; + return {from: Pos(where.line, pos), to: found && found.pos, + match: found && found.ch == match.charAt(0), forward: dir > 0}; + } + + // bracketRegex is used to specify which type of bracket to scan + // should be a regexp, e.g. /[[\]]/ + // + // Note: If "where" is on an open bracket, then this bracket is ignored. + // + // Returns false when no bracket was found, null when it reached + // maxScanLines and gave up + function scanForBracket(cm, where, dir, style, config) { + var maxScanLen = (config && config.maxScanLineLength) || 10000; + var maxScanLines = (config && config.maxScanLines) || 1000; + + var stack = []; + var re = config && config.bracketRegex ? config.bracketRegex : /[(){}[\]]/; + var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1) + : Math.max(cm.firstLine() - 1, where.line - maxScanLines); + for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) { + var line = cm.getLine(lineNo); + if (!line) continue; + var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1; + if (line.length > maxScanLen) continue; + if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0); + for (; pos != end; pos += dir) { + var ch = line.charAt(pos); + if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) { + var match = matching[ch]; + if ((match.charAt(1) == ">") == (dir > 0)) stack.push(ch); + else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch}; + else stack.pop(); + } + } + } + return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null; + } + + function matchBrackets(cm, autoclear, config) { + // Disable brace matching in long lines, since it'll cause hugely slow updates + var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000; + var marks = [], ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, false, config); + if (match && cm.getLine(match.from.line).length <= maxHighlightLen) { + var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket"; + marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style})); + if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen) + marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style})); + } + } + + if (marks.length) { + // Kludge to work around the IE bug from issue #1193, where text + // input stops going to the textare whever this fires. + if (ie_lt8 && cm.state.focused) cm.focus(); + + var clear = function() { + cm.operation(function() { + for (var i = 0; i < marks.length; i++) marks[i].clear(); + }); + }; + if (autoclear) setTimeout(clear, 800); + else return clear; + } + } + + var currentlyHighlighted = null; + function doMatchBrackets(cm) { + cm.operation(function() { + if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;} + currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets); + }); + } + + CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) { + if (old && old != CodeMirror.Init) + cm.off("cursorActivity", doMatchBrackets); + if (val) { + cm.state.matchBrackets = typeof val == "object" ? val : {}; + cm.on("cursorActivity", doMatchBrackets); + } + }); + + CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);}); + CodeMirror.defineExtension("findMatchingBracket", function(pos, strict, config){ + return findMatchingBracket(this, pos, strict, config); + }); + CodeMirror.defineExtension("scanForBracket", function(pos, dir, style, config){ + return scanForBracket(this, pos, dir, style, config); + }); +}); diff --git a/contacts/resources/public/css/main.css b/contacts/resources/public/css/main.css index c972871..9ef848c 100644 --- a/contacts/resources/public/css/main.css +++ b/contacts/resources/public/css/main.css @@ -1,20 +1,37 @@ body { - + font-size: 24px; } #demo1 { + border: 1px solid #ccc; display: -ms-flex; display: -webkit-flex; display: flex; + height: 600px; +} + +textarea { + width: 50%; } #demo1 > div { width: 50%; } +button { + font-size: 24px; + border: 2px solid black; + background-color: white; + border-radius: 4px; + margin-top: 1em; + margin-left: 1em; +} + #input { } #output { - border: 1px solid #ccc; + background-color: #efefef; + border-left: 1px solid #ccc; + height: 100%; } \ No newline at end of file diff --git a/contacts/src/clj/contacts/server.clj b/contacts/src/clj/contacts/server.clj index 6df2a20..5b2573d 100644 --- a/contacts/src/clj/contacts/server.clj +++ b/contacts/src/clj/contacts/server.clj @@ -31,8 +31,9 @@ :headers {"Content-Type" "text/html"})) (defn codemirror-css [req] - (let [cm-css (slurp (io/resource "cljsjs/codemirror/production/codemirror.min.css"))] - (assoc (response cm-css) :headers {"Content-Type" "text/css"}))) + (assoc + (resource-response "cljsjs/codemirror/production/codemirror.min.css") + :headers {"Content-Type" "text/css"})) (defn generate-response [data & [status]] {:status (or status 200) diff --git a/contacts/src/cljs/contacts/demo1.cljs b/contacts/src/cljs/contacts/demo1.cljs index c0b571d..f6d3164 100644 --- a/contacts/src/cljs/contacts/demo1.cljs +++ b/contacts/src/cljs/contacts/demo1.cljs @@ -3,13 +3,18 @@ (:require [goog.dom :as gdom] [cljs-http.client :as http] [cljs.core.async :refer [! chan]] - [cljsjs.codemirror])) + [cljsjs.codemirror.mode.clojure])) (defn main [] (let [ed (js/CodeMirror.fromTextArea (gdom/getElement "input") #js {:lineNumbers true - :mode "clojure"})] + :matchBrackets true + :mode #js {:name "clojure"}})] (.log js/console ed))) (when (gdom/getElement "demo1") - (main)) \ No newline at end of file + (main)) + +(comment + () + ) \ No newline at end of file From 8073da0f70916f2cdc7605fa83fb1315419076b3 Mon Sep 17 00:00:00 2001 From: dnolen Date: Fri, 5 Jun 2015 16:33:59 -0400 Subject: [PATCH 40/60] wip --- contacts/script/brepl.clj | 18 ++++++++++++++++-- contacts/src/cljs/contacts/demo1.cljs | 5 ++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/contacts/script/brepl.clj b/contacts/script/brepl.clj index e044e32..bec8e1d 100644 --- a/contacts/script/brepl.clj +++ b/contacts/script/brepl.clj @@ -6,9 +6,23 @@ {:main 'contacts.dev :asset-path "/js" :output-to "resources/public/js/demo.js" - :output-dir "resources/public/js"}) + :output-dir "resources/public/js" + :foreign-libs + [{:provides ["cljsjs.codemirror.addons.matchbrackets"] + :requires ["cljsjs.codemirror"] + :file "resources/public/codemirror/matchbrackets.js"} + {:provides ["cljsjs.codemirror.addons.closebrackets"] + :requires ["cljsjs.codemirror"] + :file "resources/public/codemirror/closebrackets.js"}]}) (repl/repl (browser/repl-env :host-port 8081) :asset-path "js" - :output-dir "resources/public/js") \ No newline at end of file + :output-dir "resources/public/js" + :foreign-libs + [{:provides ["cljsjs.codemirror.addons.matchbrackets"] + :requires ["cljsjs.codemirror"] + :file "resources/public/codemirror/matchbrackets.js"} + {:provides ["cljsjs.codemirror.addons.closebrackets"] + :requires ["cljsjs.codemirror"] + :file "resources/public/codemirror/closebrackets.js"}]) \ No newline at end of file diff --git a/contacts/src/cljs/contacts/demo1.cljs b/contacts/src/cljs/contacts/demo1.cljs index f6d3164..7f6e9b5 100644 --- a/contacts/src/cljs/contacts/demo1.cljs +++ b/contacts/src/cljs/contacts/demo1.cljs @@ -3,12 +3,15 @@ (:require [goog.dom :as gdom] [cljs-http.client :as http] [cljs.core.async :refer [! chan]] - [cljsjs.codemirror.mode.clojure])) + [cljsjs.codemirror.mode.clojure] + [cljsjs.codemirror.addons.matchbrackets] + [cljsjs.codemirror.addons.closebrackets])) (defn main [] (let [ed (js/CodeMirror.fromTextArea (gdom/getElement "input") #js {:lineNumbers true :matchBrackets true + :closeBrackets true :mode #js {:name "clojure"}})] (.log js/console ed))) From af722a37768833b93fe90ff46d6190b63a5893c1 Mon Sep 17 00:00:00 2001 From: dnolen Date: Fri, 5 Jun 2015 16:57:19 -0400 Subject: [PATCH 41/60] tweaks --- contacts/resources/public/css/main.css | 8 +++++++ contacts/resources/public/html/demo1.html | 6 +++--- contacts/src/clj/contacts/datomic.clj | 11 +++++----- contacts/src/cljs/contacts/demo1.cljs | 26 ++++++++++++++++++++--- 4 files changed, 40 insertions(+), 11 deletions(-) diff --git a/contacts/resources/public/css/main.css b/contacts/resources/public/css/main.css index 9ef848c..f6d9054 100644 --- a/contacts/resources/public/css/main.css +++ b/contacts/resources/public/css/main.css @@ -34,4 +34,12 @@ button { background-color: #efefef; border-left: 1px solid #ccc; height: 100%; +} + +pre { + white-space: pre-wrap; /* css-3 */ + white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + word-wrap: break-word; /* Internet Explorer 5.5+ */ } \ No newline at end of file diff --git a/contacts/resources/public/html/demo1.html b/contacts/resources/public/html/demo1.html index 316e688..d788c77 100644 --- a/contacts/resources/public/html/demo1.html +++ b/contacts/resources/public/html/demo1.html @@ -7,11 +7,11 @@
- - + +
-
+
             
diff --git a/contacts/src/clj/contacts/datomic.clj b/contacts/src/clj/contacts/datomic.clj index 8ebb51a..8b1971a 100644 --- a/contacts/src/clj/contacts/datomic.clj +++ b/contacts/src/clj/contacts/datomic.clj @@ -12,11 +12,12 @@ (defn contacts ([db] (contacts db '[*])) ([db selector] - (d/q '[:find (pull ?eid selector) - :in $ selector - :where - [?eid :person/first-name]] ;; talk about how we can make it do first OR last name - db selector))) + (mapv first + (d/q '[:find (pull ?eid selector) + :in $ selector + :where + [?eid :person/first-name]] ;; talk about how we can make it do first OR last name + db selector)))) (defn get-contact ([db id] (get-contact db id '[*])) diff --git a/contacts/src/cljs/contacts/demo1.cljs b/contacts/src/cljs/contacts/demo1.cljs index 7f6e9b5..90b3526 100644 --- a/contacts/src/cljs/contacts/demo1.cljs +++ b/contacts/src/cljs/contacts/demo1.cljs @@ -1,11 +1,22 @@ (ns contacts.demo1 (:require-macros [cljs.core.async.macros :refer [go]]) (:require [goog.dom :as gdom] + [goog.events :as events] + [cljs.pprint :as pprint :refer [pprint]] [cljs-http.client :as http] [cljs.core.async :refer [! chan]] + [cljs.reader :as reader] [cljsjs.codemirror.mode.clojure] [cljsjs.codemirror.addons.matchbrackets] - [cljsjs.codemirror.addons.closebrackets])) + [cljsjs.codemirror.addons.closebrackets]) + (:import [goog.events EventType])) + +(defn log [x] + (println) ;; flush past prompt + (pprint x)) + +(defn fetch [q] + (http/post "http://localhost:8081/query" {:transit-params q})) (defn main [] (let [ed (js/CodeMirror.fromTextArea (gdom/getElement "input") @@ -13,11 +24,20 @@ :matchBrackets true :closeBrackets true :mode #js {:name "clojure"}})] - (.log js/console ed))) + (events/listen (gdom/getElement "submit") EventType.CLICK + (fn [e] + (go + (set! (.-innerHTML (gdom/getElement "output")) + (with-out-str + (binding [pprint/*print-right-margin* 40] + (pprint + (:body + ( Date: Fri, 5 Jun 2015 17:05:18 -0400 Subject: [PATCH 42/60] tweaks --- contacts/resources/public/html/demo1.html | 3 ++- contacts/src/cljs/contacts/demo1.cljs | 4 +--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/contacts/resources/public/html/demo1.html b/contacts/resources/public/html/demo1.html index d788c77..b2817cd 100644 --- a/contacts/resources/public/html/demo1.html +++ b/contacts/resources/public/html/demo1.html @@ -7,7 +7,8 @@
- +
diff --git a/contacts/src/cljs/contacts/demo1.cljs b/contacts/src/cljs/contacts/demo1.cljs index 90b3526..cbcee6f 100644 --- a/contacts/src/cljs/contacts/demo1.cljs +++ b/contacts/src/cljs/contacts/demo1.cljs @@ -7,8 +7,7 @@ [cljs.core.async :refer [! chan]] [cljs.reader :as reader] [cljsjs.codemirror.mode.clojure] - [cljsjs.codemirror.addons.matchbrackets] - [cljsjs.codemirror.addons.closebrackets]) + [cljsjs.codemirror.addons.matchbrackets]) (:import [goog.events EventType])) (defn log [x] @@ -22,7 +21,6 @@ (let [ed (js/CodeMirror.fromTextArea (gdom/getElement "input") #js {:lineNumbers true :matchBrackets true - :closeBrackets true :mode #js {:name "clojure"}})] (events/listen (gdom/getElement "submit") EventType.CLICK (fn [e] From 2b43761f31380554f28cff2167fe8d95f11092db Mon Sep 17 00:00:00 2001 From: dnolen Date: Fri, 5 Jun 2015 18:45:43 -0400 Subject: [PATCH 43/60] styling --- contacts/resources/public/css/main.css | 2 ++ contacts/src/cljs/contacts/demo2.cljs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/contacts/resources/public/css/main.css b/contacts/resources/public/css/main.css index f6d9054..ba0176f 100644 --- a/contacts/resources/public/css/main.css +++ b/contacts/resources/public/css/main.css @@ -42,4 +42,6 @@ pre { white-space: -pre-wrap; /* Opera 4-6 */ white-space: -o-pre-wrap; /* Opera 7 */ word-wrap: break-word; /* Internet Explorer 5.5+ */ + padding: 0; + margin: 0; } \ No newline at end of file diff --git a/contacts/src/cljs/contacts/demo2.cljs b/contacts/src/cljs/contacts/demo2.cljs index 714540a..df370f1 100644 --- a/contacts/src/cljs/contacts/demo2.cljs +++ b/contacts/src/cljs/contacts/demo2.cljs @@ -23,7 +23,7 @@ Object (render [this] (let [{:keys [:person/first-name :person/last-name] :as props} - (first (om/props this))] + (om/props this)] (dom/div nil (dom/div nil (dom/label nil "Full Name:") From be83e18f7e2db4e5bd116a43d31b3dad8c09e3f6 Mon Sep 17 00:00:00 2001 From: dnolen Date: Fri, 5 Jun 2015 18:55:43 -0400 Subject: [PATCH 44/60] latest CSS changes --- contacts/resources/public/css/main.css | 5 +++++ contacts/resources/public/html/demo1.html | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/contacts/resources/public/css/main.css b/contacts/resources/public/css/main.css index ba0176f..ea31b55 100644 --- a/contacts/resources/public/css/main.css +++ b/contacts/resources/public/css/main.css @@ -14,6 +14,11 @@ textarea { width: 50%; } +.CodeMirror { + height: 510px; + border-bottom: 1px solid #ccc; +} + #demo1 > div { width: 50%; } diff --git a/contacts/resources/public/html/demo1.html b/contacts/resources/public/html/demo1.html index b2817cd..13c3a37 100644 --- a/contacts/resources/public/html/demo1.html +++ b/contacts/resources/public/html/demo1.html @@ -1,7 +1,7 @@ - + Demo 1 From 47981ede93b691c0e5ce7ee53af73896cc45d191 Mon Sep 17 00:00:00 2001 From: dnolen Date: Fri, 5 Jun 2015 20:14:23 -0400 Subject: [PATCH 45/60] latest CSS changes --- contacts/script/brepl.clj | 8 ++++---- contacts/src/cljs/contacts/demo1.cljs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/contacts/script/brepl.clj b/contacts/script/brepl.clj index bec8e1d..98e7bf4 100644 --- a/contacts/script/brepl.clj +++ b/contacts/script/brepl.clj @@ -10,10 +10,10 @@ :foreign-libs [{:provides ["cljsjs.codemirror.addons.matchbrackets"] :requires ["cljsjs.codemirror"] - :file "resources/public/codemirror/matchbrackets.js"} + :file "public/codemirror/matchbrackets.js"} {:provides ["cljsjs.codemirror.addons.closebrackets"] :requires ["cljsjs.codemirror"] - :file "resources/public/codemirror/closebrackets.js"}]}) + :file "public/codemirror/closebrackets.js"}]}) (repl/repl (browser/repl-env :host-port 8081) @@ -22,7 +22,7 @@ :foreign-libs [{:provides ["cljsjs.codemirror.addons.matchbrackets"] :requires ["cljsjs.codemirror"] - :file "resources/public/codemirror/matchbrackets.js"} + :file "public/codemirror/matchbrackets.js"} {:provides ["cljsjs.codemirror.addons.closebrackets"] :requires ["cljsjs.codemirror"] - :file "resources/public/codemirror/closebrackets.js"}]) \ No newline at end of file + :file "public/codemirror/closebrackets.js"}]) \ No newline at end of file diff --git a/contacts/src/cljs/contacts/demo1.cljs b/contacts/src/cljs/contacts/demo1.cljs index cbcee6f..dbdb40e 100644 --- a/contacts/src/cljs/contacts/demo1.cljs +++ b/contacts/src/cljs/contacts/demo1.cljs @@ -29,8 +29,8 @@ (with-out-str (binding [pprint/*print-right-margin* 40] (pprint - (:body - ( Date: Sat, 6 Jun 2015 10:15:39 -0400 Subject: [PATCH 46/60] ignore .repl* --- contacts/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/contacts/.gitignore b/contacts/.gitignore index e04714b..4188ff6 100644 --- a/contacts/.gitignore +++ b/contacts/.gitignore @@ -7,3 +7,4 @@ pom.xml.asc *.class /.lein-* /.nrepl-port +.repl* From cc1bf304ee3826b64171faebc890e5e6fffed1ba Mon Sep 17 00:00:00 2001 From: David Nolen Date: Sat, 6 Jun 2015 10:29:46 -0400 Subject: [PATCH 47/60] Submit -> Pull, simplify repl script --- contacts/resources/public/html/demo1.html | 2 +- contacts/script/brepl.clj | 24 +++++++++-------------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/contacts/resources/public/html/demo1.html b/contacts/resources/public/html/demo1.html index 13c3a37..e3cc183 100644 --- a/contacts/resources/public/html/demo1.html +++ b/contacts/resources/public/html/demo1.html @@ -9,7 +9,7 @@
- +
diff --git a/contacts/script/brepl.clj b/contacts/script/brepl.clj
index 98e7bf4..7f5ef63 100644
--- a/contacts/script/brepl.clj
+++ b/contacts/script/brepl.clj
@@ -2,10 +2,8 @@
 (require '[cljs.repl :as repl])
 (require '[cljs.repl.browser :as browser])
 
-(b/build (b/inputs "src/dev")
-  {:main 'contacts.dev
-   :asset-path "/js"
-   :output-to "resources/public/js/demo.js"
+(def shared-opts
+  {:asset-path "/js"
    :output-dir "resources/public/js"
    :foreign-libs
    [{:provides ["cljsjs.codemirror.addons.matchbrackets"]
@@ -15,14 +13,10 @@
      :requires ["cljsjs.codemirror"]
      :file "public/codemirror/closebrackets.js"}]})
 
-(repl/repl
-  (browser/repl-env :host-port 8081)
-  :asset-path "js"
-  :output-dir "resources/public/js"
-  :foreign-libs
-  [{:provides ["cljsjs.codemirror.addons.matchbrackets"]
-    :requires ["cljsjs.codemirror"]
-    :file "public/codemirror/matchbrackets.js"}
-   {:provides ["cljsjs.codemirror.addons.closebrackets"]
-    :requires ["cljsjs.codemirror"]
-    :file "public/codemirror/closebrackets.js"}])
\ No newline at end of file
+(b/build (b/inputs "src/dev")
+  (merge
+    {:main 'contacts.dev
+     :output-to "resources/public/js/demo.js"}
+    shared-opts))
+
+(repl/repl* (browser/repl-env :host-port 8081) shared-opts)
\ No newline at end of file

From fc34e64d7bb7c3b8e5fcf42d7da46251d91009bf Mon Sep 17 00:00:00 2001
From: David Nolen 
Date: Sat, 6 Jun 2015 14:50:45 -0400
Subject: [PATCH 48/60] bump ClojureScript dep

---
 contacts/project.clj | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/contacts/project.clj b/contacts/project.clj
index fef1d50..29d7e1e 100644
--- a/contacts/project.clj
+++ b/contacts/project.clj
@@ -7,7 +7,7 @@
   :jvm-opts ^:replace ["-Xms512m" "-Xmx512m" "-server"]
 
   :dependencies [[org.clojure/clojure "1.7.0-RC1"]
-                 [org.clojure/clojurescript "0.0-3308"]
+                 [org.clojure/clojurescript "0.0-3310"]
                  [com.datomic/datomic-free "0.9.5153"]
                  [bidi "1.10.2"]
                  [org.omcljs/om "0.9.0-SNAPSHOT"]

From 03e0e0829ff539bec3405295f3703f2a4868f38d Mon Sep 17 00:00:00 2001
From: David Nolen 
Date: Sat, 6 Jun 2015 14:55:27 -0400
Subject: [PATCH 49/60] query -> get-query

---
 contacts/src/cljs/contacts/demo2.cljs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/contacts/src/cljs/contacts/demo2.cljs b/contacts/src/cljs/contacts/demo2.cljs
index df370f1..ed58252 100644
--- a/contacts/src/cljs/contacts/demo2.cljs
+++ b/contacts/src/cljs/contacts/demo2.cljs
@@ -51,7 +51,7 @@
 (def contact-list (om/create-factory ContactList))
 
 (defn main []
-  (let [c (fetch (om/query ContactList))]
+  (let [c (fetch (om/get-query ContactList))]
     (go
       (let [contacts (:body (
Date: Sat, 6 Jun 2015 15:01:01 -0400
Subject: [PATCH 50/60] wrong element

---
 contacts/src/cljs/contacts/demo2.cljs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/contacts/src/cljs/contacts/demo2.cljs b/contacts/src/cljs/contacts/demo2.cljs
index ed58252..23d5423 100644
--- a/contacts/src/cljs/contacts/demo2.cljs
+++ b/contacts/src/cljs/contacts/demo2.cljs
@@ -56,7 +56,7 @@
       (let [contacts (:body (
Date: Sat, 6 Jun 2015 15:16:09 -0400
Subject: [PATCH 51/60] basic styling

---
 contacts/resources/public/css/main.css    | 20 +++++++++++++++++++-
 contacts/resources/public/html/demo2.html |  2 +-
 contacts/src/cljs/contacts/demo2.cljs     |  6 ++++--
 3 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/contacts/resources/public/css/main.css b/contacts/resources/public/css/main.css
index ea31b55..fdb550e 100644
--- a/contacts/resources/public/css/main.css
+++ b/contacts/resources/public/css/main.css
@@ -2,7 +2,7 @@ body {
     font-size: 24px;
 }
 
-#demo1 {
+#demo1, #demo2 {
     border: 1px solid #ccc;
     display: -ms-flex;
     display: -webkit-flex;
@@ -10,6 +10,24 @@ body {
     height: 600px;
 }
 
+#demo2 {
+    padding: 2em;
+    font-family: helvetica, arial, sans-serif;
+}
+
+#demo2 h3 {
+    margin: 0;
+}
+
+#demo2 li {
+    padding: 0 0 0.5em 0;
+}
+
+#demo2 li label {
+    font-weight: bold;
+    padding-right: 1em;
+}
+
 textarea {
     width: 50%;
 }
diff --git a/contacts/resources/public/html/demo2.html b/contacts/resources/public/html/demo2.html
index 17667f5..1285b74 100644
--- a/contacts/resources/public/html/demo2.html
+++ b/contacts/resources/public/html/demo2.html
@@ -1,6 +1,6 @@
 
     
-        
+        
         Demo 2
     
     
diff --git a/contacts/src/cljs/contacts/demo2.cljs b/contacts/src/cljs/contacts/demo2.cljs
index 23d5423..25b6414 100644
--- a/contacts/src/cljs/contacts/demo2.cljs
+++ b/contacts/src/cljs/contacts/demo2.cljs
@@ -45,8 +45,10 @@
   Object
   (render [this]
     (let [{:keys [:app/contacts]} (om/props this)]
-      (apply dom/ul nil
-        (map #(dom/li nil (contact %)) contacts)))))
+      (dom/div nil
+        (dom/h3 nil "Contacts")
+        (apply dom/ul nil
+          (map #(dom/li nil (contact %)) contacts))))))
 
 (def contact-list (om/create-factory ContactList))
 

From 75e88e9dc497ae6fdb3865fc0e1777684db39365 Mon Sep 17 00:00:00 2001
From: David Nolen 
Date: Sat, 6 Jun 2015 15:20:16 -0400
Subject: [PATCH 52/60] wip

---
 contacts/src/cljs/contacts/demo2.cljs | 29 ++++++++++++++++++++-------
 1 file changed, 22 insertions(+), 7 deletions(-)

diff --git a/contacts/src/cljs/contacts/demo2.cljs b/contacts/src/cljs/contacts/demo2.cljs
index 25b6414..4515c0d 100644
--- a/contacts/src/cljs/contacts/demo2.cljs
+++ b/contacts/src/cljs/contacts/demo2.cljs
@@ -15,6 +15,24 @@
 (defn fetch [q]
   (http/post "http://localhost:8081/query" {:transit-params q}))
 
+(defn label+span [label-text span-text]
+  (dom/div nil
+    (dom/label nil label-text)
+    (dom/span nil span-text)))
+
+(defui AddressInfo
+  static om/IQuery
+  (query [this]
+    '[:address/street :address/city :address/zipcode])
+  Object
+  (render [this]
+    (let [{:keys [:address/street :address/city :address/zipcode]}
+          (om/props this)]
+      (dom/div nil
+        (dom/div nil)
+        (dom/div nil)
+        (dom/div nil)))))
+
 (defui Contact
   static om/IQuery
   (query [this]
@@ -25,13 +43,10 @@
     (let [{:keys [:person/first-name :person/last-name] :as props}
           (om/props this)]
       (dom/div nil
-        (dom/div nil
-          (dom/label nil "Full Name:")
-          (dom/span nil (str last-name ", " first-name)))
-        (dom/div nil
-          (dom/label nil "Number:")
-          (dom/span nil
-            (:telephone/number (first (:person/telephone props)))))))))
+        (label+span "Full Name:"
+          (str last-name ", " first-name))
+        (label+span "Number:"
+          (:telephone/number (first (:person/telephone props))))))))
 
 (def contact (om/create-factory Contact))
 

From 010f7587b0263545ef0debc17c15af4c25e65d45 Mon Sep 17 00:00:00 2001
From: David Nolen 
Date: Sat, 6 Jun 2015 15:41:05 -0400
Subject: [PATCH 53/60] wip

---
 contacts/src/cljs/contacts/demo2.cljs | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/contacts/src/cljs/contacts/demo2.cljs b/contacts/src/cljs/contacts/demo2.cljs
index 4515c0d..b8d420e 100644
--- a/contacts/src/cljs/contacts/demo2.cljs
+++ b/contacts/src/cljs/contacts/demo2.cljs
@@ -26,12 +26,14 @@
     '[:address/street :address/city :address/zipcode])
   Object
   (render [this]
-    (let [{:keys [:address/street :address/city :address/zipcode]}
+    (let [{:keys [:address/street :address/city
+                  :address/state :address/zipcode]}
           (om/props this)]
       (dom/div nil
-        (dom/div nil)
-        (dom/div nil)
-        (dom/div nil)))))
+        (dom/div nil street)
+        (dom/div nil (str city ", " state " " zipcode))))))
+
+(def address-info (om/create-factory AddressInfo))
 
 (defui Contact
   static om/IQuery

From 48f911d6ab2e6c2548ebc305a08471d957a5b836 Mon Sep 17 00:00:00 2001
From: David Nolen 
Date: Sat, 6 Jun 2015 16:07:36 -0400
Subject: [PATCH 54/60] wrap up demo2

---
 contacts/src/cljs/contacts/demo2.cljs | 42 ++++++++++++++++++---------
 1 file changed, 28 insertions(+), 14 deletions(-)

diff --git a/contacts/src/cljs/contacts/demo2.cljs b/contacts/src/cljs/contacts/demo2.cljs
index b8d420e..6d88b21 100644
--- a/contacts/src/cljs/contacts/demo2.cljs
+++ b/contacts/src/cljs/contacts/demo2.cljs
@@ -15,10 +15,19 @@
 (defn fetch [q]
   (http/post "http://localhost:8081/query" {:transit-params q}))
 
-(defn label+span [label-text span-text]
-  (dom/div nil
-    (dom/label nil label-text)
-    (dom/span nil span-text)))
+(defn label+span
+  ([label-content span-content]
+   (label+span nil label-content span-content))
+  ([props label-content span-content]
+   (let [label-content (if-not (sequential? label-content)
+                         [label-content]
+                         label-content)
+         span-content (if-not (sequential? span-content)
+                         [span-content]
+                         span-content)]
+     (dom/div props
+       (apply dom/label nil label-content)
+       (apply dom/span nil span-content)))))
 
 (defui AddressInfo
   static om/IQuery
@@ -29,33 +38,40 @@
     (let [{:keys [:address/street :address/city
                   :address/state :address/zipcode]}
           (om/props this)]
-      (dom/div nil
-        (dom/div nil street)
-        (dom/div nil (str city ", " state " " zipcode))))))
+      (label+span #js {:className "address"}
+        "Address:"
+        (dom/span nil
+          (str street " " city ", " state " " zipcode))))))
 
 (def address-info (om/create-factory AddressInfo))
 
 (defui Contact
+  ;static om/IQueryParams
+  ;(params [this]
+  ;  {:address (om/get-query AddressInfo)})
   static om/IQuery
   (query [this]
     '[:person/first-name :person/last-name
-      {:person/telephone [:telephone/number]}])
+      {:person/telephone [:telephone/number]}
+      #_{:person/address ?address}])
   Object
   (render [this]
-    (let [{:keys [:person/first-name :person/last-name] :as props}
+    (let [{:keys [:person/first-name :person/last-name :person/address]
+           :as props}
           (om/props this)]
       (dom/div nil
         (label+span "Full Name:"
           (str last-name ", " first-name))
         (label+span "Number:"
-          (:telephone/number (first (:person/telephone props))))))))
+          (:telephone/number (first (:person/telephone props))))
+        #_(address-info (first address))))))
 
 (def contact (om/create-factory Contact))
 
 (defui ContactList
   static om/IQueryParams
   (params [this]
-    {:contact (om/query Contact)})
+    {:contact (om/get-query Contact)})
   static om/IQuery
   (query [this]
     '[{:app/contacts ?contact}])
@@ -100,7 +116,5 @@
   (main)
 
   ;; works
-  (om/bind-query
-    (om/-query ContactList)
-    (om/-params ContactList))
+  (om/get-query ContactList)
   )
\ No newline at end of file

From a0353f03ef2c3bfcea15f8565c0d5425e416dc69 Mon Sep 17 00:00:00 2001
From: David Nolen 
Date: Sat, 6 Jun 2015 16:08:20 -0400
Subject: [PATCH 55/60] clean up demos

---
 contacts/src/cljs/contacts/demo1.cljs |  5 -----
 contacts/src/cljs/contacts/demo2.cljs | 23 -----------------------
 2 files changed, 28 deletions(-)

diff --git a/contacts/src/cljs/contacts/demo1.cljs b/contacts/src/cljs/contacts/demo1.cljs
index dbdb40e..8d0f1aa 100644
--- a/contacts/src/cljs/contacts/demo1.cljs
+++ b/contacts/src/cljs/contacts/demo1.cljs
@@ -34,8 +34,3 @@
 
 (when (gdom/getElement "demo1")
   (main))
-
-(comment
-  (let [c (fetch [{:app/contacts [:person/first-name]}])]
-    (go (log (:body (
Date: Sat, 6 Jun 2015 16:18:10 -0400
Subject: [PATCH 56/60] delimiters

---
 contacts/src/cljs/contacts/demo2.cljs | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/contacts/src/cljs/contacts/demo2.cljs b/contacts/src/cljs/contacts/demo2.cljs
index bec62ed..0676370 100644
--- a/contacts/src/cljs/contacts/demo2.cljs
+++ b/contacts/src/cljs/contacts/demo2.cljs
@@ -8,6 +8,9 @@
             [cljs-http.client :as http]
             [cljs.core.async :refer [! chan]]))
 
+;; =============================================================================
+;; Utilities
+
 (defn log [x]
   (println) ;; flush past prompt
   (pprint x))
@@ -29,6 +32,9 @@
        (apply dom/label nil label-content)
        (apply dom/span nil span-content)))))
 
+;; =============================================================================
+;; AddressInfo Component
+
 (defui AddressInfo
   static om/IQuery
   (query [this]
@@ -45,6 +51,9 @@
 
 (def address-info (om/create-factory AddressInfo))
 
+;; =============================================================================
+;; Contact Component
+
 (defui Contact
   ;static om/IQueryParams
   ;(params [this]
@@ -68,6 +77,9 @@
 
 (def contact (om/create-factory Contact))
 
+;; =============================================================================
+;; ContactList Component
+
 (defui ContactList
   static om/IQueryParams
   (params [this]
@@ -85,6 +97,9 @@
 
 (def contact-list (om/create-factory ContactList))
 
+;; =============================================================================
+;; main
+
 (defn main []
   (let [c (fetch (om/get-query ContactList))]
     (go

From 13aa1e0fb6a922758c4e50fea18be1d9a09db987 Mon Sep 17 00:00:00 2001
From: David Nolen 
Date: Sat, 6 Jun 2015 16:22:21 -0400
Subject: [PATCH 57/60] executable comment

---
 contacts/src/cljs/contacts/demo2.cljs | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/contacts/src/cljs/contacts/demo2.cljs b/contacts/src/cljs/contacts/demo2.cljs
index 0676370..e79e675 100644
--- a/contacts/src/cljs/contacts/demo2.cljs
+++ b/contacts/src/cljs/contacts/demo2.cljs
@@ -110,3 +110,8 @@
 
 (when (gdom/getElement "demo2")
   (main))
+
+(comment
+  (pprint (om/get-query ContactList))
+  (go (pprint (:body (
Date: Mon, 8 Jun 2015 20:16:36 -0400
Subject: [PATCH 58/60] tweaks

---
 contacts/project.clj                  | 2 +-
 contacts/src/cljs/contacts/demo2.cljs | 6 ++++--
 contacts/src/dev/contacts/dev.cljs    | 5 +----
 3 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/contacts/project.clj b/contacts/project.clj
index 29d7e1e..5eacaf4 100644
--- a/contacts/project.clj
+++ b/contacts/project.clj
@@ -7,7 +7,7 @@
   :jvm-opts ^:replace ["-Xms512m" "-Xmx512m" "-server"]
 
   :dependencies [[org.clojure/clojure "1.7.0-RC1"]
-                 [org.clojure/clojurescript "0.0-3310"]
+                 [org.clojure/clojurescript "0.0-3311"]
                  [com.datomic/datomic-free "0.9.5153"]
                  [bidi "1.10.2"]
                  [org.omcljs/om "0.9.0-SNAPSHOT"]
diff --git a/contacts/src/cljs/contacts/demo2.cljs b/contacts/src/cljs/contacts/demo2.cljs
index e79e675..9e4cd0b 100644
--- a/contacts/src/cljs/contacts/demo2.cljs
+++ b/contacts/src/cljs/contacts/demo2.cljs
@@ -6,7 +6,8 @@
             [om.next :as om :refer-macros [defui]]
             [om.dom :as dom]
             [cljs-http.client :as http]
-            [cljs.core.async :refer [! chan]]))
+            [cljs.core.async :refer [! chan]]
+            [clojure.browser.repl :as repl]))
 
 ;; =============================================================================
 ;; Utilities
@@ -55,7 +56,7 @@
 ;; Contact Component
 
 (defui Contact
-  ;static om/IQueryParams
+  static om/IQueryParams
   ;(params [this]
   ;  {:address (om/get-query AddressInfo)})
   static om/IQuery
@@ -101,6 +102,7 @@
 ;; main
 
 (defn main []
+  (defonce conn (repl/connect "http://localhost:9000/repl"))
   (let [c (fetch (om/get-query ContactList))]
     (go
       (let [contacts (:body (
Date: Tue, 9 Jun 2015 16:05:53 -0400
Subject: [PATCH 59/60] missing comment

---
 contacts/src/cljs/contacts/demo2.cljs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/contacts/src/cljs/contacts/demo2.cljs b/contacts/src/cljs/contacts/demo2.cljs
index 9e4cd0b..3d53196 100644
--- a/contacts/src/cljs/contacts/demo2.cljs
+++ b/contacts/src/cljs/contacts/demo2.cljs
@@ -56,7 +56,7 @@
 ;; Contact Component
 
 (defui Contact
-  static om/IQueryParams
+  ;static om/IQueryParams
   ;(params [this]
   ;  {:address (om/get-query AddressInfo)})
   static om/IQuery

From 6a19ee51392c8e022bd892c74e9e06f9de01a850 Mon Sep 17 00:00:00 2001
From: David Nolen 
Date: Fri, 24 Jul 2015 11:19:29 -0500
Subject: [PATCH 60/60] bump deps

---
 contacts/project.clj      | 8 ++++----
 contacts/script/brepl.clj | 3 ++-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/contacts/project.clj b/contacts/project.clj
index 5eacaf4..761a896 100644
--- a/contacts/project.clj
+++ b/contacts/project.clj
@@ -6,11 +6,11 @@
 
   :jvm-opts ^:replace ["-Xms512m" "-Xmx512m" "-server"]
 
-  :dependencies [[org.clojure/clojure "1.7.0-RC1"]
-                 [org.clojure/clojurescript "0.0-3311"]
+  :dependencies [[org.clojure/clojure "1.7.0"]
+                 [org.clojure/clojurescript "0.0-3308"]
                  [com.datomic/datomic-free "0.9.5153"]
                  [bidi "1.10.2"]
-                 [org.omcljs/om "0.9.0-SNAPSHOT"]
+                 [org.omcljs/om "0.9.0"]
                  [ring/ring "1.2.2"]
                  [com.cognitect/transit-clj "0.8.271"]
                  [com.cognitect/transit-cljs "0.8.220"]
@@ -23,7 +23,7 @@
 
   :source-paths ["src/clj"]
 
-  :plugins [[lein-cljsbuild "1.0.2"]
+  :plugins [[lein-cljsbuild "1.0.5"]
             [lein-ring "0.8.10"]
             [lein-beanstalk "0.2.7"]]
 
diff --git a/contacts/script/brepl.clj b/contacts/script/brepl.clj
index 7f5ef63..d70da75 100644
--- a/contacts/script/brepl.clj
+++ b/contacts/script/brepl.clj
@@ -11,7 +11,8 @@
      :file "public/codemirror/matchbrackets.js"}
     {:provides ["cljsjs.codemirror.addons.closebrackets"]
      :requires ["cljsjs.codemirror"]
-     :file "public/codemirror/closebrackets.js"}]})
+     :file "public/codemirror/closebrackets.js"}]
+   :verbose true})
 
 (b/build (b/inputs "src/dev")
   (merge