Browse Source

fix: plugin api calls

Tienson Qin 1 year ago
parent
commit
85f6b3dce7

+ 8 - 0
src/main/frontend/db/async.cljs

@@ -39,6 +39,12 @@
                        [(get ?p :template) ?t]])]
                        [(get ?p :template) ?t]])]
     (into {} result)))
     (into {} result)))
 
 
+(defn <get-template-by-name
+  [name]
+  (let [repo (state/get-current-repo)]
+    (p/let [templates (<get-all-templates repo)]
+      (get templates name))))
+
 (defn <db-based-get-all-properties
 (defn <db-based-get-all-properties
   ":block/type could be one of [property, class]."
   ":block/type could be one of [property, class]."
   [graph]
   [graph]
@@ -112,6 +118,8 @@
                          :or {children? true}}]
                          :or {children? true}}]
   (let [name' (str name-or-uuid)
   (let [name' (str name-or-uuid)
         e (cond
         e (cond
+            (number? name-or-uuid)
+            (db/entity name-or-uuid)
             (util/uuid-string? name')
             (util/uuid-string? name')
             (db/entity [:block/uuid (uuid name')])
             (db/entity [:block/uuid (uuid name')])
             :else
             :else

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

@@ -878,21 +878,6 @@ independent of format as format specific heading characters are stripped"
   [property-uuid]
   [property-uuid]
   (ldb/get-classes-with-property (conn/get-db) property-uuid))
   (ldb/get-classes-with-property (conn/get-db) property-uuid))
 
 
-(defn get-template-by-name
-  [name]
-  (when (string? name)
-    (->> (d/q
-          '[:find [(pull ?b [*]) ...]
-            :in $ ?name
-            :where
-            [?b :block/properties ?p]
-            [(get ?p :template) ?t]
-            [(= ?t ?name)]]
-          (conn/get-db)
-          name)
-         (sort-by :block/name)
-         (first))))
-
 (defn get-all-referenced-blocks-uuid
 (defn get-all-referenced-blocks-uuid
   "Get all uuids of blocks with any back link exists."
   "Get all uuids of blocks with any back link exists."
   []
   []

+ 8 - 2
src/main/frontend/db/react.cljs

@@ -109,7 +109,7 @@
         (apply db-async-util/<q repo [query])))))
         (apply db-async-util/<q repo [query])))))
 
 
 (defn q
 (defn q
-  [repo k {:keys [use-cache? transform-fn query-fn inputs-fn disable-reactive?]
+  [repo k {:keys [use-cache? transform-fn query-fn inputs-fn disable-reactive? return-promise?]
            :or {use-cache? true
            :or {use-cache? true
                 transform-fn identity}} query & inputs]
                 transform-fn identity}} query & inputs]
   ;; {:pre [(s/valid? :frontend.worker.react/block k)]}
   ;; {:pre [(s/valid? :frontend.worker.react/block k)]}
@@ -127,12 +127,18 @@
                 p-or-value (<q-aux repo db query-fn inputs-fn k query inputs)]
                 p-or-value (<q-aux repo db query-fn inputs-fn k query inputs)]
             (when-not disable-reactive?
             (when-not disable-reactive?
               (add-q! k query inputs result-atom transform-fn query-fn inputs-fn))
               (add-q! k query inputs result-atom transform-fn query-fn inputs-fn))
-            (if (p/promise? p-or-value)
+            (cond
+              return-promise?
+              p-or-value
+
+              (p/promise? p-or-value)
               (do
               (do
                 (p/let [result p-or-value
                 (p/let [result p-or-value
                         result' (transform-fn result)]
                         result' (transform-fn result)]
                   (reset! result-atom result'))
                   (reset! result-atom result'))
                 result-atom)
                 result-atom)
+
+              :else
               (let [result' (transform-fn p-or-value)]
               (let [result' (transform-fn p-or-value)]
                 ;; Don't notify watches now
                 ;; Don't notify watches now
                 (set! (.-state result-atom) result')
                 (set! (.-state result-atom) result')

+ 65 - 64
src/main/frontend/handler/editor.cljs

@@ -9,6 +9,7 @@
             [frontend.db :as db]
             [frontend.db :as db]
             [frontend.db.model :as db-model]
             [frontend.db.model :as db-model]
             [frontend.db.utils :as db-utils]
             [frontend.db.utils :as db-utils]
+            [frontend.db.async :as db-async]
             [frontend.db.query-dsl :as query-dsl]
             [frontend.db.query-dsl :as query-dsl]
             [frontend.diff :as diff]
             [frontend.diff :as diff]
             [frontend.format.block :as block]
             [frontend.format.block :as block]
@@ -2150,70 +2151,70 @@
    (let [repo (state/get-current-repo)
    (let [repo (state/get-current-repo)
          db? (config/db-based-graph? repo)]
          db? (config/db-based-graph? repo)]
      (when-not db?
      (when-not db?
-       (when-let [db-id (if (integer? db-id)
-                          db-id
-                          (:db/id (db-model/get-template-by-name (name db-id))))]
-         (let [journal? (:block/journal? target)
-               target (or target (state/get-edit-block))
-               block (db/entity db-id)
-               format (:block/format block)
-               block-uuid (:block/uuid block)
-               template-including-parent? (not (false? (:template-including-parent (:block/properties block))))
-               blocks (db/get-block-and-children repo block-uuid)
-               root-block (db/pull db-id)
-               blocks-exclude-root (remove (fn [b] (= (:db/id b) db-id)) blocks)
-               sorted-blocks (tree/sort-blocks blocks-exclude-root root-block)
-               sorted-blocks (cons
-                              (-> (first sorted-blocks)
-                                  (update :block/properties-text-values dissoc :template)
-                                  (update :block/properties-order (fn [keys]
-                                                                    (vec (remove #{:template} keys)))))
-                              (rest sorted-blocks))
-               blocks (if template-including-parent?
-                        sorted-blocks
-                        (drop 1 sorted-blocks))]
-           (when element-id
-             (insert-command! element-id "" format {:end-pattern commands/command-trigger}))
-           (let [exclude-properties [:id :template :template-including-parent]
-                 content-update-fn (fn [content]
-                                     (->> content
-                                          (property-file/remove-property-when-file-based repo format "template")
-                                          (property-file/remove-property-when-file-based repo format "template-including-parent")
-                                          template/resolve-dynamic-template!))
-                 page (if (:block/name block) block
-                          (when target (:block/page (db/entity (:db/id target)))))
-                 blocks' (map (fn [block]
-                                (paste-block-cleanup repo block page exclude-properties format content-update-fn false))
-                              blocks)
-                 sibling? (:sibling? opts)
-                 sibling?' (cond
-                             (some? sibling?)
-                             sibling?
-
-                             (db/has-children? (:block/uuid target))
-                             false
-
-                             :else
-                             true)]
-             (try
-               (let [*result (atom nil)]
-                 (p/do!
-                  (ui-outliner-tx/transact!
-                   {:outliner-op :insert-blocks
-                    :created-from-journal-template? journal?}
-                   (when-not (string/blank? (state/get-edit-content))
-                     (save-current-block!))
-                   (let [result (outliner-core/insert-blocks! repo (db/get-db false) blocks'
-                                                              target
-                                                              (assoc opts :sibling? sibling?'))]
-                     (reset! *result result)))
-                  (some-> @*result edit-last-block-after-inserted!)))
-
-               (catch :default ^js/Error e
-                 (notification/show!
-                  [:p.content
-                   (util/format "Template insert error: %s" (.-message e))]
-                  :error))))))))))
+       (let [block (if (integer? db-id)
+                     (db-async/<pull repo db-id)
+                     (db-async/<get-template-by-name (name db-id)))]
+         (when-let [db-id (:db/id block)]
+           (let [journal? (:block/journal? target)
+                 target (or target (state/get-edit-block))
+                 format (:block/format block)
+                 block-uuid (:block/uuid block)
+                 template-including-parent? (not (false? (:template-including-parent (:block/properties block))))
+                 blocks (db/get-block-and-children repo block-uuid)
+                 root-block (db/pull db-id)
+                 blocks-exclude-root (remove (fn [b] (= (:db/id b) db-id)) blocks)
+                 sorted-blocks (tree/sort-blocks blocks-exclude-root root-block)
+                 sorted-blocks (cons
+                                (-> (first sorted-blocks)
+                                    (update :block/properties-text-values dissoc :template)
+                                    (update :block/properties-order (fn [keys]
+                                                                      (vec (remove #{:template} keys)))))
+                                (rest sorted-blocks))
+                 blocks (if template-including-parent?
+                          sorted-blocks
+                          (drop 1 sorted-blocks))]
+             (when element-id
+               (insert-command! element-id "" format {:end-pattern commands/command-trigger}))
+             (let [exclude-properties [:id :template :template-including-parent]
+                   content-update-fn (fn [content]
+                                       (->> content
+                                            (property-file/remove-property-when-file-based repo format "template")
+                                            (property-file/remove-property-when-file-based repo format "template-including-parent")
+                                            template/resolve-dynamic-template!))
+                   page (if (:block/name block) block
+                            (when target (:block/page (db/entity (:db/id target)))))
+                   blocks' (map (fn [block]
+                                  (paste-block-cleanup repo block page exclude-properties format content-update-fn false))
+                                blocks)
+                   sibling? (:sibling? opts)
+                   sibling?' (cond
+                               (some? sibling?)
+                               sibling?
+
+                               (db/has-children? (:block/uuid target))
+                               false
+
+                               :else
+                               true)]
+               (try
+                 (let [*result (atom nil)]
+                   (p/do!
+                    (ui-outliner-tx/transact!
+                     {:outliner-op :insert-blocks
+                      :created-from-journal-template? journal?}
+                     (when-not (string/blank? (state/get-edit-content))
+                       (save-current-block!))
+                     (let [result (outliner-core/insert-blocks! repo (db/get-db false) blocks'
+                                                                target
+                                                                (assoc opts :sibling? sibling?'))]
+                       (reset! *result result)))
+                    (some-> @*result edit-last-block-after-inserted!)))
+
+                 (catch :default ^js/Error e
+                   (notification/show!
+                    [:p.content
+                     (util/format "Template insert error: %s" (.-message e))]
+                    :error)))))))))))
 
 
 (defn template-on-chosen-handler
 (defn template-on-chosen-handler
   [element-id]
   [element-id]

+ 148 - 130
src/main/logseq/api.cljs

@@ -616,18 +616,22 @@
         (let [{:keys [pos] :or {pos :max}} (bean/->clj opts)]
         (let [{:keys [pos] :or {pos :max}} (bean/->clj opts)]
           (editor-handler/edit-block! block pos block-uuid))))))
           (editor-handler/edit-block! block pos block-uuid))))))
 
 
+(defn- <ensure-page-loaded
+  [block-uuid-or-page-name]
+  (p/let [repo (state/get-current-repo)
+          result (db-async/<get-block repo (str block-uuid-or-page-name))
+          block (if (:block result) (:block result) result)
+          _ (when-let [page-id (:db/id (:block/page block))]
+              (when-let [page-uuid (:block/uuid (db/entity page-id))]
+                (db-async/<get-block repo page-uuid)))]
+    block))
+
 (def ^:export insert_block
 (def ^:export insert_block
   (fn [block-uuid-or-page-name content ^js opts]
   (fn [block-uuid-or-page-name content ^js opts]
     (when (string/blank? block-uuid-or-page-name)
     (when (string/blank? block-uuid-or-page-name)
       (throw (js/Error. "Page title or block UUID shouldn't be empty.")))
       (throw (js/Error. "Page title or block UUID shouldn't be empty.")))
-    (p/let [repo (state/get-current-repo)
-            block? (util/uuid-string? (str block-uuid-or-page-name))
-            ;; Ensure page or block's page has been loaded
-            result (db-async/<get-block repo block-uuid-or-page-name)
-            block (if (:block result) (:block result) result)
-            _ (when-let [page-id (:db/id (:block/page block))]
-                (when-let [page-uuid (:block/uuid (db/entity page-id))]
-                  (db-async/<get-block repo page-uuid)))]
+    (p/let [block? (util/uuid-string? (str block-uuid-or-page-name))
+            block (<ensure-page-loaded block-uuid-or-page-name)]
       (if (and block? (not block))
       (if (and block? (not block))
         (throw (js/Error. "Block not exists"))
         (throw (js/Error. "Block not exists"))
         (p/let [{:keys [before sibling focus customUUID properties autoOrderedList]} (bean/->clj opts)
         (p/let [{:keys [before sibling focus customUUID properties autoOrderedList]} (bean/->clj opts)
@@ -674,52 +678,60 @@
 
 
 (def ^:export insert_batch_block
 (def ^:export insert_batch_block
   (fn [block-uuid ^js batch-blocks ^js opts]
   (fn [block-uuid ^js batch-blocks ^js opts]
-    (when-let [block (db-model/query-block-by-uuid (sdk-utils/uuid-or-throw-error block-uuid))]
-      (when-let [bb (bean/->clj batch-blocks)]
-        (let [bb (if-not (vector? bb) (vector bb) bb)
-              {:keys [sibling keepUUID before]} (bean/->clj opts)
-              keep-uuid? (or keepUUID false)
-              _ (when keep-uuid? (doseq
-                                  [block (outliner-core/tree-vec-flatten bb :children)]
-                                   (let [uuid (:id (:properties block))]
-                                     (when (and uuid (db-model/query-block-by-uuid (sdk-utils/uuid-or-throw-error uuid)))
-                                       (throw (js/Error.
-                                                (util/format "Custom block UUID already exists (%s)." uuid)))))))
-              block (if (and before sibling)
-                      (db/pull (:db/id (:block/left block))) block)
-              _ (editor-handler/insert-block-tree-after-target
-                  (:db/id block) sibling bb (:block/format block) keep-uuid?)]
-          nil)))))
+    (p/let [block (<ensure-page-loaded block-uuid)]
+      (when block
+        (when-let [bb (bean/->clj batch-blocks)]
+          (let [bb (if-not (vector? bb) (vector bb) bb)
+                {:keys [sibling keepUUID before]} (bean/->clj opts)
+                keep-uuid? (or keepUUID false)
+                _ (when keep-uuid? (doseq
+                                    [block (outliner-core/tree-vec-flatten bb :children)]
+                                     (let [uuid (:id (:properties block))]
+                                       (when (and uuid (db-model/query-block-by-uuid (sdk-utils/uuid-or-throw-error uuid)))
+                                         (throw (js/Error.
+                                                 (util/format "Custom block UUID already exists (%s)." uuid)))))))
+                block (if (and before sibling)
+                        (db/pull (:db/id (:block/left block))) block)
+                _ (editor-handler/insert-block-tree-after-target
+                   (:db/id block) sibling bb (:block/format block) keep-uuid?)]
+            nil))))))
 
 
 (def ^:export remove_block
 (def ^:export remove_block
   (fn [block-uuid ^js _opts]
   (fn [block-uuid ^js _opts]
-    (let [repo            (state/get-current-repo)]
+    (p/let [repo            (state/get-current-repo)
+            _ (<ensure-page-loaded block-uuid)]
       (editor-handler/delete-block-aux!
       (editor-handler/delete-block-aux!
        {:block/uuid (sdk-utils/uuid-or-throw-error block-uuid) :repo repo} true))))
        {:block/uuid (sdk-utils/uuid-or-throw-error block-uuid) :repo repo} true))))
 
 
 (def ^:export update_block
 (def ^:export update_block
   (fn [block-uuid content ^js opts]
   (fn [block-uuid content ^js opts]
-    (let [repo (state/get-current-repo)]
+    (p/let [repo (state/get-current-repo)
+            _ (<ensure-page-loaded block-uuid)]
       (editor-handler/save-block! repo
       (editor-handler/save-block! repo
-        (sdk-utils/uuid-or-throw-error block-uuid) content (bean/->clj opts)))))
+                                  (sdk-utils/uuid-or-throw-error block-uuid) content (bean/->clj opts)))))
 
 
 (def ^:export move_block
 (def ^:export move_block
   (fn [src-block-uuid target-block-uuid ^js opts]
   (fn [src-block-uuid target-block-uuid ^js opts]
-    (let [{:keys [before children]} (bean/->clj opts)
-          move-to      (cond
-                         (boolean before)
-                         :top
-
-                         (boolean children)
-                         :nested
-
-                         :else
-                         nil)
-          src-block    (db-model/query-block-by-uuid (sdk-utils/uuid-or-throw-error src-block-uuid))
-          target-block (db-model/query-block-by-uuid (sdk-utils/uuid-or-throw-error target-block-uuid))]
-      (editor-dnd-handler/move-blocks nil [src-block] target-block nil move-to))))
-
-(def ^:export get_block api-block/get_block)
+    (p/let [_ (<ensure-page-loaded src-block-uuid)
+            _ (<ensure-page-loaded target-block-uuid)]
+      (let [{:keys [before children]} (bean/->clj opts)
+           move-to      (cond
+                          (boolean before)
+                          :top
+
+                          (boolean children)
+                          :nested
+
+                          :else
+                          nil)
+           src-block    (db-model/query-block-by-uuid (sdk-utils/uuid-or-throw-error src-block-uuid))
+           target-block (db-model/query-block-by-uuid (sdk-utils/uuid-or-throw-error target-block-uuid))]
+       (editor-dnd-handler/move-blocks nil [src-block] target-block nil move-to)))))
+
+(def ^:export get_block
+  (fn [id ^js opts]
+    (p/let [_ (db-async/<get-block (state/get-current-repo) id)]
+      (api-block/get_block id opts))))
 
 
 (def ^:export get_current_block
 (def ^:export get_current_block
   (fn [^js opts]
   (fn [^js opts]
@@ -733,21 +745,26 @@
 
 
 (def ^:export get_previous_sibling_block
 (def ^:export get_previous_sibling_block
   (fn [block-uuid]
   (fn [block-uuid]
-    (when-let [block (db-model/query-block-by-uuid (sdk-utils/uuid-or-throw-error block-uuid))]
-      (let [{:block/keys [parent left]} block
-            block (when-not (= parent left) (db-utils/pull (:db/id left)))]
-        (and block (bean/->js (sdk-utils/normalize-keyword-for-json block)))))))
+    (p/let [id (sdk-utils/uuid-or-throw-error block-uuid)
+            _ (<ensure-page-loaded id)]
+      (when-let [block (db-model/query-block-by-uuid (sdk-utils/uuid-or-throw-error block-uuid))]
+       (let [{:block/keys [parent left]} block
+             block (when-not (= parent left) (db-utils/pull (:db/id left)))]
+         (and block (bean/->js (sdk-utils/normalize-keyword-for-json block))))))))
 
 
 (def ^:export get_next_sibling_block
 (def ^:export get_next_sibling_block
   (fn [block-uuid]
   (fn [block-uuid]
-    (when-let [block (db-model/query-block-by-uuid (sdk-utils/uuid-or-throw-error block-uuid))]
-      (when-let [right-sibling (outliner-core/get-right-sibling (db/get-db) (:db/id block))]
-        (let [block (db/pull (:db/id right-sibling))]
-          (bean/->js (sdk-utils/normalize-keyword-for-json block)))))))
+    (p/let [id (sdk-utils/uuid-or-throw-error block-uuid)
+            _ (<ensure-page-loaded id)]
+      (when-let [block (db-model/query-block-by-uuid id)]
+       (when-let [right-sibling (outliner-core/get-right-sibling (db/get-db) (:db/id block))]
+         (let [block (db/pull (:db/id right-sibling))]
+           (bean/->js (sdk-utils/normalize-keyword-for-json block))))))))
 
 
 (def ^:export set_block_collapsed
 (def ^:export set_block_collapsed
   (fn [block-uuid ^js opts]
   (fn [block-uuid ^js opts]
-    (let [block-uuid (sdk-utils/uuid-or-throw-error block-uuid)]
+    (p/let [block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
+            _ (db-async/<get-block (state/get-current-repo) block-uuid :children? false)]
       (when-let [block (db-model/get-block-by-uuid block-uuid)]
       (when-let [block (db-model/get-block-by-uuid block-uuid)]
         (let [opts (bean/->clj opts)
         (let [opts (bean/->clj opts)
               opts (if (or (string? opts) (boolean? opts)) {:flag opts} opts)
               opts (if (or (string? opts) (boolean? opts)) {:flag opts} opts)
@@ -756,34 +773,42 @@
                      (not (util/collapsed? block))
                      (not (util/collapsed? block))
                      (boolean flag))]
                      (boolean flag))]
           (if flag (editor-handler/collapse-block! block-uuid)
           (if flag (editor-handler/collapse-block! block-uuid)
-                   (editor-handler/expand-block! block-uuid))
+              (editor-handler/expand-block! block-uuid))
           nil)))))
           nil)))))
 
 
 (def ^:export upsert_block_property
 (def ^:export upsert_block_property
   (fn [block-uuid key value]
   (fn [block-uuid key value]
-    (property-handler/set-block-property!
-     (state/get-current-repo)
-     (sdk-utils/uuid-or-throw-error block-uuid) key value)))
+    (p/let [block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
+            _ (db-async/<get-block (state/get-current-repo) block-uuid :children? false)]
+      (property-handler/set-block-property!
+       (state/get-current-repo)
+       block-uuid key value))))
 
 
 (def ^:export remove_block_property
 (def ^:export remove_block_property
   (fn [block-uuid key]
   (fn [block-uuid key]
-    (property-handler/remove-block-property!
-     (state/get-current-repo)
-     (sdk-utils/uuid-or-throw-error block-uuid) key)))
+    (p/let [block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
+            _ (db-async/<get-block (state/get-current-repo) block-uuid :children? false)]
+      (property-handler/remove-block-property!
+      (state/get-current-repo)
+      block-uuid key))))
 
 
 (def ^:export get_block_property
 (def ^:export get_block_property
   (fn [block-uuid key]
   (fn [block-uuid key]
-    (when-let [block (db-model/query-block-by-uuid (sdk-utils/uuid-or-throw-error block-uuid))]
-      (let [property-id (pu/get-pid key)]
-        (get (:block/properties block) (if (string? property-id) (keyword property-id) property-id))))))
+    (p/let [block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
+            _ (db-async/<get-block (state/get-current-repo) block-uuid :children? false)]
+      (when-let [block (db-model/query-block-by-uuid block-uuid)]
+        (let [property-id (pu/get-pid key)]
+          (get (:block/properties block) (if (string? property-id) (keyword property-id) property-id)))))))
 
 
 (def ^:export get_block_properties
 (def ^:export get_block_properties
   (fn [block-uuid]
   (fn [block-uuid]
-    (when-let [block (db-model/query-block-by-uuid (sdk-utils/uuid-or-throw-error block-uuid))]
-      (let [properties (if (config/db-based-graph? (state/get-current-repo))
-                         (db-pu/readable-properties (:block/properties block))
-                         (:block/properties block))]
-        (bean/->js (sdk-utils/normalize-keyword-for-json properties))))))
+    (p/let [block-uuid (sdk-utils/uuid-or-throw-error block-uuid)
+            _ (db-async/<get-block (state/get-current-repo) block-uuid :children? false)]
+      (when-let [block (db-model/query-block-by-uuid block-uuid)]
+        (let [properties (if (config/db-based-graph? (state/get-current-repo))
+                           (db-pu/readable-properties (:block/properties block))
+                           (:block/properties block))]
+          (bean/->js (sdk-utils/normalize-keyword-for-json properties)))))))
 
 
 (def ^:export get_current_page_blocks_tree
 (def ^:export get_current_page_blocks_tree
   (fn []
   (fn []
@@ -796,21 +821,25 @@
 
 
 (def ^:export get_page_blocks_tree
 (def ^:export get_page_blocks_tree
   (fn [id-or-page-name]
   (fn [id-or-page-name]
-    (when-let [page-name (:block/name (db-model/get-page id-or-page-name))]
-      (let [blocks (db-model/get-page-blocks-no-cache page-name)
-            blocks (outliner-tree/blocks->vec-tree blocks page-name)
-            blocks (sdk-utils/normalize-keyword-for-json blocks)]
-        (bean/->js blocks)))))
+    (p/let [_ (<ensure-page-loaded id-or-page-name)]
+      (when-let [page-name (:block/name (db-model/get-page id-or-page-name))]
+        (let [blocks (db-model/get-page-blocks-no-cache page-name)
+              blocks (outliner-tree/blocks->vec-tree blocks page-name)
+              blocks (sdk-utils/normalize-keyword-for-json blocks)]
+          (bean/->js blocks))))))
 
 
 (defn ^:export get_page_linked_references
 (defn ^:export get_page_linked_references
   [page-name-or-uuid]
   [page-name-or-uuid]
-  (when-let [page (and page-name-or-uuid (db-model/get-page page-name-or-uuid))]
-    (let [page-name  (:block/name page)
+  (p/let [repo (state/get-current-repo)
+          block (db-async/<get-block repo page-name-or-uuid :children? false)
+          ;; load refs to db
+          _ (when-let [id (:db/id block)] (db-async/<get-block-refs repo id))
+          page-name (:block/name block)
           ref-blocks (if page-name
           ref-blocks (if page-name
                        (db-model/get-page-referenced-blocks-full page-name)
                        (db-model/get-page-referenced-blocks-full page-name)
-                       (db-model/get-block-referenced-blocks (:block/uuid page)))
+                       (db-model/get-block-referenced-blocks (:block/uuid block)))
           ref-blocks (and (seq ref-blocks) (into [] ref-blocks))]
           ref-blocks (and (seq ref-blocks) (into [] ref-blocks))]
-      (bean/->js (sdk-utils/normalize-keyword-for-json ref-blocks)))))
+    (bean/->js (sdk-utils/normalize-keyword-for-json ref-blocks))))
 
 
 (defn ^:export get_pages_from_namespace
 (defn ^:export get_pages_from_namespace
   [ns]
   [ns]
@@ -824,16 +853,6 @@
     (when-let [pages (db-model/get-namespace-hierarchy repo ns)]
     (when-let [pages (db-model/get-namespace-hierarchy repo ns)]
       (bean/->js (sdk-utils/normalize-keyword-for-json pages)))))
       (bean/->js (sdk-utils/normalize-keyword-for-json pages)))))
 
 
-(defn first-child-of-block
-  [block]
-  (when-let [children (:block/_parent block)]
-    (first (db-model/sort-by-left children block))))
-
-(defn second-child-of-block
-  [block]
-  (when-let [children (:block/_parent block)]
-    (second (db-model/sort-by-left children block))))
-
 (defn last-child-of-block
 (defn last-child-of-block
   [block]
   [block]
   (when-let [children (:block/_parent block)]
   (when-let [children (:block/_parent block)]
@@ -841,36 +860,32 @@
 
 
 (defn ^:export prepend_block_in_page
 (defn ^:export prepend_block_in_page
   [uuid-or-page-name content ^js opts]
   [uuid-or-page-name content ^js opts]
-  (p/let [page?           (not (util/uuid-string? uuid-or-page-name))
+  (p/let [_               (<ensure-page-loaded uuid-or-page-name)
+          page?           (not (util/uuid-string? uuid-or-page-name))
           page-not-exist? (and page? (nil? (db-model/get-page uuid-or-page-name)))
           page-not-exist? (and page? (nil? (db-model/get-page uuid-or-page-name)))
           _               (and page-not-exist? (page-handler/<create! uuid-or-page-name
           _               (and page-not-exist? (page-handler/<create! uuid-or-page-name
                                                                       {:redirect?           false
                                                                       {:redirect?           false
-                                                                       :create-first-block? true
+                                                                       :create-first-block? false
                                                                        :format              (state/get-preferred-format)}))]
                                                                        :format              (state/get-preferred-format)}))]
     (when-let [block (db-model/get-page uuid-or-page-name)]
     (when-let [block (db-model/get-page uuid-or-page-name)]
-      (let [block'   (if page? (second-child-of-block block) (first-child-of-block block))
-            sibling? (and page? (not (nil? block')))
-            opts     (bean/->clj opts)
-            opts     (merge opts {:sibling sibling? :before sibling?})
-            src      (if sibling? (str (:block/uuid block')) uuid-or-page-name)]
-        (insert_block src content (bean/->js opts))))))
+      (let [opts     (bean/->clj opts)
+            target   (str (:block/uuid block))]
+        (insert_block target content (bean/->js opts))))))
 
 
 (defn ^:export append_block_in_page
 (defn ^:export append_block_in_page
   [uuid-or-page-name content ^js opts]
   [uuid-or-page-name content ^js opts]
-  (p/let [page?           (not (util/uuid-string? uuid-or-page-name))
+  (p/let [_               (<ensure-page-loaded uuid-or-page-name)
+          page?           (not (util/uuid-string? uuid-or-page-name))
           page-not-exist? (and page? (nil? (db-model/get-page uuid-or-page-name)))
           page-not-exist? (and page? (nil? (db-model/get-page uuid-or-page-name)))
           _               (and page-not-exist? (page-handler/<create! uuid-or-page-name
           _               (and page-not-exist? (page-handler/<create! uuid-or-page-name
                                                                       {:redirect?           false
                                                                       {:redirect?           false
-                                                                       :create-first-block? true
+                                                                       :create-first-block? false
                                                                        :format              (state/get-preferred-format)}))]
                                                                        :format              (state/get-preferred-format)}))]
     (when-let [block (db-model/get-page uuid-or-page-name)]
     (when-let [block (db-model/get-page uuid-or-page-name)]
-      (let [block'   (last-child-of-block block)
-            sibling? (not (nil? block'))
+      (let [block    (or (last-child-of-block block) block)
             opts     (bean/->clj opts)
             opts     (bean/->clj opts)
-            opts     (merge opts {:sibling sibling?}
-                            (when sibling? {:before false}))
-            src      (if sibling? (str (:block/uuid block')) uuid-or-page-name)]
-        (insert_block src content (bean/->js opts))))))
+            target   (str (:block/uuid block))]
+        (insert_block target content (bean/->js opts))))))
 
 
 ;; plugins
 ;; plugins
 (defn ^:export validate_external_plugins [urls]
 (defn ^:export validate_external_plugins [urls]
@@ -887,34 +902,36 @@
 (defn ^:export q
 (defn ^:export q
   [query-string]
   [query-string]
   (when-let [repo (state/get-current-repo)]
   (when-let [repo (state/get-current-repo)]
-    (when-let [result (query-dsl/query repo query-string
-                        {:disable-reactive? true})]
+    (p/let [result (query-dsl/query repo query-string
+                                    {:disable-reactive? true
+                                     :return-promise? true})]
       (bean/->js (sdk-utils/normalize-keyword-for-json (flatten @result))))))
       (bean/->js (sdk-utils/normalize-keyword-for-json (flatten @result))))))
 
 
 (defn ^:export datascript_query
 (defn ^:export datascript_query
   [query & inputs]
   [query & inputs]
   (when-let [repo (state/get-current-repo)]
   (when-let [repo (state/get-current-repo)]
     (when-let [db (db/get-db repo)]
     (when-let [db (db/get-db repo)]
-      (let [query           (cljs.reader/read-string query)
-            resolved-inputs (map #(cond
-                                    (string? %)
-                                    (some->> % (cljs.reader/read-string) (query-react/resolve-input db))
-
-                                    (fn? %)
-                                    (fn [& args]
-                                      (.apply % nil (clj->js (mapv bean/->js args))))
-
-                                    :else %)
-                                 inputs)
-            result          (apply d/q query db resolved-inputs)]
+      (p/let [query           (cljs.reader/read-string query)
+              resolved-inputs (map #(cond
+                                      (string? %)
+                                      (some->> % (cljs.reader/read-string) (query-react/resolve-input db))
+
+                                      (fn? %)
+                                      (fn [& args]
+                                        (.apply % nil (clj->js (mapv bean/->js args))))
+
+                                      :else %)
+                                   inputs)
+              result          (db-async/<q repo (cons query resolved-inputs))]
         (bean/->js (sdk-utils/normalize-keyword-for-json result false))))))
         (bean/->js (sdk-utils/normalize-keyword-for-json result false))))))
 
 
 (defn ^:export custom_query
 (defn ^:export custom_query
   [query-string]
   [query-string]
-  (let [result (let [query (cljs.reader/read-string query-string)]
-                 (db/custom-query {:query query
-                                   :disable-reactive? true}))]
-    (bean/->js (sdk-utils/normalize-keyword-for-json (flatten @result)))))
+  (p/let [result (let [query (cljs.reader/read-string query-string)]
+                   (db/custom-query {:query query
+                                     :disable-reactive? true
+                                     :return-promise? true}))]
+    (bean/->js (sdk-utils/normalize-keyword-for-json (flatten result)))))
 
 
 (defn ^:export download_graph_db
 (defn ^:export download_graph_db
   []
   []
@@ -987,10 +1004,10 @@
 ;; templates
 ;; templates
 (defn ^:export get_template
 (defn ^:export get_template
   [name]
   [name]
-  (some-> name
-          (db-model/get-template-by-name)
-          (sdk-utils/normalize-keyword-for-json)
-          (bean/->js)))
+  (p/let [block (when name (db-async/<get-template-by-name name))]
+    (some-> block
+            (sdk-utils/normalize-keyword-for-json)
+            (bean/->js))))
 
 
 (defn ^:export insert_template
 (defn ^:export insert_template
   [target-uuid template-name]
   [target-uuid template-name]
@@ -1007,20 +1024,21 @@
   [target-uuid template-name ^js opts]
   [target-uuid template-name ^js opts]
   (when (and template-name (db-model/get-block-by-uuid target-uuid))
   (when (and template-name (db-model/get-block-by-uuid target-uuid))
     (p/let [{:keys [overwrite]} (bean/->clj opts)
     (p/let [{:keys [overwrite]} (bean/->clj opts)
-            exist? (page-handler/<template-exists? template-name)
+            block (db-async/<get-template-by-name template-name)
             repo (state/get-current-repo)]
             repo (state/get-current-repo)]
-      (if (or (not exist?) (true? overwrite))
-        (do (when-let [old-target (and exist? (db-model/get-template-by-name template-name))]
+      (if (or (not block) (true? overwrite))
+        (do (when-let [old-target block]
               (property-handler/remove-block-property! repo (:block/uuid old-target) :template))
               (property-handler/remove-block-property! repo (:block/uuid old-target) :template))
             (property-handler/set-block-property! repo target-uuid :template template-name))
             (property-handler/set-block-property! repo target-uuid :template template-name))
         (throw (js/Error. "Template already exists!"))))))
         (throw (js/Error. "Template already exists!"))))))
 
 
 (defn ^:export remove_template
 (defn ^:export remove_template
   [name]
   [name]
-  (when-let [target (db-model/get-template-by-name name)]
-    (property-handler/remove-block-property!
-     (state/get-current-repo)
-     (:block/uuid target) :template)))
+  (p/let [block (when name (db-async/<get-template-by-name name))]
+    (when block
+      (property-handler/remove-block-property!
+       (state/get-current-repo)
+       (:block/uuid block) :template))))
 
 
 ;; search
 ;; search
 (defn ^:export search
 (defn ^:export search