guesstimate/client/src/util/patch.ts

45 lines
1.0 KiB
TypeScript

// React/Redux compatible implementation of RFC 7396
// See https://tools.ietf.org/html/rfc7396
//
// Pseudo algorithm:
//
// define MergePatch(Target, Patch):
// if Patch is an Object:
// if Target is not an Object:
// Target = {} # Ignore the contents and set it to an empty Object
// for each Name/Value pair in Patch:
// if Value is null:
// if Name exists in Target:
// remove the Name/Value pair from Target
// else:
// Target[Name] = MergePatch(Target[Name], Value)
// return Target
// else:
// return Patch
export function applyPatch(target: any, patch: any): Object {
if (!isObject(patch)) {
return patch;
}
if (!isObject(target)) {
target = {};
}
Object.keys(patch).forEach((key: any) => {
const value = patch[key];
target = { ...target };
if (value === null) {
delete target[key];
} else {
target[key] = applyPatch(target[key], value);
}
});
return target;
}
function isObject(value: any): boolean {
return value === Object(value);
}