 (ns overcode.introvert)
 
-(def ->js)
+;;***************************************************************************
+;; Utilities
+;;***************************************************************************
+(defn arr? [v]
+  "Returns if an object is a JS Array."
+  (= (type v) js/Array))
+
+(defn obj? [v]
+  "Returns if an object is a JS Object."
+  (= (type v) js/Object))
+
+(defn obj-size [obj]
+  (count (filter #(.hasOwnProperty obj %) (.keys js/Object obj))))
 
 (defn array-append [arr seq]
   "Inserts all elements from a Seq into an existing JS array."

  "Converts a cljs data structure into a close JS approximation."
  ([obj flat visited]
   (cond
     (keyword? obj)      (name obj)
     (symbol? obj)       (name obj)
     (= (type obj) Atom) (->js @obj flat visited)
     (seq? obj)          (seq->js obj flat visited)
     (set? obj)          (seq->js obj flat visited)
     (map? obj)          (map->js obj flat visited)
     :else               obj))

  ([obj flat] (->js obj flat (atom {})))
  ([obj] (->js obj false (atom {}))))


(.log js/console (let [a (atom [1])
      b [9 a]
      a-js (array 1)
      b-js (array 9 a-js)]

  (swap! a conj b)
  (.push a-js b)

  (seq->js b true)))

         was-visited)
       (let [out (js-obj)]
         (visit! visited obj out)
         (dorun
          (map
           #(let [key (->js (first %)  flat visited)
                  val (->js (second %) flat visited)]
