Sfoglia il codice sorgente

wip: outliner refactor

Tienson Qin 2 anni fa
parent
commit
48b5593008

+ 12 - 0
deps/db/src/logseq/db.cljs

@@ -183,3 +183,15 @@
     (get-by-parent-&-left db
                           (:db/id (:block/parent block))
                           db-id)))
+
+(defn get-by-id
+  [conn id]
+  (try
+    (d/pull @conn '[*] id)
+    (catch :default _e nil)))
+
+(def get-by-parent-id
+  '[:find (pull ?a [*])
+    :in $ ?id
+    :where
+    [?a :block/parent ?id]])

+ 7 - 0
deps/db/src/logseq/db/frontend/property.cljs

@@ -125,6 +125,13 @@
       (when-let [properties (:block/properties block)]
         (lookup repo db properties key)))))
 
+(defn get-pid
+  "Get a property's id (name or uuid) given its name. For file and db graphs"
+  [repo db property-name]
+  (if (sqlite-util/db-based-graph? repo)
+    (:block/uuid (d/entity db [:block/name (gp-util/page-name-sanity-lc (name property-name))]))
+    property-name))
+
 (defn shape-block?
   [repo db block]
   (= :whiteboard-shape (get-property repo db block :ls-type)))

+ 11 - 11
deps/outliner/src/logseq/outliner/tree.cljs

@@ -5,17 +5,17 @@
             [datascript.core :as d]))
 
 (defprotocol INode
-  (-get-id [this])
-  (-get-parent-id [this])
-  (-get-left-id [this])
-  (-set-left-id [this left-id])
-  (-get-parent [this])
-  (-get-left [this])
-  (-get-right [this])
-  (-get-down [this])
-  (-save [this db])
-  (-del [this db children?])
-  (-get-children [this]))
+  (-get-id [this conn])
+  (-get-parent-id [this conn])
+  (-get-left-id [this conn])
+  (-set-left-id [this left-id conn])
+  (-get-parent [this conn])
+  (-get-left [this conn])
+  (-get-right [this conn])
+  (-get-down [this conn])
+  (-save [this db conn repo])
+  (-del [this db children? conn])
+  (-get-children [this conn]))
 
 (defn satisfied-inode?
   [node]

+ 2 - 2
src/main/frontend/components/block.css

@@ -366,7 +366,7 @@
 
 .ls-block {
   position: relative;
-  min-height: 24px;
+  min-height: 30px;
   padding: 2px 0;
   border-bottom: 1px solid transparent;
   transition: background-color 0.3s cubic-bezier(0.16, 1, 0.3, 1);
@@ -756,4 +756,4 @@ html.is-mac {
   &-item {
     @apply bg-gray-03 rounded p-4;
   }
-}
+}

+ 6 - 14
src/main/frontend/format/block.cljs

@@ -10,13 +10,12 @@
             [frontend.state :as state]
             [logseq.graph-parser.block :as gp-block]
             [logseq.graph-parser.property :as gp-property]
-            [logseq.graph-parser.mldoc :as gp-mldoc]
             [frontend.handler.db-based.property.util :as db-pu]
             [lambdaisland.glogi :as log]
-            [frontend.util :as util]
             [datascript.core :as d]
             [logseq.db.frontend.property :as db-property]
-            [frontend.format.mldoc :as mldoc]))
+            [frontend.format.mldoc :as mldoc]
+            [frontend.worker.mldoc :as worker-mldoc]))
 
 (defn- update-extracted-block-properties
   "Updates DB graph blocks to ensure that built-in properties are using uuids
@@ -74,17 +73,10 @@ and handles unexpected failure."
 
 (defn extract-refs-from-text
   [text]
-  (when (string? text)
-    (let [ast-refs (gp-mldoc/get-references text (mldoc/get-default-config :markdown))
-          page-refs (map #(gp-block/get-page-reference % :markdown) ast-refs)
-          block-refs (map #(gp-block/get-block-reference %) ast-refs)
-          refs' (->> (concat page-refs block-refs)
-                     (remove string/blank?)
-                     distinct)]
-      (-> (map #(if (util/uuid-string? %)
-                  {:block/uuid (uuid %)}
-                  (page-name->map % true)) refs')
-          set))))
+  (worker-mldoc/extract-refs-from-text (state/get-current-repo)
+                                       (db/get-db (state/get-current-repo))
+                                       text
+                                       (state/get-date-formatter)))
 
 (defn- normalize-as-percentage
   [block]

+ 0 - 38
src/main/frontend/format/mldoc.cljs

@@ -92,44 +92,6 @@
      ast)
     @*result))
 
-(defn extract-plain
-  "Extract plain elements including page refs"
-  [content]
-  (let [ast (->edn content :markdown)
-        *result (atom [])]
-    (walk/prewalk
-     (fn [f]
-       (cond
-           ;; tag
-         (and (vector? f)
-              (= "Tag" (first f)))
-         nil
-
-           ;; nested page ref
-         (and (vector? f)
-              (= "Nested_link" (first f)))
-         (swap! *result conj (:content (second f)))
-
-           ;; page ref
-         (and (vector? f)
-              (= "Link" (first f))
-              (map? (second f))
-              (vector? (:url (second f)))
-              (= "Page_ref" (first (:url (second f)))))
-         (swap! *result conj
-                (:full_text (second f)))
-
-           ;; plain
-         (and (vector? f)
-              (= "Plain" (first f)))
-         (swap! *result conj (second f))
-
-         :else
-         f))
-     ast)
-    (-> (string/trim (apply str @*result))
-        text/page-ref-un-brackets!)))
-
 (defn extract-tags
   "Extract tags from content"
   [content]

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

@@ -71,7 +71,7 @@
           from-id (:db/id from-page)
           from-first-child (some->> (db/pull from-id)
                                     (outliner-core/block)
-                                    (otree/-get-down)
+                                    (otree/-get-down (db/get-db false))
                                     (outliner-core/get-data))
           to-last-direct-child-id (model/get-block-last-direct-child-id (db/get-db) to-id)
           repo (state/get-current-repo)

+ 11 - 5
src/main/frontend/handler/db_based/property.cljs

@@ -67,6 +67,12 @@
     (catch :default _e
       :default)))
 
