<commit_before>(ns pani.cljs.core
  (:refer-clojure :exclude [name get-in merge])
  (:require cljsjs.firebase
            [cljs.core.async :as async :refer [<! >! chan put! merge]])
  (:require-macros [cljs.core.async.macros :refer [go go-loop]]))

(def name- clojure.core/name)

;; Firebase listeners, modeled as maps of [:channel, :close-fn, :ref]
(defonce listeners (atom []))

(defn register-listener [ref type close-fn ]
  (swap! listeners conj
         {:close-fn close-fn
          :ref      ref
          :type     type}))

(defn disable-listeners-by! [match?]
  (let [xs @listeners]
    (swap! listeners #(vec (remove match? %)))
    (doseq [{:keys [close-fn]} (vec (filter match? xs))]
      (close-fn))))

(defn- ref-match
  "Curried equality check for refs"
  [a]
  (let [s (str a)]
    (fn [b] (= s (str b)))))

(defn disable-listeners!
  ([]
   (disable-listeners-by! (constantly true)))
  ([ref]
   (disable-listeners-by! (comp (ref-match ref) :ref)))
  ([ref type]
   (disable-listeners-by! (let [r= (ref-match ref)
                                t= (let [n (name- type)] #(= n %))]
                            (fn [{t :type r :ref}]
                              (and (r= r) (t= t)))))))

(defn- clj-val [v]
  (js->clj (.val v) :keywordize-keys true))

;; Make a firebase object ouf the given URL
(defn get-ref [url]
  "Makes a root reference for firebase"
  (js/Firebase. url))

(def root get-ref)

;; A utility function to traverse through korks and get ref to a child object
;; [:hello :world :bye] refers to hello.world.bye
(defn walk-root [root korks]
  "Takes korks and reduces it to a root on which we can perform direct actions"
  (let [p (if (sequential? korks)
            (apply str (interpose "/" (map name- korks)))
            (when korks (name- korks)))]
    (if-not (seq p)
      root
      (.child root p))))

(defn name [r]
  "Get the name of the given root"
  (.key r))

(defn parent [r]
  "Get the parent of the given root"
  (let [p (.parent r)]
    (if (nil? (js->clj p))
      nil
      p)))

(defn- fb-call!
  "Set the value at the given root"
  ([push-fn root val]
   (let [as-js (clj->js val)]
     (push-fn root as-js)))

  ([push-fn root korks val]
   (fb-call! push-fn (walk-root root korks) val)))

(defn get-in
  "get-in style single shot get function, returns a channel which delivers the value"
  [root ks]
  (let [ref (walk-root root ks)
        ch  (async/chan)]
    (.once ref "value"
           #(if-let [v (.val %)]
              (put! ch (js->clj v :keywordize-keys true))
              (async/close! ch)))
    ch))

;; A function set the value on a root [korks]
;;
(defn set!
  "Set the value at the given root"
  ([root val]
   (fb-call! #(.set %1 %2) root val))

  ([root korks val]
   (fb-call! #(.set %1 %2) root korks val)))

(defn push!
  "Set the value at the given root"
  ([root val]
   (fb-call! #(.push %1 %2) root val))

  ([root korks val]
   (fb-call! #(.push %1 %2) root korks val)))

(defn remove!
  "Remove the value at the given location"
  ([r f]
   (.remove r f))
  ([r]
   (let [c (chan)]
     (remove! r #(if %
                   (async/onto-chan c [%])
                   (async/close! c)))
     c)))

(defn bind
  "Bind to a certain property under the given root"
  ([root type korks]
   (let [bind-chan (chan)
         close-fn (bind root type korks
                        #(go (>! bind-chan %)))]
     [bind-chan close-fn]))

  ([root type korks cb]
   (let [type (name- type)
         child (walk-root root korks)
         callback #(when-let [v (clj-val %1)]
                     (cb {:val v, :name (name %1)}))
         unsub #(.off child type callback)]<commit_msg>remove fb-call!<commit_after>(ns pani.cljs.core
  (:refer-clojure :exclude [name get-in merge set!])
  (:require cljsjs.firebase
            [cljs.core.async :as async :refer [<! >! chan put! merge]])
  (:require-macros [cljs.core.async.macros :refer [go go-loop]]))

(def name- clojure.core/name)

;; Firebase listeners, modeled as maps of [:channel, :close-fn, :ref]
(defonce listeners (atom []))

(defn register-listener [ref type close-fn ]
  (swap! listeners conj
         {:close-fn close-fn
          :ref      ref
          :type     type}))

(defn disable-listeners-by! [match?]
  (let [xs @listeners]
    (swap! listeners #(vec (remove match? %)))
    (doseq [{:keys [close-fn]} (vec (filter match? xs))]
      (close-fn))))

(defn- ref-match
  "Curried equality check for refs"
  [a]
  (let [s (str a)]
    (fn [b] (= s (str b)))))

(defn disable-listeners!
  ([]
   (disable-listeners-by! (constantly true)))
  ([ref]
   (disable-listeners-by! (comp (ref-match ref) :ref)))
  ([ref type]
   (disable-listeners-by! (let [r= (ref-match ref)
                                t= (let [n (name- type)] #(= n %))]
                            (fn [{t :type r :ref}]
                              (and (r= r) (t= t)))))))

(defn- clj-val [v]
  (js->clj (.val v) :keywordize-keys true))

;; Make a firebase object ouf the given URL
(defn get-ref [url]
  "Makes a root reference for firebase"
  (js/Firebase. url))

(def root get-ref)

;; A utility function to traverse through korks and get ref to a child object
;; [:hello :world :bye] refers to hello.world.bye
(defn walk-root [root korks]
  "Takes korks and reduces it to a root on which we can perform direct actions"
  (let [p (if (sequential? korks)
            (apply str (interpose "/" (map name- korks)))
            (when korks (name- korks)))]
    (if-not (seq p)
      root
      (.child root p))))

(defn name [r]
  "Get the name of the given root"
  (.key r))

(defn parent [r]
  "Get the parent of the given root"
  (let [p (.parent r)]
    (if (nil? (js->clj p))
      nil
      p)))

(defn get-in
  "get-in style single shot get function, returns a channel which delivers the value"
  [root ks]
  (let [ref (walk-root root ks)
        ch  (async/chan)]
    (.once ref "value"
           #(if-let [v (.val %)]
              (put! ch (js->clj v :keywordize-keys true))
              (async/close! ch)))
    ch))

;; A function set the value on a root [korks]
;;
(defn set!
  "Set the value at the given root"
  ([root val]
   (.set root (clj->js val)))

  ([root korks val]
   (set! (walk-root root korks) val)))

(defn push!
  "Set the value at the given root"
  ([root val]
   (.push root (clj->js val)))

  ([root korks val]
   (push! (walk-root root korks) val)))

(defn remove!
  "Remove the value at the given location"
  ([r f]
   (.remove r f))
  ([r]
   (let [c (chan)]
     (remove! r #(if %
                   (async/onto-chan c [%])
                   (async/close! c)))
     c)))

(defn bind
  "Bind to a certain property under the given root"
  ([root type korks]
   (let [bind-chan (chan)
         close-fn (bind root type korks
                        #(go (>! bind-chan %)))]
     [bind-chan close-fn]))

  ([root type korks cb]
   (let [type (name- type)
         child (walk-root root korks)
         callback #(when-let [v (clj-val %1)]
                     (cb {:val v, :name (name %1)}))
         unsub #(.off child type callback)]
{'fraction_non_alphanumeric': 0.16214305908962398, 'fraction_numerical': 0.0016963528413910093, 'mean_word_length': 2.2558674643350205, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7425903', 'n_tokens_mistral': 2647, 'n_tokens_neox': 2523, 'n_words': 872}