Skip to content

Commit d04f334

Browse files
committed
Do not emit conflict events for mutual deletions
No changes can be lost when documents are deleted on both ends
1 parent 098962d commit d04f334

File tree

2 files changed

+65
-11
lines changed

2 files changed

+65
-11
lines changed

src/sync.ts

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -507,17 +507,21 @@ export class Sync {
507507
node = mergeMutualDeletion(node);
508508
delete node.remote;
509509
} else if (node.remote.body !== undefined) {
510-
log('[Sync] Emitting conflict event');
511-
setTimeout(this.rs.local.emitChange.bind(this.rs.local), 10, {
512-
origin: 'conflict',
513-
path: node.path,
514-
oldValue: node.local.body,
515-
newValue: node.remote.body,
516-
lastCommonValue: node.common.body,
517-
oldContentType: node.local.contentType,
518-
newContentType: node.remote.contentType,
519-
lastCommonContentType: node.common.contentType
520-
});
510+
if (node.remote.body === false && node.local?.body === false) {
511+
// Deleted on both sides, nothing to do
512+
} else {
513+
log('[Sync] Emitting conflict event');
514+
setTimeout(this.rs.local.emitChange.bind(this.rs.local), 10, {
515+
origin: 'conflict',
516+
path: node.path,
517+
oldValue: node.local.body,
518+
newValue: node.remote.body,
519+
lastCommonValue: node.common.body,
520+
oldContentType: node.local.contentType,
521+
newContentType: node.remote.contentType,
522+
lastCommonContentType: node.common.contentType
523+
});
524+
}
521525

522526
if (node.remote.body === false) {
523527
node.common = {};

test/unit/sync.test.mjs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,56 @@ describe("Sync", function() {
949949
}, 20);
950950
});
951951
});
952+
953+
describe("when node was also deleted on remote", function() {
954+
beforeEach(function() {
955+
this.emitChange = sinon.spy(this.rs.local, "emitChange");
956+
957+
this.rs.sync.autoMergeDocument({
958+
path: "foo",
959+
common: { body: "foo", contentType: "bloo", revision: "common" },
960+
local: { body: false },
961+
remote: { body: false }
962+
});
963+
});
964+
965+
it("does not emit a conflict event", function(done) {
966+
setTimeout(() => {
967+
expect(this.emitChange.called).to.be.false;
968+
done();
969+
}, 20);
970+
});
971+
});
972+
973+
describe("when node was changed on remote, but deleted locally", function() {
974+
beforeEach(function() {
975+
this.emitChange = sinon.spy(this.rs.local, "emitChange");
976+
977+
this.rs.sync.autoMergeDocument({
978+
path: "foo",
979+
remote: { body: "bar", contentType: "text/plain", revision: "newrev"},
980+
common: { body: "foo", contentType: "text/plain", revision: "common" },
981+
local: { body: false }
982+
});
983+
});
984+
985+
it("emits a conflict event", function(done) {
986+
setTimeout(() => {
987+
expect(this.emitChange.called).to.be.true;
988+
expect(this.emitChange.getCall(0).firstArg).to.deep.equal({
989+
origin: "conflict",
990+
path: "foo",
991+
oldValue: false,
992+
newValue: "bar",
993+
lastCommonValue: "foo",
994+
oldContentType: undefined,
995+
newContentType: "text/plain",
996+
lastCommonContentType: "text/plain"
997+
});
998+
done();
999+
}, 20);
1000+
});
1001+
});
9521002
});
9531003

9541004
describe("#autoMergeFolder", function() {

0 commit comments

Comments
 (0)