                 ;; returns nil
                 (close! res)))
         res))
-    (-bassoc [this key blob]
-      (let [res (chan)
-            tx (.transaction db #js [store-name] "readwrite")
-            obj-store (.objectStore tx store-name)
-            req (.put obj-store #js {:key (pr-str key)
-                                     :value blob})]
-        (set! (.-onerror req)
-              (fn [e]
-                (put! res (ex-info "Cannot write binary value."
-                                   {:type :write-error
-                                    :key key
-                                    :error (.-target e)}))
-                (close! res)))
-        (set! (.-onsuccess req)
-              (fn [e] (close! res)))
-        res))
-
-    PJSONAsyncKeyValueStore
-    (-jget-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 write json value."
-                                   {:type :write-error
-                                    :key key
-                                    :error (.-target e)}))
-                (close! res)))
-        (set! (.-onsuccess req)
-              (fn [e] (when-let [r (.-result req)]
-                        (put! res (-> r
-                                      (aget "json_value")
-                                      js->clj
-                                      (get-in rkey))))
-                ;; returns nil
-                (close! res)))
-        res))
-    (-jassoc-in [this key-vec value]
-      (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 write json value."
-                                   {:type :write-error
-                                    :key key
+    (-bassoc [this key meta-up blob]
+      (let [res       (chan)
+            tx        (.transaction db #js [store-name] "readwrite")
+            obj-store (.objectStore tx store-name)
+            req       (.get obj-store (pr-str key))]
+        (set! (.-onerror req)
+              (fn [e]
+                (put! res (ex-info "Cannot read edn value."
+                                   {:type  :read-error
+                                    :key   key
                                     :error (.-target e)}))
                 (close! res)))
         (set! (.-onsuccess req)
               (fn read-old [e]
-                (let [old (when-let [r (.-result req)]
-                            (js->clj (-> r (aget "json_value"))))
-                      up-req (if (or value (not (empty? rkey)))
-                               (.put obj-store
-                                     #js {:key (pr-str fkey)
-                                          :json_value (if-not (empty? rkey)
-                                                        (clj->js (assoc-in old rkey value))
-                                                        value)})
-                               (.delete obj-store (pr-str fkey)))]
-                  (set! (.-onerror up-req)
-                        (fn [e]
-                          (put! res (ex-info "Cannot write json value."
-                                             {:type :write-error
-                                              :key key
-                                              :error (.-target e)}))
-                          (close! res)))
-                  (set! (.-onsuccess up-req)
-                        (fn [e] (close! res))))))
-        res))
-    (-jupdate-in [this key-vec up-fn]
-      (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 write json value."
-                                   {:type :write-error
-                                    :key key
-                                    :error (.-target e)}))
-                (close! res)))
-        (set! (.-onsuccess req)
-              (fn read-old [e]
-                (let [old (when-let [r (.-result req)]
-                            (-> r (aget "json_value")))
-                      new (if-not (empty? rkey)
-                            (update-in old rkey up-fn)
-                            (up-fn old))
-                      up-req (if new
-                               (.put obj-store
-                                     (clj->js {:key (pr-str fkey)
-                                               :json_value
-                                               (pr-str new)}))
-                               (.delete obj-store (pr-str fkey)))]
-                  (set! (.-onerror up-req)
-                        (fn [e]
-                          (put! res (ex-info "Cannot write json value."
-                                             {:type :write-error
-                                              :key key
-                                              :error (.-target e)}))
-                          (close! res)))
-                  (set! (.-onsuccess up-req)
-                        (fn [e]
-                          (put! res [(get-in old rkey) (get-in new rkey)])
-                          (close! res))))))
+                (try
+                  (let [old-meta (when-let [r (.-result req)]
+                                   (-deserialize serializer read-handlers (aget r "meta")))
+                        edn-meta (meta-up old-meta)]
+                    (let [up-req (.put obj-store
+                                       (clj->js {:key   (pr-str key)
+                                                 :meta
+                                                 (-serialize serializer nil write-handlers edn-meta)
+                                                 :version version
+                                                 :value blob}))]
+                      (set! (.-onerror up-req)
+                            (fn [e]
+                              (put! res (ex-info "Cannot write binary value."
+                                                 {:type  :write-error
+                                                  :key   key
+                                                  :error (.-target e)}))
+                              (close! res)))
+                      (set! (.-onsuccess up-req)
+                            (fn [e] (close! res)))))
+                  (catch :default e
+                    (put! res (ex-info "Cannot parse edn value."
+                                       {:type  :read-error
+                                        :key   key
+                                        :error e}))
+                    (close! res)))))
         res)))
 
 

                (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)

                                                      :store-name name
                                                      :read-handlers read-handlers
                                                      :write-handlers write-handlers
                                                      :locks (atom {})
                                                      :version version}))))
      (set! (.-onupgradeneeded req)
            (fn upgrade-handler [e]
              (let [db (-> e .-target .-result)]
