function copyWith (obj, key, value) { const result = typeof key === 'number' ? [...obj] : {...obj}; result[key] = value; return result; } export const cowValueModel = (key, keys = key.split('.')) => { function setField (x = {}, index, val) { if (index >= keys.length) return val; const key = keys[index], value = x[key], modified = setField(value, index + 1, val); return value === modified ? x : copyWith(x, key, modified); } const GET_SENTINEL = {}; return (obj, val = GET_SENTINEL) => val === GET_SENTINEL ? keys.reduce((x = {}, key) => x[key], obj) : setField(obj, 0, val); };