{"version":3,"file":"diff.mjs","names":[],"sources":["../../../src/common/data/diff.ts"],"sourcesContent":["// Original from https://github.com/AsyncBanana/microdiff MIT\n// Alternative https://github.com/kpdecker/jsdiff\n\nexport type DifferenceType = 'new' | 'upd' | 'del'\n\nexport interface Difference {\n  type: DifferenceType\n  path: (string | number)[]\n  value?: any\n}\n\nexport interface DiffOptions {\n  cyclesFix: boolean\n}\n\n/**\n * Describes the changes between to object with a list like:\n *\n * ```\n * [{\n *    type: 'upd',\n *    path: ['a'],\n *    value: 1\n * },\n * {\n *    type: 'del',\n *    path: ['b', 'c']\n * }\n * ...]\n * ```\n */\nexport function diffObjects(\n  obj: Record<string, any> | any[],\n  newObj: Record<string, any> | any[],\n  options: Partial<DiffOptions> = { cyclesFix: true },\n  _stack: Record<string, any>[] = [],\n): Difference[] {\n  let diffs: Difference[] = []\n  const isObjArray = Array.isArray(obj)\n\n  for (const key in obj) {\n    const objValue = (obj as any)[key] // works for both array and record, only TS doesn't know ;)\n    const path = isObjArray ? +key : key\n    if (!(key in newObj)) {\n      diffs.push({\n        type: 'del',\n        path: [path],\n      })\n      continue\n    }\n    const newValue = (newObj as any)[key]\n    const areObjects = typeof objValue === 'object' && typeof newValue === 'object'\n    if (objValue\n      && newValue\n      && areObjects\n      && !(['Date', 'RegExp', 'String', 'Number'].includes(Object.getPrototypeOf(objValue).constructor.name))\n      && (options.cyclesFix ? !_stack.includes(objValue) : true)\n    ) {\n      const nestedDiffs = diffObjects(\n        objValue,\n        newValue,\n        options,\n        options.cyclesFix ? _stack.concat([objValue]) : [],\n      )\n      diffs = [...diffs, ...nestedDiffs.map((difference) => {\n        difference.path.unshift(path)\n        return difference\n      })]\n    }\n    else if (\n      objValue !== newValue\n      && !(\n        areObjects\n        && (Number.isNaN(objValue)\n          ? `${objValue}` === `${newValue}`\n          : +objValue === +newValue)\n      )\n    ) {\n      diffs.push({\n        path: [path],\n        type: 'upd',\n        value: newValue,\n      })\n    }\n  }\n\n  const isNewObjArray = Array.isArray(newObj)\n  for (const key in newObj) {\n    if (!(key in obj)) {\n      diffs.push({\n        type: 'new',\n        path: [isNewObjArray ? +key : key],\n        value: (newObj as any)[key], // works for both array and record, only TS doesn't know ;)\n      })\n    }\n  }\n  return diffs\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AA+BA,SAAgB,YACd,KACA,QACA,UAAgC,EAAE,WAAW,MAAM,EACnD,SAAgC,EAAE,EACpB;CACd,IAAI,QAAsB,EAAE;CAC5B,MAAM,aAAa,MAAM,QAAQ,IAAI;AAErC,MAAK,MAAM,OAAO,KAAK;EACrB,MAAM,WAAY,IAAY;EAC9B,MAAM,OAAO,aAAa,CAAC,MAAM;AACjC,MAAI,EAAE,OAAO,SAAS;AACpB,SAAM,KAAK;IACT,MAAM;IACN,MAAM,CAAC,KAAK;IACb,CAAC;AACF;;EAEF,MAAM,WAAY,OAAe;EACjC,MAAM,aAAa,OAAO,aAAa,YAAY,OAAO,aAAa;AACvE,MAAI,YACC,YACA,cACA,CAAE;GAAC;GAAQ;GAAU;GAAU;GAAS,CAAC,SAAS,OAAO,eAAe,SAAS,CAAC,YAAY,KAAK,KAClG,QAAQ,YAAY,CAAC,OAAO,SAAS,SAAS,GAAG,OACrD;GACA,MAAM,cAAc,YAClB,UACA,UACA,SACA,QAAQ,YAAY,OAAO,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE,CACnD;AACD,WAAQ,CAAC,GAAG,OAAO,GAAG,YAAY,KAAK,eAAe;AACpD,eAAW,KAAK,QAAQ,KAAK;AAC7B,WAAO;KACP,CAAC;aAGH,aAAa,YACV,EACD,eACI,OAAO,MAAM,SAAS,GACtB,GAAG,eAAe,GAAG,aACrB,CAAC,aAAa,CAAC,WAGrB,OAAM,KAAK;GACT,MAAM,CAAC,KAAK;GACZ,MAAM;GACN,OAAO;GACR,CAAC;;CAIN,MAAM,gBAAgB,MAAM,QAAQ,OAAO;AAC3C,MAAK,MAAM,OAAO,OAChB,KAAI,EAAE,OAAO,KACX,OAAM,KAAK;EACT,MAAM;EACN,MAAM,CAAC,gBAAgB,CAAC,MAAM,IAAI;EAClC,OAAQ,OAAe;EACxB,CAAC;AAGN,QAAO"}