import { updateChildren, updateDecendents, } from '/imports/api/creature/parenting/parenting.js'; import { inheritedFields } from '/imports/api/creature/parenting/ChildSchema.js'; import MONGO_OPERATORS from '/imports/constants/MONGO_OPERATORS.js'; // This mixin can be safely applied to all update methods which are validated // with the updateSchemaMixin. It will propagate updates to fields which // are inherited and normalised on the parent or ancestor docs // It should have neglible performance impact for updates that aren't inherited function propagateInheritanceUpdate({_id, update}){ let childModifier = {}; let decendentModifier = {}; // For each operator for (let operator of MONGO_OPERATORS){ // If the operator is in the update, for each field if (update[operator]) for (let field in update[operator]){ // Get the top level field that was actually modified const indexOfDot = field.indexOf('.'); let modifiedField; if (indexOfDot !== -1) { modifiedField = field.substring(0, indexOfDot); } else { modifiedField = field; } // If that field is updated and inherited if (inheritedFields.has(modifiedField)){ // Perform the same update on the decendents if (!childModifier[operator]) childModifier[operator] = {}; if (!decendentModifier[operator]) decendentModifier[operator] = {}; childModifier[operator][`parent.${field}`] = update[operator][field]; decendentModifier[operator][`ancestors.$.${field}`] = update[operator][field]; } } } // Update the parent object of its children updateChildren({ parentId: _id, modifier: childModifier, }); // Update the ancestors object of its decendents updateDecendents({ ancestorId: _id, modifier: decendentModifier, }); } export default function propagateInheritanceUpdateMixin(methodOptions){ let runFunc = methodOptions.run; methodOptions.run = function({_id, update}){ const result = runFunc.apply(this, arguments); propagateInheritanceUpdate({_id, update}); return result; }; return methodOptions; }