123456789101112131415161718192021222324252627282930313233343536373839404142434445464748 |
- function copyWith (obj, key, value) {
- const result = typeof key === 'number' ? obj == null ? [] : [...obj] : obj == null ? {} : {...obj};
- result[key] = value;
- return result;
- }
- export const cowValueModel = (...keyDescriptions) => {
- const keys = [];
- function fillKeys (keyDescriptions) {
- keyDescriptions.forEach(each => {
- if (typeof each === 'number') keys.push(each);
- else if (Array.isArray(each)) fillKeys(each);
- else keys.push(...each.toString().split('.'));
- });
- }
- fillKeys(keyDescriptions);
- function setField (x, index, val) {
- if (index >= keys.length) return val;
- const key = keys[index],
- value = x == null ? undefined : 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 == null ? undefined : x[key], obj) :
- setField(obj, 0, val);
- };
- export const cowWorkshop = (keys, fn = x => x) => (obj, {result = obj, resultKeys = keys, diff} = {}) => {
- keys.forEach((key, index) => {
- const value = fn(cowValueModel(key)(obj));
- if (typeof value === "undefined") return;
- const modifier = cowValueModel(resultKeys[index]);
- const oldResult = result;
- result = modifier(oldResult, value);
- if (result !== oldResult) {
- diff = modifier(diff, value);
- }
- });
- return {result, diff};
- };
|