소스 검색

wip: move file parse to worker

Tienson Qin 6 달 전
부모
커밋
33b6433dc9

+ 8 - 16
deps/graph-parser/src/logseq/graph_parser.cljs

@@ -51,7 +51,7 @@
   (let [existing-file-page (get-file-page db file-path)
   (let [existing-file-page (get-file-page db file-path)
         pages-to-clear (distinct (filter some? [existing-file-page (:db/id file-page)]))
         pages-to-clear (distinct (filter some? [existing-file-page (:db/id file-page)]))
         blocks (mapcat (fn [page-id]
         blocks (mapcat (fn [page-id]
-                         (ldb/get-page-blocks db page-id {:pull-keys [:db/id :block/uuid]}))
+                         (:block/_page (d/entity db page-id)))
                        pages-to-clear)
                        pages-to-clear)
         retain-uuids (set (keep :block/uuid retain-uuid-blocks))]
         retain-uuids (set (keep :block/uuid retain-uuid-blocks))]
     (retract-blocks-tx (distinct blocks) retain-uuids)))
     (retract-blocks-tx (distinct blocks) retain-uuids)))
@@ -63,16 +63,14 @@ Options available:
   * :delete-blocks-fn - Optional fn which is called with the new page, file and existing block uuids
   * :delete-blocks-fn - Optional fn which is called with the new page, file and existing block uuids
   which may be referenced elsewhere. Used to delete the existing blocks before saving the new ones.
   which may be referenced elsewhere. Used to delete the existing blocks before saving the new ones.
    Implemented in file-common-handler/validate-and-get-blocks-to-delete for IoC
    Implemented in file-common-handler/validate-and-get-blocks-to-delete for IoC
-* :skip-db-transact? - Boolean which skips transacting in order to batch transactions. Default is false
-* :extract-options - Options map to pass to extract/extract"
+  * :extract-options - Options map to pass to extract/extract"
   ([conn file-path content] (parse-file conn file-path content {}))
   ([conn file-path content] (parse-file conn file-path content {}))
-  ([conn file-path content {:keys [delete-blocks-fn extract-options skip-db-transact? ctime mtime]
-                            :or {delete-blocks-fn (constantly [])
-                                 skip-db-transact? false}
+  ([conn file-path content {:keys [delete-blocks-fn extract-options ctime mtime]
+                            :or {delete-blocks-fn (constantly [])}
                             :as options}]
                             :as options}]
    (let [format (common-util/get-format file-path)
    (let [format (common-util/get-format file-path)
          file-content [{:file/path file-path}]
          file-content [{:file/path file-path}]
-         {:keys [tx ast]}
+         {:keys [tx]}
          (let [extract-options' (merge {:block-pattern (common-config/get-block-pattern format)
          (let [extract-options' (merge {:block-pattern (common-config/get-block-pattern format)
                                         :date-formatter "MMM do, yyyy"
                                         :date-formatter "MMM do, yyyy"
                                         :uri-encoded? false
                                         :uri-encoded? false
@@ -91,7 +89,7 @@ Options available:
 
 
                      :else nil)
                      :else nil)
                block-ids (map (fn [block] {:block/uuid (:block/uuid block)}) blocks)
                block-ids (map (fn [block] {:block/uuid (:block/uuid block)}) blocks)
-               delete-blocks (delete-blocks-fn @conn (first pages) file-path block-ids)
+               delete-blocks (delete-blocks-fn (first pages) file-path block-ids)
                block-refs-ids (->> (mapcat :block/refs blocks)
                block-refs-ids (->> (mapcat :block/refs blocks)
                                    (filter (fn [ref] (and (vector? ref)
                                    (filter (fn [ref] (and (vector? ref)
                                                           (= :block/uuid (first ref)))))
                                                           (= :block/uuid (first ref)))))
@@ -110,14 +108,8 @@ Options available:
                           (or ctime (nil? file-entity))
                           (or ctime (nil? file-entity))
                           (assoc :file/created-at (or ctime (js/Date.)))
                           (assoc :file/created-at (or ctime (js/Date.)))
                           mtime
                           mtime
-                          (assoc :file/last-modified-at mtime))])
-         result (if skip-db-transact?
-                  tx
-                  (do
-                    (ldb/transact! conn tx (select-keys options [:new-graph? :from-disk?]))
-                    nil))]
-     {:tx result
-      :ast ast})))
+                          (assoc :file/last-modified-at mtime))])]
+     (ldb/transact! conn tx (select-keys options [:new-graph? :from-disk?])))))
 
 
 (defn filter-files
 (defn filter-files
   "Filters files in preparation for parsing. Only includes files that are
   "Filters files in preparation for parsing. Only includes files that are

+ 7 - 14
deps/graph-parser/src/logseq/graph_parser/block.cljs

@@ -698,23 +698,16 @@
                                                    (str (gp-property/colons-org "id") " " (:block/uuid block)))))]
                                                    (str (gp-property/colons-org "id") " " (:block/uuid block)))))]
                                (string/replace-first c replace-str ""))))))
                                (string/replace-first c replace-str ""))))))
 
 
