Explorar o código

refactor: db/transact! as outliner op

The benefits:
1. all db transactions from the UI thread can be described in outliner
ops now.
2. batch undo/redo
Tienson Qin hai 1 ano
pai
achega
c862ad0d10

+ 16 - 4
deps/outliner/src/logseq/outliner/op.cljs

@@ -4,7 +4,8 @@
             [logseq.outliner.core :as outliner-core]
             [logseq.outliner.property :as outliner-property]
             [datascript.core :as d]
-            [malli.core :as m]))
+            [malli.core :as m]
+            [logseq.db :as ldb]))
 
 (def ^:private ^:large-vars/data-var op-schema
   [:multi {:dispatch first}
@@ -86,7 +87,13 @@
    [:add-existing-values-to-closed-values
     [:catn
      [:op :keyword]
-     [:args [:tuple ::property-id ::values]]]]])
+     [:args [:tuple ::property-id ::values]]]]
+
+   ;; transact
+   [:transact
+    [:catn
+     [:op :keyword]
+     [:args [:tuple ::tx-data ::tx-meta]]]]])
 
 (def ^:private ops-schema
   [:schema {:registry {::id int?
@@ -101,7 +108,9 @@
                        ::values [:sequential ::value]
                        ::option [:maybe map?]
                        ::blocks [:sequential ::block]
-                       ::ids [:sequential ::id]}}
+                       ::ids [:sequential ::id]
+                       ::tx-data [:sequential :any]
+                       ::tx-meta [:maybe map?]}}
    [:sequential op-schema]])
 
 (def ^:private ops-validator (m/validator ops-schema))
@@ -189,6 +198,9 @@
          (apply outliner-property/delete-closed-value! conn args)
 
          :add-existing-values-to-closed-values
-         (apply outliner-property/add-existing-values-to-closed-values! conn args))))
+         (apply outliner-property/add-existing-values-to-closed-values! conn args)
+
+         :transact
+         (apply ldb/transact! conn args))))
 
     @*result))

+ 43 - 9
src/main/frontend/db.cljs

@@ -5,10 +5,13 @@
             [frontend.db.query-custom]
             [frontend.db.query-react]
             [frontend.db.react :as react]
-            [frontend.db.transact :as db-transact]
             [frontend.db.utils]
             [frontend.namespaces :refer [import-vars]]
-            [logseq.db :as ldb]))
+            [logseq.db :as ldb]
+            [frontend.modules.outliner.ui :as ui-outliner-tx]
+            [frontend.modules.outliner.op :as outliner-op]
+            [frontend.state :as state]
+            [frontend.config :as config]))
 
 (import-vars
  [frontend.db.conn
@@ -23,7 +26,7 @@
 
  [frontend.db.utils
   group-by-page seq-flatten
-  entity pull pull-many transact! get-key-value]
+  entity pull pull-many get-key-value]
 
  [frontend.db.model
   delete-blocks get-pre-block
@@ -39,14 +42,14 @@
   get-page-referenced-blocks get-page-referenced-blocks-full get-page-referenced-pages
   get-all-pages get-pages-relation get-pages-that-mentioned-page
   journal-page? page? page-alias-set sub-block
-  set-file-last-modified-at! page-empty? page-exists? get-alias-source-page
-  set-file-content! has-children? whiteboard-page?
+  page-empty? page-exists? get-alias-source-page
+  has-children? whiteboard-page?
   get-namespace-pages get-all-namespace-relation]
 
  [frontend.db.react
-  get-current-page set-key-value
-  remove-key! remove-q! remove-query-component! add-q! add-query-component! clear-query-state!
-  kv q
+  get-current-page
+  remove-q! remove-query-component! add-q! add-query-component! clear-query-state!
+  q
   query-state query-components remove-custom-query! set-new-result! sub-key-value]
 
  [frontend.db.query-custom
@@ -62,4 +65,35 @@
    (conn/start! repo option)))
 
 (def new-block-id ldb/new-block-id)
