cow-value-model.js 862 B

12345678910111213141516171819202122232425262728
  1. function copyWith (obj, key, value) {
  2. const result = typeof key === 'number' ? [...obj] : {...obj};
  3. result[key] = value;
  4. return result;
  5. }
  6. export const cowValueModel = (...keyDescriptions) => {
  7. const keys = [];
  8. keyDescriptions.forEach(each => {
  9. if (typeof each === 'number') keys.push(each);
  10. else keys.push(...each.toString().split('.'));
  11. });
  12. function setField (x = {}, index, val) {
  13. if (index >= keys.length) return val;
  14. const key = keys[index],
  15. value = x[key],
  16. modified = setField(value, index + 1, val);
  17. return value === modified ? x : copyWith(x, key, modified);
  18. }
  19. const GET_SENTINEL = {};
  20. return (obj, val = GET_SENTINEL) =>
  21. val === GET_SENTINEL ?
  22. keys.reduce((x = {}, key) => x[key], obj) :
  23. setField(obj, 0, val);
  24. };