-(defn block-exists-in-another-page?
-  "For sanity check only.
-   For renaming file externally, the file is actually deleted and transacted before-hand."
-  [db block-uuid current-page-name]
-  (when (and db current-page-name)
-    (when-let [block-page-name (:block/name (:block/page (d/entity db [:block/uuid block-uuid])))]
-      (not= current-page-name block-page-name))))
-
 (defn fix-block-id-if-duplicated!
 (defn fix-block-id-if-duplicated!
-  "If the block exists in another page, we need to fix it
-   If the block exists in the current extraction process, we also need to fix it"
-  [db page-name *block-exists-in-extraction block]
-  (let [block (if (or (@*block-exists-in-extraction (:block/uuid block))
-                      (block-exists-in-another-page? db (:block/uuid block) page-name))
+  "If the block exists in another page or the current page, we need to fix it"
+  [db page-name *extracted-block-ids block]
+  (let [existing-block (d/entity db [:block/uuid (:block/uuid block)])
+        block (if (and existing-block
+                       (or (not= (:block/name (:block/page existing-block)) page-name)
+                           (contains? @*extracted-block-ids (:block/uuid block))))
                 (fix-duplicate-id block)
                 (fix-duplicate-id block)
                 block)]
                 block)]
-    (swap! *block-exists-in-extraction conj (:block/uuid block))
+    (swap! *extracted-block-ids conj (:block/uuid block))
     block))
     block))
 
 
 (defn extract-blocks
 (defn extract-blocks

+ 7 - 8
deps/graph-parser/src/logseq/graph_parser/cli.cljs

@@ -3,10 +3,10 @@
   (:require ["fs" :as fs]
   (:require ["fs" :as fs]
             ["path" :as path]
             ["path" :as path]
             [clojure.edn :as edn]
             [clojure.edn :as edn]
-            [logseq.common.graph :as common-graph]
             [logseq.common.config :as common-config]
             [logseq.common.config :as common-config]
-            [logseq.graph-parser :as graph-parser]
+            [logseq.common.graph :as common-graph]
             [logseq.common.util :as common-util]
             [logseq.common.util :as common-util]
+            [logseq.graph-parser :as graph-parser]
             [logseq.graph-parser.db :as gp-db]))
             [logseq.graph-parser.db :as gp-db]))
 
 
 (defn- slurp
 (defn- slurp
@@ -28,10 +28,10 @@
   [dir* config]
   [dir* config]
   (let [dir (path/resolve dir*)]
   (let [dir (path/resolve dir*)]
     (->> (common-graph/get-files dir)
     (->> (common-graph/get-files dir)
-        (map #(hash-map :file/path %))
-        graph-parser/filter-files
-        (remove-hidden-files dir config)
-        (mapv #(assoc % :file/content (slurp (:file/path %)))))))
+         (map #(hash-map :file/path %))
+         graph-parser/filter-files
+         (remove-hidden-files dir config)
+         (mapv #(assoc % :file/content (slurp (:file/path %)))))))
 
 
 (defn- read-config
 (defn- read-config
   "Reads repo-specific config from logseq/config.edn"
   "Reads repo-specific config from logseq/config.edn"
@@ -45,8 +45,7 @@
   [conn files {:keys [config] :as options}]
   [conn files {:keys [config] :as options}]
   (let [extract-options (merge {:date-formatter (common-config/get-date-formatter config)
   (let [extract-options (merge {:date-formatter (common-config/get-date-formatter config)
                                 :user-config config
                                 :user-config config
-                                :filename-format (or (:file/name-format config) :legacy)
-                                :extracted-block-ids (atom #{})}
+                                :filename-format (or (:file/name-format config) :legacy)}
                                (select-keys options [:verbose]))]
                                (select-keys options [:verbose]))]
     (mapv
     (mapv
      (fn [{:file/keys [path content]}]
      (fn [{:file/keys [path content]}]

+ 4 - 5
deps/graph-parser/src/logseq/graph_parser/extract.cljc

@@ -220,15 +220,13 @@
 (defn- extract-pages-and-blocks
 (defn- extract-pages-and-blocks
   "uri-encoded? - if is true, apply URL decode on the file path
   "uri-encoded? - if is true, apply URL decode on the file path
    options -
    options -
-     :extracted-block-ids - An atom that contains all block ids that have been extracted in the current page (not yet saved to db)
      :resolve-uuid-fn - Optional fn which is called to resolve uuids of each block. Enables diff-merge
      :resolve-uuid-fn - Optional fn which is called to resolve uuids of each block. Enables diff-merge
        (2 ways diff) based uuid resolution upon external editing.
        (2 ways diff) based uuid resolution upon external editing.
        returns a list of the uuids, given the receiving ast, or nil if not able to resolve.
        returns a list of the uuids, given the receiving ast, or nil if not able to resolve.
        Implemented in reset-file-handler/diff-merge-uuids-2ways for IoC
        Implemented in reset-file-handler/diff-merge-uuids-2ways for IoC
        Called in gp-extract/extract as AST is being parsed and properties are extracted there"
        Called in gp-extract/extract as AST is being parsed and properties are extracted there"
-  [format ast properties file content {:keys [date-formatter db filename-format extracted-block-ids resolve-uuid-fn]
-                                       :or {extracted-block-ids (atom #{})
-                                            resolve-uuid-fn (constantly nil)}
+  [format ast properties file content {:keys [date-formatter db filename-format resolve-uuid-fn]
+                                       :or {resolve-uuid-fn (constantly nil)}
                                        :as options}]
                                        :as options}]
   (assert db "Datascript DB is required")
   (assert db "Datascript DB is required")
   (try
   (try
@@ -237,9 +235,10 @@
           options' (assoc options :page-name page-name)
           options' (assoc options :page-name page-name)
           ;; In case of diff-merge (2way) triggered, use the uuids to override the ones extracted from the AST
           ;; In case of diff-merge (2way) triggered, use the uuids to override the ones extracted from the AST
           override-uuids (resolve-uuid-fn format ast content options')
           override-uuids (resolve-uuid-fn format ast content options')
+          *extracted-block-ids (atom #{})
           blocks (->> (gp-block/extract-blocks ast content format options')
           blocks (->> (gp-block/extract-blocks ast content format options')
                       (attach-block-ids-if-match override-uuids)
                       (attach-block-ids-if-match override-uuids)
-                      (mapv #(gp-block/fix-block-id-if-duplicated! db page-name extracted-block-ids %))
+                      (mapv #(gp-block/fix-block-id-if-duplicated! db page-name *extracted-block-ids %))
                       ;; FIXME: use page uuid
                       ;; FIXME: use page uuid
                       (gp-block/with-parent-and-order {:block/name page-name})
                       (gp-block/with-parent-and-order {:block/name page-name})
                       (vec))
                       (vec))

+ 5 - 5
deps/graph-parser/test/logseq/graph_parser_test.cljs

@@ -1,12 +1,12 @@
 (ns logseq.graph-parser-test
 (ns logseq.graph-parser-test
   (:require [cljs.test :refer [deftest testing is are]]
   (:require [cljs.test :refer [deftest testing is are]]
             [clojure.string :as string]
             [clojure.string :as string]
+            [datascript.core :as d]
+            [logseq.db :as ldb]
             [logseq.graph-parser :as graph-parser]
             [logseq.graph-parser :as graph-parser]
-            [logseq.graph-parser.db :as gp-db]
             [logseq.graph-parser.block :as gp-block]
             [logseq.graph-parser.block :as gp-block]
-            [logseq.graph-parser.property :as gp-property]
-            [datascript.core :as d]
-            [logseq.db :as ldb]))
+            [logseq.graph-parser.db :as gp-db]
+            [logseq.graph-parser.property :as gp-property]))
 
 
 (def foo-edn
 (def foo-edn
   "Example exported whiteboard page as an edn exportable."
   "Example exported whiteboard page as an edn exportable."
@@ -78,7 +78,7 @@
                                                         (throw (js/Error "Testing unexpected failure")))]
                                                         (throw (js/Error "Testing unexpected failure")))]
         (try
         (try
           (parse-file conn "foo.md" "- id:: 628953c1-8d75-49fe-a648-f4c612109098"
           (parse-file conn "foo.md" "- id:: 628953c1-8d75-49fe-a648-f4c612109098"
-                      {:delete-blocks-fn (fn [_db page _file _uuids]
+                      {:delete-blocks-fn (fn [page _file _uuids]
                                            (reset! deleted-page page))})
                                            (reset! deleted-page page))})
           (catch :default _)))
           (catch :default _)))
       (is (= nil @deleted-page)
       (is (= nil @deleted-page)

+ 30 - 26
src/main/frontend/handler/file_based/file.cljs

@@ -7,7 +7,6 @@
             [frontend.db.file-based.model :as file-model]
             [frontend.db.file-based.model :as file-model]
             [frontend.fs :as fs]
             [frontend.fs :as fs]
             [frontend.handler.common.config-edn :as config-edn-common-handler]
             [frontend.handler.common.config-edn :as config-edn-common-handler]
-            [frontend.handler.file-based.reset-file :as reset-file-handler]
             [frontend.handler.global-config :as global-config-handler]
             [frontend.handler.global-config :as global-config-handler]
             [frontend.handler.repo-config :as repo-config-handler]
             [frontend.handler.repo-config :as repo-config-handler]
             [frontend.handler.ui :as ui-handler]
             [frontend.handler.ui :as ui-handler]
@@ -33,6 +32,10 @@
       (println "Load file failed: " path)
       (println "Load file failed: " path)
       (js/console.error e)))))
       (js/console.error e)))))
 
 
+(defn reset-file!
+  [repo file-path content opts]
+  (state/<invoke-db-worker :thread-api/reset-file repo file-path content opts))
+
 (defn- load-multiple-files
 (defn- load-multiple-files
   [repo-url paths]
   [repo-url paths]
   (doall
   (doall
@@ -133,7 +136,7 @@
 (defn alter-file
 (defn alter-file
   "Write any in-DB file, e.g. repo config, page, whiteboard, etc."
   "Write any in-DB file, e.g. repo config, page, whiteboard, etc."
   [repo path content {:keys [reset? re-render-root? from-disk? skip-compare? new-graph? verbose
   [repo path content {:keys [reset? re-render-root? from-disk? skip-compare? new-graph? verbose
-                             skip-db-transact? extracted-block-ids ctime mtime]
+                             ctime mtime]
                       :fs/keys [event]
                       :fs/keys [event]
                       :or {reset? true
                       :or {reset? true
                            re-render-root? false
                            re-render-root? false
@@ -147,25 +150,22 @@
     (when (or config-valid? (not config-file?)) ; non-config file or valid config
     (when (or config-valid? (not config-file?)) ; non-config file or valid config
       (let [opts {:new-graph? new-graph?
       (let [opts {:new-graph? new-graph?
                   :from-disk? from-disk?
                   :from-disk? from-disk?
-                  :skip-db-transact? skip-db-transact?
                   :fs/event event
                   :fs/event event
                   :ctime ctime
                   :ctime ctime
-                  :mtime mtime}
-            result (if reset?
-                     (do
-                       (when-not skip-db-transact?
-                         (when-let [page-id (file-model/get-file-page-id path)]
-                           (db/transact! repo
-                                         [[:db/retract page-id :block/alias]
-                                          [:db/retract page-id :block/tags]]
-                                         opts)))
-                       (reset-file-handler/reset-file!
-                        repo path content (merge opts
-                                                 ;; To avoid skipping the `:or` bounds for keyword destructuring
-                                                 (when (some? extracted-block-ids) {:extracted-block-ids extracted-block-ids})
-                                                 (when (some? verbose) {:verbose verbose}))))
-                     (db/set-file-content! repo path content opts))]
-        (-> (p/let [_ (when-not from-disk?
+                  :mtime mtime}]
+        (-> (p/let [result (if reset?
+                             (p/do!
+                              (when-let [page-id (file-model/get-file-page-id path)]
+                                (db/transact! repo
+                                              [[:db/retract page-id :block/alias]
+                                               [:db/retract page-id :block/tags]]
+                                              opts))
+                              (reset-file!
+                               repo path content (merge opts
+                                                         ;; To avoid skipping the `:or` bounds for keyword destructuring
+                                                        (when (some? verbose) {:verbose verbose}))))
+                             (db/set-file-content! repo path content opts))
+                    _ (when-not from-disk?
                         (write-file-aux! repo path content {:skip-compare? skip-compare?}))]
                         (write-file-aux! repo path content {:skip-compare? skip-compare?}))]
               (when re-render-root? (ui-handler/re-render-root!))
               (when re-render-root? (ui-handler/re-render-root!))
 
 
@@ -178,15 +178,16 @@
 
 
                 (= path "logseq/config.edn")
                 (= path "logseq/config.edn")
                 (p/let [_ (repo-config-handler/restore-repo-config! repo content)]
                 (p/let [_ (repo-config-handler/restore-repo-config! repo content)]
-                  (state/pub-event! [:shortcut/refresh]))))
+                  (state/pub-event! [:shortcut/refresh])))
+
+              result)
             (p/catch
             (p/catch
              (fn [error]
              (fn [error]
                (println "Write file failed, path: " path ", content: " content)
                (println "Write file failed, path: " path ", content: " content)
                (log/error :write/failed error)
                (log/error :write/failed error)
                (state/pub-event! [:capture-error
                (state/pub-event! [:capture-error
                                   {:error error
                                   {:error error
-                                   :payload {:type :write-file/failed-for-alter-file}}]))))
-        result))))
+                                   :payload {:type :write-file/failed-for-alter-file}}]))))))))
 
 
 (defn set-file-content!
 (defn set-file-content!
   [repo path new-content]
   [repo path new-content]
@@ -234,10 +235,13 @@
                                 (map (fn [path] (db/get-file repo path)) paths)))]
                                 (map (fn [path] (db/get-file repo path)) paths)))]
     ;; update db
     ;; update db
     (when update-db?
     (when update-db?
-      (doseq [[path content] files]
-        (if reset?
-          (reset-file-handler/reset-file! repo path content)
-          (db/set-file-content! repo path content))))
+      (p/all
+       (map
+        (fn [[path content]]
+          (if reset?
+            (reset-file! repo path content {})
+            (db/set-file-content! repo path content)))
+        files)))
     (alter-files-handler! repo files opts file->content)))
     (alter-files-handler! repo files opts file->content)))
 
 
 (defn watch-for-current-graph-dir!
 (defn watch-for-current-graph-dir!

+ 41 - 65
src/main/frontend/handler/file_based/repo.cljs

@@ -7,7 +7,6 @@
             [frontend.db.file-based.model :as file-model]
             [frontend.db.file-based.model :as file-model]
             [frontend.fs :as fs]
             [frontend.fs :as fs]
             [frontend.handler.file-based.file :as file-handler]
             [frontend.handler.file-based.file :as file-handler]
-            [frontend.handler.file-based.reset-file :as reset-file-handler]
             [frontend.handler.repo-config :as repo-config-handler]
             [frontend.handler.repo-config :as repo-config-handler]
             [frontend.handler.route :as route-handler]
             [frontend.handler.route :as route-handler]
             [frontend.handler.ui :as ui-handler]
             [frontend.handler.ui :as ui-handler]
@@ -38,7 +37,7 @@
         (p/let [_ (fs/mkdir-if-not-exists (path/path-join repo-dir pages-dir))
         (p/let [_ (fs/mkdir-if-not-exists (path/path-join repo-dir pages-dir))
                 file-exists? (fs/create-if-not-exists repo-url repo-dir file-rpath default-content)]
                 file-exists? (fs/create-if-not-exists repo-url repo-dir file-rpath default-content)]
           (when-not file-exists?
           (when-not file-exists?
-            (reset-file-handler/reset-file! repo-url file-rpath default-content)))))))
+            (file-handler/reset-file! repo-url file-rpath default-content {})))))))
 
 
 (defn- create-custom-theme
 (defn- create-custom-theme
   [repo-url]
   [repo-url]
@@ -50,7 +49,7 @@
     (p/let [_ (fs/mkdir-if-not-exists (path/path-join repo-dir config/app-name))
     (p/let [_ (fs/mkdir-if-not-exists (path/path-join repo-dir config/app-name))
             file-exists? (fs/create-if-not-exists repo-url repo-dir file-rpath default-content)]
             file-exists? (fs/create-if-not-exists repo-url repo-dir file-rpath default-content)]
       (when-not file-exists?
       (when-not file-exists?
-        (reset-file-handler/reset-file! repo-url path default-content)))))
+        (file-handler/reset-file! repo-url path default-content {})))))
 
 
 (comment
 (comment
   (defn- create-dummy-notes-page
   (defn- create-dummy-notes-page
@@ -60,7 +59,7 @@
           file-rpath (str (config/get-pages-directory) "/how_to_make_dummy_notes.md")]
           file-rpath (str (config/get-pages-directory) "/how_to_make_dummy_notes.md")]
       (p/let [_ (fs/mkdir-if-not-exists (path/path-join repo-dir (config/get-pages-directory)))
       (p/let [_ (fs/mkdir-if-not-exists (path/path-join repo-dir (config/get-pages-directory)))
               _file-exists? (fs/create-if-not-exists repo-url repo-dir file-rpath content)]
               _file-exists? (fs/create-if-not-exists repo-url repo-dir file-rpath content)]
-        (reset-file-handler/reset-file! repo-url file-rpath content)))))
+        (file-handler/reset-file! repo-url file-rpath content {})))))
 
 
 (defn create-config-file-if-not-exists
 (defn create-config-file-if-not-exists
   "Creates a default logseq/config.edn if it doesn't exist"
   "Creates a default logseq/config.edn if it doesn't exist"
@@ -74,7 +73,7 @@
             path (str app-dir "/" config/config-file)]
             path (str app-dir "/" config/config-file)]
         (p/let [file-exists? (fs/create-if-not-exists repo-url repo-dir "logseq/config.edn" default-content)]
         (p/let [file-exists? (fs/create-if-not-exists repo-url repo-dir "logseq/config.edn" default-content)]
           (when-not file-exists?
           (when-not file-exists?
-            (reset-file-handler/reset-file! repo-url path default-content)
+            (file-handler/reset-file! repo-url path default-content {})
             (repo-config-handler/set-repo-config-state! repo-url default-content)))))))
             (repo-config-handler/set-repo-config-state! repo-url default-content)))))))
 
 
 (defn- create-default-files!
 (defn- create-default-files!
@@ -89,36 +88,30 @@
            (create-custom-theme repo-url)
            (create-custom-theme repo-url)
            (state/pub-event! [:page/create-today-journal repo-url]))))
            (state/pub-event! [:page/create-today-journal repo-url]))))
 
 
