<commit_before>(ns figwheel-sidecar.build-middleware.javascript-reloading
  (:require
   [clojure.java.io :as io]
   [cljs.build.api :as bapi]
   [cljs.closure]))

;; live javascript reloading

(defn get-foreign-lib [{:keys [foreign-libs]} file-path]
  (when foreign-libs
    (let [file (io/file file-path)]
      (first (filter (fn [fl]
                       (= (.getCanonicalPath (io/file (:file fl)))
                          (.getCanonicalPath file)))
                     foreign-libs)))))

(defn js-file->namespaces [{:keys [foreign-libs] :as state} js-file-path]
  (if-let [foreign (get-foreign-lib state js-file-path)]
    (:provides foreign)
    (:provides (bapi/parse-js-ns js-file-path))))

(defn cljs-target-file-from-foreign [output-dir file-path]
  (io/file (str output-dir java.io.File/separator (.getName (io/file file-path)))))

(defn closure-lib-target-file-for-ns [output-dir namesp]
  (let [path (cljs.closure/lib-rel-path {:provides [namesp]})]
    (io/file output-dir path)))

(defn get-js-copies [{:keys [output-dir] :as state} changed-js]
  (keep
   (fn [f]
     (if-let [foreign (get-foreign-lib state f)]
       {:output-file (cljs-target-file-from-foreign output-dir f)
        :file f}
       (when-let [namesp (first (js-file->namespaces state f))]
         {:output-file (closure-lib-target-file-for-ns output-dir namesp)
          :file f})))
   changed-js))

(defn make-copies [copies]
  (doseq [{:keys [file output-file]} copies]
    (spit output-file (slurp file))))

(defn copy-changed-js [state changed-js]
  ;; TODO there is an easy way to do this built into the clojurescript
  ;; compiler source
  ;; the idea here is we are only copying files that make sense to
  ;; copy i.e. they have a provide
  (when-not (empty? changed-js)
    (make-copies (get-js-copies state changed-js))))

(defn hook [build-fn]
  (fn [{:keys [figwheel-server build-config changed-files] :as build-state}]
    (if-let [changed-js-files (filter #(.endsWith % ".js") changed-files)]
      (let [build-options (or (:build-options build-config) (:compiler build-config))
            additional-changed-ns   ;; add in js namespaces
            (mapcat (partial js-file->namespaces build-options)
                    changed-js-files)]
        (copy-changed-js build-options changed-js-files)
        (build-fn (update-in
                   build-state [:additional-changed-ns] concat additional-changed-ns)))
      (build-fn build-state))))<commit_msg>cleaned up javascript reloading, in prep for compiled foreign lib reloading<commit_after>(ns figwheel-sidecar.build-middleware.javascript-reloading
  (:require
   [clojure.java.io :as io]
   [cljs.build.api :as bapi]
   [figwheel-sidecar.utils :as utils]
   [clojure.pprint :as pp]))

;; live javascript reloading

(defn get-foreign-lib [{:keys [foreign-libs]} file-path]
  (when foreign-libs
    (let [file (io/file file-path)]
      (first (filter (fn [fl]
                       (= (.getCanonicalPath (io/file (:file fl)))
                          (.getCanonicalPath file)))
                     foreign-libs)))))

;; extremely tenuous relationship, this could break easily
;; file-path is a string and it is an absolute path
(defn cljs-target-file-from-foreign [output-dir file-path]
  (first (filter #(.exists %)
                 ;; try the projected location
                 [(io/file output-dir (utils/relativize-local file-path))
                  (io/file output-dir (.getName (io/file file-path)))])))

(defn closure-lib-target-file-for-ns [output-dir namesp]
  (let [path (cljs.closure/lib-rel-path {:provides [namesp]})]
    (io/file output-dir path)))

(defn safe-js->ns [file-path]
  (:provides
   (try (bapi/parse-js-ns file-path)
        (catch Throwable e
          ;; couldn't parse js for namespace
          {}))))

(defn best-try-js-ns [state js-file-path]
  (let [provs (and (.exists (io/file js-file-path))
                   (safe-js->ns js-file-path))]
    (if-not (empty? provs)
      provs
      (let [out-file (cljs-target-file-from-foreign (:output-dir state) js-file-path)]
        (and (.exists out-file)
             (safe-js->ns out-file))))))

(defn js-file->namespaces [{:keys [foreign-libs output-dir] :as state} js-file-path]
  (if-let [foreign (get-foreign-lib state js-file-path)]
    (best-try-js-ns state js-file-path)
    (safe-js->ns js-file-path)))

(defn hook [build-fn]
  (fn [{:keys [figwheel-server build-config changed-files] :as build-state}]
    (if-let [changed-js-files (filter #(.endsWith % ".js") changed-files)]
      (let [build-options (or (:build-options build-config) (:compiler build-config))
            additional-changed-ns ;; add in js namespaces
            (mapcat (partial js-file->namespaces build-options)
                    changed-js-files)]
        (build-fn (update-in
                   build-state [:additional-changed-ns] concat additional-changed-ns)))
      (build-fn build-state))))
{'fraction_non_alphanumeric': 0.15436105476673428, 'fraction_numerical': 0.0, 'mean_word_length': 2.658011869436202, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5326737', 'n_tokens_mistral': 1692, 'n_tokens_neox': 1611, 'n_words': 409}