const clone = (state) => {
return Array.isArray(state) ? [...state] : {...state};
}
const createProxy = (getState, callback) => {
return new Proxy({}, {
get: function (target, property) {
const state = getState();
if (typeof state[property] === 'object' && state[property] !== null) {
return createProxy(() => state[property], (fn) => {
callback((parent) => {
const copy = clone(parent[property]);
parent[property] = copy;
fn(copy);
});
});
} else {
const state = getState();
return state[property];
}
},
set: function (target, property, value) {
callback((parent) => {
parent[property] = value;
});
return true;
}
});
};
const produce = (state, producer) => {
let copy = state;
producer(createProxy(() => copy, (fn) => {
copy = clone(copy);
fn(copy);
}));
return copy;
};
const state = {
ref: {},
count: {
all: {
a: 0,
b: 0
}
},
};
const value = produce(state, draft => {
draft.count.all.a = 1;
draft.count.all.b = draft.count.all.a + 1;
});
console.log(state, value, state.ref === value.ref);
const clone = (state) => {
return Array.isArray(state) ? [...state] : {...state};
}
const createProxy = (getState, iteratorFunc) => {
return new Proxy({}, {
get: function (target, property) {
const state = getState();
if (typeof state[property] === 'object' && state[property] !== null) {
const iterator = iteratorFunc();
return createProxy(() => state[property], function* () {
const {value: parent} = iterator.next();
const copy = clone(parent[property]);
parent[property] = copy;
yield copy;
});
} else {
const state = getState();
return state[property];
}
},
set: function (target, property, value) {
const iterator = iteratorFunc();
const {value: parent} = iterator.next();
parent[property] = value;
return true;
}
});
};
const produce = (state, producer) => {
let copy = state;
producer(createProxy(() => copy, function* () {
copy = clone(copy);
yield copy;
}));
return copy;
};
const state = {
ref: {},
count: {
all: {
a: 0,
b: 0
}
},
};
const value = produce(state, draft => {
draft.count.all.a = 1;
draft.count.all.b = draft.count.all.a + 1;
});
console.log(state, value, state.ref === value.ref);