-(defonce *file-tx (atom nil))
-
 (defn- parse-and-load-file!
 (defn- parse-and-load-file!
   "Accept: .md, .org, .edn, .css"
   "Accept: .md, .org, .edn, .css"
-  [repo-url file {:keys [new-graph? verbose skip-db-transact? extracted-block-ids]
-                  :or {skip-db-transact? true}}]
-  (try
-    (reset! *file-tx
-            (file-handler/alter-file repo-url
-                                     (:file/path file)
-                                     (:file/content file)
-                                     (merge (:stat file)
-                                            {:new-graph? new-graph?
-                                             :re-render-root? false
-                                             :from-disk? true
-                                             :skip-db-transact? skip-db-transact?}
-                                            ;; To avoid skipping the `:or` bounds for keyword destructuring
-                                            (when (some? extracted-block-ids) {:extracted-block-ids extracted-block-ids})
-                                            (when (some? verbose) {:verbose verbose}))))
-    (state/set-parsing-state! (fn [m]
-                                (update m :finished inc)))
-    @*file-tx
-    (catch :default e
-      (println "Parse and load file failed: " (str (:file/path file)))
-      (js/console.error e)
-      (state/set-parsing-state! (fn [m]
-                                  (update m :failed-parsing-files conj [(:file/path file) e])))
-      (state/set-parsing-state! (fn [m]
-                                  (update m :finished inc)))
-      nil)))
+  [repo-url file {:keys [new-graph? verbose]}]
+  (->
+   (p/let [result (file-handler/alter-file repo-url
+                                           (:file/path file)
+                                           (:file/content file)
+                                           (merge (:stat file)
+                                                  {:new-graph? new-graph?
+                                                   :re-render-root? false
+                                                   :from-disk? true}
+                                                  ;; To avoid skipping the `:or` bounds for keyword destructuring
+                                                  (when (some? verbose) {:verbose verbose})))]
+     (state/set-parsing-state! (fn [m]
+                                 (update m :finished inc)))
+     result)
+   (p/catch (fn [e]
+              (println "Parse and load file failed: " (str (:file/path file)))
+              (js/console.error e)
+              (state/set-parsing-state! (fn [m]
+                                          (update m :failed-parsing-files conj [(:file/path file) e])))
+              (state/set-parsing-state! (fn [m]
+                                          (update m :finished inc)))
+              nil))))
 
 
 (defn- after-parse
 (defn- after-parse
   [repo-url re-render? re-render-opts opts graph-added-chan]
   [repo-url re-render? re-render-opts opts graph-added-chan]
@@ -145,8 +138,7 @@
         total (count supported-files)
         total (count supported-files)
         large-graph? (> total 1000)
         large-graph? (> total 1000)
         *page-names (atom #{})
         *page-names (atom #{})
-        *page-name->path (atom {})
-        *extracted-block-ids (atom #{})]
+        *page-name->path (atom {})]
     (when (seq delete-data) (db/transact! repo-url delete-data {:delete-files? true}))
     (when (seq delete-data) (db/transact! repo-url delete-data {:delete-files? true}))
     (state/set-current-repo! repo-url)
     (state/set-current-repo! repo-url)
     (state/set-parsing-state! {:total (count supported-files)})
     (state/set-parsing-state! {:total (count supported-files)})
@@ -157,11 +149,9 @@
           (state/set-parsing-state! (fn [m]
           (state/set-parsing-state! (fn [m]
                                       (assoc m
                                       (assoc m
                                              :current-parsing-file (:file/path file))))
                                              :current-parsing-file (:file/path file))))
-          (parse-and-load-file! repo-url file (assoc
-                                               (select-keys opts [:new-graph? :verbose])
-                                               :skip-db-transact? false)))
+          (parse-and-load-file! repo-url file (select-keys opts [:new-graph? :verbose])))
         (after-parse repo-url re-render? re-render-opts opts graph-added-chan))
         (after-parse repo-url re-render? re-render-opts opts graph-added-chan))
