               source-text
               (if expression? "Expression" "File")
               (merge
-                {:ns           @current-ns
-                 :source-map   false
-                 :verbose      (:verbose @app-env)
-                 :cache-source (fn [x cb]
-                                 #_(when (and path (:source x))
-                                     (js/PLANCK_CACHE path (:source x) nil))
-                                 (cb {:value nil}))}
-                (when expression?
+                {:ns         @current-ns
+                 :source-map false
+                 :verbose    (:verbose @app-env)}
+                (if expression?
                   {:context       :expr
-                   :def-emits-var true}))
+                   :def-emits-var true}
+                  (when (:cache-path @app-env)
+                    {:cache-source (fn [x cb]
+                                     (when (and (= "File" (:name x)) (:source x))
+                                       (let [source (:source x)
+                                             [file-namespace relpath] (extract-cache-metadata-mem source-text)]
+                                         (js/PLANCK_CACHE (cache-prefix-for-path relpath) source
+                                           (when file-namespace
+                                             (cljs->transit-json (get-in @st [:cljs.analyzer/namespaces file-namespace]))))))
+                                     (cb {:value nil}))})))
               (fn [{:keys [ns value error] :as ret}]
                 (if expression?
                   (when-not error

(defn- cache-prefix-for-path [path]
  (str (:cache-path @app-env) "/" (munge path)))

(defn caching-js-eval
  [{:keys [path name source cache]}]
  (when (and path source cache (:cache-path @app-env))

        (-> (r/read {:read-cond :allow :features #{:cljs}} rdr)
          meta :source)))))

(defn- run-async!
  "Like cljs.core/run!, but for an async procedure, and with the
  ability to break prior to processing the entire collection.

  Chains successive calls to the supplied procedure for items in
  the collection. The procedure should accept an item from the
  collection and a callback of one argument. If the break? predicate,
  when applied to the procedure callback value, yields a truthy
  result, terminates early calling the supplied cb with the callback
  value. Otherwise, when complete, calls cb with nil."
  [proc coll break? cb]
  (if (seq coll)
    (proc (first coll)
      (fn [res]
        (if (break? res)
          (cb res)
          (run-async! proc (rest coll) break? cb))))
    (cb nil)))

(defn- process-deps
  [names opts cb]
  (run-async! (fn [name cb]
                (cljs/require name opts cb))
    names
    :error
    cb))

(defn- process-macros-deps
  [cache cb]
  (process-deps (distinct (vals (:require-macros cache))) {:macros-ns true} cb))

(defn- process-libs-deps
  [cache cb]
  (process-deps (distinct (concat (vals (:requires cache)) (vals (:imports cache)))) {} cb))

(defn execute-source
  [[source-type source-value] {:keys [expression? print-nil-expression? in-exit-context? include-stacktrace?] :as opts}]
  (binding [ana/*cljs-ns* @current-ns
