benjamine / jsondiffpatch

Diff & patch JavaScript objects
MIT License
4.83k stars 472 forks source link

Method to detect conflicts? #33

Closed drpepper closed 10 years ago

drpepper commented 10 years ago

Hi, I'm very interested in using JsonDiffPatch, but can't find how to detect and spell out conflicts between patches. That is, I'm looking for a function that, given the original data and a list of patches, spits out any unresolvable conflicts between the patches.

Does such a function exist, or would it be easy to write? Thanks

benjamine commented 10 years ago

currently, patch conflicts will only arise (as exceptions) when you apply them. I'm doing a big refactoring on a separate branch that will add the capability to combine 2 (or more) patches, raising conflicts (and hopefully I want to add the option to specify custom conflict resolution). that might arrive in 2 or 3 weeks, but if finding conflicts might no be that hard to implement, here are some tips:

patches reflect the hierarchical structure of the diffed object, so first step is going recursively thru the patch objects, if at some path a member is only found on one patch, you can ignore it (no conflict there).

if at some path you find an array on both patches (arrays represent a change), that is almost for sure, a conflict.

the only exception are changes that might not conflict, like text diffs (array with 3 items: [theTextDiff, 0, 3]) that modify different lines in the text, that could be found out by parsing the line numbers.

Example code, that could get you started:


function findConflicts(patch1, patch2, path) {
  path = path || '/';
  if (typeof patch2 == 'undefined') return;
  if (typeof patch1 == 'undefined') return;
  if (Array.isArray(patch1) && Array.isArray(patch2) throw "conflict at " + path;
  for (var member in patch1) {
    if (typeof patch2[member] == 'undefined') continue;
    findConflicts(patch1[member], patch2[member], path + member + '/');
  }
}
benjamine commented 10 years ago

BTW, speaking of gaming, on the refactoring branch I'm moving to a pipes&filter pattern internally, that will make it easy to plugin different strategies for diffing, patching, serializing and conflict resolution, one of the things I wanted to plugin is the ability to support things like FPS client-side predicition for certain properties (eg. coordinates for position and speed).

drpepper commented 10 years ago

Looks good, thanks!

ghost commented 10 years ago

Noticed you finished the refactor, but how do you now combine multiple patches? That would be immensely useful for me.