-      (async/go-loop [tx []]
+      (async/go-loop []
         (if-let [item (async/<! chan)]
         (if-let [item (async/<! chan)]
           (let [[idx file] item
           (let [[idx file] item
                 whiteboard? (common-config/whiteboard? (:file/path file))
                 whiteboard? (common-config/whiteboard? (:file/path file))
@@ -174,13 +164,9 @@
 
 
             (when yield-for-ui? (async/<! (async/timeout 1)))
             (when yield-for-ui? (async/<! (async/timeout 1)))
 
 
-            (let [opts' (-> (select-keys opts [:new-graph? :verbose])
-                            (assoc :extracted-block-ids *extracted-block-ids))
+            (let [opts' (select-keys opts [:new-graph? :verbose])
                   ;; whiteboards might have conflicting block IDs so that db transaction could be failed
                   ;; whiteboards might have conflicting block IDs so that db transaction could be failed
-                  opts' (if whiteboard?
-                          (assoc opts' :skip-db-transact? false)
-                          opts')
-                  result (parse-and-load-file! repo-url file opts')
+                  result (async/<! (p->c (parse-and-load-file! repo-url file opts')))
                   page-name (when (coll? result) ; result could be a promise
                   page-name (when (coll? result) ; result could be a promise
                               (some (fn [x] (when (and (map? x)
                               (some (fn [x] (when (and (map? x)
                                                        (:block/title x)
                                                        (:block/title x)
@@ -188,29 +174,19 @@
                                               (:block/name x)))
                                               (:block/name x)))
                                     result))
                                     result))
                   page-exists? (and page-name (get @*page-names page-name))
                   page-exists? (and page-name (get @*page-names page-name))
-                  tx' (cond
-                        whiteboard? tx
-                        page-exists? (do
-                                       (state/pub-event! [:notification/show
-                                                          {:content [:div
-                                                                     (util/format "The file \"%s\" will be skipped because another file \"%s\" has the same page title."
-                                                                                  (:file/path file)
-                                                                                  (get @*page-name->path page-name))]
-                                                           :status :warning
-                                                           :clear? false}])
-                                       tx)
-                        :else (concat tx result))
+                  _ (when page-exists?
+                      (state/pub-event! [:notification/show
+                                         {:content [:div
+                                                    (util/format "The file \"%s\" will be skipped because another file \"%s\" has the same page title."
+                                                                 (:file/path file)
+                                                                 (get @*page-name->path page-name))]
+                                          :status :warning
+                                          :clear? false}]))
                   _ (when (and page-name (not page-exists?))
                   _ (when (and page-name (not page-exists?))
                       (swap! *page-names conj page-name)
                       (swap! *page-names conj page-name)
-                      (swap! *page-name->path assoc page-name (:file/path file)))
-                  tx' (if (zero? (rem (inc idx) 100))
-                        (do
-                          (async/<! (p->c (db/transact! repo-url tx' {:from-disk? true})))
-                          [])
-                        tx')]
-              (recur tx')))
+                      (swap! *page-name->path assoc page-name (:file/path file)))]
+              (recur)))
           (p/do!
           (p/do!
-           (when (seq tx) (db/transact! repo-url tx {:from-disk? true}))
            (after-parse repo-url re-render? re-render-opts opts graph-added-chan)))))
            (after-parse repo-url re-render? re-render-opts opts graph-added-chan)))))
     graph-added-chan))
     graph-added-chan))
 
 

+ 0 - 105
src/main/frontend/handler/file_based/reset_file.cljs

@@ -1,105 +0,0 @@
-(ns frontend.handler.file-based.reset-file
-  "Fns for resetting a db file with parsed file content"
-  (:require [frontend.config :as config]
-            [frontend.state :as state]
-            [frontend.db :as db]
-            [frontend.db.file-based.model :as file-model]
-            [logseq.graph-parser :as graph-parser]
-            [logseq.common.util :as common-util]
-            [frontend.fs.diff-merge :as diff-merge]
-            [frontend.fs :as fs]
-            [frontend.context.i18n :refer [t]]
-            [promesa.core :as p]
-            [clojure.string :as string]
-            [cljs-bean.core :as bean]
-            [lambdaisland.glogi :as log]))
-
-(defn- page-exists-in-another-file
-  "Conflict of files towards same page"
-  [repo-url page file]
-  (when-let [page-name (:block/name page)]
-    (let [current-file (:file/path (file-model/get-page-file repo-url page-name))]
-      (when (not= file current-file)
-        current-file))))
-
-(defn- validate-existing-file
-  "Handle the case when the file is already exists in db
-     Likely caused by renaming between caps and non-caps, then cause file system
-     bugs on some OS
-     e.g. on macOS, it doesn't fire the file change event when renaming between
-       caps and non-caps"
-  [repo-url file-page file-path]
-  (when-let [current-file (page-exists-in-another-file repo-url file-page file-path)]
-    (when (not= file-path current-file)
-      (cond
-        ;; TODO: handle case sensitive file system
-        (= (common-util/path-normalize (string/lower-case current-file))
-           (common-util/path-normalize (string/lower-case file-path)))
-        ;; case renamed
-        (when-let [file (db/pull [:file/path current-file])]
-          (p/let [disk-content (fs/read-file "" current-file)]
-            (fs/backup-db-file! repo-url current-file (:file/content file) disk-content))
-          (db/transact! repo-url [{:db/id (:db/id file)
-                                   :file/path file-path}]))
-
-        :else
-        (let [error (t :file/validate-existing-file-error current-file file-path)]
-          (state/pub-event! [:notification/show
-                             {:content error
-                              :status :error
-                              :clear? false}]))))))
-
-(defn- validate-and-get-blocks-to-delete
-  "An implementation for the delete-blocks-fn in graph-parser/parse-file"
-  [repo-url db file-page file-path retain-uuid-blocks]
-  (validate-existing-file repo-url file-page file-path)
-  (graph-parser/get-blocks-to-delete db file-page file-path retain-uuid-blocks))
-
-(defn- diff-merge-uuids-2ways
-  "Infer new uuids from existing DB data and diff with the new AST
-   Return a list of uuids for the new blocks"
-  [format ast content {:keys [page-name] :as options}]
-  (try
-    (let [base-diffblocks (diff-merge/db->diff-blocks page-name)
-          income-diffblocks (diff-merge/ast->diff-blocks ast content format options)
-          diff-ops (diff-merge/diff base-diffblocks income-diffblocks)
-          new-uuids (diff-merge/attachUUID diff-ops (map :uuid base-diffblocks))]
-      (bean/->clj new-uuids))
-    (catch js/Error e
-      (log/error :diff-merge/diff-merge-2way-calling-failed e))))
-
-(defn- reset-file!*
-  "Parse file considering diff-merge with local or remote file
-   Decide how to treat the parsed file based on the file's triggering event
-   options -
-     :fs/reset-event - the event that triggered the file update
-     :fs/local-file-change - file changed on local disk
-     :fs/remote-file-change - file changed on remote"
-  [repo-url file-path content {:fs/keys [event] :as options}]
-  (when-let [db-conn (db/get-db repo-url false)]
-    (case event
-      ;; the file is already in db, so we can use the existing file's blocks
-      ;; to do the diff-merge
-      :fs/local-file-change
-      (graph-parser/parse-file db-conn file-path content (assoc-in options [:extract-options :resolve-uuid-fn] diff-merge-uuids-2ways))
-
-      ;; default to parse the file
-      (graph-parser/parse-file db-conn file-path content options))))
-
-(defn reset-file!
-  "Main fn for updating a db with the results of a parsed file"
-  ([repo-url file-path content]
-   (reset-file! repo-url file-path content {}))
-  ([repo-url file-path content {:keys [verbose extracted-block-ids _ctime _mtime] :as options}]
-   (let [options (merge (dissoc options :verbose :extracted-block-ids)
-                        {:delete-blocks-fn (partial validate-and-get-blocks-to-delete repo-url)
-                         ;; Options here should also be present in gp-cli/parse-graph
-                         :extract-options (merge
-                                           {:user-config (state/get-config)
-                                            :date-formatter (state/get-date-formatter)
-                                            :block-pattern (config/get-block-pattern (common-util/get-format file-path))
-                                            :filename-format (state/get-filename-format repo-url)}
-                                           ;; To avoid skipping the `:or` bounds for keyword destructuring
-                                           (when (some? extracted-block-ids) {:extracted-block-ids extracted-block-ids})
-                                           (when (some? verbose) {:verbose verbose}))})]
-     (:tx (reset-file!* repo-url file-path content options)))))

+ 7 - 0
src/main/frontend/worker/db_worker.cljs

@@ -20,6 +20,7 @@
             [frontend.worker.db.validate :as worker-db-validate]
             [frontend.worker.db.validate :as worker-db-validate]
             [frontend.worker.export :as worker-export]
             [frontend.worker.export :as worker-export]
             [frontend.worker.file :as file]
             [frontend.worker.file :as file]
+            [frontend.worker.file.reset :as file-reset]
             [frontend.worker.handler.page :as worker-page]
             [frontend.worker.handler.page :as worker-page]
             [frontend.worker.handler.page.file-based.rename :as file-worker-page-rename]
             [frontend.worker.handler.page.file-based.rename :as file-worker-page-rename]
             [frontend.worker.rtc.asset-db-listener]
             [frontend.worker.rtc.asset-db-listener]
@@ -782,6 +783,12 @@
   [graph]
   [graph]
   (fix-broken-graph graph))
   (fix-broken-graph graph))
 
 
+(def-thread-api :thread-api/reset-file
+  [repo file-path content opts]
+  ;; (prn :debug :reset-file :file-path file-path :opts opts)
+  (when-let [conn (worker-state/get-datascript-conn repo)]
+    (file-reset/reset-file! repo conn file-path content opts)))
+
 (comment
 (comment
   (def-thread-api :general/dangerousRemoveAllDbs
   (def-thread-api :general/dangerousRemoveAllDbs
     []
     []

+ 83 - 0
src/main/frontend/worker/file/reset.cljs

@@ -0,0 +1,83 @@
+(ns frontend.worker.file.reset
+  "Fns for resetting a db file with parsed file content"
+  (:require [clojure.string :as string]
+            [datascript.core :as d]
+            [frontend.worker.state :as worker-state]
+            [logseq.common.config :as common-config]
+            [logseq.common.util :as common-util]
+            [logseq.db :as ldb]
+            [logseq.graph-parser :as graph-parser]
+            [logseq.graph-parser.db :as gp-db]))
+
+(defn- page-exists-in-another-file
+  "Conflict of files towards same page"
+  [db page file]
+  (when-let [page-name (:block/name page)]
+    (let [current-file (:file/path (gp-db/get-page-file db page-name))]
+      (when (not= file current-file)
+        current-file))))
+
+(defn- validate-existing-file
+  "Handle the case when the file is already exists in db
+     Likely caused by renaming between caps and non-caps, then cause file system
+     bugs on some OS
+     e.g. on macOS, it doesn't fire the file change event when renaming between
+       caps and non-caps"
+  [repo conn file-page file-path]
+  (when-let [current-file (page-exists-in-another-file @conn file-page file-path)]
+    (let [db @conn]
+      (when (not= file-path current-file)
+        (cond
+        ;; TODO: handle case sensitive file system
+          (= (common-util/path-normalize (string/lower-case current-file))
+             (common-util/path-normalize (string/lower-case file-path)))
+        ;; case renamed
+          (when-let [file (d/entity @conn [:file/path current-file])]
+          ;; (p/let [disk-content (fs/read-file "" current-file)]
+            ;;   (fs/backup-db-file! repo current-file (:file/content file) disk-content))
+            (ldb/transact! conn [{:db/id (:db/id file)
+                                  :file/path file-path}]))
+
+          :else
+          nil
+          ;; (let [error (t :file/validate-existing-file-error current-file file-path)]
+          ;;   (state/pub-event! [:notification/show
+          ;;                      {:content error
+          ;;                       :status :error
+          ;;                       :clear? false}]))
+          )))))
+
+(defn- validate-and-get-blocks-to-delete
+  "An implementation for the delete-blocks-fn in graph-parser/parse-file"
+  [repo conn file-page file-path retain-uuid-blocks]
+  (validate-existing-file repo conn file-page file-path)
+  (graph-parser/get-blocks-to-delete @conn file-page file-path retain-uuid-blocks))
+
+(defn- reset-file!*
+  "Parse file.
+   Decide how to treat the parsed file based on the file's triggering event
+   options -
+     :fs/reset-event - the event that triggered the file update
+     :fs/local-file-change - file changed on local disk
+     :fs/remote-file-change - file changed on remote"
+  [db-conn file-path content options]
+  (graph-parser/parse-file db-conn file-path content options))
+
+(defn reset-file!
+  "Main fn for updating a db with the results of a parsed file"
+  ([repo conn file-path content]
+   (reset-file! repo conn file-path content {}))
+  ([repo conn file-path content {:keys [verbose _ctime _mtime] :as options}]
+   (let [config (worker-state/get-config repo)
+         options (merge (dissoc options :verbose)
+                        {:delete-blocks-fn (partial validate-and-get-blocks-to-delete repo conn)
+                         ;; Options here should also be present in gp-cli/parse-graph
+                         :extract-options (merge
+                                           {:user-config config
+                                            :date-formatter (worker-state/get-date-formatter repo)
+                                            :block-pattern (common-config/get-block-pattern
+                                                            (or (common-util/get-format file-path) :markdown))
+                                            :filename-format (:file/name-format config)}
+                                           ;; To avoid skipping the `:or` bounds for keyword destructuring
+                                           (when (some? verbose) {:verbose verbose}))})]
+     (:tx (reset-file!* conn file-path content options)))))

+ 87 - 176
src/test/frontend/fs/diff_merge_test.cljs

@@ -3,7 +3,6 @@
             [cljs.test :refer [are deftest is]]
             [cljs.test :refer [are deftest is]]
             [frontend.db.conn :as conn]
             [frontend.db.conn :as conn]
             [frontend.fs.diff-merge :as fs-diff]
             [frontend.fs.diff-merge :as fs-diff]
-            [frontend.handler.file-based.reset-file :as reset-file-handler]
             [logseq.graph-parser :as graph-parser]
             [logseq.graph-parser :as graph-parser]
             [logseq.graph-parser.db :as gp-db]
             [logseq.graph-parser.db :as gp-db]
             [logseq.graph-parser.mldoc :as gp-mldoc]
             [logseq.graph-parser.mldoc :as gp-mldoc]
@@ -25,13 +24,13 @@
   (are [text diff-blocks]
   (are [text diff-blocks]
        (= (org-text->diffblocks text)
        (= (org-text->diffblocks text)
           diff-blocks)
           diff-blocks)
-        ":PROPERTIES:
+    ":PROPERTIES:
 :ID:       72289d9a-eb2f-427b-ad97-b605a4b8c59b
 :ID:       72289d9a-eb2f-427b-ad97-b605a4b8c59b
 :END:
 :END:
 #+tItLe: Well parsed!"
 #+tItLe: Well parsed!"
-[{:body ":PROPERTIES:\n:ID:       72289d9a-eb2f-427b-ad97-b605a4b8c59b\n:END:\n#+tItLe: Well parsed!"
-  :uuid "72289d9a-eb2f-427b-ad97-b605a4b8c59b"
-  :level 1}]
+    [{:body ":PROPERTIES:\n:ID:       72289d9a-eb2f-427b-ad97-b605a4b8c59b\n:END:\n#+tItLe: Well parsed!"
+      :uuid "72289d9a-eb2f-427b-ad97-b605a4b8c59b"
+      :level 1}]
 
 
     "#+title: Howdy"
     "#+title: Howdy"
     [{:body "#+title: Howdy" :uuid nil :level 1}]
     [{:body "#+title: Howdy" :uuid nil :level 1}]
@@ -62,37 +61,37 @@
   (are [text diff-blocks]
   (are [text diff-blocks]
        (= (text->diffblocks text)
        (= (text->diffblocks text)
           diff-blocks)
           diff-blocks)
-  "- a
+    "- a
 \t- b
 \t- b
 \t\t- c"
 \t\t- c"
-  [{:body "a" :uuid nil :level 1}
-   {:body "b" :uuid nil :level 2}
-   {:body "c" :uuid nil :level 3}]
+    [{:body "a" :uuid nil :level 1}
+     {:body "b" :uuid nil :level 2}
+     {:body "c" :uuid nil :level 3}]
 
 
-"- a
+    "- a
 \t- b
 \t- b
 \t\t- c
 \t\t- c
 \t\t  multiline
 \t\t  multiline
 - d"
 - d"
-[{:body "a" :uuid nil :level 1}
- {:body "b" :uuid nil :level 2}
- {:body "c\nmultiline" :uuid nil :level 3}
- {:body "d" :uuid nil :level 1}]
+    [{:body "a" :uuid nil :level 1}
+     {:body "b" :uuid nil :level 2}
+     {:body "c\nmultiline" :uuid nil :level 3}
+     {:body "d" :uuid nil :level 1}]
 
 
-  "## hello
+    "## hello
 \t- world
 \t- world
 \t\t- nice
 \t\t- nice
 \t\t\t- nice
 \t\t\t- nice
 \t\t\t- bingo
 \t\t\t- bingo
 \t\t\t- world"
 \t\t\t- world"
-  [{:body "## hello" :uuid nil :level 1}
-   {:body "world" :uuid nil :level 2}
-   {:body "nice" :uuid nil :level 3}
-   {:body "nice" :uuid nil :level 4}
-   {:body "bingo" :uuid nil :level 4}
-   {:body "world" :uuid nil :level 4}]
-
-  "# a
+    [{:body "## hello" :uuid nil :level 1}
+     {:body "world" :uuid nil :level 2}
+     {:body "nice" :uuid nil :level 3}
+     {:body "nice" :uuid nil :level 4}
+     {:body "bingo" :uuid nil :level 4}
+     {:body "world" :uuid nil :level 4}]
+
+    "# a
 ## b
 ## b
 ### c
 ### c
 #### d
 #### d
@@ -102,27 +101,27 @@
 \t\t- h
 \t\t- h
 \t- i
 \t- i
 - j"
 - j"
-  [{:body "# a" :uuid nil :level 1}
-   {:body "## b" :uuid nil :level 1}
-   {:body "### c" :uuid nil :level 1}
-   {:body "#### d" :uuid nil :level 1}
-   {:body "### e" :uuid nil :level 1}
-   {:body "f" :uuid nil :level 1}
-   {:body "g" :uuid nil :level 2}
-   {:body "h" :uuid nil :level 3}
-   {:body "i" :uuid nil :level 2}
-   {:body "j" :uuid nil :level 1}]
+    [{:body "# a" :uuid nil :level 1}
+     {:body "## b" :uuid nil :level 1}
+     {:body "### c" :uuid nil :level 1}
+     {:body "#### d" :uuid nil :level 1}
+     {:body "### e" :uuid nil :level 1}
+     {:body "f" :uuid nil :level 1}
+     {:body "g" :uuid nil :level 2}
+     {:body "h" :uuid nil :level 3}
+     {:body "i" :uuid nil :level 2}
+     {:body "j" :uuid nil :level 1}]
 
 
     "- a\n  id:: 63e25526-3612-4fb1-8cf9-f66db1254a58
     "- a\n  id:: 63e25526-3612-4fb1-8cf9-f66db1254a58
 \t- b
 \t- b
 \t\t- c"
 \t\t- c"
-[{:body "a\nid:: 63e25526-3612-4fb1-8cf9-f66db1254a58"
-  :uuid "63e25526-3612-4fb1-8cf9-f66db1254a58" :level 1}
- {:body "b" :uuid nil :level 2}
- {:body "c" :uuid nil :level 3}]
+    [{:body "a\nid:: 63e25526-3612-4fb1-8cf9-f66db1254a58"
+      :uuid "63e25526-3612-4fb1-8cf9-f66db1254a58" :level 1}
+     {:body "b" :uuid nil :level 2}
+     {:body "c" :uuid nil :level 3}]
 
 
-  "alias:: ⭐️\nicon:: ⭐️"
-[{:body "alias:: ⭐️\nicon:: ⭐️", :level 1, :uuid nil}]))
+    "alias:: ⭐️\nicon:: ⭐️"
+    [{:body "alias:: ⭐️\nicon:: ⭐️", :level 1, :uuid nil}]))
 
 
 (defn text->diffblocks-alt
 (defn text->diffblocks-alt
   [text]
   [text]
@@ -206,7 +205,7 @@
 \t\t\t- nice
 \t\t\t- nice
 \t\t\t- bingo
 \t\t\t- bingo
 \t\t\t- world"
 \t\t\t- world"
-      "## Halooooo
+    "## Halooooo
 \t- world
 \t- world
 \t\t- nice
 \t\t- nice
 \t\t\t- nice
 \t\t\t- nice
@@ -216,26 +215,26 @@
     ;; See https://github.com/logseq/diff-merge#usage
     ;; See https://github.com/logseq/diff-merge#usage
     [[]
     [[]
      [[-1 {:body "## hello"
      [[-1 {:body "## hello"
-          :level 1
-          :uuid nil}]
+           :level 1
+           :uuid nil}]
       [1  {:body "## Halooooo"
       [1  {:body "## Halooooo"
-          :level 1
-          :uuid nil}]]
+           :level 1
+           :uuid nil}]]
      [[0 {:body "world"
      [[0 {:body "world"
-         :level 2
-         :uuid nil}]]
+          :level 2
+          :uuid nil}]]
      [[0 {:body "nice"
      [[0 {:body "nice"
-         :level 3
-         :uuid nil}]]
+          :level 3
+          :uuid nil}]]
      [[0 {:body "nice"
      [[0 {:body "nice"
-         :level 4
-         :uuid nil}]]
+          :level 4
+          :uuid nil}]]
      [[0 {:body "bingo"
      [[0 {:body "bingo"
-         :level 4
-         :uuid nil}]]
+          :level 4
+          :uuid nil}]]
      [[0 {:body "world"
      [[0 {:body "world"
-         :level 4
-         :uuid nil}]]]
+          :level 4
+          :uuid nil}]]]
 
 
     "## hello
     "## hello
 \t- world
 \t- world
@@ -244,7 +243,7 @@
 \t\t\t- nice
 \t\t\t- nice
 \t\t\t- bingo
 \t\t\t- bingo
 \t\t\t- world"
 \t\t\t- world"
-"## Halooooo
+    "## Halooooo
 \t- world
 \t- world
 \t\t- nice
 \t\t- nice
 \t\t\t- nice
 \t\t\t- nice
@@ -252,37 +251,37 @@
 \t\t\t- world"
 \t\t\t- world"
 ;; Empty op, because no insertion op before the first base block required
 ;; Empty op, because no insertion op before the first base block required
 ;; See https://github.com/logseq/diff-merge#usage
 ;; See https://github.com/logseq/diff-merge#usage
-[[]
- [[-1 {:body "## hello"
-       :level 1
-       :uuid nil}]
-  [1  {:body "## Halooooo"
-       :level 1
-       :uuid nil}]
-  [1 {:body "world"
-      :level 2
-      :uuid nil}]]
- [[-1 {:body "world\nid:: 63e25526-3612-4fb1-8cf9-abcd12354abc"
-      :level 2
-      :uuid "63e25526-3612-4fb1-8cf9-abcd12354abc"}]]
- [[0 {:body "nice"
-      :level 3
-      :uuid nil}]]
- [[0 {:body "nice"
-      :level 4
-      :uuid nil}]]
- [[0 {:body "bingo"
-      :level 4
-      :uuid nil}]]
- [[0 {:body "world"
-      :level 4
-      :uuid nil}]]]
-
-""
-"- abc def"
-[[[1 {:body "abc def"
-      :level 1
-      :uuid nil}]]]))
+    [[]
+     [[-1 {:body "## hello"
+           :level 1
+           :uuid nil}]
+      [1  {:body "## Halooooo"
+           :level 1
+           :uuid nil}]
+      [1 {:body "world"
+          :level 2
+          :uuid nil}]]
+     [[-1 {:body "world\nid:: 63e25526-3612-4fb1-8cf9-abcd12354abc"
+           :level 2
+           :uuid "63e25526-3612-4fb1-8cf9-abcd12354abc"}]]
+     [[0 {:body "nice"
+          :level 3
+          :uuid nil}]]
+     [[0 {:body "nice"
+          :level 4
+          :uuid nil}]]
+     [[0 {:body "bingo"
+          :level 4
+          :uuid nil}]]
+     [[0 {:body "world"
+          :level 4
+          :uuid nil}]]]
+
+    ""
+    "- abc def"
+    [[[1 {:body "abc def"
+          :level 1
+          :uuid nil}]]]))
 
 
 (deftest db->diffblocks
 (deftest db->diffblocks
   (let [conn (gp-db/start-conn)]
   (let [conn (gp-db/start-conn)]
@@ -351,7 +350,7 @@
           diff-blocks)
           diff-blocks)
     [[["Property_Drawer" [["foo" "#bar" [["Tag" [["Plain" "bar"]]]]] ["baz" "#bing" [["Tag" [["Plain" "bing"]]]]]]] {:start_pos 0, :end_pos 22}]]
     [[["Property_Drawer" [["foo" "#bar" [["Tag" [["Plain" "bar"]]]]] ["baz" "#bing" [["Tag" [["Plain" "bing"]]]]]]] {:start_pos 0, :end_pos 22}]]
     "foo:: #bar\nbaz:: #bing"
     "foo:: #bar\nbaz:: #bing"
-     [{:body "foo:: #bar\nbaz:: #bing", :level 1, :uuid nil}]))
+    [{:body "foo:: #bar\nbaz:: #bing", :level 1, :uuid nil}]))
 
 
 (deftest ast-empty-diff-test
 (deftest ast-empty-diff-test
   (are [ast text diff-ops]
   (are [ast text diff-ops]
@@ -360,95 +359,7 @@
           diff-ops)
           diff-ops)
     [[["Property_Drawer" [["foo" "#bar" [["Tag" [["Plain" "bar"]]]]] ["baz" "#bing" [["Tag" [["Plain" "bing"]]]]]]] {:start_pos 0, :end_pos 22}]]
     [[["Property_Drawer" [["foo" "#bar" [["Tag" [["Plain" "bar"]]]]] ["baz" "#bing" [["Tag" [["Plain" "bing"]]]]]]] {:start_pos 0, :end_pos 22}]]
     "foo:: #bar\nbaz:: #bing"
     "foo:: #bar\nbaz:: #bing"
-     [[[1 {:body "foo:: #bar\nbaz:: #bing", :level 1, :uuid nil}]]]))
-
-;; Ensure diff-merge-uuids follows the id:: in the content
-(deftest diff-merge-uuid-extract-test
-  (let [conn (gp-db/start-conn)
-        foo-content (str "- abc
-  id:: 11451400-0000-0000-0000-000000000000\n"
-                 "- def
-  id:: 63246324-6324-6324-6324-632463246324\n")
-        bar-content (str "- ghi
-  id:: 11451411-1111-1111-1111-111111111111\n"
-                         "\t- jkl
-\t  id:: 63241234-1234-1234-1234-123412341234\n") ]
-    (graph-parser/parse-file conn "foo.md" foo-content {})
-    (graph-parser/parse-file conn "bar.md" bar-content {})
-    (are [ast content page-name uuids]
-         (= (with-redefs [conn/get-db (constantly @conn)]
-              (#'reset-file-handler/diff-merge-uuids-2ways :markdown ast content {:page-name page-name
-                                                                             :block-pattern "-"}))
-            uuids)
-
-      (gp-mldoc/->edn (str foo-content "- newline\n") (gp-mldoc/default-config :markdown))
-      (str foo-content "- newline\n")
-      "foo"
-      ["11451400-0000-0000-0000-000000000000"
-       "63246324-6324-6324-6324-632463246324"
-       nil]
-
-      (gp-mldoc/->edn (str bar-content "- newline\n") (gp-mldoc/default-config :markdown))
-      (str bar-content "- newline\n")
-      "bar"
-      ["11451411-1111-1111-1111-111111111111"
-       "63241234-1234-1234-1234-123412341234"
-       nil])))
-
-;; Ensure diff-merge-uuids keeps the block uuids unchanged at best effort
-(deftest diff-merge-uuid-persist-test
-  (let [conn (gp-db/start-conn)
-        foo-content (str "- abc\n"
-                         "- def\n")
-        bar-content (str "- ghi\n"
-                         "\t- jkl\n")
-        foo-new-content (str foo-content "- newline\n")
-        new-bar-content (str  "- newline\n" bar-content)]
-    (graph-parser/parse-file conn "foo-persist.md" foo-content {})
-    (graph-parser/parse-file conn "bar-persist.md" bar-content {})
-    ;; Compare if the uuids are the same as those inside DB when the modified content (adding new line) is parsed
-    (are [ast content page-name DB-uuids->new-uuids-fn]
-         (= (with-redefs [conn/get-db (constantly @conn)]
-              (#'reset-file-handler/diff-merge-uuids-2ways :markdown ast content {:page-name page-name
-                                                                             :block-pattern "-"}))
-            ;; Get all uuids under the page
-            (->> page-name
-                 (test-db->diff-blocks conn)
-                 (map :uuid)
-                 (vec)
-                 (DB-uuids->new-uuids-fn)))
-
-      ;; Append a new line to foo
-      (gp-mldoc/->edn foo-new-content (gp-mldoc/default-config :markdown))
-      foo-new-content
-      "foo-persist"
-      (fn [db-uuids] (conj db-uuids nil))
-
-      ;; Prepend a new line to bar
-      (gp-mldoc/->edn new-bar-content (gp-mldoc/default-config :markdown))
-      new-bar-content
-      "bar-persist"
-      (fn [db-uuids] (cons nil db-uuids)))))
-
-(deftest diff-merge-error-capture-test
-  ;; Any exception thrown in diff-merge-uuids-2ways should be captured and returned a nil
-  (let [conn (gp-db/start-conn)
-        foo-content (str "- abc\n"
-                         "- def\n")
-        foo-new-content (str foo-content "- newline\n")]
-    (graph-parser/parse-file conn "foo-error-cap.md" foo-content {})
-    (are [ast content page-name]
-         (= (with-redefs [conn/get-db (constantly @conn)
-                                ;; Hijack the function to throw an exception
-                          fs-diff/db->diff-blocks #(throw (js/Error. "intentional exception for testing diff-merge-uuids-2ways error capture"))]
-              (#'reset-file-handler/diff-merge-uuids-2ways :markdown ast content {:page-name page-name
-                                                                                   :block-pattern "-"}))
-            nil)
-
-            ;; Append a new line to foo
-      (gp-mldoc/->edn foo-new-content (gp-mldoc/default-config :markdown))
-      foo-new-content
-      "foo-error-cap")))
+    [[[1 {:body "foo:: #bar\nbaz:: #bing", :level 1, :uuid nil}]]]))
 
 
 (deftest test-remove-indentation-spaces
 (deftest test-remove-indentation-spaces
   (is (= "" (gp-mldoc/remove-indentation-spaces "" 0 false)))
   (is (= "" (gp-mldoc/remove-indentation-spaces "" 0 false)))