AsyncBanana / microdiff

A fast, zero dependency object and array comparison library. Significantly faster than most other deep comparison libraries and has full TypeScript support.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Recreation from diff

FluentCoding opened this issue · comments

Hey!

I'm currently considering to use microdiff for my project, however I also have to be able to recreate an object from the diff and the source object (basically so that im able to send smaller-sized updates to a client state via a websocket connection), but it seems like microdiff is not offering any method for this. I will implement this in my project but I would like to know if this is in the ToDo.

Yeah, I plan to add patching soon. I can’t give you an exact ETA, but it will probably be a week or two. I will give you an update when I release it.

Alright, thanks! I'm down to help you at this, you can hit me up on discord (FluentCoding#3314) if you want to discuss the API/implementation.

this might be the same as what you're thinking for patching, but is it possible to lump together CHANGE events with similar paths? So

{
  path: [ 'states', 0, 'jsonlist', 61, 'offsetP', 'x' ],
  type: 'CHANGE',
  value: 569.73
},
{
  path: [ 'states', 0, 'jsonlist', 61, 'offsetP', 'y' ],
  type: 'CHANGE',
  value: 266.862
},

would become

{
  path: [ 'states', 0, 'jsonlist', 61, 'offsetP' ],
  type: 'CHANGE',
  value: { x: 569.73, y: 266.862 }
},

I think you could do this but at the cost of a bit of performance as you would have to look up the equal path parents and then combine them.

Oh, also, related to this issue, here is the PR that I posted about 11 days ago: #13

If you have lodash in your project, here is how I'm currently experimenting with patch functionality:

function patch (target: any, diff: any[]): any {
  target = cloneDeep(target);

  for (let i = 0; i < diff.length; i++) {
    const {
      type,
      path,
      value,
    } = diff[i];

    switch (type) {
      case 'CREATE': {
        set(target, path, value);
        break;
      }
      case 'CHANGE': {
        set(target, path, value);
        break;
      }
      case 'REMOVE': {
        // Note this does not actually remove the entry
        set(target, path, undefined);
        break;
      }
      default: {
        throw new Error(`unknown diff entry type: ${type}`);
      }
    }
  }

  return target;
}

Hopefully this helps someone waiting for the patch functionality. It would be less trivial to implement without lodash, but doable. I'm not sure how REMOVE would work - right now I'm just setting it to undefined, but that isn't the same as removal since the ownEnumerableProperty still exists.

Would lodash.unset work here for the REMOVE?

Micropatch is where FluentCoding's implementation ended up. Currently, you can use it directly from GitHub, and I am working on publishing it to NPM.