// Rôle : fournit les helpers purs de versioning et rollback optimiste des données modules. function hasOwnValue(data, key) { return Object.prototype.hasOwnProperty.call(data, key); } function uniqueKeys(keys) { return [...new Set((Array.isArray(keys) ? keys : []).map((key) => String(key || "")).filter(Boolean))]; } export function createModuleDataCheckpoint(moduleData, versionsByKey, key) { const version = (versionsByKey[key] || 0) + 1; return { key, version, hadValue: hasOwnValue(moduleData, key), value: moduleData[key] }; } export function createModuleDataCheckpoints(moduleData, versionsByKey, keys) { return uniqueKeys(keys).map((key) => createModuleDataCheckpoint(moduleData, versionsByKey, key)); } export function commitModuleDataCheckpoints(versionsByKey, checkpoints) { const nextVersions = { ...versionsByKey }; checkpoints.forEach((checkpoint) => { nextVersions[checkpoint.key] = checkpoint.version; }); return nextVersions; } export function applyModuleDataValue(moduleData, key, value) { const nextModuleData = { ...moduleData }; if (value == null) delete nextModuleData[key]; else nextModuleData[key] = value; return nextModuleData; } export function removeModuleDataKeys(moduleData, keys) { const nextModuleData = { ...moduleData }; uniqueKeys(keys).forEach((key) => { delete nextModuleData[key]; }); return nextModuleData; } export function rollbackModuleDataCheckpoints(moduleData, versionsByKey, checkpoints) { let nextModuleData = moduleData; checkpoints.forEach((checkpoint) => { if (versionsByKey[checkpoint.key] !== checkpoint.version) return; if (nextModuleData === moduleData) nextModuleData = { ...moduleData }; if (checkpoint.hadValue) nextModuleData[checkpoint.key] = checkpoint.value; else delete nextModuleData[checkpoint.key]; }); return nextModuleData; }