UNPKG

merge-change

Version:

Advanced library for deep merging, patching, and immutable updates of data structures. Features declarative operations for specific merging behaviors, property management, custom type merging rules, and difference tracking. Supports complex data transform

116 lines 4.48 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.patch = exports.update = exports.merge = void 0; exports.createMerge = createMerge; exports.createUpdate = createUpdate; exports.createPatch = createPatch; const types_1 = require("./types"); const type_1 = require("../type"); const operations_1 = require("./operations"); // Default methods for handling different type combinations const defaultMethods = { unknown_unknown(first, second, kind, mc) { return mc(undefined, second); }, unknown_undefined(first, second, kind, mc) { return mc(undefined, first); }, undefined_unknown(first, second) { return second; }, undefined_Date(first, second, kind) { return kind === types_1.MergeChangeKind.MERGE ? new Date(second) : second; }, undefined_Set(first, second, kind) { return kind === types_1.MergeChangeKind.MERGE ? new Set(second) : second; }, undefined_Map(first, second, kind) { return kind === types_1.MergeChangeKind.MERGE ? new Map(second) : second; }, undefined_Array(first, second, kind, mc) { return kind === types_1.MergeChangeKind.MERGE ? defaultMethods.Array_Array([], second, kind, mc) : second; }, undefined_object(first, second, kind, mc) { const operations = (0, operations_1.extractOperations)(second); return defaultMethods.object_object(second, operations, kind, mc); }, object_object(first, second, kind, mc) { const result = kind === types_1.MergeChangeKind.PATCH ? first : {}; let resultField; let isChange = kind === types_1.MergeChangeKind.MERGE; const operations = []; const keysFirst = Object.keys(first); const keysSecond = new Set(Object.keys(second)); for (const key of keysFirst) { if (key in second) { resultField = mc(first[key], second[key]); keysSecond.delete(key); } else { resultField = mc(first[key], undefined); } isChange = isChange || resultField !== first[key]; result[key] = resultField; } for (const key of keysSecond) { if ((0, operations_1.isOperation)(key)) { operations.push([key, second[key]]); } else { resultField = mc(undefined, second[key]); isChange = isChange || resultField !== first[key]; result[key] = resultField; } } // execute declarative operations for (const [operation, params] of operations) { isChange = operations_1.defaultOperations[operation](result, params) || isChange; } return isChange ? result : first; }, Array_Array(first, second, kind, mc) { if (kind === types_1.MergeChangeKind.MERGE) { return second.map((item) => mc(undefined, item)); } return second; }, }; function createMergeChange(kind, customMethods = {}) { const methods = Object.assign(Object.assign({}, defaultMethods), customMethods); const mergeChange = (...values) => { return values.reduce((first, second) => { const firstType = (0, type_1.type)(first); const secondType = (0, type_1.type)(second); const actions = [ `${firstType}_${secondType}`, `${firstType}_unknown`, `unknown_${secondType}`, `unknown_unknown`, ]; for (const action of actions) { if (methods[action]) { return methods[action](first, second, kind, mergeChange); } } return first; }); }; return mergeChange; } // Factory functions for the three merge types function createMerge(customMethods = {}) { return createMergeChange(types_1.MergeChangeKind.MERGE, customMethods); } function createUpdate(customMethods = {}) { return createMergeChange(types_1.MergeChangeKind.UPDATE, customMethods); } function createPatch(customMethods = {}) { return createMergeChange(types_1.MergeChangeKind.PATCH, customMethods); } exports.merge = createMerge(); exports.update = createUpdate(); exports.patch = createPatch(); exports.default = { merge: exports.merge, update: exports.update, patch: exports.patch }; //# sourceMappingURL=index.js.map