clementine 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/.gitignore +7 -0
  2. data/Gemfile +4 -0
  3. data/README.md +52 -0
  4. data/Rakefile +1 -0
  5. data/clementine.gemspec +23 -0
  6. data/lib/clementine.rb +27 -0
  7. data/lib/clementine/clementine_rails.rb +8 -0
  8. data/lib/clementine/clojurescript_engine.rb +49 -0
  9. data/lib/clementine/clojurescript_engine_mri.rb +65 -0
  10. data/lib/clementine/clojurescript_template.rb +21 -0
  11. data/lib/clementine/options.rb +9 -0
  12. data/lib/clementine/version.rb +3 -0
  13. data/test/clojurescript_engine_test.rb +46 -0
  14. data/test/options_test.rb +22 -0
  15. data/vendor/assets/bin/cljsc.clj +21 -0
  16. data/vendor/assets/lib/clojure.jar +0 -0
  17. data/vendor/assets/lib/compiler.jar +0 -0
  18. data/vendor/assets/lib/goog.jar +0 -0
  19. data/vendor/assets/lib/js.jar +0 -0
  20. data/vendor/assets/src/clj/cljs/closure.clj +823 -0
  21. data/vendor/assets/src/clj/cljs/compiler.clj +1341 -0
  22. data/vendor/assets/src/clj/cljs/core.clj +702 -0
  23. data/vendor/assets/src/clj/cljs/repl.clj +162 -0
  24. data/vendor/assets/src/clj/cljs/repl/browser.clj +341 -0
  25. data/vendor/assets/src/clj/cljs/repl/rhino.clj +170 -0
  26. data/vendor/assets/src/cljs/cljs/core.cljs +3330 -0
  27. data/vendor/assets/src/cljs/cljs/nodejs.cljs +11 -0
  28. data/vendor/assets/src/cljs/cljs/nodejs_externs.js +2 -0
  29. data/vendor/assets/src/cljs/cljs/nodejscli.cljs +9 -0
  30. data/vendor/assets/src/cljs/cljs/reader.cljs +360 -0
  31. data/vendor/assets/src/cljs/clojure/browser/dom.cljs +106 -0
  32. data/vendor/assets/src/cljs/clojure/browser/event.cljs +100 -0
  33. data/vendor/assets/src/cljs/clojure/browser/net.cljs +182 -0
  34. data/vendor/assets/src/cljs/clojure/browser/repl.cljs +109 -0
  35. data/vendor/assets/src/cljs/clojure/set.cljs +162 -0
  36. data/vendor/assets/src/cljs/clojure/string.cljs +160 -0
  37. data/vendor/assets/src/cljs/clojure/walk.cljs +94 -0
  38. data/vendor/assets/src/cljs/clojure/zip.cljs +291 -0
  39. metadata +103 -0
