            (<! (-update-in my-store [i] (fn [_] (inc i)))))
          #_(doseq [i (range 10)]
              (println (<! (-get-in my-store [i]))))))
-    (go (println (<! (-get-in my-store [999]))))
+    (go (println (<! (-get my-store 999))))
+
+    (go (prn (<! (-update-in my-store ["foo"] (fn [_] {:meta "META"}) (fn [_] 0) []))))
+
+    (go (prn (<! (-update-in my-store ["foo"] (fn [_] {:meta "META"}) inc []))))
+
+    (go (println (<! (-get-meta my-store "foo"))))
+
+    (go (println (<! (-get my-store "foo"))))
+
 
     (go (println (<! (-assoc-in my-store ["rec-test"] (Test. 5)))))
-    (go (println (<! (-get-in my-store ["rec-test"]))))
+    (go (println (<! (-get my-store "rec-test"))))
 
     (go (println (<! (-assoc-in my-store ["test2"] {:a 1 :b 4.2}))))
 
     (go (println (<! (-assoc-in my-store ["test"] {:a 43}))))
 
     (go (println (<! (-update-in my-store ["test" :a] inc))))
-    (go (println (<! (-get-in my-store ["test2"]))))
+    (go (println (<! (-get my-store "test2"))))
 
 
     (go (println (<! (-bassoc my-store
                               "blob-fun"
+                              (fn [_] "my meta")
                               (new js/Blob #js ["hello worlds"], #js {"type" "text/plain"})))))
+
+    (go (println (<! (-get-meta my-store "blob-fun"))))
+
     (go (.log js/console (<! (-bget my-store "blob-fun" identity))))
-    ))
+
+
+    )

                (close! res)))
        res))

    (-get-in [this key-vec]
      (let [[fkey & rkey] key-vec
            res (chan)
            tx (.transaction db #js [store-name])
            obj-store (.objectStore tx store-name)
            req (.get obj-store (pr-str fkey))]
        (set! (.-onerror req)
              (fn [e]
                (put! res (ex-info "Cannot read edn value."
                                   {:type :read-error
                                    :key key-vec
                                    :error (.-target e)}))
                (close! res)))
        (set! (.-onsuccess req)
              (fn [e] (when-let [r (.-result req)]
                        (put! res (get-in (-deserialize serializer read-handlers (aget r "edn_value"))
                                          rkey)))
                ;; returns nil
                (close! res)))
        res))

    (-update-in [this key-vec up-fn] (-update-in this key-vec up-fn []))
    (-update-in [this key-vec up-fn up-fn-args]
      (let [[fkey & rkey] key-vec
            res (chan)
            tx (.transaction db #js [store-name] "readwrite")
            obj-store (.objectStore tx store-name)
            req (.get obj-store (pr-str fkey))]
        (set! (.-onerror req)
              (fn [e]
                (put! res (ex-info "Cannot read edn value."
                                   {:type :read-error
                                    :key key-vec
                                    :error (.-target e)}))
                (close! res)))
        (set! (.-onsuccess req)
              (fn read-old [e]
                (try
                  (let [old (when-let [r (.-result req)]
                              (-deserialize serializer read-handlers (aget r "edn_value")))
                        up (if-not (empty? rkey)
                             (apply update-in old rkey up-fn up-fn-args)
                             (apply up-fn old up-fn-args))]
                    (let [up-req (.put obj-store
                                       (clj->js {:key (pr-str fkey)
                                                 :edn_value
                                                 (-serialize serializer nil write-handlers up)}))]
                      (set! (.-onerror up-req)
                            (fn [e]
                              (put! res (ex-info "Cannot write edn value."
                                                 {:type :write-error
                                                  :key key-vec
                                                  :error (.-target e)}))
                              (close! res)))
                      (set! (.-onsuccess up-req)
                            (fn [e]
                              (put! res [(get-in old rkey) up])
                              (close! res)))))
                  (catch :default e
                    (put! res (ex-info "Cannot parse edn value."
                                       {:type :read-error
                                        :key key-vec
                                        :error e}))
                    (close! res)))))
        res))

    (-assoc-in [this key-vec val] (-update-in this key-vec (fn [_] val)))

    (-dissoc [this key]
      (let [res (chan)
            tx (.transaction db #js [store-name] "readwrite")
            obj-store (.objectStore tx store-name)
            up-req (.delete obj-store (pr-str key))]
        (set! (.-onerror up-req)
              (fn [e]
                (put! res (ex-info "Cannot write edn value."
                                   {:type :write-error
                                    :key key
                                    :error (.-target e)}))
                (close! res)))
        (set! (.-onsuccess up-req)

(ns konserve.indexeddb
  (:require [incognito.edn :refer [read-string-safe]]
            [konserve.core :as k]
            [konserve.serializers :as ser]
            [konserve.protocols :refer [PEDNAsyncKeyValueStore -exists? -get -update-in -assoc-in -get-meta
                                        PBinaryAsyncKeyValueStore -bget -bassoc
                                        PStoreSerializer -serialize -deserialize]]
            [cljs.core.async :as async :refer (take! <! >! put! close! chan poll!)])
  (:require-macros [cljs.core.async.macros :refer [go go-loop]]))


  (defrecord IndexedDBKeyValueStore [db store-name serializer read-handlers write-handlers locks version]
    PEDNAsyncKeyValueStore
    (-exists? [this key]
      (let [res       (chan)
            tx        (.transaction db #js [store-name])
            obj-store (.objectStore tx store-name)
            req       (.openCursor obj-store (pr-str key))]
        (set! (.-onerror req)
              (fn [e]
                (put! res (ex-info "Cannot check for existence."
                                   {:type  :access-error
                                    :key   key
                                    :error (.-target e)}))
                (close! res)))
        (set! (.-onsuccess req)
