fix(rtc): lost first block's rtc-ops when paste multiple blocks

This commit is contained in:
rcmerci
2025-12-15 22:54:31 +08:00
parent c9f1920e16
commit 208e3df662
2 changed files with 87 additions and 8 deletions

View File

@@ -6,13 +6,52 @@
[logseq.db :as ldb]
[logseq.db.frontend.property :as db-property]))
(defn remove-conflict-same-block-datoms
"remove conflict entity-datoms for same-block(same block/uuid) in same-entity-datoms-coll.
merge
[[[182 :block/uuid block-uuid1 1 false], ...]
[[183 :block/uuid block-uuid1 1 true], ...]]
into
[[[183 :block/uuid block-uuid1 1 true], ...]]
"
[same-entity-datoms-coll]
(let [entity-info (map (fn [datoms]
(let [first-datom (first datoms)
e (nth first-datom 0)
t (nth first-datom 3)
uuid (some (fn [d]
(when (keyword-identical? :block/uuid (nth d 1))
(nth d 2)))
datoms)]
{:e e :t t :uuid uuid :datoms datoms}))
same-entity-datoms-coll)
uuid-groups (group-by :uuid (filter :uuid entity-info))
loser-eids (reduce
(fn [acc [_uuid infos]]
(let [t-groups (group-by :t infos)]
(reduce
(fn [acc* [_t infos*]]
(if (> (count infos*) 1)
(let [sorted-infos (sort-by :e > infos*)
losers (rest sorted-infos)]
(into acc* (map :e losers)))
acc*))
acc
t-groups)))
#{}
uuid-groups)]
(if (seq loser-eids)
(map :datoms (remove #(contains? loser-eids (:e %)) entity-info))
same-entity-datoms-coll)))
(defn group-datoms-by-entity
"Groups transaction datoms by entity and returns a map of entity-id to datoms."
[tx-data]
(let [datom-vec-coll (map vec tx-data)
id->same-entity-datoms (group-by first datom-vec-coll)
id-order (distinct (map first datom-vec-coll))
same-entity-datoms-coll (map id->same-entity-datoms id-order)]
same-entity-datoms-coll (map id->same-entity-datoms id-order)
same-entity-datoms-coll (remove-conflict-same-block-datoms same-entity-datoms-coll)]
{:same-entity-datoms-coll same-entity-datoms-coll
:id->same-entity-datoms id->same-entity-datoms}))

View File

@@ -167,10 +167,10 @@
:block/tags :block/title :db/cardinality}]
#_{:clj-kondo/ignore [:unresolved-symbol :invalid-arity]}
(is (->> (me/find (subject/generate-rtc-ops-from-property-entities [ent])
([:move _ {:block-uuid ?block-uuid}]
[:update-page _ {:block-uuid ?block-uuid}]
[:update _ {:block-uuid ?block-uuid :av-coll ([!av-coll-attrs . _ ...] ...)}])
!av-coll-attrs)
([:move _ {:block-uuid ?block-uuid}]
[:update-page _ {:block-uuid ?block-uuid}]
[:update _ {:block-uuid ?block-uuid :av-coll ([!av-coll-attrs . _ ...] ...)}])
!av-coll-attrs)
set
(set/difference av-coll-attrs)
empty?))))
@@ -183,9 +183,49 @@
:block/tags :block/title}]
#_{:clj-kondo/ignore [:unresolved-symbol :invalid-arity]}
(is (->> (me/find (subject/generate-rtc-ops-from-class-entities [ent])
([:update-page _ {:block-uuid ?block-uuid}]
[:update _ {:block-uuid ?block-uuid :av-coll ([!av-coll-attrs . _ ...] ...)}])
!av-coll-attrs)
([:update-page _ {:block-uuid ?block-uuid}]
[:update _ {:block-uuid ?block-uuid :av-coll ([!av-coll-attrs . _ ...] ...)}])
!av-coll-attrs)
set
(set/difference av-coll-attrs)
empty?))))
(deftest remove-conflict-same-block-datoms-test
(testing "remove conflict entity-datoms for same-block"
(let [block-uuid #uuid "693ec519-e73e-4f2c-b517-7e75ca2c64da"
datoms-182 [[182 :logseq.property/created-by-ref 161 536870976 false]
[182 :block/created-at 1765721369994 536870976 false]
[182 :block/parent 162 536870976 false]
[182 :block/order "aF" 536870976 false]
[182 :block/tx-id 536870972 536870976 false]
[182 :block/page 162 536870976 false]
[182 :block/uuid block-uuid 536870976 false]
[182 :block/title "" 536870976 false]
[182 :block/updated-at 1765721369994 536870976 false]]
datoms-185 [[185 :block/parent 162 536870976 true]
[185 :logseq.property/created-by-ref 161 536870976 true]
[185 :block/title "111" 536870976 true]
[185 :logseq.property.embedding/hnsw-label-updated-at 0 536870976 true]
[185 :block/order "aG" 536870976 true]
[185 :block/page 162 536870976 true]
[185 :block/created-at 1765721370449 536870976 true]
[185 :block/updated-at 1765721370449 536870976 true]
[185 :block/uuid block-uuid 536870976 true]
[185 :block/tx-id 536870976 536870977 true]]
same-entity-datoms-coll [datoms-182 datoms-185]
result (subject/remove-conflict-same-block-datoms same-entity-datoms-coll)]
(is (= 1 (count result)))
(is (= 185 (nth (ffirst result) 0)))
(is (= datoms-185 (first result)))))
(testing "remove conflict entity-datoms should preserve order"
(let [block-uuid1 #uuid "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
block-uuid2 #uuid "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
datoms-1 [[100 :block/uuid block-uuid1 1 true]]
datoms-2 [[101 :block/uuid block-uuid2 2 true]]
datoms-3 [[102 :block/uuid block-uuid2 2 true]] ;; Conflict with datoms-2, wins (higher ID)
same-entity-datoms-coll [datoms-1 datoms-2 datoms-3]
result (subject/remove-conflict-same-block-datoms same-entity-datoms-coll)]
(is (= 2 (count result)))
(is (= datoms-1 (first result)))
(is (= datoms-3 (second result))))))