+(defn- rebuild-block-refs
+  [repo block new-properties & opts]
+  (let [db (db/get-db repo)
+        date-formatter (state/get-date-formatter)]
+    (outliner-core/rebuild-block-refs repo db date-formatter block new-properties opts)))
+
 (defn convert-property-input-string
   [schema-type v-str]
   (if (and (not (string? v-str)) (not (object? v-str)))
@@ -155,7 +161,7 @@
                 (upsert-property! repo k-name (assoc property-schema :type property-type)
                                   {:property-uuid property-uuid})
                 (let [block-properties (assoc properties property-uuid values')
-                      refs (outliner-core/rebuild-block-refs repo block block-properties)]
+                      refs (rebuild-block-refs repo block block-properties)]
                   (db/transact! repo
                                 [[:db/retract (:db/id block) :block/refs]
                                  {:block/uuid (:block/uuid block)
@@ -250,7 +256,7 @@
                                         (set (remove string/blank? new-value)))
                                       new-value)
                           block-properties (assoc properties property-uuid new-value)
-                          refs (outliner-core/rebuild-block-refs repo
+                          refs (rebuild-block-refs repo
                                                                  block
                                                                  block-properties)]
                       (db/transact! repo
@@ -377,7 +383,7 @@
                                 nil))
                          properties (:block/properties block)
                          block-properties (assoc properties property-uuid v*)
-                         refs (outliner-core/rebuild-block-refs repo block block-properties)]
+                         refs (rebuild-block-refs repo block block-properties)]
                      [[:db/retract (:db/id block) :block/refs]
                       {:block/uuid (:block/uuid block)
                        :block/properties block-properties
@@ -397,7 +403,7 @@
                    (let [origin-properties (:block/properties block)]
                      (when (contains? (set (keys origin-properties)) property-uuid)
                        (let [properties' (dissoc origin-properties property-uuid)
-                             refs (outliner-core/rebuild-block-refs repo block properties')
+                             refs (rebuild-block-refs repo block properties')
                              property (db/entity [:block/uuid property-uuid])
                              value (get origin-properties property-uuid)
                              block-value? (and (= :default (get-in property [:block/schema :type] :default))
@@ -464,7 +470,7 @@
                     properties' (update properties property-id
                                         (fn [col]
                                           (set (remove #{property-value} col))))
-                    refs (outliner-core/rebuild-block-refs repo block properties')]
+                    refs (rebuild-block-refs repo block properties')]
                 (db/transact! repo
                               [[:db/retract (:db/id block) :block/refs]
                                {:block/uuid (:block/uuid block)

+ 6 - 5
src/main/frontend/handler/dnd.cljs

@@ -39,18 +39,19 @@
                           :clear? true}])
 
       (every? map? (conj blocks' target-block))
-      (let [target-node (outliner-core/block target-block)]
+      (let [target-node (outliner-core/block target-block)
+            conn (db/get-db false)]
         (ui-outliner-tx/transact!
          {:outliner-op :move-blocks}
          (editor-handler/save-current-block!)
          (if top?
            (let [first-child?
-                 (= (otree/-get-parent-id target-node)
-                    (otree/-get-left-id target-node))]
+                 (= (otree/-get-parent-id target-node conn)
+                    (otree/-get-left-id target-node conn))]
              (if first-child?
-               (when-let [parent (otree/-get-parent target-node)]
+               (when-let [parent (otree/-get-parent target-node conn)]
                  (outliner-core/move-blocks! blocks' (:data parent) false))
-               (when-let [before-node (otree/-get-left target-node)]
+               (when-let [before-node (otree/-get-left target-node conn)]
                  (outliner-core/move-blocks! blocks' (:data before-node) true))))
            (outliner-core/move-blocks! blocks' target-block (not nested?)))))
 

+ 4 - 4
src/main/frontend/handler/editor.cljs

@@ -771,7 +771,7 @@
             :else
             (let [has-children? (seq (:block/_parent block-e))
                   block (db/pull (:db/id block-e))
-                  left (otree/-get-left (outliner-core/block block))
+                  left (otree/-get-left (outliner-core/block block) (db/get-db false))
                   left-has-children? (and left
                                           (when-let [block-id (:block/uuid (:data left))]
                                             (let [block (db/entity [:block/uuid block-id])]
@@ -2256,7 +2256,7 @@
 (defn outdent-on-enter
   [node]
   (let [original-block (outliner-core/get-current-editing-original-block)
-        parent-node (otree/-get-parent node)
+        parent-node (otree/-get-parent node (db/get-db false))
         target (or original-block (:data parent-node))
         pos (state/get-edit-pos)
         block (:data node)]
@@ -2275,7 +2275,7 @@
     (when-let [entity (if-let [id' (parse-uuid (str id))]
                         (db/entity [:block/uuid id'])
                         (db/entity [:block/name (util/page-name-sanity-lc id)]))]
-      (= (:block/uuid entity) (otree/-get-parent-id current-node)))))
+      (= (:block/uuid entity) (otree/-get-parent-id current-node (db/get-db false))))))
 
 (defn insert
   ([insertion]
@@ -2472,7 +2472,7 @@
               content (gobj/get input "value")
               pos (cursor/pos input)
               current-node (outliner-core/block block)
-              has-right? (-> (otree/-get-right current-node)
+              has-right? (-> (otree/-get-right current-node (db/get-db false))
                              (tree/satisfied-inode?))
               db-based? (config/db-based-graph? (state/get-current-repo))
               thing-at-point ;intern is not supported in cljs, need a more elegant solution

+ 2 - 2
src/main/frontend/handler/file_based/page.cljs

@@ -196,7 +196,7 @@
       (let [old-original-name   (:block/original-name page)
             file                (:block/file page)
             journal?            (:block/journal? page)
-            properties-block    (:data (otree/-get-down (outliner-core/block page)))
+            properties-block    (:data (otree/-get-down (outliner-core/block page) (db/get-db false)))
             properties-content  (:block/content properties-block)
             properties-block-tx (when (and properties-block
                                            properties-content
@@ -312,7 +312,7 @@
           from-id (:db/id from-page)
           from-first-child (some->> (db/pull from-id)
                                     (outliner-core/block)
-                                    (otree/-get-down)
+                                    (otree/-get-down (db/get-db false))
                                     (outliner-core/get-data))
           to-last-direct-child-id (model/get-block-last-direct-child-id (db/get-db) to-id)
           repo (state/get-current-repo)

+ 3 - 4
src/main/frontend/handler/property/util.cljs

@@ -33,10 +33,9 @@
 (defn get-pid
   "Get a property's id (name or uuid) given its name. For file and db graphs"
   [property-name]
-  (let [repo (state/get-current-repo)]
-    (if (config/db-based-graph? repo)
-      (:block/uuid (db/entity [:block/name (util/page-name-sanity-lc (name property-name))]))
-      property-name)))
+  (let [repo (state/get-current-repo)
+        db (db/get-db repo)]
+    (db-property/get-pid repo db property-name)))
 
 (defn block->shape [block]
   (get-property block :logseq.tldraw.shape))

+ 154 - 131
src/main/frontend/modules/outliner/core.cljs

@@ -2,26 +2,28 @@
   (:require [clojure.set :as set]
             [clojure.string :as string]
             [datascript.impl.entity :as de]
-            [frontend.db :as db]
-            [frontend.db.model :as db-model]
+            [datascript.core :as d]
             [logseq.db.frontend.schema :as db-schema]
-            [frontend.db.conn :as conn]
-            [frontend.db.outliner :as db-outliner]
             [frontend.modules.outliner.datascript :as ds]
             [logseq.outliner.tree :as otree]
             [frontend.modules.outliner.utils :as outliner-u]
-            [frontend.state :as state]
-            [frontend.util :as util]
-            [frontend.config :as config]
             [logseq.graph-parser.util :as gp-util]
             [cljs.spec.alpha :as s]
-            [frontend.format.block :as block]
-            [frontend.handler.file-based.property.util :as property-util]
-            [frontend.handler.property.util :as pu]
-            [frontend.format.mldoc :as mldoc]
-            [dommy.core :as dom]
             [goog.object :as gobj]
-            [logseq.outliner.pipeline :as outliner-pipeline]))
+            [logseq.outliner.pipeline :as outliner-pipeline]
+            [logseq.db :as ldb]
+            [frontend.worker.mldoc :as mldoc]
+            [logseq.graph-parser.block :as gp-block]
+            [frontend.worker.file.property-util :as wpu]
+            [logseq.db.frontend.property :as db-property]
+            [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]
+            [dommy.core :as dom]))
 
 (s/def ::block-map (s/keys :opt [:db/id :block/uuid :block/page :block/left :block/parent]))
 
@@ -33,32 +35,41 @@
 (defn block
   [m]
   (assert (or (map? m) (de/entity? m)) (util/format "block data must be map or entity, got: %s %s" (type m) m))
-  (if (de/entity? m)
-    (->Block {:db/id (:db/id m)
-              :block/uuid (:block/uuid m)
-              :block/page (:block/page m)
-              :block/left (:block/left m)
-              :block/parent (:block/parent m)})
-    (->Block m)))
+  (let [e (if (de/entity? m)
+            m
+            (let [eid (if (:block/uuid m)
+                        [:block/uuid (:block/uuid m)]
+                        (:db/id m))]
+              (assert eid "eid doesn't exist")
+              (db/entity eid)))
+        e-map {:db/id (:db/id e)
+               :block/uuid (:block/uuid e)
+               :block/page {:db/id (:db/id (:block/page e))
+                            :block/uuid (:block/uuid (:block/page e))}
+               :block/left {:db/id (:db/id (:block/left e))
+                            :block/uuid (:block/uuid (:block/left e))}
+               :block/parent {:db/id (:db/id (:block/parent e))
+                              :block/uuid (:block/uuid (:block/parent e))}}
+        data (merge e-map m)]
+    (->Block data)))
 
 (defn get-data
   [block]
   (:data block))
 
 (defn get-block-by-id
-  [id]
-  (let [c (conn/get-db false)
-        r (db-outliner/get-by-id c (outliner-u/->block-lookup-ref id))]
+  [db id]
+  (let [r (ldb/get-by-id db (outliner-u/->block-lookup-ref id))]
     (when r (->Block r))))
 
 (defn- get-by-parent-&-left
-  [parent-uuid left-uuid]
-  (let [parent-id (:db/id (db/entity [:block/uuid parent-uuid]))
-        left-id (:db/id (db/entity [:block/uuid left-uuid]))]
+  [db parent-uuid left-uuid]
+  (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 (conn/get-db) parent-id left-id)
+     (db-model/get-by-parent-&-left db parent-id left-id)
      :db/id
-     db/pull
+     d/entity
      block)))
 
 (defn- block-with-timestamps
@@ -151,10 +162,10 @@
                                         (:block/macros block-entity)))))))
 
 (defn- create-linked-page-when-save
-  [txs-state block-entity m tags-has-class?]
+  [conn db date-formatter txs-state block-entity m tags-has-class?]
   (if tags-has-class?
     (let [content (state/get-edit-content)
-          linked-page (some-> content mldoc/extract-plain)
+          linked-page (some-> content #(mldoc/extract-plain (state/get-current-repo) %))
           sanity-linked-page (some-> linked-page util/page-name-sanity-lc)
           linking-page? (and (not (string/blank? sanity-linked-page))
                              @(:editor/create-page? @state/state))]
@@ -163,11 +174,12 @@
                                       (when (= sanity-linked-page (:block/name r))
                                         (:block/uuid r)))
                                     (:block/refs m))
-              page-m (block/page-name->map linked-page (or existing-ref-id true))
-              _ (when-not (db/entity [:block/uuid (:block/uuid page-m)])
-                  (db/transact! [page-m]))
+              page-m (gp-block/page-name->map linked-page (or existing-ref-id true)
+                                              db true date-formatter)
+              _ (when-not (d/entity db [:block/uuid (:block/uuid page-m)])
+                  (d/transact! conn [page-m]))
               merge-tx (let [children (:block/_parent block-entity)
-                             page (db/entity [:block/uuid (:block/uuid page-m)])
+                             page (d/entity db [:block/uuid (:block/uuid page-m)])
                              [target sibling?] (get-last-child-or-self page)]
                          (when (seq children)
                            (:tx-data
@@ -187,7 +199,7 @@
     (reset! (:editor/create-page? @state/state) false)))
 
 (defn rebuild-block-refs
-  [repo block new-properties & {:keys [skip-content-parsing?]}]
+  [repo conn db date-formatter block new-properties & {:keys [skip-content-parsing?]}]
   (let [property-key-refs (keys new-properties)
         property-value-refs (->> (vals new-properties)
                                  (mapcat (fn [v]
@@ -196,7 +208,7 @@
                                              v
 
                                              (uuid? v)
-                                             (when-let [entity (db/entity repo [:block/uuid v])]
+                                             (when-let [entity (d/entity conn [:block/uuid v])]
                                                (let [from-property? (get-in entity [:block/metadata :created-from-property])]
                                                  (if (and from-property? (not (contains? (:block/type entity) "closed value")))
                                                    ;; don't reference hidden block property values except closed values
@@ -204,24 +216,25 @@
                                                    [v])))
 
                                              (and (coll? v) (string? (first v)))
-                                             (mapcat block/extract-refs-from-text v)
+                                             (mapcat #(mldoc/extract-refs-from-text repo db % date-formatter) v)
 
                                              (string? v)
-                                             (block/extract-refs-from-text v)
+                                             (mldoc/extract-refs-from-text repo db v date-formatter)
 
                                              :else
                                              nil))))
         property-refs (->> (concat property-key-refs property-value-refs)
                            (map (fn [id-or-map] (if (uuid? id-or-map) {:block/uuid id-or-map} id-or-map)))
-                           (remove (fn [b] (nil? (db/entity [:block/uuid (:block/uuid b)])))))
+                           (remove (fn [b] (nil? (d/entity db [:block/uuid (:block/uuid b)])))))
         content-refs (when-not skip-content-parsing?
-                       (some-> (:block/content block) block/extract-refs-from-text))]
+                       (when-let [content (:block/content block)]
+                         (mldoc/extract-refs-from-text repo db content date-formatter)))]
     (concat property-refs content-refs)))
 
 (defn- rebuild-refs
-  [repo txs-state block m]
-  (when (config/db-based-graph? repo)
-    (let [refs (->> (rebuild-block-refs repo block (:block/properties block)
+  [repo conn db date-formatter txs-state block m]
+  (when (sqlite-util/db-based-graph? repo)
+    (let [refs (->> (rebuild-block-refs repo conn db date-formatter block (:block/properties block)
                                         :skip-content-parsing? true)
                     (concat (:block/refs m))
                     (concat (:block/tags m)))]
@@ -250,49 +263,49 @@
 
 (extend-type Block
   otree/INode
-  (-get-id [this]
+  (-get-id [this conn]
     (or
      (when-let [block-id (get-in this [:data :block/uuid])]
        block-id)
-     (when-let [db-id (get-in this [:data :db/id])]
-       (let [uuid (:block/uuid (db/pull db-id))]
+     (when-let [data (:data this)]
+       (let [uuid (:block/uuid data)]
          (if uuid
            uuid
            (let [new-id (db/new-block-id)]
-             (db/transact! [{:db/id db-id
-                             :block/uuid new-id}])
+             (d/transact! conn [{:db/id (:db/id data)
+                                 :block/uuid new-id}])
              new-id))))))
 
-  (-get-parent-id [this]
+  (-get-parent-id [this _conn]
     (-> (get-in this [:data :block/parent])
-        (outliner-u/->block-id)))
+        :block/uuid))
 
-  (-get-left-id [this]
+  (-get-left-id [this _conn]
     (-> (get-in this [:data :block/left])
-        (outliner-u/->block-id)))
+        :block/uuid))
 
-  (-set-left-id [this left-id]
+  (-set-left-id [this left-id _conn]
     (outliner-u/check-block-id left-id)
     (update this :data assoc :block/left [:block/uuid left-id]))
 
-  (-get-parent [this]
-    (when-let [parent-id (otree/-get-parent-id this)]
-      (get-block-by-id parent-id)))
+  (-get-parent [this conn]
+    (when-let [parent-id (otree/-get-parent-id this conn)]
+      (get-block-by-id @conn parent-id)))
 
-  (-get-left [this]
-    (let [left-id (otree/-get-left-id this)]
-      (get-block-by-id left-id)))
+  (-get-left [this conn]
+    (let [left-id (otree/-get-left-id this conn)]
+      (get-block-by-id @conn left-id)))
 
-  (-get-right [this]
-    (let [left-id (otree/-get-id this)
-          parent-id (otree/-get-parent-id this)]
-      (get-by-parent-&-left parent-id left-id)))
+  (-get-right [this conn]
+    (let [left-id (otree/-get-id this conn)
+          parent-id (otree/-get-parent-id this conn)]
+      (get-by-parent-&-left @conn parent-id left-id)))
 
-  (-get-down [this]
-    (let [parent-id (otree/-get-id this)]
-      (get-by-parent-&-left parent-id parent-id)))
+  (-get-down [this conn]
+    (let [parent-id (otree/-get-id this conn)]
+      (get-by-parent-&-left @conn parent-id parent-id)))
 
-  (-save [this txs-state]
+  (-save [this txs-state conn repo]
     (assert (ds/outliner-txs-state? txs-state)
             "db should be satisfied outliner-tx-state?")
     (let [m (-> (:data this)
@@ -301,25 +314,23 @@
                 gp-util/remove-nils
                 block-with-updated-at
                 fix-tag-ids)
-          repo (state/get-current-repo)
-          db-based? (config/db-based-graph? repo)
+          db @conn
+          date-formatter (state/get-date-formatter)
+          db-based? (sqlite-util/db-based-graph? repo)
           db-id (:db/id (:data this))
           block-uuid (:block/uuid (:data this))
           eid (or db-id (when block-uuid [:block/uuid block-uuid]))
-          block-entity (db/entity eid)
+          block-entity (d/entity db eid)
           tags-has-class? (and db-based?
                                (some (fn [tag]
-                                       (contains? (:block/type (db/entity [:block/uuid (:block/uuid tag)])) "class"))
+                                       (contains? (:block/type (d/entity db [:block/uuid (:block/uuid tag)])) "class"))
                                      (:block/tags m)))]
 
       ;; Ensure block UUID never changes
       (when (and db-id block-uuid)
-        (let [uuid-not-changed? (= block-uuid (:block/uuid (db/entity db-id)))]
+        (let [uuid-not-changed? (= block-uuid (:block/uuid (d/entity db db-id)))]
           (when-not uuid-not-changed?
-            (when config/dev?
-              (state/pub-event! [:notification/show
-                                {:content "Block UUID shouldn't be changed"
-                                 :status :error}])))
+            (js/console.error "Block UUID shouldn't be changed once created"))
           (assert uuid-not-changed? "Block UUID changed")))
 
       (when eid
@@ -350,16 +361,16 @@
         (swap! txs-state conj
                (dissoc m :db/other-tx)))
 
-      (create-linked-page-when-save txs-state block-entity m tags-has-class?)
+      (create-linked-page-when-save conn db (state/get-date-formatter) txs-state block-entity m tags-has-class?)
 
-      (rebuild-refs repo txs-state block-entity m)
+      (rebuild-refs repo conn db date-formatter txs-state block-entity m)
 
       this))
 
-  (-del [this txs-state children?]
+  (-del [this txs-state children? conn]
     (assert (ds/outliner-txs-state? txs-state)
             "db should be satisfied outliner-tx-state?")
-    (let [block-id (otree/-get-id this)
+    (let [block-id (otree/-get-id this conn)
           ids (set (if children?
                      (let [children (db/get-block-children (state/get-current-repo) block-id)
                            children-ids (map :block/uuid children)]
@@ -369,7 +380,7 @@
           txs (if-not children?
                 (let [immediate-children (db/get-block-immediate-children (state/get-current-repo) block-id)]
                   (if (seq immediate-children)
-                    (let [left-id (otree/-get-id (otree/-get-left this))]
+                    (let [left-id (otree/-get-id (otree/-get-left this conn) conn)]
                       (concat txs
                               (map-indexed (fn [idx child]
                                              (let [parent [:block/uuid left-id]]
@@ -381,7 +392,7 @@
                                            immediate-children)))
                     txs))
                 txs)
-          page-tx (let [block (db/entity [:block/uuid block-id])]
+          page-tx (let [block (d/entity @conn [:block/uuid block-id])]
                     (when (:block/pre-block? block)
                       (let [id (:db/id (:block/page block))]
                         [[:db/retract id :block/properties]
@@ -392,8 +403,8 @@
       (swap! txs-state concat txs page-tx)
       block-id))
 
-  (-get-children [this]
-    (let [parent-id (otree/-get-id this)
+  (-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)]
       (map block children))))
 
@@ -495,16 +506,16 @@
         (get-new-id block (nth blocks (dec idx))))))
 
 (defn- get-left-nodes
-  [node limit]
-  (let [parent (otree/-get-parent node)]
+  [conn node limit]
+  (let [parent (otree/-get-parent node conn)]
     (loop [node node
            limit limit
            result []]
       (if (zero? limit)
         result
-        (if-let [left (otree/-get-left node)]
+        (if-let [left (otree/-get-left node conn)]
           (if-not (= left parent)
-            (recur left (dec limit) (conj result (otree/-get-id left)))
+            (recur left (dec limit) (conj result (otree/-get-id left conn)))
             result)
           result)))))
 
@@ -536,10 +547,11 @@
 
 (defn save-block
   "Save the `block`."
-  [block']
+  [repo block']
   {:pre [(map? block')]}
-  (let [txs-state (atom [])]
-    (otree/-save (block block') txs-state)
+  (let [conn (db/get-db false)
+        txs-state (atom [])]
+    (otree/-save (block block') txs-state conn repo)
     {:tx-data @txs-state}))
 
 (defn blocks-with-level
@@ -608,23 +620,29 @@
     (->> (filter (fn [b] (= 1 (:block/level b))) level-blocks)
          (map (fn [b]
                 (let [original (get-original-block b)]
-                  (or (and original (db/pull (:db/id original))) b)))))))
+                  (or (and original (db/entity (:db/id original))) b)))))))
 
 (defn- get-right-siblings
   "Get `node`'s right siblings."
   [node]
   {:pre [(otree/satisfied-inode? node)]}
-  (when-let [parent (otree/-get-parent node)]
-    (let [children (otree/-get-children parent)]
-      (->> (split-with #(not= (otree/-get-id node) (otree/-get-id %)) children)
-           last
-           rest))))
+  (let [conn (db/get-db false)]
+    (when-let [parent (otree/-get-parent node conn)]
+     (let [children (otree/-get-children parent conn)]
+       (->> (split-with #(not= (otree/-get-id node conn) (otree/-get-id % conn)) children)
+            last
+            rest)))))
 
 (defn- blocks-with-ordered-list-props
   [blocks target-block sibling?]
-  (let [target-block (if sibling? target-block (some-> target-block :db/id db/pull block otree/-get-down :data))
-        list-type-fn (fn [block] (pu/get-property block :logseq.order-list-type))
-        k (pu/get-pid :logseq.order-list-type)]
+  (let [repo (state/get-current-repo)
+        conn (db/get-db repo false)
+        db (db/get-db repo)
+        target-block (if sibling? target-block (some-> target-block :db/id db/entity block
+                                                       (#(otree/-get-down % conn))
+                                                       :data))
+        list-type-fn (fn [block] (db-property/get-property repo db block :logseq.order-list-type))
+        k (db-property/get-pid repo db :logseq.order-list-type)]
     (if-let [list-type (and target-block (list-type-fn target-block))]
       (mapv
        (fn [{:block/keys [content format] :as block}]
@@ -633,8 +651,8 @@
                 (nil? (list-type-fn block)))
            (update :block/properties assoc k list-type)
 
-           (not (config/db-based-graph? (state/get-current-repo)))
-           (assoc :block/content (property-util/insert-property format content :logseq.order-list-type list-type))))
+           (not (sqlite-util/db-based-graph? (state/get-current-repo)))
+           (assoc :block/content (wpu/insert-property (state/get-current-repo) format content :logseq.order-list-type list-type))))
        blocks)
       blocks)))
 
@@ -772,7 +790,8 @@
                         :or {update-timestamps? true}}]
   {:pre [(seq blocks)
          (s/valid? ::block-map-or-entity target-block)]}
-  (let [[target-block' sibling?] (get-target-block blocks target-block opts)
+  (let [conn (db/get-db false)
+        [target-block' sibling?] (get-target-block blocks target-block opts)
         _ (assert (some? target-block') (str "Invalid target: " target-block))
         sibling? (if (page-block? target-block') false sibling?)
         move? (contains? #{:move-blocks :move-blocks-up-down :indent-outdent-blocks} outliner-op)
@@ -821,12 +840,12 @@
                  (assign-temp-id tx replace-empty-target? target-block'))
             target-node (block target-block')
             next (if sibling?
-                   (otree/-get-right target-node)
-                   (otree/-get-down target-node))
+                   (otree/-get-right target-node conn)
+                   (otree/-get-down target-node conn))
             next-tx (when (and next
                                (if move? (not (contains? (set (map :db/id blocks)) (:db/id (:data next)))) true))
                       (when-let [left (last (filter (fn [b] (= 1 (:block/level b))) tx))]
-                        [{:block/uuid (otree/-get-id next)
+                        [{:block/uuid (otree/-get-id next conn)
                           :block/left (:db/id left)}]))
             full-tx (util/concat-without-nil (if (and keep-uuid? replace-empty-target?) (rest uuids-tx) uuids-tx) tx next-tx)]
         (when (and replace-empty-target? (state/editing?))
@@ -891,12 +910,14 @@
            (first (:block/_parent (db/entity [:block/uuid (:block/uuid (get-data node))]))))
     (throw (ex-info "Block can't be deleted because it still has children left, you can pass `children?` equals to `true`."
                     {:block (get-data node)}))
-    (let [right-node (otree/-get-right node)]
-      (otree/-del node txs-state children?)
+    (let [repo (state/get-current-repo)
+          conn (db/get-db false)
+          right-node (otree/-get-right node conn)]
+      (otree/-del node txs-state children? conn)
       (when (otree/satisfied-inode? right-node)
-        (let [left-node (otree/-get-left node)
-              new-right-node (otree/-set-left-id right-node (otree/-get-id left-node))]
-          (otree/-save new-right-node txs-state)))
+        (let [left-node (otree/-get-left node conn)
+              new-right-node (otree/-set-left-id right-node (otree/-get-id left-node conn) conn)]
+          (otree/-save new-right-node txs-state conn repo)))
       @txs-state)))
 
 (defn- delete-blocks
@@ -907,7 +928,9 @@
            :or {children? true}
            :as delete-opts}]
   [:pre [(seq blocks)]]
-  (let [txs-state (ds/new-outliner-txs-state)
+  (let [repo (state/get-current-repo)
+        conn (db/get-db false)
+        txs-state (ds/new-outliner-txs-state)
         blocks (get-top-level-blocks blocks)
         block-ids (map (fn [b] [:block/uuid (:block/uuid b)]) blocks)
         start-block (first blocks)
@@ -916,29 +939,29 @@
         end-node (block end-block)
         end-node-parents (->>
                           (db/get-block-parents
-                           (state/get-current-repo)
-                           (otree/-get-id end-node)
+                           repo
+                           (otree/-get-id end-node conn)
                            {:depth 1000})
                           (map :block/uuid)
                           (set))
-        self-block? (contains? end-node-parents (otree/-get-id start-node))]
+        self-block? (contains? end-node-parents (otree/-get-id start-node conn))]
     (if (or
          (= 1 (count blocks))
          (= start-node end-node)
          self-block?)
       (delete-block txs-state start-node (assoc delete-opts :children? children?))
-      (let [sibling? (= (otree/-get-parent-id start-node)
-                        (otree/-get-parent-id end-node))
-            right-node (otree/-get-right end-node)]
+      (let [sibling? (= (otree/-get-parent-id start-node conn)
+                        (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))
                 left-node-id (if sibling?
-                               (otree/-get-id (otree/-get-left start-node))
-                               (let [end-node-left-nodes (get-left-nodes end-node (count block-ids))
+                               (otree/-get-id (otree/-get-left start-node conn) conn)
+                               (let [end-node-left-nodes (get-left-nodes conn end-node (count block-ids))
                                      parents (->>
                                               (db/get-block-parents
-                                               (state/get-current-repo)
-                                               (otree/-get-id start-node)
+                                               repo
+                                               (otree/-get-id start-node conn)
                                                {:depth 1000})
                                               (map :block/uuid)
                                               (set))
@@ -950,15 +973,15 @@
             (when (and (nil? left-node-id) (not non-consecutive?))
               (assert left-node-id
                       (str "Can't find the left-node-id: "
-                           (pr-str {:start (db/entity [:block/uuid (otree/-get-id start-node)])
-                                    :end (db/entity [:block/uuid (otree/-get-id end-node)])
-                                    :right-node (db/entity [:block/uuid (otree/-get-id right-node)])}))))
+                           (pr-str {:start (db/entity [:block/uuid (otree/-get-id start-node conn)])
+                                    :end (db/entity [:block/uuid (otree/-get-id end-node conn)])
+                                    :right-node (db/entity [:block/uuid (otree/-get-id right-node conn)])}))))
             (when left-node-id
-              (let [new-right-node (otree/-set-left-id right-node left-node-id)]
-                (otree/-save new-right-node txs-state)))))
+              (let [new-right-node (otree/-set-left-id right-node left-node-id conn)]
+                (otree/-save new-right-node txs-state conn repo)))))
         (doseq [id block-ids]
-          (let [node (block (db/pull id))]
-            (otree/-del node txs-state true)))
+          (let [node (block (db/entity id))]
+            (otree/-del node txs-state true conn)))
         (let [fix-non-consecutive-tx (fix-non-consecutive-blocks blocks nil false)]
           (swap! txs-state concat fix-non-consecutive-tx))))
     {:tx-data @txs-state}))
@@ -977,7 +1000,7 @@
                         :as opts}]
   [:pre [(seq blocks)
          (s/valid? ::block-map-or-entity target-block)]]
-  (let [blocks (map (fn [b] (db/pull [:block/uuid (:block/uuid b)])) blocks)
+  (let [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))
@@ -1128,7 +1151,7 @@
                 (if (state/logical-outdenting?)
                   result
                   ;; direct outdenting (default behavior)
-                  (let [last-top-block (db/pull (:db/id (last blocks')))
+                  (let [last-top-block (db/entity (:db/id (last blocks')))
                         right-siblings (->> (get-right-siblings (block last-top-block))
                                             (map :data))]
                     (if (seq right-siblings)

+ 1 - 1
src/main/frontend/modules/outliner/transaction.cljc

@@ -39,7 +39,7 @@
          ~@body)
        (let [repo# (get-in opts# [:transact-opts :repo])
              transaction-args# (cond-> {:repo repo#}
-                                 (and (frontend.config/db-based-graph? repo#)
+                                 (and (logseq.db.sqlite.util/db-based-graph? repo#)
                                       (get opts*# :persist-op? true))
                                  (assoc :persist-op? true))]
          (binding [frontend.modules.outliner.core/*transaction-data* (transient [])

+ 3 - 30
src/main/frontend/modules/outliner/utils.cljs

@@ -1,8 +1,6 @@
 (ns frontend.modules.outliner.utils
-  (:require [frontend.db.conn :as conn]
-            [frontend.db.outliner :as db-outliner]
-            [datascript.impl.entity :as e]
-            [frontend.util :as util]))
+  (:require [datascript.impl.entity :as e]
+            [frontend.worker.util :as worker-util]))
 
 (defn block-id?
   [id]
@@ -14,32 +12,7 @@
 (defn check-block-id
   [id]
   (assert (block-id? id)
-    (util/format "The id should match block-id?: %s" (pr-str id))))
-
-(defn ->block-id
-  [id]
-  (cond
-    (block-id? id)
-    id
-
-    (and
-      (vector? id)
-      (= (first id) :block/uuid))
-    (second id)
-
-    (and
-      (vector? id)
-      (= (first id) :block/name))
-    (let [conn (conn/get-db false)]
-      (-> (db-outliner/get-by-id conn id)
-        (:block/uuid)))
-
-    (or (e/entity? id) (map? id))
-    (let [conn (conn/get-db false)]
-      (-> (db-outliner/get-by-id conn (:db/id id))
-        (:block/uuid)))
-
-    :else nil))
+    (worker-util/format "The id should match block-id?: %s" (pr-str id))))
 
 (defn ->block-lookup-ref
   "

+ 58 - 1
src/main/frontend/worker/mldoc.cljs

@@ -3,7 +3,11 @@
   (:require [logseq.graph-parser.mldoc :as gp-mldoc]
             [cljs-bean.core :as bean]
             [logseq.db.sqlite.util :as sqlite-util]
-            [clojure.string :as string]))
+            [clojure.string :as string]
+            [logseq.graph-parser.text :as text]
+            [clojure.walk :as walk]
+            [logseq.graph-parser.block :as gp-block]
+            [frontend.worker.util :as worker-util]))
 
 (defn get-default-config
   "Gets a mldoc default config for the given format. Works for DB and file graphs"
@@ -45,3 +49,56 @@
     (if (has-title? repo content format)
       [(first lines) (string/join "\n" (rest lines))]
       [nil (string/join "\n" lines)])))
+
+(defn extract-plain
+  "Extract plain elements including page refs"
+  [repo content]
+  (let [ast (->edn repo content :markdown)
+        *result (atom [])]
+    (walk/prewalk
+     (fn [f]
+       (cond
+           ;; tag
+         (and (vector? f)
+              (= "Tag" (first f)))
+         nil
+
+           ;; nested page ref
+         (and (vector? f)
+              (= "Nested_link" (first f)))
+         (swap! *result conj (:content (second f)))
+
+           ;; page ref
+         (and (vector? f)
+              (= "Link" (first f))
+              (map? (second f))
+              (vector? (:url (second f)))
+              (= "Page_ref" (first (:url (second f)))))
+         (swap! *result conj
+                (:full_text (second f)))
+
+           ;; plain
+         (and (vector? f)
+              (= "Plain" (first f)))
+         (swap! *result conj (second f))
+
+         :else
+         f))
+     ast)
+    (-> (string/trim (apply str @*result))
+        text/page-ref-un-brackets!)))
+
+(defn extract-refs-from-text
+  [repo db text date-formatter]
+  (when (string? text)
+    (let [ast-refs (gp-mldoc/get-references text (get-default-config repo :markdown))
+          page-refs (map #(gp-block/get-page-reference % :markdown) ast-refs)
+          block-refs (map #(gp-block/get-block-reference %) ast-refs)
+          refs' (->> (concat page-refs block-refs)
+                     (remove string/blank?)
+                     distinct)]
+      (-> (map #(if (worker-util/uuid-string? %)
+                  {:block/uuid (uuid %)}
+                  (gp-block/page-name->map % true db true date-formatter))
+               refs')
+          set))))

+ 3 - 3
src/test/frontend/db/outliner_test.cljs

@@ -2,7 +2,7 @@
   (:require [cljs.test :refer [deftest is use-fixtures]]
             [datascript.core :as d]
             [frontend.core-test :as core-test]
-            [frontend.db.outliner :as outliner]
+            [logseq.db :as db]
             [frontend.test.fixtures :as fixtures]))
 
 (use-fixtures :each fixtures/reset-db)
@@ -12,7 +12,7 @@
         block-id "1"
         data [{:block/uuid block-id}]
         _ (d/transact! conn data)
-        result (outliner/get-by-id conn [:block/uuid block-id])]
+        result (db/get-by-id conn [:block/uuid block-id])]
     (is (= block-id (:block/uuid result)))))
 
 (deftest test-get-by-parent-id
@@ -25,6 +25,6 @@
                :block/parent [:block/uuid "1"]
                :block/left [:block/uuid "2"]}]
         _ (d/transact! conn data)
-        r (d/q outliner/get-by-parent-id @conn [:block/uuid "1"])
+        r (d/q db/get-by-parent-id @conn [:block/uuid "1"])
         result (flatten r)]
     (is (= ["2" "3"] (mapv :block/uuid result)))))

+ 1 - 1
src/test/frontend/modules/outliner/core_test.cljs

@@ -106,7 +106,7 @@
 (defn get-children
   [id]
   (->> (get-block id true)
-       (otree/-get-children)
+       (otree/-get-children (db/get-db test-db false))
        (mapv #(-> % :data :block/uuid))))
 
 (deftest test-delete-block