Tienson Qin 2 лет назад
Родитель
Сommit
0ca1bd61eb

+ 159 - 1
deps/db/src/logseq/db.cljs

@@ -11,7 +11,8 @@
             [clojure.string :as string]
             [logseq.graph-parser.util :as gp-util]
             [logseq.graph-parser.config :as gp-config]
-            [logseq.db.frontend.content :as db-content]))
+            [logseq.db.frontend.content :as db-content]
+            [clojure.set :as set]))
 
 ;; Use it as an input argument for datalog queries
 (def block-attrs
@@ -195,3 +196,160 @@
     :in $ ?id
     :where
     [?a :block/parent ?id]])
+
+(defn hidden-page?
+  [page]
+  (when page
+    (if (string? page)
+      (and (string/starts-with? page "$$$")
+           (gp-util/uuid-string? (gp-util/safe-subs page 3)))
+      (contains? (set (:block/type page)) "hidden"))))
+
+(defn get-pages
+  [db]
+  (->> (d/q
+        '[:find ?page-original-name
+          :where
+          [?page :block/name ?page-name]
+          [(get-else $ ?page :block/original-name ?page-name) ?page-original-name]]
+         db)
+       (map first)
+       (remove hidden-page?)))
+
+(defn page-empty?
+  "Whether a page is empty. Does it has a non-page block?
+  `page-id` could be either a string or a db/id."
+  [db page-id]
+  (let [page-id (if (string? page-id)
+                  [:block/name (gp-util/page-name-sanity-lc page-id)]
+                  page-id)
+        page (d/entity db page-id)]
+    (nil? (:block/_left page))))
+
+(defn get-orphaned-pages
+  [db {:keys [pages empty-ref-f]
+       :or {empty-ref-f (fn [page] (zero? (count (:block/_refs page))))}}]
+  (let [pages (->> (or pages (get-pages db))
+                   (remove nil?))
+        built-in-pages (set (map string/lower-case default-db/built-in-pages-names))
+        orphaned-pages (->>
+                        (map
+                         (fn [page]
+                           (let [name (gp-util/page-name-sanity-lc page)]
+                             (when-let [page (d/entity db [:block/name name])]
+                               (and
+                                (empty-ref-f page)
+                                (or
+                                 (page-empty? db (:db/id page))
+                                 (let [first-child (first (:block/_left page))
+                                       children (:block/_page page)]
+                                   (and
+                                    first-child
+                                    (= 1 (count children))
+                                    (contains? #{"" "-" "*"} (string/trim (:block/content first-child))))))
+                                (not (contains? built-in-pages name))
+                                (not (whiteboard-page? db page))
+                                (not (:block/_namespace page))
+                                (not (contains? (:block/type page) "property"))
+                                 ;; a/b/c might be deleted but a/b/c/d still exists (for backward compatibility)
+                                (not (and (string/includes? name "/")
+                                          (not (:block/journal? page))))
+                                page))))
+                         pages)
+                        (remove false?)
+                        (remove nil?)
+                        (remove hidden-page?))]
+    orphaned-pages))
+
+(defn has-children?
+  [db block-id]
+  (some? (:block/_parent (d/entity db [:block/uuid block-id]))))
+
+(defn- collapsed-and-has-children?
+  [db block]
+  (and (:block/collapsed? block) (has-children? db (:block/uuid block))))
+
+(defn get-block-last-direct-child-id
+  "Notice: if `not-collapsed?` is true, will skip searching for any collapsed block."
+  ([db db-id]
+   (get-block-last-direct-child-id db db-id false))
+  ([db db-id not-collapsed?]
+   (when-let [block (d/entity db db-id)]
+     (when (if not-collapsed?
+             (not (collapsed-and-has-children? db block))
+             true)
+       (let [children (:block/_parent block)
+             all-left (set (concat (map (comp :db/id :block/left) children) [db-id]))
+             all-ids (set (map :db/id children))]
+         (first (set/difference all-ids all-left)))))))
+
+(defn get-block-immediate-children
+  "Doesn't include nested children."
+  [db block-uuid]
+  (when-let [parent (d/entity db [:block/uuid block-uuid])]
+    (sort-by-left (:block/_parent parent) parent)))
+
+(defn- get-sorted-page-block-ids
+  [db page-id]
+  (let [root (d/entity db page-id)]
+    (loop [result []
+           children (sort-by-left (:block/_parent root) root)]
+      (if (seq children)
+        (let [child (first children)]
+          (recur (conj result (:db/id child))
+                 (concat
+                  (sort-by-left (:block/_parent child) child)
+                  (rest children))))
+        result))))
+
+(defn sort-page-random-blocks
+  "Blocks could be non consecutive."
+  [db blocks]
+  (assert (every? #(= (:block/page %) (:block/page (first blocks))) blocks) "Blocks must to be in a same page.")
+  (let [page-id (:db/id (:block/page (first blocks)))
+        ;; TODO: there's no need to sort all the blocks
+        sorted-ids (get-sorted-page-block-ids db page-id)
+        blocks-map (zipmap (map :db/id blocks) blocks)]
+    (keep blocks-map sorted-ids)))
+
+(defn get-prev-sibling
+  [db id]
+  (when-let [e (d/entity db id)]
+    (let [left (:block/left e)]
+      (when (not= (:db/id left) (:db/id (:block/parent e)))
+        left))))
+
+(defn last-child-block?
+  "The child block could be collapsed."
+  [db parent-id child-id]
+  (when-let [child (d/entity db child-id)]
+    (cond
+      (= parent-id child-id)
+      true
+
+      (get-right-sibling db child-id)
+      false
+
+      :else
+      (last-child-block? db parent-id (:db/id (:block/parent child))))))
+
+(defn- consecutive-block?
+  [db block-1 block-2]
+  (let [        aux-fn (fn [block-1 block-2]
+                 (and (= (:block/page block-1) (:block/page block-2))
+                      (or
+                       ;; sibling or child
+                       (= (:db/id (:block/left block-2)) (:db/id block-1))
+                       (when-let [prev-sibling (get-prev-sibling db (:db/id block-2))]
+                         (last-child-block? db (:db/id prev-sibling) (:db/id block-1))))))]
+    (or (aux-fn block-1 block-2) (aux-fn block-2 block-1))))
+
+(defn get-non-consecutive-blocks
+  [db blocks]
+  (vec
+   (keep-indexed
+    (fn [i _block]
+      (when (< (inc i) (count blocks))
+        (when-not (consecutive-block? db (nth blocks i) (nth blocks (inc i)))
+          (nth blocks i))))
+    blocks)))

+ 17 - 0
deps/graph-parser/src/logseq/graph_parser/util.cljs

@@ -288,3 +288,20 @@
    (if-let [[ks' & kss] (seq kss)]
      (recur (dissoc-in m ks) ks' kss)
      (dissoc-in m ks))))
+
+(defn safe-re-find
+  {:malli/schema [:=> [:cat :any :string] [:or :nil :string [:vector [:maybe :string]]]]}
+  [pattern s]
+  (when-not (string? s)
+       ;; TODO: sentry
+    (js/console.trace))
+  (when (string? s)
+    (re-find pattern s)))
+
+(def uuid-pattern "[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}")
+(defonce exactly-uuid-pattern (re-pattern (str "(?i)^" uuid-pattern "$")))
+
+(defn uuid-string?
+  {:malli/schema [:=> [:cat :string] :boolean]}
+  [s]
+  (boolean (safe-re-find exactly-uuid-pattern s)))

+ 14 - 149
src/main/frontend/db/model.cljs

@@ -79,24 +79,12 @@
   (->> (get-all-namespace-relation repo)
        (map second)))
 
-(defn hidden-page?
-  [page]
-  (when page
-    (if (string? page)
-      (and (string/starts-with? page "$$$")
-           (util/uuid-string? (gp-util/safe-subs page 3)))
-      (contains? (set (:block/type page)) "hidden"))))
+(def hidden-page? ldb/hidden-page?)
 
 (defn get-pages
   [repo]
-  (->> (d/q
-        '[:find ?page-original-name
-          :where
-          [?page :block/name ?page-name]
-          [(get-else $ ?page :block/original-name ?page-name) ?page-original-name]]
-         (conn/get-db repo))
-       (map first)
-       (remove hidden-page?)))
+  (let [db (conn/get-db repo)]
+    (ldb/get-pages db)))
 
 (defn get-all-pages
   [repo]
@@ -336,13 +324,6 @@ independent of format as format specific heading characters are stripped"
      (set)
      (set/union #{page-id}))))
 
-(defn get-entities-by-ids
-  ([ids]
-   (get-entities-by-ids (state/get-current-repo) ids))
-  ([repo ids]
-   (when repo
-     (db-utils/pull-many repo '[*] ids))))
-
 (defn get-page-names-by-ids
   ([ids]
    (get-page-names-by-ids (state/get-current-repo) ids))
@@ -427,28 +408,11 @@ independent of format as format specific heading characters are stripped"
                      f))
                  form))
 
-(defn get-sorted-page-block-ids
-  [page-id]
-  (let [root (db-utils/entity page-id)]
-    (loop [result []
-           children (sort-by-left (:block/_parent root) root)]
-      (if (seq children)
-        (let [child (first children)]
-          (recur (conj result (:db/id child))
-                 (concat
-                  (sort-by-left (:block/_parent child) child)
-                  (rest children))))
-        result))))
-
 (defn sort-page-random-blocks
   "Blocks could be non consecutive."
   [blocks]
-  (assert (every? #(= (:block/page %) (:block/page (first blocks))) blocks) "Blocks must to be in a same page.")
-  (let [page-id (:db/id (:block/page (first blocks)))
-        ;; TODO: there's no need to sort all the blocks
-        sorted-ids (get-sorted-page-block-ids page-id)
-        blocks-map (zipmap (map :db/id blocks) blocks)]
-    (keep blocks-map sorted-ids)))
+  (let [db (conn/get-db)]
+    (ldb/sort-page-random-blocks db blocks)))
 
 ;; Diverged of get-sorted-page-block-ids
 (defn get-sorted-page-block-ids-and-levels
@@ -482,11 +446,7 @@ independent of format as format specific heading characters are stripped"
   ([block-id]
    (has-children? (conn/get-db) block-id))
   ([db block-id]
-   (some? (:block/_parent (db-utils/entity db [:block/uuid block-id])))))
-
-(defn- collapsed-and-has-children?
-  [db block]
-  (and (:block/collapsed? block) (has-children? db (:block/uuid block))))
+   (ldb/has-children? db block-id)))
 
 (def get-by-parent-&-left ldb/get-by-parent-&-left)
 
@@ -515,19 +475,7 @@ independent of format as format specific heading characters are stripped"
           '[:db/id :block/collapsed? :block/properties {:block/parent ...}]
           [:block/uuid block-id]))
 
-(defn get-block-last-direct-child-id
-  "Notice: if `not-collapsed?` is true, will skip searching for any collapsed block."
-  ([db db-id]
-   (get-block-last-direct-child-id db db-id false))
-  ([db db-id not-collapsed?]
-   (when-let [block (db-utils/entity db db-id)]
-     (when (if not-collapsed?
-             (not (collapsed-and-has-children? db block))
-             true)
-       (let [children (:block/_parent block)
-             all-left (set (concat (map (comp :db/id :block/left) children) [db-id]))
-             all-ids (set (map :db/id children))]
-         (first (set/difference all-ids all-left)))))))
+(def get-block-last-direct-child-id ldb/get-block-last-direct-child-id)
 
 (defn get-block-deep-last-open-child-id
   [db db-id]
@@ -539,12 +487,7 @@ independent of format as format specific heading characters are stripped"
           (recur e)))
       nil)))
 
