jotai-valtio
Version:
48 lines (47 loc) • 1.64 kB
JavaScript
import { atom } from 'jotai/vanilla';
import { snapshot, subscribe } from 'valtio/vanilla';
const isObject = (x) => typeof x === 'object' && x !== null && !(x instanceof Promise);
const applyChanges = (proxyObject, prev, next) => {
Object.getOwnPropertyNames(prev).forEach((key) => {
if (!(key in next)) {
delete proxyObject[key];
}
else if (Object.is(prev[key], next[key])) {
// unchanged
}
else if (isObject(proxyObject[key]) &&
isObject(prev[key]) &&
isObject(next[key])) {
applyChanges(proxyObject[key], prev[key], next[key]);
}
else {
proxyObject[key] = next[key];
}
});
Object.keys(next).forEach((key) => {
if (!(key in prev)) {
proxyObject[key] = next[key];
}
});
};
export function atomWithProxy(proxyObject, options) {
const baseAtom = atom(snapshot(proxyObject));
if (process.env.NODE_ENV !== 'production') {
baseAtom.debugPrivate = true;
}
baseAtom.onMount = (setValue) => {
const callback = () => {
setValue(snapshot(proxyObject));
};
const unsub = subscribe(proxyObject, callback, options === null || options === void 0 ? void 0 : options.sync);
callback();
return unsub;
};
const derivedAtom = atom((get) => get(baseAtom), (get, _set, update) => {
const newValue = typeof update === 'function'
? update(get(baseAtom))
: update;
applyChanges(proxyObject, snapshot(proxyObject), newValue);
});
return derivedAtom;
}