Browse Source

refactor: use defmethod to collect all db-listen-handlers

rcmerci 1 year ago
parent
commit
6339d76db0

+ 4 - 3
src/main/frontend/db_worker.cljs

@@ -10,6 +10,7 @@
             [datascript.core :as d]
             [datascript.storage :refer [IStorage]]
             [frontend.worker.async-util :include-macros true :refer [<?] :as async-util]
+            [frontend.worker.db-listener :as db-listener]
             [frontend.worker.db-metadata :as worker-db-metadata]
             [frontend.worker.export :as worker-export]
             [frontend.worker.file :as file]
@@ -22,7 +23,7 @@
             [frontend.worker.rtc.snapshot :as rtc-snapshot]
             [frontend.worker.search :as search]
             [frontend.worker.state :as worker-state]
-            [frontend.worker.undo-redo :as undo-redo]
+            [frontend.worker.undo-redo]
             [frontend.worker.util :as worker-util]
             [logseq.db :as ldb]
             [logseq.db.sqlite.common-db :as sqlite-common-db]
@@ -175,8 +176,8 @@
             conn (sqlite-common-db/get-storage-conn storage schema)]
         (swap! *datascript-conns assoc repo conn)
         (p/let [_ (op-mem-layer/<init-load-from-indexeddb! repo)]
-          (rtc-db-listener/listen-to-db-changes! repo conn))
-        (undo-redo/listen-to-db-changes! repo conn)
+          (rtc-db-listener/listen-to-db-changes! repo conn)
+          (db-listener/listen-db-changes! repo conn))
         ))))
 
 (defn- iter->vec [iter]

+ 45 - 0
src/main/frontend/worker/db_listener.cljs

@@ -0,0 +1,45 @@
+(ns frontend.worker.db-listener
+  (:require [datascript.core :as d]))
+
+
+(defn- entity-datoms=>attr->datom
+  [entity-datoms]
+  (reduce
+   (fn [m datom]
+     (let [[_e a _v t add?] datom]
+       (if-let [[_e _a _v old-t old-add?] (get m a)]
+         (cond
+           (and (= old-t t)
+                (true? add?)
+                (false? old-add?))
+           (assoc m a datom)
+
+           (< old-t t)
+           (assoc m a datom)
+
+           :else
+           m)
+         (assoc m a datom))))
+   {} entity-datoms))
+
+
+(defmulti listen-db-changes
+  (fn [listen-key & _] listen-key))
+
+(defn listen-db-changes!
+  [repo conn]
+  (let [handlers (methods listen-db-changes)]
+    (prn :listen-db-changes! (keys handlers))
+    (d/unlisten! conn ::listen-db-changes!)
+    (d/listen! conn ::listen-db-changes!
+               (fn [{:keys [tx-data] :as args}]
+                 (let [datom-vec-coll (map vec tx-data)
+                       id->same-entity-datoms (group-by first datom-vec-coll)
+                       id-order (distinct (map first datom-vec-coll))
+                       same-entity-datoms-coll (map id->same-entity-datoms id-order)
+                       id->attr->datom (update-vals id->same-entity-datoms entity-datoms=>attr->datom)]
+                   (doseq [[k handler-fn] handlers]
+                     (handler-fn k (assoc args
+                                          :repo repo
+                                          :id->attr->datom id->attr->datom
+                                          :same-entity-datoms-coll same-entity-datoms-coll))))))))

+ 43 - 69
src/main/frontend/worker/undo_redo.cljs

@@ -1,6 +1,7 @@
 (ns frontend.worker.undo-redo
   "undo/redo related fns and op-schema"
-  (:require [datascript.core :as d]
+  (:require [frontend.worker.db-listener :as db-listener]
+            [datascript.core :as d]
             [malli.util :as mu]
             [malli.core :as m]))
 
@@ -82,28 +83,6 @@
          (cond-> {:block-uuid block-uuid}
            block-origin-content (assoc :block-origin-content block-origin-content))]))))
 