@@ -0,0 +1,100 @@
1
+ ;; Copyright (c) Rich Hickey. All rights reserved.
2
+ ;; The use and distribution terms for this software are covered by the
3
+ ;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4
+ ;; which can be found in the file epl-v10.html at the root of this distribution.
5
+ ;; By using this software in any fashion, you are agreeing to be bound by
6
+ ;; the terms of this license.
7
+ ;; You must not remove this notice, or any other, from this software.
8
+
9
+ (ns ^{:doc "This namespace contains functions to work with browser
10
+ events. It is based on the Google Closure Library event system."
11
+ :author "Bobby Calderwood"}
12
+ clojure.browser.event
13
+ (:require [goog.events :as events]
14
+ [goog.events.EventTarget :as gevent-target]
15
+ [goog.events.EventType :as gevent-type]))
16
+
17
+ (defprotocol EventType
18
+ (event-types [this]))
19
+
20
+ (extend-protocol EventType
21
+
22
+ goog.events.EventTarget
23
+ (event-types
24
+ [this]
25
+ (into {}
26
+ (map
27
+ (fn [[k v]]
28
+ [(keyword (. k (toLowerCase)))
29
+ v])
30
+ (merge
31
+ (js->clj goog.events.EventType)))))
32
+
33
+ js/Element
34
+ (event-types
35
+ [this]
36
+ (into {}
37
+ (map
38
+ (fn [[k v]]
39
+ [(keyword (. k (toLowerCase)))
40
+ v])
41
+ (merge
42
+ (js->clj goog.events.EventType))))))
43
+
44
+ (defn listen
45
+ ([src type fn]
46
+ (listen src type fn false))
47
+ ([src type fn capture?]
48
+ (goog.events/listen src
49
+ (get (event-types src) type type)
50
+ fn
51
+ capture?)))
52
+
53
+ (defn listen-once
54
+ ([src type fn]
55
+ (listen-once src type fn false))
56
+ ([src type fn capture?]
57
+ (goog.events/listenOnce src
58
+ (get (event-types src) type type)
59
+ fn
60
+ capture?)))
61
+
62
+ (defn unlisten
63
+ ([src type fn]
64
+ (unlisten src type fn false))
65
+ ([src type fn capture?]
66
+ (goog.events/unlisten src
67
+ (get (event-types src) type type)
68
+ fn
69
+ capture?)))
70
+
71
+ (defn unlisten-by-key
72
+ [key]
73
+ (goog.events/unlistenByKey key))
74
+
75
+ (defn dispatch-event
76
+ [src event]
77
+ (goog.events/dispatchEvent src event))
78
+
79
+ (defn expose [e]
80
+ (goog.events/expose e))
81
+
82
+ (defn fire-listeners
83
+ [obj type capture event])
84
+
85
+ (defn total-listener-count []
86
+ (goog.events/getTotalListenerCount))
87
+
88
+ ;; TODO
89
+ (defn get-listener [src type listener opt_capt opt_handler]); ⇒ ?Listener
90
+ (defn all-listeners [obj type capture]); ⇒ Array.<Listener>
91
+
92
+ (defn unique-event-id [event-type]); ⇒ string
93
+
94
+ (defn has-listener [obj opt_type opt_capture]); ⇒ boolean
95
+ ;; TODO? (defn listen-with-wrapper [src wrapper listener opt_capt opt_handler])
96
+ ;; TODO? (defn protect-browser-event-entry-point [errorHandler])
97
+
98
+ (defn remove-all [opt_obj opt_type opt_capt]); ⇒ number
99
+ ;; TODO? (defn unlisten-with-wrapper [src wrapper listener opt_capt opt_handler])
100
+
@@ -0,0 +1,182 @@
1
+ ;; Copyright (c) Rich Hickey. All rights reserved.
2
+ ;; The use and distribution terms for this software are covered by the
3
+ ;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4
+ ;; which can be found in the file epl-v10.html at the root of this distribution.
5
+ ;; By using this software in any fashion, you are agreeing to be bound by
6
+ ;; the terms of this license.
7
+ ;; You must not remove this notice, or any other, from this software.
8
+
9
+ (ns ^{:doc "Network communication library, wrapping goog.net.
10
+ Includes a common API over XhrIo, CrossPageChannel, and Websockets."
11
+ :author "Bobby Calderwood and Alex Redington"}
12
+ clojure.browser.net
13
+ (:require [clojure.browser.event :as event]
14
+ [goog.net.XhrIo :as gxhrio]
15
+ [goog.net.EventType :as gnet-event-type]
16
+ [goog.net.xpc.CfgFields :as gxpc-config-fields]
17
+ [goog.net.xpc.CrossPageChannel :as xpc]
18
+ #_[goog.net.WebSocket :as gwebsocket]
19
+ [goog.json :as gjson]))
20
+
21
+ (def *timeout* 10000)
22
+
23
+ (def event-types
24
+ (into {}
25
+ (map
26
+ (fn [[k v]]
27
+ [(keyword (. k (toLowerCase)))
28
+ v])
29
+ (merge
30
+ (js->clj goog.net.EventType)))))
31
+
32
+ (defprotocol IConnection
33
+ (connect
34
+ [this]
35
+ [this opt1]
36
+ [this opt1 opt2]
37
+ [this opt1 opt2 opt3])
38
+ (transmit
39
+ [this opt]
40
+ [this opt opt2]
41
+ [this opt opt2 opt3]
42
+ [this opt opt2 opt3 opt4]
43
+ [this opt opt2 opt3 opt4 opt5])
44
+ (close [this]))
45
+
46
+ (extend-type goog.net.XhrIo
47
+
48
+ IConnection
49
+ (transmit
50
+ ([this uri]
51
+ (transmit this uri "GET" nil nil *timeout*))
52
+ ([this uri method]
53
+ (transmit this uri method nil nil *timeout*))
54
+ ([this uri method content]
55
+ (transmit this uri method content nil *timeout*))
56
+ ([this uri method content headers]
57
+ (transmit this uri method content headers *timeout*))
58
+ ([this uri method content headers timeout]
59
+ (.setTimeoutInterval this timeout)
60
+ (.send this uri method content headers)))
61
+
62
+
63
+ event/EventType
64
+ (event-types [this]
65
+ (into {}
66
+ (map
67
+ (fn [[k v]]
68
+ [(keyword (. k (toLowerCase)))
69
+ v])
70
+ (merge
71
+ (js->clj goog.net.EventType))))))
72
+
73
+ ;; TODO jQuery/sinatra/RestClient style API: (get [uri]), (post [uri payload]), (put [uri payload]), (delete [uri])
74
+
75
+ (def xpc-config-fields
76
+ (into {}
77
+ (map
78
+ (fn [[k v]]
79
+ [(keyword (. k (toLowerCase)))
80
+ v])
81
+ (js->clj goog.net.xpc.CfgFields))))
82
+
83
+ (defn xhr-connection
84
+ "Returns an XhrIo connection"
85
+ []
86
+ (goog.net.XhrIo.))
87
+
88
+ (defprotocol ICrossPageChannel
89
+ (register-service [this service-name fn] [this service-name fn encode-json?]))
90
+
91
+ (extend-type goog.net.xpc.CrossPageChannel
92
+
93
+ ICrossPageChannel
94
+ (register-service
95
+ ([this service-name fn]
96
+ (register-service this service-name fn false))
97
+ ([this service-name fn encode-json?]
98
+ (.registerService this (name service-name) fn encode-json?)))
99
+
100
+ IConnection
101
+ (connect
102
+ ([this]
103
+ (connect this nil))
104
+ ([this on-connect-fn]
105
+ (.connect this on-connect-fn))
106
+ ([this on-connect-fn config-iframe-fn]
107
+ (connect this on-connect-fn config-iframe-fn (.body js/document)))
108
+ ([this on-connect-fn config-iframe-fn iframe-parent]
109
+ (.createPeerIframe this iframe-parent config-iframe-fn)
110
+ (.connect this on-connect-fn)))
111
+
112
+ (transmit [this service-name payload]
113
+ (.send this (name service-name) payload))
114
+
115
+ (close [this]
116
+ (.close this ())))
117
+
118
+ (defn xpc-connection
119
+ "When passed with a config hash-map, returns a parent
120
+ CrossPageChannel object. Keys in the config hash map are downcased
121
+ versions of the goog.net.xpc.CfgFields enum keys,
122
+ e.g. goog.net.xpc.CfgFields.PEER_URI becomes :peer_uri in the config
123
+ hash.
124
+
125
+ When passed with no args, creates a child CrossPageChannel object,
126
+ and the config is automatically taken from the URL param 'xpc', as
127
+ per the CrossPageChannel API."
128
+ ([]
129
+ (when-let [config (.getParameterValue
130
+ (goog.Uri. (.href (.location js/window)))
131
+ "xpc")]
132
+ (goog.net.xpc.CrossPageChannel. (gjson/parse config))))
133
+ ([config]
134
+ (goog.net.xpc.CrossPageChannel.
135
+ (.strobj (reduce (fn [sum [k v]]
136
+ (when-let [field (get xpc-config-fields k)]
137
+ (assoc sum field v)))
138
+ {}
139
+ config)))))
140
+
141
+ ;; WebSocket is not supported in the 3/23/11 release of Google
142
+ ;; Closure, but will be included in the next release.
143
+
144
+ #_(defprotocol IWebSocket
145
+ (open? [this]))
146
+
147
+ #_(extend-type goog.net.WebSocket
148
+
149
+ IWebSocket
150
+ (open? [this]
151
+ (.isOpen this ()))
152
+
153
+ IConnection
154
+ (connect
155
+ ([this url]
156
+ (connect this url nil))
157
+ ([this url protocol]
158
+ (.open this url protocol)))
159
+
160
+ (transmit [this message]
161
+ (.send this message))
162
+
163
+ (close [this]
164
+ (.close this ()))
165
+
166
+ event/EventType
167
+ (event-types [this]
168
+ (into {}
169
+ (map
170
+ (fn [[k v]]
171
+ [(keyword (. k (toLowerCase)))
172
+ v])
173
+ (merge
174
+ (js->clj goog.net.WebSocket/EventType))))))
175
+
176
+ #_(defn websocket-connection
177
+ ([]
178
+ (websocket-connection nil nil))
179
+ ([auto-reconnect?]
180
+ (websocket-connection auto-reconnect? nil))
181
+ ([auto-reconnect? next-reconnect-fn]
182
+ (goog.net.WebSocket. auto-reconnect? next-reconnect-fn)))
@@ -0,0 +1,109 @@
1
+ ;; Copyright (c) Rich Hickey. All rights reserved.
2
+ ;; The use and distribution terms for this software are covered by the
3
+ ;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4
+ ;; which can be found in the file epl-v10.html at the root of this distribution.
5
+ ;; By using this software in any fashion, you are agreeing to be bound by
6
+ ;; the terms of this license.
7
+ ;; You must not remove this notice, or any other, from this software.
8
+
9
+ (ns ^{:doc "Receive - Eval - Print - Loop
10
+
11
+ Receive a block of JS (presumably generated by a ClojureScript compiler)
12
+ Evaluate it naively
13
+ Print the result of evaluation to a string
14
+ Send the resulting string back to the server Loop!"
15
+
16
+ :author "Bobby Calderwood and Alex Redington"}
17
+ clojure.browser.repl
18
+ (:require [clojure.browser.net :as net]
19
+ [clojure.browser.event :as event]))
20
+
21
+ (def xpc-connection (atom nil))
22
+
23
+ (defn repl-print [data]
24
+ (if-let [conn @xpc-connection]
25
+ (net/transmit conn :print (pr-str data))))
26
+
27
+ (defn evaluate-javascript
28
+ "Process a single block of JavaScript received from the server"
29
+ [conn block]
30
+ (let [result (try {:status :success :value (str (js* "eval(~{block})"))}
31
+ (catch js/Error e
32
+ {:status :exception :value (pr-str e)
33
+ :stacktrace (if (.hasOwnProperty e "stack")
34
+ (.stack e)
35
+ "No stacktrace available.")}))]
36
+ (pr-str result)))
37
+
38
+ (defn send-result [connection url data]
39
+ (net/transmit connection url "POST" data nil 0))
40
+
41
+ (defn send-print
42
+ "Send data to be printed in the REPL. If there is an error, try again
43
+ up to 10 times."
44
+ ([url data]
45
+ (send-print url data 0))
46
+ ([url data n]
47
+ (let [conn (net/xhr-connection)]
48
+ (event/listen conn :error
49
+ (fn [_]
50
+ (if (< n 10)
51
+ (send-print url data (inc n))
52
+ (.log js/console (str "Could not send " data " after " n " attempts.")))))
53
+ (net/transmit conn url "POST" data nil 0))))
54
+
55
+ (def order (atom 0))
56
+
57
+ (defn wrap-message [t data]
58
+ (pr-str {:type t :content data :order (swap! order inc)}))
59
+
60
+ (defn start-evaluator
61
+ "Start the REPL server connection."
62
+ [url]
63
+ (if-let [repl-connection (net/xpc-connection)]
64
+ (let [connection (net/xhr-connection)]
65
+ (event/listen connection
66
+ :success
67
+ (fn [e]
68
+ (net/transmit
69
+ repl-connection
70
+ :evaluate-javascript
71
+ (.getResponseText e/currentTarget
72
+ ()))))
73
+
74
+ (net/register-service repl-connection
75
+ :send-result
76
+ (fn [data]
77
+ (send-result connection url (wrap-message :result data))))
78
+
79
+ (net/register-service repl-connection
80
+ :print
81
+ (fn [data]
82
+ (send-print url (wrap-message :print data))))
83
+
84
+ (net/connect repl-connection
85
+ (constantly nil))
86
+
87
+ (js/setTimeout #(send-result connection url (wrap-message :ready "ready")) 50))
88
+ (js/alert "No 'xpc' param provided to child iframe.")))
89
+
90
+ (defn connect
91
+ "Connects to a REPL server from an HTML document. After the
92
+ connection is made, the REPL will evaluate forms in the context of
93
+ the document that called this function."
94
+ [repl-server-url]
95
+ (let [repl-connection (net/xpc-connection
96
+ {:peer_uri repl-server-url})]
97
+ (swap! xpc-connection (constantly repl-connection))
98
+ (net/register-service repl-connection
99
+ :evaluate-javascript
100
+ (fn [js]
101
+ (net/transmit
102
+ repl-connection
103
+ :send-result
104
+ (evaluate-javascript repl-connection js))))
105
+ (net/connect repl-connection
106
+ (constantly nil)
107
+ (fn [iframe]
108
+ (set! iframe.style.display
109
+ "none")))))
@@ -0,0 +1,162 @@
1
+ ; Copyright (c) Rich Hickey. All rights reserved.
2
+ ; The use and distribution terms for this software are covered by the
3
+ ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4
+ ; which can be found in the file epl-v10.html at the root of this distribution.
5
+ ; By using this software in any fashion, you are agreeing to be bound by
6
+ ; the terms of this license.
7
+ ; You must not remove this notice, or any other, from this software.
8
+
9
+ (ns ^{:doc "Set operations such as union/intersection."
10
+ :author "Rich Hickey"}
11
+ clojure.set)
12
+
13
+ (defn- bubble-max-key [k coll]
14
+ "Move a maximal element of coll according to fn k (which returns a number)
15
+ to the front of coll."
16
+ (let [max (apply max-key k coll)]
17
+ (cons max (remove #(identical? max %) coll))))
18
+
19
+ (defn union
20
+ "Return a set that is the union of the input sets"
21
+ ([] #{})
22
+ ([s1] s1)
23
+ ([s1 s2]
24
+ (if (< (count s1) (count s2))
25
+ (reduce conj s2 s1)
26
+ (reduce conj s1 s2)))
27
+ ([s1 s2 & sets]
28
+ (let [bubbled-sets (bubble-max-key count (conj sets s2 s1))]
29
+ (reduce into (first bubbled-sets) (rest bubbled-sets)))))
30
+
31
+ (defn intersection
32
+ "Return a set that is the intersection of the input sets"
33
+ ([s1] s1)
34
+ ([s1 s2]
35
+ (if (< (count s2) (count s1))
36
+ (recur s2 s1)
37
+ (reduce (fn [result item]
38
+ (if (contains? s2 item)
39
+ result
40
+ (disj result item)))
41
+ s1 s1)))
42
+ ([s1 s2 & sets]
43
+ (let [bubbled-sets (bubble-max-key #(- (count %)) (conj sets s2 s1))]
44
+ (reduce intersection (first bubbled-sets) (rest bubbled-sets)))))
45
+
46
+ (defn difference
47
+ "Return a set that is the first set without elements of the remaining sets"
48
+ ([s1] s1)
49
+ ([s1 s2]
50
+ (if (< (count s1) (count s2))
51
+ (reduce (fn [result item]
52
+ (if (contains? s2 item)
53
+ (disj result item)
54
+ result))
55
+ s1 s1)
56
+ (reduce disj s1 s2)))
57
+ ([s1 s2 & sets]
58
+ (reduce difference s1 (conj sets s2))))
59
+
60
+
61
+ (defn select
62
+ "Returns a set of the elements for which pred is true"
63
+ [pred xset]
64
+ (reduce (fn [s k] (if (pred k) s (disj s k)))
65
+ xset xset))
66
+
67
+ (defn project
68
+ "Returns a rel of the elements of xrel with only the keys in ks"
69
+ [xrel ks]
70
+ (set (map #(select-keys % ks) xrel)))
71
+
72
+ (defn rename-keys
73
+ "Returns the map with the keys in kmap renamed to the vals in kmap"
74
+ [map kmap]
75
+ (reduce
76
+ (fn [m [old new]]
77
+ (if (and (not= old new)
78
+ (contains? m old))
79
+ (-> m (assoc new (get m old)) (dissoc old))
80
+ m))
81
+ map kmap))
82
+
83
+ (defn rename
84
+ "Returns a rel of the maps in xrel with the keys in kmap renamed to the vals in kmap"
85
+ [xrel kmap]
86
+ (set (map #(rename-keys % kmap) xrel)))
87
+
88
+ (defn index
89
+ "Returns a map of the distinct values of ks in the xrel mapped to a
90
+ set of the maps in xrel with the corresponding values of ks."
91
+ [xrel ks]
92
+ (reduce
93
+ (fn [m x]
94
+ (let [ik (select-keys x ks)]
95
+ (assoc m ik (conj (get m ik #{}) x))))
96
+ {} xrel))
97
+
98
+ (defn map-invert
99
+ "Returns the map with the vals mapped to the keys."
100
+ [m] (reduce (fn [m [k v]] (assoc m v k)) {} m))
101
+
102
+ (defn join
103
+ "When passed 2 rels, returns the rel corresponding to the natural
104
+ join. When passed an additional keymap, joins on the corresponding
105
+ keys."
106
+ ([xrel yrel] ;natural join
107
+ (if (and (seq xrel) (seq yrel))
108
+ (let [ks (intersection (set (keys (first xrel))) (set (keys (first yrel))))
109
+ [r s] (if (<= (count xrel) (count yrel))
110
+ [xrel yrel]
111
+ [yrel xrel])
112
+ idx (index r ks)]
113
+ (reduce (fn [ret x]
114
+ (let [found (idx (select-keys x ks))]
115
+ (if found
116
+ (reduce #(conj %1 (merge %2 x)) ret found)
117
+ ret)))
118
+ #{} s))
119
+ #{}))
120
+ ([xrel yrel km] ;arbitrary key mapping
121
+ (let [[r s k] (if (<= (count xrel) (count yrel))
122
+ [xrel yrel (map-invert km)]
123
+ [yrel xrel km])
124
+ idx (index r (vals k))]
125
+ (reduce (fn [ret x]
126
+ (let [found (idx (rename-keys (select-keys x (keys k)) k))]
127
+ (if found
128
+ (reduce #(conj %1 (merge %2 x)) ret found)
129
+ ret)))
130
+ #{} s))))
131
+
132
+ (defn subset?
133
+ "Is set1 a subset of set2?"
134
+ [set1 set2]
135
+ (and (<= (count set1) (count set2))
136
+ (every? #(contains? set2 %) set1)))
137
+
138
+ (defn superset?
139
+ "Is set1 a superset of set2?"
140
+ [set1 set2]
141
+ (and (>= (count set1) (count set2))
142
+ (every? #(contains? set1 %) set2)))
143
+
144
+ (comment
145
+ (refer 'set)
146
+ (def xs #{{:a 11 :b 1 :c 1 :d 4}
147
+ {:a 2 :b 12 :c 2 :d 6}
148
+ {:a 3 :b 3 :c 3 :d 8 :f 42}})
149
+
150
+ (def ys #{{:a 11 :b 11 :c 11 :e 5}
151
+ {:a 12 :b 11 :c 12 :e 3}
152
+ {:a 3 :b 3 :c 3 :e 7 }})
153
+
154
+ (join xs ys)
155
+ (join xs (rename ys {:b :yb :c :yc}) {:a :a})
156
+
157
+ (union #{:a :b :c} #{:c :d :e })
158
+ (difference #{:a :b :c} #{:c :d :e})
159
+ (intersection #{:a :b :c} #{:c :d :e})
160
+
161
+ (index ys [:b]))
162
+