                       (add-modules modules)
                       )))]
 
-    (alter-var-root #'cljs-compiler-state
-                    (fn [_]
-                      (-> state
-                          (cljs/step-reload-modified)
-                          (cljs/step-compile-modules)
-                          (cljs/flush-unoptimized))))
+    (let [new-state (-> state
+                        (cljs/step-reload-modified)
+                        (cljs/step-compile-modules)
+                        (cljs/flush-unoptimized))]
+      (dosync
+       (alter cljs-compiler-state (fn [m] (assoc-in m [builder] new-state)))
+       (alter cljs-compiler-compile-count (fn [m] (update-in m [builder] (fnil inc 0))))))
 
-    (alter-var-root #'cljs-compiler-compile-count inc)
-
-    (println (format "Compiled %d times since last full compile" cljs-compiler-compile-count)))
+    (println (format "Compiled %d times since last full compile" (get @cljs-compiler-compile-count builder))))
 
   :done)
 

  (start [this]
    (let [modules (map get-definition (filter (partial satisfies? ClojureScriptModule) (vals this)))]
      (try
        (compile-cljs modules (select-keys this (keys new-cljs-builder-schema)))
        this
        (catch Exception e
          (println "ClojureScript build failed:" e)
          (assoc this :error e)))

      (cond
       (and (= (:optimizations this) :none)
            (= (:pretty-print this) true))
       ;; Only do this on optimizations: none and pretty-print: true - do
       ;; something different for each optimization mode (TODO)
       (assoc this
         :javascripts
         (for [n (dep/topo-sort
                  ;; Build a dependency graph between all the modules so
                  ;; they load in the correct order.
                  (reduce (fn [g {:keys [name dependencies]}]
                            (reduce (fn [g d] (dep/depend g name d)) g dependencies))
                          (dep/graph) modules))]
           (str (:context this) (name n) ".js")))
       :otherwise this)))
  (stop [this] this)

  WebService

   [schema.core :as s]
   [com.stuartsierra.dependency :as dep]))

(def cljs-compiler-state (ref {}))

(def cljs-compiler-compile-count (ref {}))

(defn add-modules [state modules]
  (reduce (fn [state {:keys [name mains dependencies]}]
            (cljs/step-configure-module state name mains dependencies))
          state modules))

(defn compile-cljs [builder modules {:keys [context source-path target-dir work-dir
                                            optimizations pretty-print]}]

  (let [state (if-let [s (get @cljs-compiler-state builder)]
                (do
                  (println "cljs: Using existing state")
                  s)
