fix: cut paste lost children after synced

This commit is contained in:
Tienson Qin
2026-03-05 17:08:49 +08:00
parent 7cef3c749e
commit 7cddf537da
2 changed files with 55 additions and 5 deletions

View File

@@ -696,6 +696,17 @@
;; (prn :debug :sanitized-tx-data sanitized-tx-data))
sanitized-tx-data))
(defn- created-block-uuids
[tx-data]
(->> tx-data
(keep (fn [item]
(when (and (vector? item)
(= :db/add (first item))
(>= (count item) 4)
(= :block/uuid (nth item 2)))
(nth item 3))))
set))
(defn- flush-pending!
[repo client]
(let [inflight @(:inflight client)
@@ -1224,11 +1235,16 @@
*remote-deleted-ids (atom #{})
*rebase-tx-data (atom [])
db @conn
remote-deleted-blocks (->> tx-data
(keep (fn [item]
(when (= :db/retractEntity (first item))
(d/entity db (second item))))))
remote-deleted-block-ids (set (map :block/uuid remote-deleted-blocks))
recreated-block-ids (created-block-uuids tx-data)
raw-remote-deleted-blocks (->> tx-data
(keep (fn [item]
(when (= :db/retractEntity (first item))
(d/entity db (second item))))))
raw-remote-deleted-block-ids (set (keep :block/uuid raw-remote-deleted-blocks))
remote-deleted-block-ids (set/difference raw-remote-deleted-block-ids recreated-block-ids)
remote-deleted-blocks (remove (fn [block]
(contains? recreated-block-ids (:block/uuid block)))
raw-remote-deleted-blocks)
safe-remote-tx-data (->> tx-data
(remove (fn [item]
(or (= :db/retractEntity (first item))

View File

@@ -385,6 +385,40 @@
(let [child' (d/entity @conn [:block/uuid child-uuid])]
(is (nil? child'))))))))
(deftest ^:long cut-paste-parent-with-child-keeps-child-parent-after-sync-test
(testing "remote tx can retract and recreate target uuid; child should point to recreated parent"
(let [conn (db-test/create-conn-with-blocks
{:pages-and-blocks
[{:page {:block/title "page 1"}
:blocks [{:block/title "parent"
:build/children [{:block/title "child"}]}
{:block/title "target"}]}]})
parent (db-test/find-block-by-content @conn "parent")
child (db-test/find-block-by-content @conn "child")
target (db-test/find-block-by-content @conn "target")
page-uuid (:block/uuid (:block/page parent))
parent-uuid (:block/uuid parent)
child-uuid (:block/uuid child)
target-uuid (:block/uuid target)
target-order (:block/order target)]
(with-datascript-conns conn nil
(fn []
(#'db-sync/apply-remote-tx!
test-repo
nil
[[:db/retractEntity [:block/uuid parent-uuid]]
[:db/retractEntity [:block/uuid target-uuid]]
[:db/add -1 :block/uuid target-uuid]
[:db/add -1 :block/title "parent"]
[:db/add -1 :block/parent [:block/uuid page-uuid]]
[:db/add -1 :block/page [:block/uuid page-uuid]]
[:db/add -1 :block/order target-order]
[:db/add [:block/uuid child-uuid] :block/parent [:block/uuid target-uuid]]])
(let [parent' (d/entity @conn [:block/uuid target-uuid])
child' (d/entity @conn [:block/uuid child-uuid])]
(is (= "parent" (:block/title parent')))
(is (= (:db/id parent') (:db/id (:block/parent child'))))))))))
(deftest ^:long fix-duplicate-orders-after-rebase-test
(testing "duplicate order updates are fixed after remote rebase"
(let [{:keys [conn client-ops-conn child1 child2]} (setup-parent-child)