UNPKG

jotai-valtio

Version:
48 lines (47 loc) • 1.64 kB
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; }