From 32806264cefeff3aba96208a2344a33cb5d6e57f Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Fri, 10 Apr 2026 14:49:54 +0800 Subject: [PATCH] fix: reversed datoms should be normalized too for rebase --- deps/db/src/logseq/db/common/normalize.cljs | 61 +++++++------------- src/main/frontend/worker/sync/apply_txs.cljs | 8 ++- src/test/frontend/worker/db_sync_test.cljs | 12 ++-- 3 files changed, 33 insertions(+), 48 deletions(-) diff --git a/deps/db/src/logseq/db/common/normalize.cljs b/deps/db/src/logseq/db/common/normalize.cljs index aa4d61b6e6..f88af2f4fe 100644 --- a/deps/db/src/logseq/db/common/normalize.cljs +++ b/deps/db/src/logseq/db/common/normalize.cljs @@ -141,16 +141,6 @@ tx-data)] (concat recreated-block-retract-ops datoms-for-retracted-eids others end-retract-ops))) -(defn- collect-title-updated-entities - [tx-data] - (->> tx-data - (keep (fn [d] - (when (= (count d) 5) - (let [[e a _v _t added] d] - (when (and added (= :block/title a)) - e))))) - set)) - (defn- resolve-eid [db-before db-after retract? e] (if retract? @@ -163,25 +153,19 @@ (or (= :db.type/ref (:db/valueType (d/entity db-after attr))) (= :db.type/ref (:db/valueType (d/entity db-before attr))))) -(defn- normalize-datom-item - [db-after db-before title-updated-entities [e a v t added]] +(defn normalize-datom + [db-after db-before [e a v t added]] (let [retract? (not added) - drop-retract? - (and retract? - (or (contains? #{:block/created-at :block/updated-at} a) - (and (= :block/title a) - (contains? title-updated-entities e))))] - (when-not drop-retract? - (let [e' (resolve-eid db-before db-after retract? e) - v' (if (and (integer? v) - (pos? v) - (ref-value-type? db-after db-before a)) - (resolve-eid db-before db-after retract? v) - v)] - (when (and (some? e') (some? v')) - (if added - [:db/add e' a v' t] - [:db/retract e' a v' t])))))) + e' (resolve-eid db-before db-after retract? e) + v' (if (and (integer? v) + (pos? v) + (ref-value-type? db-after db-before a)) + (resolve-eid db-before db-after retract? v) + v)] + (when (and (some? e') (some? v')) + (if added + [:db/add e' a v' t] + [:db/retract e' a v' t])))) (defn- normalize-retract-entity-item [db-before d] @@ -192,20 +176,19 @@ [op e']))) (defn- normalize-tx-item - [db-after db-before title-updated-entities d] + [db-after db-before d] (case (count d) - 5 (normalize-datom-item db-after db-before title-updated-entities d) + 5 (normalize-datom db-after db-before d) 2 (normalize-retract-entity-item db-before d) nil)) (defn normalize-tx-data [db-after db-before tx-data] - (let [title-updated-entities (collect-title-updated-entities tx-data)] - (->> tx-data - remove-conflict-datoms - (replace-attr-retract-with-retract-entity db-after) - sort-datoms - (keep #(normalize-tx-item db-after db-before title-updated-entities %)) - (remove-retract-entity-ref db-after) - reorder-retract-entity - distinct))) + (->> tx-data + remove-conflict-datoms + (replace-attr-retract-with-retract-entity db-after) + sort-datoms + (keep #(normalize-tx-item db-after db-before %)) + (remove-retract-entity-ref db-after) + reorder-retract-entity + distinct)) diff --git a/src/main/frontend/worker/sync/apply_txs.cljs b/src/main/frontend/worker/sync/apply_txs.cljs index daf775f032..2ad99ab336 100644 --- a/src/main/frontend/worker/sync/apply_txs.cljs +++ b/src/main/frontend/worker/sync/apply_txs.cljs @@ -98,12 +98,13 @@ (declare replay-canonical-outliner-op! invalid-rebase-op!) -(defn reverse-tx-data [_db-before db-after tx-data] +(defn reverse-tx-data [db-before db-after tx-data] (->> tx-data reverse (keep (fn [[e a v t added]] - (when (and (some? a) (some? v) (some? t) (boolean? added)) - [(if added :db/retract :db/add) e a v t]))) + (let [reversed-datom (d/datom e a v t (not added))] + ;; trick: reverse the order of `db-before` and `db-after` + (db-normalize/normalize-datom db-before db-after reversed-datom)))) (db-normalize/replace-attr-retract-with-retract-entity-v2 db-after))) (defn normalize-rebased-pending-tx @@ -1075,6 +1076,7 @@ [repo {:keys [tx-data db-after db-before] :as tx-report}] (let [normalized (normalize-tx-data db-after db-before tx-data) reversed-datoms (reverse-tx-data db-before db-after tx-data)] + ;; (prn :debug :reversed-datoms reversed-datoms) ;; (prn :debug :enqueue-local-tx :tx-data) ;; (cljs.pprint/pprint tx-data) ;; (prn :debug :enqueue-local-tx :normalized) diff --git a/src/test/frontend/worker/db_sync_test.cljs b/src/test/frontend/worker/db_sync_test.cljs index fedfee8fc5..e0f9b031be 100644 --- a/src/test/frontend/worker/db_sync_test.cljs +++ b/src/test/frontend/worker/db_sync_test.cljs @@ -3617,13 +3617,13 @@ (d/transact! conn [[:db/add (:db/id child1) :block/title "same"]]) (let [pending-before (#'sync-apply/pending-txs test-repo)] (is (= 1 (count pending-before))) - (#'sync-apply/apply-remote-tx! - test-repo - nil - [[:db/add (:db/id child1) :block/title "same"]]) + (#'sync-apply/apply-remote-tx! + test-repo + nil + [[:db/add (:db/id child1) :block/title "same"]]) (let [pending-after (#'sync-apply/pending-txs test-repo)] - (is (empty? pending-after)) - (is (nil? (:tx-id (first pending-after)))))))))))) + (is (= 1 (count pending-after))) + (is (uuid? (:tx-id (first pending-after)))))))))))) (deftest rebase-later-tx-for-new-block-uses-lookup-ref-test (testing "rebased tx after creating a block should use lookup ref instead of stale tempid"