-(def request-finished? db-transact/request-finished?)
+
+(defn transact!
+  ([tx-data]
+   (transact! (state/get-current-repo) tx-data nil))
+  ([repo tx-data]
+   (transact! repo tx-data nil))
+  ([repo tx-data tx-meta]
+   (if config/publishing?
+     ;; :save-block is for query-table actions like sorting and choosing columns
+     (when (or (#{:collapse-expand-blocks :save-block} (:outliner-op tx-meta))
+               (:init-db? tx-meta))
+       (conn/transact! repo tx-data tx-meta))
+     (ui-outliner-tx/transact! tx-meta
+                               (outliner-op/transact! tx-data tx-meta)))))
+
+(defn set-file-last-modified-at!
+  "Refresh file timestamps to DB"
+  [repo path last-modified-at]
+  (when (and repo path last-modified-at)
+    (transact! repo
+               [{:file/path path
+                 :file/last-modified-at last-modified-at}]
+               {:skip-refresh? true})))
+
+(defn set-file-content!
+  ([repo path content]
+   (set-file-content! repo path content {}))
+  ([repo path content opts]
+   (when (and repo path)
+     (let [tx-data {:file/path path
+                    :file/content content}]
+       (transact! repo [tx-data] (merge opts {:skip-refresh? true}))))))

+ 0 - 18
src/main/frontend/db/model.cljs

@@ -87,15 +87,6 @@
              (conn/get-db repo-url) pred)
         db-utils/seq-flatten)))
 
-(defn set-file-last-modified-at!
-  "Refresh file timestamps to DB"
-  [repo path last-modified-at]
-  (when (and repo path last-modified-at)
-    (db-utils/transact! repo
-                        [{:file/path path
-                          :file/last-modified-at last-modified-at}]
-                        {:skip-refresh? true})))
-
 (defn get-file-last-modified-at
   [repo path]
   (when (and repo path)
@@ -712,15 +703,6 @@ independent of format as format specific heading characters are stripped"
     (when (seq pages)
       (mapv (fn [page] [:db.fn/retractEntity [:block/name page]]) (map util/page-name-sanity-lc pages)))))
 
-(defn set-file-content!
-  ([repo path content]
-   (set-file-content! repo path content {}))
-  ([repo path content opts]
-   (when (and repo path)
-     (let [tx-data {:file/path path
-                    :file/content content}]
-       (db-utils/transact! repo [tx-data] (merge opts {:skip-refresh? true}))))))
-
 ;; TODO: check whether this works when adding pdf back on Web
 (defn get-pre-block
   [repo page-id]

+ 0 - 13
src/main/frontend/db/react.cljs

@@ -35,13 +35,6 @@
   (when-let [result-atom (get-in @query-state [k :result])]
     (reset! result-atom new-result)))
 
-(def kv conn/kv)
-
-(defn remove-key!
-  [repo-url key]
-  (db-utils/transact! repo-url [[:db.fn/retractEntity [:db/ident key]]])
-  (set-new-result! [repo-url :kv key] nil))
-
 (defn clear-query-state!
   []
   (reset! query-state {}))
@@ -206,12 +199,6 @@
   (when (and repo-url (seq affected-keys))
     (refresh-affected-queries! repo-url affected-keys)))
 
-(defn set-key-value
-  [repo-url key value]
-  (if value
-    (db-utils/transact! repo-url [(kv key value)])
-    (remove-key! repo-url key)))
-
 (defn sub-key-value
   ([key]
    (sub-key-value (state/get-current-repo) key))

+ 0 - 18
src/main/frontend/db/utils.cljs

@@ -3,7 +3,6 @@
   (:require [datascript.core :as d]
             [frontend.state :as state]
             [frontend.db.conn :as conn]
-            [frontend.config :as config]
             [logseq.db.frontend.content :as db-content]))
 
 ;; transit serialization
