Skip to content
This repository was archived by the owner on Jul 31, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 35 additions & 11 deletions client/recordUtil.js
Original file line number Diff line number Diff line change
Expand Up @@ -250,25 +250,49 @@ const mergeRecord = (record1, record2) => {

/**
* Within an array of [record, object], merge items whose records have the
* same objectId.
* same objectId and same actions.
* Requirements:
* 1) should not combine CREATE when object is not null:
* [[CREATE, object], [UPDATE, object]] => [[CREATE, object], [UPDATE, object]]
* [[CREATE, null], [UPDATE, null]] => [[CREATE(2), null]]
* [[CREATE, null], [UPDATE, object]] => ??? seems impossible => [[CREATE(2), object]]
* 2) should not combine any DELETE
* 3) all of UPDATE should be combined to single update
* @param {Array} recordsAndObjects Same format as input to resolveRecords().
* @returns {Array}
*/
const mergeRecords = (recordsAndObjects) => {
const objectIdMap = {} // map of objectId to [record, object]
var mergedResult = []
recordsAndObjects.forEach((recordAndObject) => {
const record = recordAndObject[0]
const object = recordAndObject[1]
const existingObject = recordAndObject[1]
const id = JSON.stringify(record.objectId)
if (objectIdMap[id]) {
const mergedRecord = mergeRecord(objectIdMap[id][0], record)
objectIdMap[id] = [mergedRecord, object]
} else {
objectIdMap[id] = recordAndObject

if (!mergedResult.length ||
(record.action === proto.actions.CREATE && existingObject) ||
record.action === proto.actions.DELETE) {
mergedResult.push(recordAndObject)
return
}
})
// webkit does not support Object.values
return Object.keys(objectIdMap).map((key) => objectIdMap[key])

// We reach this point in 2 cases
// 1. record.action is UPDATE => should merge with UPDATE or [CREATE, null]
// 2. record.action is CREATE and existingObject is null => should merge with UPDATE or [CREATE, null]

// Go through mergedResult from last to first
for (var j = mergedResult.length - 1; j >= 0; --j) {
if (JSON.stringify(mergedResult[j][0].objectId) === id &&
// Should not merge with CREATE or DELETE, only UPDATE
(mergedResult[j][0].action === proto.actions.UPDATE ||
(mergedResult[j][0].action === proto.actions.CREATE && !mergedResult[j][1]))) {
mergedResult[j][0] = mergeRecord(mergedResult[j][0], record)
return
}
}
mergedResult.push(recordAndObject)
}) // recordsAndObjects.forEach

return mergedResult
}

/**
Expand Down
6 changes: 6 additions & 0 deletions lib/api.proto
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ message SecretboxRecord {
bytes nonceRandom = 3;
}

message MetaInfo {
optional string key = 1;
optional string value = 2;
}

message SyncRecord {
enum Action {
CREATE = 0;
Expand All @@ -49,6 +54,7 @@ message SyncRecord {
repeated string fields = 6;
bool hideInToolbar = 7;
string order = 8;
repeated MetaInfo metaInfo= 9;
}
message SiteSetting {
string hostPattern = 1;
Expand Down
Loading