浏览代码

feat: returns a deferred promise for logseq.db/transact!

This enables callers to wait for the result.
Tienson Qin 1 年之前
父节点
当前提交
5cad97c617

+ 20 - 6
deps/db/src/logseq/db.cljs

@@ -5,16 +5,14 @@
             [datascript.core :as d]
             [cljs-time.core :as t]
             [cljs-time.coerce :as tc]
-            [logseq.db.frontend.property :as db-property]
-            [logseq.db.frontend.property.util :as db-property-util]
-            [logseq.db.sqlite.util :as sqlite-util]
             [clojure.string :as string]
             [logseq.common.util :as common-util]
             [logseq.common.config :as common-config]
             [logseq.db.frontend.content :as db-content]
             [clojure.set :as set]
             [logseq.db.frontend.rules :as rules]
-            [logseq.db.frontend.entity-plus]))
+            [logseq.db.frontend.entity-plus]
+            [promesa.core :as p]))
 
 ;; Use it as an input argument for datalog queries
 (def block-attrs
@@ -53,6 +51,14 @@
   [f]
   (when f (reset! *transact-fn f)))
 
+(defonce *request-id (atom 0))
+(defonce *request-id->response (atom {}))
+
+(defn get-deferred-response
+  [request-id]
+  (assert request-id "request-id shouldn't be empty")
+  (get @*request-id->response request-id))
+
 (defn transact!
   ([conn tx-data]
    (transact! conn tx-data nil))
@@ -63,8 +69,16 @@
        ;; (prn :debug :transact)
        ;; (cljs.pprint/pprint tx-data)
 
-       (let [f (or @*transact-fn d/transact!)]
-         (f conn tx-data tx-meta))))))
+       (let [f (or @*transact-fn d/transact!)
+             sync? (= f d/transact!)
+             request-id (swap! *request-id inc)
+             tx-meta' (if sync? tx-meta
+                          (assoc tx-meta :request-id request-id))
+             result (f conn tx-data tx-meta')]
+         (if sync? result
+             (let [resp (p/deferred)]
+               (swap! *request-id->response assoc request-id resp)
+               resp)))))))
 
 (defn build-default-pages-tx
   []

+ 2 - 4
deps/outliner/src/logseq/outliner/datascript.cljs

@@ -75,7 +75,7 @@
     txs))
 
 (defn transact!
-  [txs tx-meta {:keys [repo conn unlinked-graph? after-transact-fn set-state-fn] :as opts}]
+  [txs tx-meta {:keys [repo conn unlinked-graph? set-state-fn]}]
   (let [db-based? (and repo (sqlite-util/db-based-graph? repo))
         txs (map (fn [m]
                    (if (map? m)
@@ -100,9 +100,7 @@
       ;; (cljs.pprint/pprint txs)
 
       (try
-        (let [tx-report (ldb/transact! conn txs (assoc tx-meta :outliner/transact? true))]
-          (when (fn? after-transact-fn) (after-transact-fn tx-report opts))
-          tx-report)
+        (ldb/transact! conn txs (assoc tx-meta :outliner/transact? true))
         (catch :default e
           (js/console.error e)
           (throw e))))))

+ 1 - 4
deps/outliner/src/logseq/outliner/transaction.cljc

@@ -55,7 +55,4 @@
 
              (when (seq all-tx#) ;; If it's empty, do nothing
                (when-not (:nested-transaction? opts#) ; transact only for the whole transaction
-                 (let [result# (logseq.outliner.datascript/transact! all-tx# (dissoc opts## :transact-opts) (:transact-opts opts##))]
-                   {:tx-report result#
-                    :tx-data all-tx#
-                    :tx-meta tx-meta#})))))))))
+                 (logseq.outliner.datascript/transact! all-tx# (dissoc opts## :transact-opts) (:transact-opts opts##))))))))))

+ 35 - 31
src/main/frontend/handler/editor.cljs

@@ -268,40 +268,44 @@
                       ;; :block/uuid might be changed when backspace/delete
                       ;; a block that has been refed
                       (assoc :block/uuid (:block/uuid block)))
-           opts' (assoc opts :outliner-op :save-block)]
-       (let [original-block (db/entity (:db/id block))
-             original-props (:block/properties original-block)
-             {:keys [tx-data]}
-             (ui-outliner-tx/transact!
-              opts'
-              (outliner-save-block! block')
-              ;; page properties changed
-              (when-let [page-name (and (:block/pre-block? block')
-                                        (not= original-props (:block/properties block'))
-                                        (some-> (:block/page block') :db/id (db-utils/pull) :block/name))]
-                (state/set-page-properties-changed! page-name)))
-             [original linked] (when-not (:insert-block? opts)
-                                 (let [original-block (some (fn [m] (and (map? m) (:block/link m) m)) tx-data)
-                                       link (:block/link original-block)
-                                       link' (if (and (map? link) (:db/id link))
-                                               (db/entity (:db/id link))
-                                               (db/entity link))]
-                                   [original-block link']))]
+           opts' (assoc opts :outliner-op :save-block)
+           original-block (db/entity (:db/id block))
+           original-props (:block/properties original-block)]
+       (p/let [{:keys [tx-data] :as result}
+               (ui-outliner-tx/transact!
+                opts'
+                (outliner-save-block! block')
+                ;; page properties changed
+                (when-let [page-name (and (:block/pre-block? block')
+                                          (not= original-props (:block/properties block'))
+                                          (some-> (:block/page block') :db/id (db-utils/pull) :block/name))]
+                  (state/set-page-properties-changed! page-name)))
+               [original linked] (when-not (:insert-block? opts)
+                                   (let [original-block (some (fn [m] (and (map? m) (:block/link m) m)) tx-data)
+                                         link (:block/link original-block)
+                                         link' (if (and (map? link) (:db/id link))
+                                                 (db/entity (:db/id link))
+                                                 (db/entity link))]
+                                     [original-block link']))]
+
+         ;; FIXME move this to pipeline
          ;; Block has been tagged, so we need to edit the linked page now
          (when (and linked
                     (= (:db/id (state/get-edit-block)) (:db/id original)))
-           (edit-block! linked :max nil {})))
-
-       ;; file based graph only
-       ;; sanitized page name changed
-       (when-let [title (get-in block' [:block/properties :title])]
-         (if (string? title)
-           (when-let [old-page-name (:block/name (db/entity (:db/id (:block/page block'))))]
-             (when (and (:block/pre-block? block')
-                        (not (string/blank? title))
-                        (not= (util/page-name-sanity-lc title) old-page-name))
-               (state/pub-event! [:page/title-property-changed old-page-name title true])))
-           (js/console.error (str "Title is not a string: " title))))))))
+           (edit-block! linked :max nil {}))
+
+         ;; file based graph only
+         ;; sanitized page name changed
+         (when-let [title (get-in block' [:block/properties :title])]
+           (if (string? title)
+             (when-let [old-page-name (:block/name (db/entity (:db/id (:block/page block'))))]
+               (when (and (:block/pre-block? block')
+                          (not (string/blank? title))
+                          (not= (util/page-name-sanity-lc title) old-page-name))
+                 (state/pub-event! [:page/title-property-changed old-page-name title true])))
+             (js/console.error (str "Title is not a string: " title))))
+
+         result)))))
 
 ;; id: block dom id, "ls-block-counter-uuid"
 (defn- another-block-with-same-id-exists?

+ 12 - 3
src/main/frontend/modules/outliner/pipeline.cljs

@@ -9,7 +9,9 @@
             [frontend.modules.editor.undo-redo :as undo-redo]
             [datascript.core :as d]
             [frontend.handler.ui :as ui-handler]
-            [frontend.handler.history :as history]))
+            [frontend.handler.history :as history]
+            [logseq.db :as ldb]
+            [promesa.core :as p]))
 
 (defn- reset-editing-block-content!
   [tx-data]
@@ -61,12 +63,14 @@
   (history/restore-app-state! app-state))
 
 (defn invoke-hooks
-  [{:keys [tx-meta tx-data deleted-block-uuids affected-keys blocks] :as opts}]
+  [{:keys [request-id tx-meta tx-data deleted-block-uuids affected-keys blocks] :as opts}]
   (let [{:keys [from-disk? new-graph? local-tx? undo? redo?]} tx-meta
         repo (state/get-current-repo)
         tx-report {:tx-meta tx-meta
                    :tx-data tx-data}]
 
+    (prn :debug :worker-response :request-id request-id)
+
     (let [conn (db/get-db repo false)
           tx-report (d/transact! conn tx-data tx-meta)]
       (when local-tx?
@@ -120,4 +124,9 @@
                                (= :block/uuid (:a datom))
                                (= (:v datom) deleting-block-id)
                                (true? (:added datom)))) tx-data) ; editing-block was added back (could be undo or from remote sync)
-        (state/set-state! :ui/deleting-block nil)))))
+        (state/set-state! :ui/deleting-block nil)))
+
+    (when-let [deferred (ldb/get-deferred-response request-id)]
+      (p/resolve! deferred {:tx-meta tx-meta
+                            :tx-data tx-data})
+      (swap! ldb/*request-id->response dissoc request-id))))

+ 2 - 1
src/main/frontend/worker/rtc/db_listener.cljs

@@ -183,7 +183,8 @@
                  (when-not pipeline-replace?
                    (let [data (pr-str
                                (merge
-                                {:repo repo
+                                {:request-id (:request-id tx-meta)
+                                 :repo repo
                                  :search-indice search-indice
                                  :tx-data (:tx-data tx-report')
                                  :tx-meta tx-meta}