Skip to content

Commit 112a321

Browse files
committed
fix: Fix "failed to map parentId" errors
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
1 parent bb2fc75 commit 112a321

4 files changed

Lines changed: 55 additions & 20 deletions

File tree

src/lib/Diff.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,25 +109,45 @@ export default class Diff<L1 extends TItemLocation, L2 extends TItemLocation, A
109109

110110
static findChain(
111111
mappingsSnapshot: MappingSnapshot,
112-
actions: Action<TItemLocation, TItemLocation>[], itemTree: Folder<TItemLocation>,
112+
actions: Action<TItemLocation, TItemLocation>[],
113+
itemTree: Folder<TItemLocation>,
113114
currentItem: TItem<TItemLocation>,
114115
targetAction: Action<TItemLocation, TItemLocation>,
115116
chain: Action<TItemLocation, TItemLocation>[] = []
116117
): boolean {
117-
const targetItemInTree = itemTree.findFolder(Mappings.mapId(mappingsSnapshot, targetAction.payload, itemTree.location))
118+
const targetItemInTree = itemTree.findItem(targetAction.payload.type, Mappings.mapId(mappingsSnapshot, targetAction.payload, itemTree.location))
118119
if (
120+
// target action payload contains currentItem's parent
119121
targetAction.payload.findItem(ItemType.FOLDER,
120122
Mappings.mapParentId(mappingsSnapshot, currentItem, targetAction.payload.location)) ||
121-
(targetItemInTree && targetItemInTree.findFolder(Mappings.mapParentId(mappingsSnapshot, currentItem, itemTree.location)))
123+
// target action payload contains currentItem
124+
targetAction.payload.findItem(ItemType.FOLDER,
125+
Mappings.mapId(mappingsSnapshot, currentItem, targetAction.payload.location)) ||
126+
// or target in tree contains currentItem
127+
(targetItemInTree && targetItemInTree.findItem(ItemType.FOLDER, Mappings.mapParentId(mappingsSnapshot, currentItem, itemTree.location))) ||
128+
// or target action payload is the currentItem
129+
Mappings.mapId(mappingsSnapshot, targetAction.payload, currentItem.location) === currentItem.id ||
130+
// or target action payload is the currentItem's parent
131+
Mappings.mapId(mappingsSnapshot, targetAction.payload, currentItem.location) === currentItem.parentId ||
132+
// or target action payload is the currentItem
133+
Mappings.mapId(mappingsSnapshot, currentItem, targetAction.payload.location) === targetAction.payload.id ||
134+
// or target action payload is the currentItems parent
135+
Mappings.mapParentId(mappingsSnapshot, currentItem, targetAction.payload.location) === targetAction.payload.id
122136
) {
123137
return true
124138
}
125139
const newCurrentActions = actions.filter(targetAction =>
126140
!chain.includes(targetAction) && (
127141
targetAction.payload.findItem(ItemType.FOLDER, Mappings.mapParentId(mappingsSnapshot, currentItem, targetAction.payload.location)) ||
142+
targetAction.payload.findItem(currentItem.type, Mappings.mapId(mappingsSnapshot, currentItem, targetAction.payload.location)) ||
143+
(
144+
itemTree.findFolder(Mappings.mapId(mappingsSnapshot, targetAction.payload, itemTree.location)) &&
145+
itemTree.findFolder(Mappings.mapId(mappingsSnapshot, targetAction.payload, itemTree.location)).findFolder(Mappings.mapParentId(mappingsSnapshot, currentItem, itemTree.location))
146+
) ||
128147
(
129148
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)))
149+
itemTree.findFolder(Mappings.mapId(mappingsSnapshot, targetAction.payload, itemTree.location)).findItem(currentItem.type, Mappings.mapId(mappingsSnapshot, currentItem, itemTree.location))
150+
)
131151
)
132152
)
133153
if (newCurrentActions.length) {

src/lib/Mappings.ts

Lines changed: 7 additions & 0 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

src/lib/strategies/Default.ts

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
} from '../Tree'
1010
import Logger from '../Logger'
1111
import Diff, {
12+
Action,
1213
ActionType,
1314
CreateAction,
1415
MoveAction,
@@ -296,8 +297,8 @@ export default class SyncProcess {
296297
if ('orderFolder' in this.server && !this.localReordersFinal) {
297298
// mappings have been updated, reload
298299
mappingsSnapshot = this.mappings.getSnapshot()
299-
this.localReordersFinal = this.reconcileReorderings(this.localReorders, this.serverDonePlan, ItemLocation.LOCAL, mappingsSnapshot)
300-
this.serverReorderFinal = this.reconcileReorderings(this.serverReorders, this.localDonePlan, ItemLocation.SERVER, mappingsSnapshot)
300+
this.localReordersFinal = this.reconcileReorderings(this.localReorders, this.localDonePlan, ItemLocation.LOCAL, mappingsSnapshot)
301+
this.serverReorderFinal = this.reconcileReorderings(this.serverReorders, this.serverDonePlan, ItemLocation.SERVER, mappingsSnapshot)
301302
}
302303

303304
if (this.canceled) {
@@ -763,8 +764,9 @@ export default class SyncProcess {
763764
}
764765
}
765766

766-
const concurrentRemoval = targetRemovals.find(a =>
767-
a.payload.findItem('folder', action.payload.id))
767+
const concurrentRemoval = targetRemovals.find(targetRemoval =>
768+
Diff.findChain(mappingsSnapshot, allCreateAndMoveActions, sourceTree, action.payload, targetRemoval)
769+
)
768770
if (concurrentRemoval) {
769771
// Already deleted on target, do nothing.
770772
return
@@ -1096,15 +1098,17 @@ export default class SyncProcess {
10961098

10971099
reconcileReorderings<L1 extends TItemLocation, L2 extends TItemLocation>(
10981100
targetReorders: Diff<L2, TItemLocation, ReorderAction<L2, TItemLocation>>,
1099-
sourceDonePlan: PlanStage3<L1, TItemLocation, L2>,
1101+
targetDonePlan: PlanStage3<L2, TItemLocation, L1>,
11001102
targetLocation: L1,
11011103
mappingSnapshot: MappingSnapshot
11021104
) : Diff<L1, TItemLocation, ReorderAction<L1, TItemLocation>> {
11031105
Logger.log('Reconciling reorders to create a plan')
11041106

1105-
const sourceCreations = sourceDonePlan.CREATE.getActions()
1106-
const sourceRemovals = sourceDonePlan.REMOVE.getActions()
1107-
const sourceMoves = sourceDonePlan.MOVE.getActions()
1107+
const sourceCreations = targetDonePlan.CREATE.getActions()
1108+
const sourceRemovals = targetDonePlan.REMOVE.getActions()
1109+
const sourceMoves = targetDonePlan.MOVE.getActions()
1110+
const sourceCreationsAndMoves : Action<TItemLocation, TItemLocation>[] = (sourceCreations as Action<TItemLocation, TItemLocation>[]).concat(sourceMoves)
1111+
const sourceTree = targetLocation === ItemLocation.LOCAL ? this.localTreeRoot : this.serverTreeRoot
11081112

11091113
const newReorders = new Diff<L2, TItemLocation, ReorderAction<L2, TItemLocation>>
11101114

@@ -1117,37 +1121,41 @@ export default class SyncProcess {
11171121
const reorderAction = {...oldReorderAction, order: oldReorderAction.order.slice()}
11181122

11191123
const removed = sourceRemovals
1120-
.filter(removal => removal.payload.findItem(reorderAction.payload.type, removal.payload.id))
1124+
.filter(removal =>
1125+
Diff.findChain(mappingSnapshot, sourceCreationsAndMoves, sourceTree, oldReorderAction.payload, removal))
11211126
if (removed.length) {
11221127
return
11231128
}
11241129

11251130
// Find Away-moves
11261131
const childAwayMoves = sourceMoves
11271132
.filter(move =>
1128-
(String(reorderAction.payload.id) !== String(move.payload.parentId) && // reorder IDs are from localTree (source of this plan), move.oldItem IDs are from server tree (source of other plan)
1129-
reorderAction.order.find(item => String(item.id) === String(move.payload.id) && item.type === move.payload.type))// move.payload IDs are from localTree (target of the other plan
1133+
Mappings.mapId(mappingSnapshot, reorderAction.payload, move.payload.location) !== String(move.payload.parentId) &&
1134+
reorderAction.order.find(item =>
1135+
Mappings.mapRawId(mappingSnapshot, item.id, item.type, reorderAction.payload.location, move.payload.location) === String(move.payload.id) && item.type === move.payload.type)
11301136
)
11311137

11321138
// Find removals
11331139
const concurrentRemovals = sourceRemovals
1134-
.filter(removal => reorderAction.order.find(item => String(item.id) === String(removal.payload.id) && item.type === removal.payload.type))
1140+
.filter(removal =>
1141+
reorderAction.order.find(item =>
1142+
Mappings.mapRawId(mappingSnapshot, item.id, item.type, reorderAction.payload.location, removal.payload.location) === String(removal.payload.id) && item.type === removal.payload.type))
11351143

11361144
// Remove away-moves and removals
11371145
reorderAction.order = reorderAction.order.filter(item => {
11381146
let action
11391147
if (
11401148
// eslint-disable-next-line no-cond-assign
11411149
action = childAwayMoves.find(move =>
1142-
String(item.id) === String(move.payload.id) && move.payload.type === item.type)) {
1150+
Mappings.mapRawId(mappingSnapshot, item.id, item.type, reorderAction.payload.location, move.payload.location) === String(move.payload.id) && move.payload.type === item.type)) {
11431151
Logger.log('ReconcileReorders: Removing moved item from order', {move: action, reorder: reorderAction})
11441152
return false
11451153
}
11461154

11471155
if (
11481156
// eslint-disable-next-line no-cond-assign
11491157
action = concurrentRemovals.find(removal =>
1150-
String(item.id) === String(removal.payload.id) && removal.payload.type === item.type)
1158+
Mappings.mapRawId(mappingSnapshot, item.id, item.type, reorderAction.payload.location, removal.payload.location) === String(removal.payload.id) && removal.payload.type === item.type)
11511159
) {
11521160
Logger.log('ReconcileReorders: Removing removed item from order', {item, reorder: reorderAction, removal: action})
11531161
return false

src/lib/strategies/Merge.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,11 @@ export default class MergeSyncProcess extends DefaultSyncProcess {
175175

176176
reconcileReorderings<L1 extends TItemLocation, L2 extends TItemLocation>(
177177
targetReorders: Diff<L2, TItemLocation, ReorderAction<L2, TItemLocation>>,
178-
sourceDonePlan: PlanStage3<L1, TItemLocation, L2>,
178+
targetDonePlan: PlanStage3<L2, TItemLocation, L1>,
179179
targetLocation: L1,
180180
mappingSnapshot: MappingSnapshot
181181
) : Diff<L1, TItemLocation, ReorderAction<L1, TItemLocation>> {
182-
return super.reconcileReorderings(targetReorders, sourceDonePlan, targetLocation, mappingSnapshot)
182+
return super.reconcileReorderings(targetReorders, targetDonePlan, targetLocation, mappingSnapshot)
183183
}
184184

185185
async loadChildren(serverTreeRoot: Folder<typeof ItemLocation.SERVER>):Promise<void> {

0 commit comments

Comments
 (0)