> > My worry is that if someone else moves another file called rope.h to > the resources directory at the same time, I don't want the result to > ever be that one of our files gets deleted from disk. >
If the client/server keeps recent operations in memory and supports undo / has their own logic to recognize and handle move collisions, this seems less of a problem. Alternatively, are any tests supported? (like in 6902 <https://tools.ietf.org/html/rfc6902#appendix-A.8>) in which case each move could include a test that the original value is missing, and so would automatically be undone when transformed against an identical move. Some observations: > - This will almost never actually happen in real life. > - Even if we turn the operation will transform into a 'replace', we > could add a flag to the operation to mark that it was unintentionally > overwritten, and then the process which is making the corresponding > changes on disk could see that and do some special > application-specific behaviour instead of actually deleting the file. Indeed - your structure could instead be: { "name": "librope", "package": { "src": { "rope.c": "somelonguniqueid", "rope.h": "anotherfileid", }}, data: { "somelonguniqueid": { "text": "#include <rope.h>\n ..." }, "anotherfileid": { "text": "// This is a cool header" }, }} Then deletion is some separate offline index/cleanup, and resolving conflicts is simpler. (although 'move' is less useful here as there are no child properties). > > > Regarding object move, I'm in favor of keeping things simple, but I'm > also > > in favor of thinking about this in terms of what people might actually do > > with this capability. Since mapping a directory structure of files is the > > one good example you have, then maybe multiple moves to the same key > should > > merge their values as directory moves merge their files. That would mean > a > > slightly modified version of your option 1. In the simple case, you have > > {x:1, y:2} -> {z:2}, but in the complex case you have {x:{a:1}, y:{b:2}} > -> > > {z:{a:1, b:2}}. > Does move distinguish between PUT vs. PATCH? I would assume PUT (x: {a: 1}) -> z and PUT (y: {b: 2}) -> z would end up in z: {b:2} but if the second operation received was a PATCH operation, they would be merged rather than replaced. For file system moves they'd probably be PUT, but their might be instances where a PATCH is useful.