UNPKG

@pomgui/deep

Version:

Ultrasmall footprint deepmerge, deepfreeze, diff, patch tools

1 lines 11.1 kB
{"version":3,"sources":["../src/deepfreeze.ts","../src/deepmerge.ts","../src/diff.ts","../src/patch.ts"],"sourcesContent":["/**\n * Performs a recursive Object.freeze for all the objects in the parameter.\n * @param objects one or more objects to be freezed with the target\n * @returns the modified object or an array if there's more than one\n */\nexport function deepFreeze(...objects: object[]): object | object[] {\n const ret: any[] = [];\n for (const source of objects) {\n ret.push(freeze(source));\n }\n return ret.length == 1 ? ret[0] : ret;\n}\n\nfunction freeze(obj: any): any {\n if (!obj || typeof obj != 'object')\n return obj;\n for (const key in Object.getOwnPropertyNames(obj))\n freeze(obj[key]);\n return Object.freeze(obj);\n}","/**\n * Performs a merge of all the objects into the target.\n * It provides the almost same functionality that the 'lodash.merge'\n * npm package, with a very small footprint (1K vs 50K)\n * @see /tests/deepmerge.test.ts to see the considered use cases and examples\n * @param target Object that may be altered with the merge procedure \n * @param objects one or more objects to be merged with the target\n * @returns the modified target\n */\nexport function deepMerge<T>(target: T, ...objects: any[]): T {\n for (const source of objects) {\n if (target !== source)\n Object.entries(source).forEach(([key, sourceValue]) => {\n let targetValue = (target as any)[key];\n if (targetValue !== sourceValue || !(target as any).hasOwnProperty(key)) {\n if (typeof sourceValue === 'object' && sourceValue !== null) {\n if (Array.isArray(sourceValue) && !Array.isArray(targetValue))\n targetValue = (target as any)[key] = [];\n else if (typeof targetValue !== 'object')\n targetValue = (target as any)[key] = {};\n deepMerge(targetValue, sourceValue);\n } else if (targetValue === undefined || sourceValue !== undefined) {\n (target as any)[key] = sourceValue;\n }\n }\n })\n }\n return target;\n}","export type DiffResult = Record<string, any>;\n\n/**\n * Function derivated from https://github.com/Open-Tech-Foundation/obj-diff/blob/main/packages/obj-diff/src/diff.ts\n * and changed to return a smaller data length\n */\nfunction objDiff(\n a: object,\n b: object,\n path: string,\n _refs: WeakSet<WeakKey>\n): DiffResult {\n let result: DiffResult = {};\n\n if (\n typeof a === \"object\" &&\n typeof b === \"object\" &&\n a !== null &&\n b !== null\n ) {\n // For circular refs\n if (_refs.has(a) && _refs.has(b)) {\n return {};\n }\n\n _refs.add(a as WeakKey);\n _refs.add(b as WeakKey);\n\n if (Array.isArray(a) && Array.isArray(b)) {\n for (let i = 0; i < a.length; i++) {\n const apath = getSubPath(path, i);\n if (Object.hasOwn(b, i)) {\n Object.assign(result, objDiff(\n a[i],\n (b as Array<unknown>)[i] as object,\n apath,\n _refs\n )\n );\n } else\n result['-' + apath] = 0;\n }\n\n for (let i = 0; i < (b as []).length; i++)\n if (!Object.hasOwn(a, i)) {\n const apath = getSubPath(path, i);\n result['+' + apath] = (b as Array<unknown>)[i];\n }\n\n _refs.delete(a);\n _refs.delete(b);\n\n return result;\n }\n\n if (\n Object.prototype.toString.call(a) === \"[object Object]\" &&\n Object.prototype.toString.call(b) === \"[object Object]\"\n ) {\n for (const k in a) {\n const apath = getSubPath(path, k);\n if (Object.hasOwn(b, k)) {\n Object.assign(result, objDiff(\n (a as Record<string, unknown>)[k] as object,\n (b as Record<string, unknown>)[k] as object,\n apath,\n _refs\n ));\n } else {\n result['-' + apath] = 0;\n }\n }\n\n for (const k of Object.keys(b))\n if (!Object.hasOwn(a, k)) {\n const apath = getSubPath(path, k);\n result['+' + apath] = (b as Record<string, unknown>)[k];\n }\n\n _refs.delete(a);\n _refs.delete(b);\n\n return result;\n }\n\n if (a instanceof Date && b instanceof Date) {\n if (!Object.is(a.getTime(), b.getTime()))\n return { ['=' + path]: b };\n }\n\n if (Object.prototype.toString.call(a) !== Object.prototype.toString.call(b))\n return { ['=' + path]: b };\n\n } else\n if (!Object.is(a, b))\n return { ['=' + path]: b };\n\n return result;\n}\n\nfunction getSubPath(path: string, sub: string|number): string {\n const subkey = typeof sub=='string'? sub.replace('.', '\\\\.'): sub.toString();\n if (path != '') return path + '.' + subkey;\n else return subkey;\n}\n\n/**\n * Performs a deep difference between two objects.\n *\n * @example\n * diff({a: 1}, {a: 5}) //=> [{t: 2, p: ['a'], v: 5}]\n */\nexport function diff(obj1: object, obj2: object): DiffResult {\n return objDiff(obj1, obj2, '', new WeakSet());\n}","import { DiffResult } from \"./diff\";\n\n/**\n * You can apply the diff result onto the original object to get the modified object.\n *\n * Some portions of this file is derivated from https://github.com/Open-Tech-Foundation/obj-diff/blob/main/packages/obj-diff/src/patch.ts\n * to use our version of diff.\n * \n * @example\n * const a = {a: 1, b: 2};\n * const b = {a: 2, c: 3};\n * const out = patch(a, diff(a, b));\n * assert.deepStrictEqual(out, b); // ok\n */\nexport function patch<T>(obj: T, patches: DiffResult): T {\n for (const p in patches) {\n if (p[0] == '+' || p[0] == '=') {\n set(obj, p.substring(1), patches[p]);\n }\n\n if (p[0] == '-') {\n unset(obj, p.substring(1));\n }\n }\n\n return obj;\n}\n\nfunction set(obj: any, path: string, value: any): any {\n const keys = path.split(/(?<!\\\\)\\./).map(k => k.replace(/\\\\./g, '.'));\n const lastKey = keys.pop()!;\n for (let i = 0; i < keys.length; i++) {\n const k = keys[i];\n const k2 = keys[i + 1];\n if (!(k in obj) || !obj[k] || typeof obj[k] != 'object')\n obj[k] = /^\\d+$/.test(k2 ?? lastKey) ? [] : {};\n obj = obj[k];\n }\n obj[lastKey] = value;\n}\n\nfunction unset(obj: any, path: string): void {\n const keys = path.split(/(?<!\\\\)\\./).map(k => k.replace(/\\\\./g, '.'));\n const lastKey = keys.pop()!;\n for (let i = 0; i < keys.length; i++) {\n const k = keys[i];\n if (!(k in obj)) return;\n obj = obj[k];\n if (!obj) return;\n }\n delete obj[lastKey];\n}"],"mappings":"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","names":["deepFreeze","objects","ret","source","freeze","obj","key","deepMerge","target","objects","source","key","sourceValue","targetValue","objDiff","a","b","path","_refs","result","i","apath","getSubPath","k","sub","subkey","diff","obj1","obj2","patch","obj","patches","p","set","unset","path","value","keys","k","lastKey","i","k2"]}