1 | import { snapshot, subscribe } from 'valtio/vanilla';
|
2 | import { atom } from 'jotai';
|
3 |
|
4 | const isObject = (x) => typeof x === "object" && x !== null;
|
5 | const applyChanges = (proxyObject, prev, next) => {
|
6 | Object.getOwnPropertyNames(prev).forEach((key) => {
|
7 | if (!(key in next)) {
|
8 | delete proxyObject[key];
|
9 | } else if (Object.is(prev[key], next[key])) ; else if (isObject(proxyObject[key]) && isObject(prev[key]) && isObject(next[key])) {
|
10 | applyChanges(
|
11 | proxyObject[key],
|
12 | prev[key],
|
13 | next[key]
|
14 | );
|
15 | } else {
|
16 | proxyObject[key] = next[key];
|
17 | }
|
18 | });
|
19 | Object.keys(next).forEach((key) => {
|
20 | if (!(key in prev)) {
|
21 | proxyObject[key] = next[key];
|
22 | }
|
23 | });
|
24 | };
|
25 | function atomWithProxy(proxyObject, options) {
|
26 | const baseAtom = atom(snapshot(proxyObject));
|
27 | baseAtom.onMount = (setValue) => {
|
28 | const callback = () => {
|
29 | setValue(snapshot(proxyObject));
|
30 | };
|
31 | const unsub = subscribe(proxyObject, callback, options == null ? void 0 : options.sync);
|
32 | callback();
|
33 | return unsub;
|
34 | };
|
35 | const derivedAtom = atom(
|
36 | (get) => get(baseAtom),
|
37 | (get, _set, update) => {
|
38 | const newValue = typeof update === "function" ? update(get(baseAtom)) : update;
|
39 | applyChanges(proxyObject, snapshot(proxyObject), newValue);
|
40 | }
|
41 | );
|
42 | return derivedAtom;
|
43 | }
|
44 |
|
45 | export { atomWithProxy };
|