mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-21 22:19:41 +01:00
fix: expect merge conflicts in notebooks
This commit is contained in:
@@ -259,6 +259,46 @@ test.skip(
|
|||||||
60 * 1000
|
60 * 1000
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test.skip(
|
||||||
|
"issue: new topics on 2 devices are not properly synced",
|
||||||
|
async () => {
|
||||||
|
const deviceA = await initializeDevice("deviceA");
|
||||||
|
const deviceB = await initializeDevice("deviceB");
|
||||||
|
|
||||||
|
const id = await deviceA.notebooks.add({ title: "Notebook 1" });
|
||||||
|
|
||||||
|
await syncAndWait(deviceA, deviceB, false);
|
||||||
|
|
||||||
|
expect(deviceB.notebooks.notebook(id)).toBeDefined();
|
||||||
|
|
||||||
|
await deviceA.notebooks.notebook(id).topics.add("Topic 1");
|
||||||
|
|
||||||
|
// to create a conflict
|
||||||
|
await delay(1500);
|
||||||
|
|
||||||
|
await deviceB.notebooks.notebook(id).topics.add("Topic 2");
|
||||||
|
|
||||||
|
expect(deviceA.notebooks.notebook(id).topics.has("Topic 1")).toBeTruthy();
|
||||||
|
|
||||||
|
expect(deviceB.notebooks.notebook(id).topics.has("Topic 2")).toBeTruthy();
|
||||||
|
|
||||||
|
await syncAndWait(deviceA, deviceB, false);
|
||||||
|
|
||||||
|
await delay(1000);
|
||||||
|
|
||||||
|
await syncAndWait(deviceB, deviceB, false);
|
||||||
|
|
||||||
|
expect(deviceA.notebooks.notebook(id).topics.has("Topic 1")).toBeTruthy();
|
||||||
|
expect(deviceB.notebooks.notebook(id).topics.has("Topic 1")).toBeTruthy();
|
||||||
|
|
||||||
|
expect(deviceA.notebooks.notebook(id).topics.has("Topic 2")).toBeTruthy();
|
||||||
|
expect(deviceB.notebooks.notebook(id).topics.has("Topic 2")).toBeTruthy();
|
||||||
|
|
||||||
|
await cleanup(deviceA, deviceB);
|
||||||
|
},
|
||||||
|
60 * 1000
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {string} id
|
* @param {string} id
|
||||||
@@ -274,11 +314,11 @@ async function initializeDevice(id, capabilities = []) {
|
|||||||
|
|
||||||
const device = new Database(new NodeStorageInterface(), EventSource, FS);
|
const device = new Database(new NodeStorageInterface(), EventSource, FS);
|
||||||
device.host({
|
device.host({
|
||||||
API_HOST: "http://192.168.43.221:5264",
|
API_HOST: "http://192.168.10.29:5264",
|
||||||
AUTH_HOST: "http://192.168.43.221:8264",
|
AUTH_HOST: "http://192.168.10.29:8264",
|
||||||
SSE_HOST: "http://192.168.43.221:7264",
|
SSE_HOST: "http://192.168.10.29:7264",
|
||||||
ISSUES_HOST: "http://192.168.43.221:2624",
|
ISSUES_HOST: "http://192.168.10.29:2624",
|
||||||
SUBSCRIPTIONS_HOST: "http://192.168.43.221:9264",
|
SUBSCRIPTIONS_HOST: "http://192.168.10.29:9264",
|
||||||
});
|
});
|
||||||
|
|
||||||
await device.init(id);
|
await device.init(id);
|
||||||
|
|||||||
@@ -20,10 +20,13 @@ class Merger {
|
|||||||
set: (item) => this._db.notes.merge(item),
|
set: (item) => this._db.notes.merge(item),
|
||||||
},
|
},
|
||||||
notebook: {
|
notebook: {
|
||||||
|
threshold: 1000,
|
||||||
get: (id) => this._db.notebooks.notebook(id),
|
get: (id) => this._db.notebooks.notebook(id),
|
||||||
set: (item) => this._db.notebooks.merge(item),
|
set: (item) => this._db.notebooks.merge(item),
|
||||||
|
conflict: (_local, remote) => this._db.notebooks.merge(remote),
|
||||||
},
|
},
|
||||||
content: {
|
content: {
|
||||||
|
threshold: process.env.NODE_ENV === "test" ? 6 * 1000 : 60 * 1000,
|
||||||
get: (id) => this._db.content.raw(id),
|
get: (id) => this._db.content.raw(id),
|
||||||
set: (item) => this._db.content.add(item),
|
set: (item) => this._db.content.add(item),
|
||||||
conflict: async (local, remote) => {
|
conflict: async (local, remote) => {
|
||||||
@@ -138,7 +141,13 @@ class Merger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async _mergeItemWithConflicts(remoteItem, get, add, markAsConflicted) {
|
async _mergeItemWithConflicts(
|
||||||
|
remoteItem,
|
||||||
|
get,
|
||||||
|
add,
|
||||||
|
markAsConflicted,
|
||||||
|
threshold
|
||||||
|
) {
|
||||||
remoteItem = await this._deserialize(remoteItem);
|
remoteItem = await this._deserialize(remoteItem);
|
||||||
let localItem = await get(remoteItem.id);
|
let localItem = await get(remoteItem.id);
|
||||||
|
|
||||||
@@ -149,15 +158,13 @@ class Merger {
|
|||||||
const isModified = localItem.dateModified > this._lastSynced;
|
const isModified = localItem.dateModified > this._lastSynced;
|
||||||
if (isModified && !isResolved) {
|
if (isModified && !isResolved) {
|
||||||
// If time difference between local item's edits & remote item's edits
|
// If time difference between local item's edits & remote item's edits
|
||||||
// is less than 1 minute, we shouldn't trigger a merge conflict; instead
|
// is less than threshold, we shouldn't trigger a merge conflict; instead
|
||||||
// we will keep the most recently changed item.
|
// we will keep the most recently changed item.
|
||||||
const timeDiff =
|
const timeDiff =
|
||||||
Math.max(remoteItem.dateModified, localItem.dateModified) -
|
Math.max(remoteItem.dateModified, localItem.dateModified) -
|
||||||
Math.min(remoteItem.dateModified, localItem.dateModified);
|
Math.min(remoteItem.dateModified, localItem.dateModified);
|
||||||
|
|
||||||
const ONE_MINUTE =
|
if (timeDiff < threshold) {
|
||||||
process.env.NODE_ENV === "test" ? 6 * 1000 : 60 * 1000;
|
|
||||||
if (timeDiff < ONE_MINUTE) {
|
|
||||||
if (remoteItem.dateModified > localItem.dateModified) {
|
if (remoteItem.dateModified > localItem.dateModified) {
|
||||||
await add(remoteItem);
|
await add(remoteItem);
|
||||||
}
|
}
|
||||||
@@ -188,7 +195,8 @@ class Merger {
|
|||||||
item,
|
item,
|
||||||
definition.get,
|
definition.get,
|
||||||
definition.set,
|
definition.set,
|
||||||
definition.conflict
|
definition.conflict,
|
||||||
|
definition.threshold
|
||||||
);
|
);
|
||||||
} else if (definition.get && definition.set) {
|
} else if (definition.get && definition.set) {
|
||||||
await this._mergeItem(item, definition.get, definition.set);
|
await this._mergeItem(item, definition.get, definition.set);
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ export default class Notebooks extends Collection {
|
|||||||
isChanged = true;
|
isChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isChanged) remoteNotebook.dateModified = Date.now(); // we update the dateEdited so it can be synced back
|
remoteNotebook.remote = !isChanged;
|
||||||
}
|
}
|
||||||
return await this._collection.addItem(remoteNotebook);
|
return await this._collection.addItem(remoteNotebook);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user