cow-value-model.js 1017 B

12345678910111213141516171819202122232425262728293031323334
  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. function fillKeys (keyDescriptions) {
  9. keyDescriptions.forEach(each => {
  10. if (typeof each === 'number') keys.push(each);
  11. else if (Array.isArray(each)) fillKeys(each);
  12. else keys.push(...each.toString().split('.'));
  13. });
  14. }
  15. fillKeys(keyDescriptions);
  16. function setField (x = {}, index, val) {
  17. if (index >= keys.length) return val;
  18. const key = keys[index],
  19. value = x[key],
  20. modified = setField(value, index + 1, val);
  21. return value === modified ? x : copyWith(x, key, modified);
  22. }
  23. const GET_SENTINEL = {};
  24. return (obj, val = GET_SENTINEL) =>
  25. val === GET_SENTINEL ?
  26. keys.reduce((x = {}, key) => x[key], obj) :
  27. setField(obj, 0, val);
  28. };