clementine 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+