@@ -63,23 +62,6 @@
        (->> (d/pull-many db selector eids)
             (map #(update-block-content % (:db/id %))))))))
 
-(if config/publishing?
-  (defn- transact!*
-    [repo-url tx-data tx-meta]
-    ;; :save-block is for query-table actions like sorting and choosing columns
-    (when (or (#{:collapse-expand-blocks :save-block} (:outliner-op tx-meta))
-              (:init-db? tx-meta))
-      (conn/transact! repo-url tx-data tx-meta)))
-  (def transact!* conn/transact!))
-
-(defn transact!
-  ([tx-data]
-   (transact! (state/get-current-repo) tx-data))
-  ([repo-url tx-data]
-   (transact! repo-url tx-data nil))
-  ([repo-url tx-data tx-meta]
-   (transact!* repo-url tx-data tx-meta)))
-
 (defn get-key-value
   ([key]
    (get-key-value (state/get-current-repo) key))

+ 1 - 1
src/main/frontend/handler/db_based/property.cljs

@@ -26,7 +26,7 @@
   [block-id property-id]
   (ui-outliner-tx/transact!
    {:outliner-op :remove-block-property}
-    (outliner-op/remove-block-property! block-id property-id)))
+   (outliner-op/remove-block-property! block-id property-id)))
 
 (defn delete-property-value!
   [block-id property-id property-value]

+ 5 - 3
src/main/frontend/handler/editor.cljs

@@ -2145,9 +2145,11 @@
         block-refs (->> (mapcat :block/refs blocks)
                         (set)
                         (filter (fn [ref] (and (vector? ref) (= :block/uuid (first ref))))))]
-    (when (seq block-refs)
-      (db/transact! (map (fn [[_ id]] {:block/uuid id}) block-refs)))
-    (paste-blocks blocks opts)))
+    (ui-outliner-tx/transact!
+     {:outliner-op :paste-blocks}
+     (when (seq block-refs)
+       (db/transact! (map (fn [[_ id]] {:block/uuid id}) block-refs)))
+     (paste-blocks blocks opts))))
 
 (defn insert-block-tree-after-target
   "`tree-vec`: a vector of blocks.

+ 9 - 7
src/main/frontend/handler/whiteboard.cljs

@@ -169,21 +169,22 @@
             metadata' (cond
                         ;; group
                         (some #(= "group" (:type %)) new-shapes)
-                        (assoc metadata :whiteboard/op :group)
+                        (assoc metadata :outliner-op :group)
 
                         ;; ungroup
                         (and (not-empty deleted-shapes) (every? #(= "group" (:type %)) deleted-shapes))
-                        (assoc metadata :whiteboard/op :un-group)
+                        (assoc metadata :outliner-op :un-group)
 
                         ;; arrow
                         (some #(and (= "line" (:type %))
                                     (= "arrow " (:end (:decorations %)))) new-shapes)
 
-                        (assoc metadata :whiteboard/op :new-arrow)
+                        (assoc metadata :outliner-op :new-arrow)
+
                         :else
-                        metadata)]
+                        (assoc metadata :outliner-op :save-whiteboard))]
         (swap! *last-shapes-nonce assoc-in [repo page-uuid] new-id-nonces)
-        (if (contains? #{:new-arrow} (:whiteboard/op metadata'))
+        (if (contains? #{:new-arrow} (:outliner-op metadata'))
           (state/set-state! :whiteboard/pending-tx-data
                             {:tx-data tx-data
                              :metadata metadata'})
@@ -222,7 +223,7 @@
   ([name]
    (p/let [uuid (or (and name (parse-uuid name)) (d/squuid))
            name (or name (str uuid))
-           _ (db/transact! (get-default-new-whiteboard-tx name uuid))]
+           _ (db/transact! (state/get-current-repo) (get-default-new-whiteboard-tx name uuid) {:outliner-op :create-page})]
      uuid)))
 
 (defn <create-new-whiteboard-and-redirect!
@@ -278,7 +279,8 @@
                :block/format :markdown
                :block/page (:db/id page-entity)
                :block/parent (:db/id page-entity)})
-          _ (db/transact! repo [tx] {:whiteboard/transact? true})]
+          _ (db/transact! repo [tx] {:outliner-op :insert-blocks
+                                     :whiteboard/transact? true})]
     new-block-id))
 
 (defn inside-portal?

+ 5 - 0
src/main/frontend/modules/outliner/op.cljs

@@ -116,3 +116,8 @@
   [property-id values]
   (op-transact!
    [:add-existing-values-to-closed-values [property-id values]]))
+
+(defn transact!
+  [tx-data tx-meta]
+  (op-transact!
+   [:transact [tx-data tx-meta]]))

+ 4 - 3
src/main/frontend/modules/outliner/ui.cljc

@@ -1,14 +1,15 @@
 (ns frontend.modules.outliner.ui
   #?(:cljs (:require-macros [frontend.modules.outliner.ui]))
   #?(:cljs (:require [frontend.state :as state]
-                     [frontend.db :as db]
+                     [frontend.db.transact]
+                     [frontend.db.conn]
                      [logseq.outliner.op]
                      [frontend.modules.outliner.op])))
 
 (defmacro transact!
   [opts & body]
   `(let [test?# frontend.util/node-test?]
-     (when (or test?# (db/request-finished?))
+     (when (or test?# (frontend.db.transact/request-finished?))
        (let [ops# frontend.modules.outliner.op/*outliner-ops*
              editor-info# (state/get-editor-info)]
          (if ops#
@@ -20,7 +21,7 @@
                (if test?#
                  (when (seq r#)
                    (logseq.outliner.op/apply-ops! (state/get-current-repo)
-                                                  (db/get-db false)
+                                                  (frontend.db.conn/get-db false)
                                                   r#
                                                   (state/get-date-formatter)
                                                   ~opts))