       new-db)))
 
 
-(defn undoable
-  "Middleware which stores an undo checkpoint."
-  [handler]
-  (fn undoable-handler
-    [app-db event-vec]
-    (store-now!)
-    (handler app-db event-vec)))
-
 
 (defn trim-v
   "Middleware which removes the first element of v which allows you to write


(defn pure
  "Acts as an adaptor, allowing handlers to be writen as pure functions.
  The re-frame router will pass in an atom as the first parameter. This middleware
  adapts that to the value within the atom.
  If you strip away the error/efficiency checks, this middleware is just:
     (reset! app-db (handler @app-db event-vec))"
  [handler]
  (fn pure-handler
    [app-db event-vec]

        (let [val (get-in db p)
              val (if (nil? val) (default-fn) val)]
          (assoc-in db p (handler val v)))))))


(defn undoable
  "A Middleware factory which stores an undo checkpoint.
  \"explanation\" can be either a string or a function. If it is a
  function then it must be:  (db event-vec) -> string.
  \"explanation\" can be nil. in which case no
  "
  [explanation]
  (fn middleware
    [handler]
    (fn undoable-handler
      [db event-vec]
      (let [explanation (cond
                          (fn? explanation)     (explanation db event-vec)
                          (string? explanation) explanation
                          (nil? explanation)    ""
                          :else (warn "re-frame: undoable given bad parameter. Got: " explanation))]
      (store-now! explanation)
      (handler db event-vec)))))


(defn enrich
