UNPKG

@r/platform

Version:

A set of tools to enable easy universal rendering and page navigation on a React + Redux stack

54 lines (47 loc) 1.55 kB
import { isPlainObject } from 'lodash/lang'; import { isEmpty } from 'lodash/lang'; export default function merge(state, stateDiff, options={}) { const { emptyDict='strict', array='replace', } = options; // Empty state diffs get special handling. In 'replace' mode they should be // overwriting the current state. In 'skip' mode, we should be 'skipping' // the merge of any objects, and return the current state. In 'strict' mode (default) // we should still be creating a new object. if (!Object.keys(stateDiff).length) { if (emptyDict === 'replace') { return stateDiff; } else if (emptyDict === 'skip') { return state; } } const newState = { ...state }; Object.keys(stateDiff).forEach(key => { const oldVal = newState[key]; const newVal = stateDiff[key]; const newValIsEmpty = isEmpty(newVal); if (isPlainObject(oldVal) && isPlainObject(newVal)) { if (newValIsEmpty && emptyDict === 'skip') { newState[key] = oldVal; } else if (newValIsEmpty && emptyDict === 'replace') { newState[key] = newVal; } else { newState[key] = merge(oldVal, newVal, options); } } else if (Array.isArray(oldVal) && Array.isArray(newVal)) { if (array === 'concat') { if (!newVal.length) { newState[key] = oldVal; } else { newState[key] = oldVal.concat(newVal); } } else { newState[key] = newVal; } } else { newState[key] = newVal; } }); return newState; }