 (defn add-request-urls [opts files]
   (map (partial add-request-url opts) files))
 
+(defn eval-body [{:keys [eval-body file]}]
+  (when (and eval-body (string? eval-body))
+    (let [code eval-body]
+      (try
+        (utils/debug-prn (str "Evaling file " file))
+        (js* "eval(~{code})")
+        (catch :default e
+          (utils/log :error (str "Unable to evaluate " file)))))))
+
 (defn reload-js-files [{:keys [before-jsload on-jsload load-from-figwheel] :as opts} {:keys [files] :as msg}]
   (go
     (before-jsload files)
-    (let [files'  (add-request-urls opts (filter #(not (:dependency-file %)) files))
+    ;; evaluate the eval bodies first
+    (doseq [eval-body-file (filter #(:eval-body %) files)]
+      (eval-body eval-body-file))
+    (let [files'  (add-request-urls opts (filter #(not (:eval-body %)) files))
           res'    (<! (load-all-js-files files'))
           res     (filter :loaded-file res')
           files-not-loaded  (filter #(not (:loaded-file %)) res')]

  (set! (.-provide js/goog) (.-exportPath_ js/goog))
  (set! (.-CLOSURE_IMPORT_SCRIPT (.-global js/goog)) reload-file*))

;; may not need to load these deps as we may not be using them
#_(def goog-deps-path (str (.-basePath js/goog) "deps.js"))

#_(defn get-main-file-path
  "Very unreliable way to get the main js file for reloading. 
   Fortunately its not the end of the world if this file doesn't 
   get reloaded."
  []
  (when (utils/html-env?)
    (let [sel  (str "script[src='" goog-deps-path "']")]
      (when-let [el (.querySelector js/document sel)]
        (when-let [el (.-nextElementSibling el)]
          (.getAttribute el "src"))))))

#_(let [main-file-path (get-main-file-path)]
  (defn resolve-deps-path [file]
    (cond
      (re-matches #".*goog/deps\.js" file) goog-deps-path
      (and main-file-path
           (apply = (mapv #(last (string/split % "/")) [main-file-path file])))
      main-file-path
      :else (do
              (utils/debug-prn (str "No deps match:" file))
              file))))

;; server should add a type to each file
(defn file-type [{:keys [type dependency-file namespace]}]
    (cond
      (= type :css)   :css
      ;; dependency-file :dependency-file
      namespace       :namespace))

(defmulti resolve-url file-type)

(defmethod resolve-url :default [{:keys [file]}] file)

#_(defmethod resolve-url :dependency-file [{:keys [file]}]
    (resolve-deps-path file))

(defmethod resolve-url :namespace [{:keys [namespace]}]
  (resolve-ns namespace))

(defmulti reload-base utils/host-env?)

(defmethod reload-base :node [request-url callback]
  (let [root (string/join "/" (reverse (drop 2 (reverse (string/split js/__dirname "/")))))
        path (str root "/" request-url)]
    (aset (.-cache js/require) path nil)

(ns figwheel.client.file-reloading
  (:require
   [figwheel.client.utils :as utils :refer-macros [dev-assert]]
   [goog.Uri :as guri]
   [goog.string]
   [goog.net.jsloader :as loader]