-(defn get-prev-sibling
-  [db id]
-  (when-let [e (db-utils/entity db id)]
-    (let [left (:block/left e)]
-      (when (not= (:db/id left) (:db/id (:block/parent e)))
-        left))))
+(def get-prev-sibling ldb/get-prev-sibling)
 
 (def get-right-sibling ldb/get-right-sibling)
 
@@ -576,42 +519,9 @@ independent of format as format specific heading characters are stripped"
        (when-not (:block/name parent)
          parent)))))
 
-(defn last-child-block?
-  "The child block could be collapsed."
-  [db parent-id child-id]
-  (when-let [child (db-utils/entity db child-id)]
-    (cond
-      (= parent-id child-id)
-      true
-
-      (get-right-sibling db child-id)
-      false
-
-      :else
-      (last-child-block? db parent-id (:db/id (:block/parent child))))))
-
-(defn- consecutive-block?
-  [block-1 block-2]
-  (let [db (conn/get-db)
-        aux-fn (fn [block-1 block-2]
-                 (and (= (:block/page block-1) (:block/page block-2))
-                      (or
-                       ;; sibling or child
-                       (= (:db/id (:block/left block-2)) (:db/id block-1))
-                       (when-let [prev-sibling (get-prev-sibling db (:db/id block-2))]
-                         (last-child-block? db (:db/id prev-sibling) (:db/id block-1))))))]
-    (or (aux-fn block-1 block-2) (aux-fn block-2 block-1))))
-
 (defn get-non-consecutive-blocks
   [blocks]
-  (vec
-   (keep-indexed
-    (fn [i _block]
-      (when (< (inc i) (count blocks))
-        (when-not (consecutive-block? (nth blocks i)
-                                      (nth blocks (inc i)))
-          (nth blocks i))))
-    blocks)))
+  (ldb/get-non-consecutive-blocks (conn/get-db) blocks))
 
 (defn get-page-blocks-no-cache
   ([page]
@@ -638,20 +548,7 @@ independent of format as format specific heading characters are stripped"
   `page-id` could be either a string or a db/id."
   [repo page-id]
   (when-let [db (conn/get-db repo)]
-    (try
-      (let [page-id (if (string? page-id)
-                      [:block/name (util/safe-page-name-sanity-lc page-id)]
-                      page-id)
-            page (db-utils/entity db page-id)]
-        (nil? (:block/_left page)))
-      (catch :default e
-        (when (string/includes? (ex-message e) "Lookup ref attribute should be marked as :db/unique: [:block/name")
-          ;; old db schema
-          (state/pub-event! [:notification/show
-                             {:content (if (config/db-based-graph? repo)
-                                         "Unexpected error occurred."
-                                         "It seems that the current graph is outdated, please re-index it.")
-                              :status :error}]))))))
+    (ldb/page-empty? db page-id)))
 
 (defn page-empty-or-dummy?
   [repo page-id]
@@ -693,8 +590,7 @@ independent of format as format specific heading characters are stripped"
   "Doesn't include nested children."
   [repo block-uuid]
   (when-let [db (conn/get-db repo)]
-    (when-let [parent (db-utils/entity repo [:block/uuid block-uuid])]
-      (sort-by-left (:block/_parent parent) parent))))
+    (ldb/get-block-immediate-children db block-uuid)))
 
 (defn get-block-children
   "Including nested children."
@@ -1256,40 +1152,9 @@ independent of format as format specific heading characters are stripped"
   (ldb/whiteboard-page? (conn/get-db) page))
 
 (defn get-orphaned-pages
-  [{:keys [repo pages empty-ref-f]
-    :or {repo (state/get-current-repo)
-         empty-ref-f (fn [page] (zero? (count (:block/_refs page))))}}]
-  (let [pages (->> (or pages (get-pages repo))
-                   (remove nil?))
-        built-in-pages (set (map string/lower-case default-db/built-in-pages-names))
-        orphaned-pages (->>
-                        (map
-                         (fn [page]
-                           (let [name (util/page-name-sanity-lc page)]
-                             (when-let [page (db-utils/entity [:block/name name])]
-                               (and
-                                (empty-ref-f page)
-                                (or
-                                 (page-empty? repo (:db/id page))
-                                 (let [first-child (first (:block/_left page))
-                                       children (:block/_page page)]
-                                   (and
-                                    first-child
-                                    (= 1 (count children))
-                                    (contains? #{"" "-" "*"} (string/trim (:block/content first-child))))))
-                                (not (contains? built-in-pages name))
-                                (not (whiteboard-page? page))
-                                (not (:block/_namespace page))
-                                (not (contains? (:block/type page) "property"))
-                                 ;; a/b/c might be deleted but a/b/c/d still exists (for backward compatibility)
-                                (not (and (string/includes? name "/")
-                                          (not (:block/journal? page))))
-                                page))))
-                         pages)
-                        (remove false?)
-                        (remove nil?)
-                        (remove hidden-page?))]
-    orphaned-pages))
+  [opts]
+  (let [db (conn/get-db)]
+    (ldb/get-orphaned-pages db opts)))
 
 ;; FIXME: replace :logseq.macro-name with id
 (defn get-macro-blocks

+ 27 - 26
src/main/frontend/modules/outliner/core.cljs

@@ -19,7 +19,6 @@
             [logseq.db.sqlite.util :as sqlite-util]
 
             [frontend.db :as db]
-            [frontend.db.model :as db-model]
             [frontend.db.conn :as conn]
             [frontend.state :as state]
             [frontend.util :as util]
@@ -67,7 +66,7 @@
   (let [parent-id (:db/id (d/entity db [:block/uuid parent-uuid]))
         left-id (:db/id (d/entity db [:block/uuid left-uuid]))]
     (some->
-     (db-model/get-by-parent-&-left db parent-id left-id)
+     (ldb/get-by-parent-&-left db parent-id left-id)
      :db/id
      d/entity
      block)))
@@ -87,7 +86,7 @@
     (assoc block :block/updated-at updated-at)))
 
 (defn- remove-orphaned-page-refs!
-  [db-id txs-state old-refs new-refs]
+  [db db-id txs-state old-refs new-refs]
   (let [old-refs (remove #(some #{"class" "property"} (:block/type %)) old-refs)]
     (when (not= old-refs new-refs)
       (let [new-refs (set (map (fn [ref]
@@ -95,16 +94,16 @@
                                      (and (:db/id ref)
                                           (:block/name (db/entity (:db/id ref)))))) new-refs))
             old-pages (->> (map :db/id old-refs)
-                           (db-model/get-entities-by-ids)
+                           (d/pull-many db '[*])
                            (remove (fn [e] (contains? new-refs (:block/name e))))
                            (map :block/name)
                            (remove nil?))
             orphaned-pages (when (seq old-pages)
-                             (db-model/get-orphaned-pages {:pages old-pages
-                                                           :empty-ref-f (fn [page]
-                                                                          (let [refs (:block/_refs page)]
-                                                                            (or (zero? (count refs))
-                                                                                (= #{db-id} (set (map :db/id refs))))))}))]
+                             (ldb/get-orphaned-pages db {:pages old-pages
+                                                         :empty-ref-f (fn [page]
+                                                                        (let [refs (:block/_refs page)]
+                                                                          (or (zero? (count refs))
+                                                                              (= #{db-id} (set (map :db/id refs))))))}))]
         (when (seq orphaned-pages)
           (let [tx (mapv (fn [page] [:db/retractEntity (:db/id page)]) orphaned-pages)]
             (swap! txs-state (fn [state] (vec (concat state tx))))))))))
@@ -135,16 +134,16 @@
             (swap! txs-state into txs))))
 
 (defn- remove-orphaned-refs-when-save
-  [txs-state block-entity m]
+  [db txs-state block-entity m]
   (let [remove-self-page #(remove (fn [b]
                                     (= (:db/id b) (:db/id (:block/page block-entity)))) %)
         old-refs (remove-self-page (:block/refs block-entity))
         new-refs (remove-self-page (:block/refs m))]
-    (remove-orphaned-page-refs! (:db/id block-entity) txs-state old-refs new-refs)))
+    (remove-orphaned-page-refs! db (:db/id block-entity) txs-state old-refs new-refs)))
 
 (defn- get-last-child-or-self
   [block]
-  (let [last-child (some-> (db-model/get-block-last-direct-child-id (conn/get-db) (:db/id block) true)
+  (let [last-child (some-> (ldb/get-block-last-direct-child-id (conn/get-db) (:db/id block) true)
                            db/entity)
         target (or last-child block)]
     [target (some? last-child)]))
@@ -351,7 +350,7 @@
         ;; Remove macros as they are replaced by new ones
         (remove-macros-when-save repo txs-state block-entity)
         ;; Remove orphaned refs from block
-        (remove-orphaned-refs-when-save txs-state block-entity m))
+        (remove-orphaned-refs-when-save @conn txs-state block-entity m))
 
       ;; handle others txs
       (let [other-tx (:db/other-tx m)]
@@ -405,13 +404,13 @@
 
   (-get-children [this conn]
     (let [parent-id (otree/-get-id this conn)
-          children (db-model/get-block-immediate-children (state/get-current-repo) parent-id)]
+          children (ldb/get-block-immediate-children @conn parent-id)]
       (map block children))))
 
 (defn get-right-sibling
   [db-id]
   (when db-id
-    (db-model/get-right-sibling (conn/get-db) db-id)))
+    (ldb/get-right-sibling (conn/get-db) db-id)))
 
 (defn- assoc-level-aux
   [tree-vec children-key init-level]
@@ -882,12 +881,13 @@
 (defn- fix-non-consecutive-blocks
   [blocks target-block sibling?]
   (when (> (count blocks) 1)
-    (let [page-blocks (group-by :block/page blocks)
+    (let [db (db/get-db)
+          page-blocks (group-by :block/page blocks)
           near-by? (= (:db/id target-block) (:db/id (:block/left (first blocks))))]
       (->>
        (mapcat (fn [[_page blocks]]
-                 (let [blocks (db-model/sort-page-random-blocks blocks)
-                       non-consecutive-blocks (->> (conj (db-model/get-non-consecutive-blocks blocks) (last blocks))
+                 (let [blocks (ldb/sort-page-random-blocks db blocks)
+                       non-consecutive-blocks (->> (conj (ldb/get-non-consecutive-blocks db blocks) (last blocks))
                                                    (util/distinct-by :db/id))]
                    (when (seq non-consecutive-blocks)
                      (map-indexed (fn [idx block]
@@ -954,7 +954,7 @@
                         (otree/-get-parent-id end-node conn))
             right-node (otree/-get-right end-node conn)]
         (when (otree/satisfied-inode? right-node)
-          (let [non-consecutive? (seq (db-model/get-non-consecutive-blocks blocks))
+          (let [non-consecutive? (seq (ldb/get-non-consecutive-blocks @conn blocks))
                 left-node-id (if sibling?
                                (otree/-get-id (otree/-get-left start-node conn) conn)
                                (let [end-node-left-nodes (get-left-nodes conn end-node (count block-ids))
@@ -1000,10 +1000,11 @@
                         :as opts}]
   [:pre [(seq blocks)
          (s/valid? ::block-map-or-entity target-block)]]
-  (let [blocks (map (fn [b] (db/entity [:block/uuid (:block/uuid b)])) blocks)
+  (let [db (db/get-db)
+        blocks (map (fn [b] (db/entity [:block/uuid (:block/uuid b)])) blocks)
         blocks (get-top-level-blocks blocks)
         [target-block sibling?] (get-target-block blocks target-block opts)
-        non-consecutive-blocks? (seq (db-model/get-non-consecutive-blocks blocks))
+        non-consecutive-blocks? (seq (ldb/get-non-consecutive-blocks db blocks))
         original-position? (move-to-original-position? blocks target-block sibling? non-consecutive-blocks?)]
     (when (and (not (contains? (set (map :db/id blocks)) (:db/id target-block)))
                (not original-position?))
@@ -1102,13 +1103,13 @@
   "Indent or outdent `blocks`."
   [blocks indent?]
   {:pre [(seq blocks) (boolean? indent?)]}
-  (let [top-level-blocks (get-top-level-blocks blocks)
-        non-consecutive-blocks (db-model/get-non-consecutive-blocks top-level-blocks)]
+  (let [db (db/get-db)
+        top-level-blocks (get-top-level-blocks blocks)
+        non-consecutive-blocks (ldb/get-non-consecutive-blocks db top-level-blocks)]
     (when (empty? non-consecutive-blocks)
       (let [first-block (db/entity (:db/id (first top-level-blocks)))
             left (db/entity (:db/id (:block/left first-block)))
             parent (:block/parent first-block)
-            db (db/get-db)
             concat-tx-fn (fn [& results]
                            {:tx-data (->> (map :tx-data results)
                                           (apply util/concat-without-nil))
@@ -1116,7 +1117,7 @@
             opts {:outliner-op :indent-outdent-blocks}]
         (if indent?
           (when (and left (not (page-first-child? first-block)))
-            (let [last-direct-child-id (db-model/get-block-last-direct-child-id db (:db/id left))
+            (let [last-direct-child-id (ldb/get-block-last-direct-child-id db (:db/id left))
                   blocks' (drop-while (fn [b]
                                         (= (:db/id (:block/parent b))
                                            (:db/id left)))
@@ -1155,7 +1156,7 @@
                         right-siblings (->> (get-right-siblings (block last-top-block))
                                             (map :data))]
                     (if (seq right-siblings)
-                      (let [result2 (if-let [last-direct-child-id (db-model/get-block-last-direct-child-id db (:db/id last-top-block))]
+                      (let [result2 (if-let [last-direct-child-id (ldb/get-block-last-direct-child-id db (:db/id last-top-block))]
                                       (move-blocks right-siblings (db/entity last-direct-child-id) (merge opts {:sibling? true}))
                                       (move-blocks right-siblings last-top-block (merge opts {:sibling? false})))]
                         (concat-tx-fn result result2))

+ 3 - 16
src/main/frontend/worker/util.cljs

@@ -33,22 +33,9 @@
            (removeAccents normalize-str)
            normalize-str))))
 
-(defn safe-re-find
-  {:malli/schema [:=> [:cat :any :string] [:or :nil :string [:vector [:maybe :string]]]]}
-  [pattern s]
-  (when-not (string? s)
-       ;; TODO: sentry
-    (js/console.trace))
-  (when (string? s)
-    (re-find pattern s)))
-
-(def uuid-pattern "[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}")
-(defonce exactly-uuid-pattern (re-pattern (str "(?i)^" uuid-pattern "$")))
-
-(defn uuid-string?
-  {:malli/schema [:=> [:cat :string] :boolean]}
-  [s]
-  (boolean (safe-re-find exactly-uuid-pattern s)))
+(def safe-re-find gp-util/safe-re-find)
+
+(def uuid-string? gp-util/uuid-string?)
 
 (def page-name-sanity-lc
   "Delegate to gp-util to loosely couple app usages to graph-parser"