Skip to content

Commit abee5bc

Browse files
authored
Merge pull request #2008 from floccusaddon/fix/correctness-fixes
Fix "failed to map parentId" errors and other correctness fixes
2 parents 56e461d + 7af73ed commit abee5bc

File tree

7 files changed

+135
-61
lines changed

7 files changed

+135
-61
lines changed

src/lib/Diff.ts

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -107,36 +107,59 @@ export default class Diff<L1 extends TItemLocation, L2 extends TItemLocation, A
107107
)
108108
}
109109

110+
static containsParent(mappingsSnapshot: MappingSnapshot, item1: TItem<TItemLocation>, item2: TItem<TItemLocation>, itemTree: Folder<TItemLocation>, cache: Record<string, boolean>): boolean {
111+
const cacheKey = 'contains:' + Mappings.mapId(mappingsSnapshot, item2, ItemLocation.LOCAL) + ':' + Mappings.mapId(mappingsSnapshot, item2, ItemLocation.SERVER) +
112+
'-' + Mappings.mapId(mappingsSnapshot, item1, ItemLocation.LOCAL) + ':' + Mappings.mapId(mappingsSnapshot, item1, ItemLocation.SERVER)
113+
if (typeof cache[cacheKey] !== 'undefined') {
114+
return cache[cacheKey]
115+
}
116+
const item1InTree = itemTree.findItem(item1.type, Mappings.mapId(mappingsSnapshot, item1, itemTree.location))
117+
if (
118+
item1.findItem(ItemType.FOLDER,
119+
Mappings.mapParentId(mappingsSnapshot, item2, item1.location)) ||
120+
(item1InTree && item1InTree.findItem(ItemType.FOLDER, Mappings.mapParentId(mappingsSnapshot, item2, itemTree.location))) ||
121+
String(Mappings.mapId(mappingsSnapshot, item1, item2.location)) === String(item2.parentId) ||
122+
String(Mappings.mapParentId(mappingsSnapshot, item2, item1.location)) === String(item1.id)
123+
) {
124+
cache[cacheKey] = true
125+
return true
126+
}
127+
cache[cacheKey] = false
128+
return false
129+
}
130+
110131
static findChain(
111132
mappingsSnapshot: MappingSnapshot,
112-
actions: Action<TItemLocation, TItemLocation>[], itemTree: Folder<TItemLocation>,
133+
actions: Action<TItemLocation, TItemLocation>[],
134+
itemTree: Folder<TItemLocation>,
113135
currentItem: TItem<TItemLocation>,
114136
targetAction: Action<TItemLocation, TItemLocation>,
137+
cache: Record<string, boolean> = {},
115138
chain: Action<TItemLocation, TItemLocation>[] = []
116139
): boolean {
117-
const targetItemInTree = itemTree.findFolder(Mappings.mapId(mappingsSnapshot, targetAction.payload, itemTree.location))
118-
if (
119-
targetAction.payload.findItem(ItemType.FOLDER,
120-
Mappings.mapParentId(mappingsSnapshot, currentItem, targetAction.payload.location)) ||
121-
(targetItemInTree && targetItemInTree.findFolder(Mappings.mapParentId(mappingsSnapshot, currentItem, itemTree.location)))
122-
) {
140+
const currentItemLocalId = Mappings.mapId(mappingsSnapshot, currentItem, ItemLocation.LOCAL)
141+
const currentItemServerId = Mappings.mapId(mappingsSnapshot, currentItem, ItemLocation.SERVER)
142+
const targetPayloadLocalId = Mappings.mapId(mappingsSnapshot, targetAction.payload, ItemLocation.LOCAL)
143+
const targetPayloadServerId = Mappings.mapId(mappingsSnapshot, targetAction.payload, ItemLocation.SERVER)
144+
const cacheKey = `hasChain:${currentItemLocalId}:${currentItemServerId}-${targetPayloadLocalId}:${targetPayloadServerId}`
145+
if (typeof cache[cacheKey] !== 'undefined') {
146+
return cache[cacheKey]
147+
}
148+
if (Diff.containsParent(mappingsSnapshot, targetAction.payload, currentItem, itemTree, cache)) {
149+
cache[cacheKey] = true
123150
return true
124151
}
125-
const newCurrentActions = actions.filter(targetAction =>
126-
!chain.includes(targetAction) && (
127-
targetAction.payload.findItem(ItemType.FOLDER, Mappings.mapParentId(mappingsSnapshot, currentItem, targetAction.payload.location)) ||
128-
(
129-
itemTree.findFolder(Mappings.mapId(mappingsSnapshot, targetAction.payload, itemTree.location)) &&
130-
itemTree.findFolder(Mappings.mapId(mappingsSnapshot, targetAction.payload, itemTree.location)).findFolder(Mappings.mapParentId(mappingsSnapshot, currentItem, itemTree.location)))
131-
)
152+
const newCurrentActions = actions.filter(newTargetAction =>
153+
!chain.includes(newTargetAction) && Diff.containsParent(mappingsSnapshot, newTargetAction.payload, currentItem, itemTree, cache)
132154
)
133155
if (newCurrentActions.length) {
134156
for (const newCurrentAction of newCurrentActions) {
135-
if (Diff.findChain(mappingsSnapshot, actions, itemTree, newCurrentAction.payload, targetAction, [...chain, newCurrentAction])) {
157+
if (Diff.findChain(mappingsSnapshot, actions, itemTree, newCurrentAction.payload, targetAction, cache,[...chain, newCurrentAction])) {
136158
return true
137159
}
138160
}
139161
}
162+
cache[cacheKey] = false
140163
return false
141164
}
142165

src/lib/Mappings.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,13 @@ export default class Mappings {
7979
}
8080
}
8181

82+
static mapRawId(mappingsSnapshot:MappingSnapshot, id: string|number, type: TItemType, source: TItemLocation, target: TItemLocation) : string|number {
83+
if (target === source) {
84+
return id
85+
}
86+
return mappingsSnapshot[source + 'To' + target][type][id]
87+
}
88+
8289
static mapId(mappingsSnapshot:MappingSnapshot, item: TItem<TItemLocation>, target: TItemLocation) : string|number {
8390
if (item.location === target) {
8491
return item.id
@@ -94,10 +101,10 @@ export default class Mappings {
94101
}
95102

96103
static mappable(mappingsSnapshot: MappingSnapshot, item1: TItem<TItemLocation>, item2: TItem<TItemLocation>) : boolean {
97-
if (Mappings.mapId(mappingsSnapshot, item1, item2.location) === item2.id) {
104+
if (String(Mappings.mapId(mappingsSnapshot, item1, item2.location)) === String(item2.id)) {
98105
return true
99106
}
100-
if (Mappings.mapId(mappingsSnapshot, item2, item1.location) === item1.id) {
107+
if (String(Mappings.mapId(mappingsSnapshot, item2, item1.location)) === String(item1.id)) {
101108
return true
102109
}
103110
return false

src/lib/browser/BrowserTree.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,10 @@ export default class BrowserTree implements IResource<typeof ItemLocation.LOCAL>
249249
const [realTree] = await browser.bookmarks.getSubTree(id)
250250
try {
251251
for (let index = 0; index < order.length; index++) {
252+
if (!realTree.children.find(item => String(item.id) === String(order[index].id))) {
253+
Logger.log('(local)ORDERFOLDER: skipping item ', order[index])
254+
continue
255+
}
252256
await browser.bookmarks.move(order[index].id, { parentId: id.toString(), index })
253257
}
254258
} catch (e) {

0 commit comments

Comments
 (0)