From 3232536a4fd68c965f286649a52a2a3776451289 Mon Sep 17 00:00:00 2001
From: Petter Eriksson <ipetterik@gmail.com>
Date: Fri, 30 Sep 2016 17:21:54 +0200
Subject: [PATCH] Writes om/next/cache.cljs in .cljc and uses it in next.cljc

---
 src/main/om/next.cljc       | 24 +++++++++++++-----------
 src/main/om/next/cache.cljc | 30 ++++++++++++++++++++++++++++++
 src/main/om/next/cache.cljs | 16 ----------------
 3 files changed, 43 insertions(+), 27 deletions(-)
 create mode 100644 src/main/om/next/cache.cljc
 delete mode 100644 src/main/om/next/cache.cljs

diff --git a/src/main/om/next.cljc b/src/main/om/next.cljc
index 6403c1ea..8361c543 100644
--- a/src/main/om/next.cljc
+++ b/src/main/om/next.cljc
@@ -7,9 +7,9 @@
                        [cljs.util]]
                 :cljs [[goog.string :as gstring]
                        [goog.object :as gobj]
-                       [goog.log :as glog]
-                       [om.next.cache :as c]])
+                       [goog.log :as glog]])
             [om.next.impl.parser :as parser]
+            [om.next.cache :as c]
             [om.tempid :as tempid]
             [om.transit :as transit]
             [om.util :as util]
@@ -1281,7 +1281,8 @@
          st   (:state cfg)
          id   #?(:clj  (java.util.UUID/randomUUID)
                  :cljs (random-uuid))]
-     #?(:cljs (.add (:history cfg) id @st))
+     (when-let [h (:history cfg)]
+       (c/add h id @st))
      #?(:cljs
         (when-let [l (:logger cfg)]
           (glog/info l
@@ -1503,12 +1504,13 @@
                  {:ref ref}))
         id   #?(:clj  (java.util.UUID/randomUUID)
                 :cljs (random-uuid))
+        _ (when-let [h (:history cfg)]
+            (c/add h id @(:state cfg)))
         #?@(:cljs
-            [_    (.add (:history cfg) id @(:state cfg))
-             _    (when-let [l (:logger cfg)]
-                    (glog/info l
-                      (str (when ref (str (pr-str ref) " "))
-                        "transacted '" tx ", " (pr-str id))))])
+            [_ (when-let [l (:logger cfg)]
+                 (glog/info l
+                            (str (when ref (str (pr-str ref) " "))
+                                 "transacted '" tx ", " (pr-str id))))])
         v    ((:parser cfg) env tx)
         snds (gather-sends env tx (:remotes cfg))
         xs   (cond-> []
@@ -2725,7 +2727,7 @@
          merge-ident  default-merge-ident
          prune-tree   default-extract-errors
          optimize     (fn [cs] (sort-by depth cs))
-         history      100
+         history      #?(:clj nil :cljs 100)
          root-render  #?(:clj  (fn [c target] c)
                          :cljs #(js/ReactDOM.render %1 %2))
          root-unmount #?(:clj   (fn [x])
@@ -2751,7 +2753,7 @@
                   :prune-tree prune-tree
                   :optimize optimize
                   :normalize (or (not norm?) normalize)
-                  :history #?(:clj  []
+                  :history #?(:clj  (when history (c/cache history))
                               :cljs (c/cache history))
                   :root-render root-render :root-unmount root-unmount
                   :logger logger :pathopt pathopt
@@ -2798,7 +2800,7 @@
    may be configured by the :history option when constructing the reconciler."
   [reconciler uuid]
   {:pre [(reconciler? reconciler)]}
-  (.get (-> reconciler :config :history) uuid))
+  (c/get (-> reconciler :config :history) uuid))
 
 (defn tempid
   "Return a temporary id."
diff --git a/src/main/om/next/cache.cljc b/src/main/om/next/cache.cljc
new file mode 100644
index 00000000..49057721
--- /dev/null
+++ b/src/main/om/next/cache.cljc
@@ -0,0 +1,30 @@
+(ns om.next.cache
+  (:refer-clojure :exclude [get]))
+
+(defprotocol ICache
+  (add [this id x])
+  (get [this id])
+  (get-most-recent-id [this]))
+
+(deftype Cache [state size]
+  ICache
+  (add [this id x]
+    (let [x' (vary-meta x assoc :client-time #?(:cljs (js/Date.) :clj (java.util.Date.)))
+          append-cache #(-> (update % :queue conj id)
+                            (assoc-in [:index id] x'))
+          trim-cache #(-> (update % :queue pop)
+                          (update :index dissoc (first (:queue %))))]
+      (swap! state (cond-> append-cache
+                           (<= size (count (:queue @state)))
+                           (comp trim-cache)))))
+  (get [this id]
+    (get-in @state [:index id]))
+  (get-most-recent-id [this]
+    (let [q (:queue @state)]
+      (nth q (dec (count q)) nil))))
+
+(defn cache [size]
+  (Cache. (atom {:index {}
+                 :queue #?(:clj  clojure.lang.PersistentQueue/EMPTY
+                           :cljs cljs.core.PersistentQueue.EMPTY)})
+          size))
diff --git a/src/main/om/next/cache.cljs b/src/main/om/next/cache.cljs
deleted file mode 100644
index 9cc56906..00000000
--- a/src/main/om/next/cache.cljs
+++ /dev/null
@@ -1,16 +0,0 @@
-(ns om.next.cache)
-
-(deftype Cache [arr index size]
-  Object
-  (add [this id x]
-    (let [x' (vary-meta x assoc :client-time (js/Date.))]
-      (if (<= size (alength arr))
-        (let [id' (.shift arr)]
-          (swap! index #(-> % (dissoc id') (assoc id x'))))
-        (swap! index assoc id x')))
-    (.push arr id))
-  (get [this id]
-    (get @index id)))
-
-(defn cache [size]
-  (Cache. #js [] (atom {}) size))