-(defn- entity-datoms=>attr->datom
-  [entity-datoms]
-  (reduce
-   (fn [m datom]
-     (let [[_e a _v t add?] datom]
-       (if-let [[_e _a _v old-t old-add?] (get m a)]
-         (cond
-           (and (= old-t t)
-                (true? add?)
-                (false? old-add?))
-           (assoc m a datom)
-
-           (< old-t t)
-           (assoc m a datom)
-
-           :else
-           m)
-         (assoc m a datom))))
-   {} entity-datoms))
-
-
-
 (def entity-map-pull-pattern
   [:block/uuid
    {:block/left [:block/uuid]}
@@ -130,55 +109,50 @@
 
 
 (defn entity-datoms=>op
-  [db-before db-after entity-datoms]
+  [db-before db-after id->attr->datom entity-datoms]
   {:post [(or (nil? %)
               (undo-op-validator %))]}
-  (let [attr->datom (entity-datoms=>attr->datom entity-datoms)]
-    (when (seq attr->datom)
-      (let [e (some-> attr->datom first second first)
-            {[_ _ block-uuid _ add1?]    :block/uuid
-             [_ _ block-content _ add2?] :block/content
-             [_ _ _ _ add3?]             :block/left
-             [_ _ _ _ add4?]             :block/parent} attr->datom
-            entity-before (d/entity db-before e)
-            entity-after (d/entity db-after e)]
-        (cond
-          (and (not add1?) block-uuid
-               (normal-block? entity-before))
-          [:remove-block
-           {:block-uuid (:block/uuid entity-before)
-            :block-entity-map (->block-entity-map db-before e)}]
-
-          (and add1? block-uuid
-               (normal-block? entity-after))
-          [:insert-block {:block-uuid (:block/uuid entity-after)}]
-
-          (and (or add3? add4?)
-               (normal-block? entity-after))
-          [:move-block
-           {:block-uuid (:block/uuid entity-after)
-            :block-origin-left (:block/uuid (:block/left entity-before))
-            :block-origin-parent (:block/uuid (:block/parent entity-before))}]
-
-          (and add2? block-content
-               (normal-block? entity-after))
-          [:update-block
-           {:block-uuid (:block/uuid entity-after)
-            :block-origin-content (:block/content entity-before)}])))))
+  (when-let [e (ffirst entity-datoms)]
+    (let [attr->datom (id->attr->datom e)]
+      (when (seq attr->datom)
+        (let [{[_ _ block-uuid _ add1?]    :block/uuid
+               [_ _ block-content _ add2?] :block/content
+               [_ _ _ _ add3?]             :block/left
+               [_ _ _ _ add4?]             :block/parent} attr->datom
+              entity-before (d/entity db-before e)
+              entity-after (d/entity db-after e)]
+          (cond
+            (and (not add1?) block-uuid
+                 (normal-block? entity-before))
+            [:remove-block
+             {:block-uuid (:block/uuid entity-before)
+              :block-entity-map (->block-entity-map db-before e)}]
+
+            (and add1? block-uuid
+                 (normal-block? entity-after))
+            [:insert-block {:block-uuid (:block/uuid entity-after)}]
+
+            (and (or add3? add4?)
+                 (normal-block? entity-after))
+            [:move-block
+             {:block-uuid (:block/uuid entity-after)
+              :block-origin-left (:block/uuid (:block/left entity-before))
+              :block-origin-parent (:block/uuid (:block/parent entity-before))}]
+
+            (and add2? block-content
+                 (normal-block? entity-after))
+            [:update-block
+             {:block-uuid (:block/uuid entity-after)
+              :block-origin-content (:block/content entity-before)}]))))))
 
 (defn generate-undo-ops
-  [_repo db-before db-after datoms]
-  (let [datom-vec-coll (map vec datoms)
-        id->same-entity-datoms (group-by first datom-vec-coll)
-        id-order (distinct (map first datom-vec-coll))
-        same-entity-datoms-coll (map id->same-entity-datoms id-order)
-        ops (keep (partial entity-datoms=>op db-before db-after) same-entity-datoms-coll)]
+  [_repo db-before db-after same-entity-datoms-coll id->attr->datom]
+  (let [ops (keep (partial entity-datoms=>op db-before db-after id->attr->datom) same-entity-datoms-coll)]
     (prn ::debug-undo-ops ops)))
 
-(defn listen-to-db-changes!
-  [repo conn]
-  (d/unlisten! conn :gen-undo-ops)
-  (d/listen! conn :gen-undo-ops
-             (fn [{:keys [tx-data tx-meta db-before db-after]}]
-               (when (:gen-undo-op? tx-meta true)
-                 (generate-undo-ops repo db-before db-after tx-data)))))
+
+(defmethod db-listener/listen-db-changes :gen-undo-ops
+  [_ {:keys [_tx-data tx-meta db-before db-after
+             repo id->attr->datom same-entity-datoms-coll]}]
+  (when (:gen-undo-op? tx-meta true)
+    (generate-undo-ops repo db-before db-after same-entity-datoms-coll id->attr->datom)))