UNPKG

29.6 kBJavaScriptView Raw
1System.register(['react'], (function (exports) {
2 'use strict';
3 var createContext, useState, useEffect, useRef, createElement, useContext, useReducer, useDebugValue, useCallback;
4 return {
5 setters: [function (module) {
6 createContext = module.createContext;
7 useState = module.useState;
8 useEffect = module.useEffect;
9 useRef = module.useRef;
10 createElement = module.createElement;
11 useContext = module.useContext;
12 useReducer = module.useReducer;
13 useDebugValue = module.useDebugValue;
14 useCallback = module.useCallback;
15 }],
16 execute: (function () {
17
18 exports({
19 atom: atom,
20 useAtom: useAtom,
21 useAtomValue: useAtomValue,
22 useSetAtom: useSetAtom
23 });
24
25 const SUSPENSE_PROMISE = Symbol();
26 const isSuspensePromise = (promise) => !!promise[SUSPENSE_PROMISE];
27 const isSuspensePromiseAlreadyCancelled = (suspensePromise) => !suspensePromise[SUSPENSE_PROMISE].c;
28 const cancelSuspensePromise = (suspensePromise) => {
29 var _a, _b;
30 (_b = (_a = suspensePromise[SUSPENSE_PROMISE]).c) == null ? void 0 : _b.call(_a);
31 };
32 const isEqualSuspensePromise = (oldSuspensePromise, newSuspensePromise) => {
33 const oldOriginalPromise = oldSuspensePromise[SUSPENSE_PROMISE].o;
34 const newOriginalPromise = newSuspensePromise[SUSPENSE_PROMISE].o;
35 return oldOriginalPromise === newOriginalPromise || oldSuspensePromise === newOriginalPromise || isSuspensePromise(oldOriginalPromise) && isEqualSuspensePromise(oldOriginalPromise, newSuspensePromise);
36 };
37 const createSuspensePromise = (promise) => {
38 const objectToAttach = {
39 o: promise,
40 c: null
41 };
42 const suspensePromise = new Promise((resolve) => {
43 objectToAttach.c = () => {
44 objectToAttach.c = null;
45 resolve();
46 };
47 promise.then(objectToAttach.c, objectToAttach.c);
48 });
49 suspensePromise[SUSPENSE_PROMISE] = objectToAttach;
50 return suspensePromise;
51 };
52
53 const hasInitialValue = (atom) => "init" in atom;
54 const READ_ATOM = "r";
55 const WRITE_ATOM = "w";
56 const COMMIT_ATOM = "c";
57 const SUBSCRIBE_ATOM = "s";
58 const RESTORE_ATOMS = "h";
59 const DEV_SUBSCRIBE_STATE = "n";
60 const DEV_GET_MOUNTED_ATOMS = "l";
61 const DEV_GET_ATOM_STATE = "a";
62 const DEV_GET_MOUNTED = "m";
63 const createStore = (initialValues) => {
64 const committedAtomStateMap = /* @__PURE__ */ new WeakMap();
65 const mountedMap = /* @__PURE__ */ new WeakMap();
66 const pendingMap = /* @__PURE__ */ new Map();
67 let stateListeners;
68 let mountedAtoms;
69 {
70 stateListeners = /* @__PURE__ */ new Set();
71 mountedAtoms = /* @__PURE__ */ new Set();
72 }
73 if (initialValues) {
74 for (const [atom, value] of initialValues) {
75 const atomState = { v: value, r: 0, d: /* @__PURE__ */ new Map() };
76 {
77 Object.freeze(atomState);
78 if (!hasInitialValue(atom)) {
79 console.warn("Found initial value for derived atom which can cause unexpected behavior", atom);
80 }
81 }
82 committedAtomStateMap.set(atom, atomState);
83 }
84 }
85 const suspensePromiseCacheMap = /* @__PURE__ */ new WeakMap();
86 const addSuspensePromiseToCache = (version, atom, suspensePromise) => {
87 let cache = suspensePromiseCacheMap.get(atom);
88 if (!cache) {
89 cache = /* @__PURE__ */ new Map();
90 suspensePromiseCacheMap.set(atom, cache);
91 }
92 suspensePromise.then(() => {
93 if (cache.get(version) === suspensePromise) {
94 cache.delete(version);
95 if (!cache.size) {
96 suspensePromiseCacheMap.delete(atom);
97 }
98 }
99 });
100 cache.set(version, suspensePromise);
101 };
102 const cancelAllSuspensePromiseInCache = (atom) => {
103 const versionSet = /* @__PURE__ */ new Set();
104 const cache = suspensePromiseCacheMap.get(atom);
105 if (cache) {
106 suspensePromiseCacheMap.delete(atom);
107 cache.forEach((suspensePromise, version) => {
108 cancelSuspensePromise(suspensePromise);
109 versionSet.add(version);
110 });
111 }
112 return versionSet;
113 };
114 const versionedAtomStateMapMap = /* @__PURE__ */ new WeakMap();
115 const getVersionedAtomStateMap = (version) => {
116 let versionedAtomStateMap = versionedAtomStateMapMap.get(version);
117 if (!versionedAtomStateMap) {
118 versionedAtomStateMap = /* @__PURE__ */ new Map();
119 versionedAtomStateMapMap.set(version, versionedAtomStateMap);
120 }
121 return versionedAtomStateMap;
122 };
123 const getAtomState = (version, atom) => {
124 if (version) {
125 const versionedAtomStateMap = getVersionedAtomStateMap(version);
126 let atomState = versionedAtomStateMap.get(atom);
127 if (!atomState) {
128 atomState = getAtomState(version.p, atom);
129 if (atomState) {
130 versionedAtomStateMap.set(atom, atomState);
131 }
132 }
133 return atomState;
134 }
135 return committedAtomStateMap.get(atom);
136 };
137 const setAtomState = (version, atom, atomState) => {
138 {
139 Object.freeze(atomState);
140 }
141 if (version) {
142 const versionedAtomStateMap = getVersionedAtomStateMap(version);
143 versionedAtomStateMap.set(atom, atomState);
144 } else {
145 const prevAtomState = committedAtomStateMap.get(atom);
146 committedAtomStateMap.set(atom, atomState);
147 if (!pendingMap.has(atom)) {
148 pendingMap.set(atom, prevAtomState);
149 }
150 }
151 };
152 const createReadDependencies = (version, prevReadDependencies = /* @__PURE__ */ new Map(), dependencies) => {
153 if (!dependencies) {
154 return prevReadDependencies;
155 }
156 const readDependencies = /* @__PURE__ */ new Map();
157 let changed = false;
158 dependencies.forEach((atom) => {
159 var _a;
160 const revision = ((_a = getAtomState(version, atom)) == null ? void 0 : _a.r) || 0;
161 readDependencies.set(atom, revision);
162 if (prevReadDependencies.get(atom) !== revision) {
163 changed = true;
164 }
165 });
166 if (prevReadDependencies.size === readDependencies.size && !changed) {
167 return prevReadDependencies;
168 }
169 return readDependencies;
170 };
171 const setAtomValue = (version, atom, value, dependencies, suspensePromise) => {
172 const atomState = getAtomState(version, atom);
173 if (atomState) {
174 if (suspensePromise && (!("p" in atomState) || !isEqualSuspensePromise(atomState.p, suspensePromise))) {
175 return atomState;
176 }
177 if ("p" in atomState) {
178 cancelSuspensePromise(atomState.p);
179 }
180 }
181 const nextAtomState = {
182 v: value,
183 r: (atomState == null ? void 0 : atomState.r) || 0,
184 d: createReadDependencies(version, atomState == null ? void 0 : atomState.d, dependencies)
185 };
186 let changed = false;
187 if (!atomState || !("v" in atomState) || !Object.is(atomState.v, value)) {
188 changed = true;
189 ++nextAtomState.r;
190 if (nextAtomState.d.has(atom)) {
191 nextAtomState.d = new Map(nextAtomState.d).set(atom, nextAtomState.r);
192 }
193 } else if ("i" in atomState || nextAtomState.d !== atomState.d && (nextAtomState.d.size !== atomState.d.size || !Array.from(nextAtomState.d.keys()).every((a) => atomState.d.has(a)))) {
194 changed = true;
195 Promise.resolve().then(() => {
196 flushPending(version);
197 });
198 }
199 if (atomState && !changed) {
200 return atomState;
201 }
202 setAtomState(version, atom, nextAtomState);
203 return nextAtomState;
204 };
205 const setAtomReadError = (version, atom, error, dependencies, suspensePromise) => {
206 const atomState = getAtomState(version, atom);
207 if (atomState) {
208 if (suspensePromise && (!("p" in atomState) || !isEqualSuspensePromise(atomState.p, suspensePromise))) {
209 return atomState;
210 }
211 if ("p" in atomState) {
212 cancelSuspensePromise(atomState.p);
213 }
214 }
215 const nextAtomState = {
216 e: error,
217 r: (atomState == null ? void 0 : atomState.r) || 0,
218 d: createReadDependencies(version, atomState == null ? void 0 : atomState.d, dependencies)
219 };
220 setAtomState(version, atom, nextAtomState);
221 return nextAtomState;
222 };
223 const setAtomSuspensePromise = (version, atom, suspensePromise, dependencies) => {
224 const atomState = getAtomState(version, atom);
225 if (atomState && "p" in atomState) {
226 if (isEqualSuspensePromise(atomState.p, suspensePromise)) {
227 return atomState;
228 }
229 cancelSuspensePromise(atomState.p);
230 }
231 addSuspensePromiseToCache(version, atom, suspensePromise);
232 const nextAtomState = {
233 p: suspensePromise,
234 r: (atomState == null ? void 0 : atomState.r) || 0,
235 d: createReadDependencies(version, atomState == null ? void 0 : atomState.d, dependencies)
236 };
237 setAtomState(version, atom, nextAtomState);
238 return nextAtomState;
239 };
240 const setAtomPromiseOrValue = (version, atom, promiseOrValue, dependencies) => {
241 if (promiseOrValue instanceof Promise) {
242 const suspensePromise = createSuspensePromise(promiseOrValue.then((value) => {
243 setAtomValue(version, atom, value, dependencies, suspensePromise);
244 }).catch((e) => {
245 if (e instanceof Promise) {
246 if (isSuspensePromise(e)) {
247 return e.then(() => {
248 readAtomState(version, atom, true);
249 });
250 }
251 return e;
252 }
253 setAtomReadError(version, atom, e, dependencies, suspensePromise);
254 }));
255 return setAtomSuspensePromise(version, atom, suspensePromise, dependencies);
256 }
257 return setAtomValue(version, atom, promiseOrValue, dependencies);
258 };
259 const setAtomInvalidated = (version, atom) => {
260 const atomState = getAtomState(version, atom);
261 if (atomState) {
262 const nextAtomState = {
263 ...atomState,
264 i: atomState.r
265 };
266 setAtomState(version, atom, nextAtomState);
267 } else {
268 console.warn("[Bug] could not invalidate non existing atom", atom);
269 }
270 };
271 const readAtomState = (version, atom, force) => {
272 if (!force) {
273 const atomState = getAtomState(version, atom);
274 if (atomState) {
275 if (atomState.r !== atomState.i && "p" in atomState && !isSuspensePromiseAlreadyCancelled(atomState.p)) {
276 return atomState;
277 }
278 atomState.d.forEach((_, a) => {
279 if (a !== atom) {
280 if (!mountedMap.has(a)) {
281 readAtomState(version, a);
282 } else {
283 const aState = getAtomState(version, a);
284 if (aState && aState.r === aState.i) {
285 readAtomState(version, a);
286 }
287 }
288 }
289 });
290 if (Array.from(atomState.d).every(([a, r]) => {
291 const aState = getAtomState(version, a);
292 return aState && "v" in aState && aState.r === r;
293 })) {
294 return atomState;
295 }
296 }
297 }
298 const dependencies = /* @__PURE__ */ new Set();
299 try {
300 const promiseOrValue = atom.read((a) => {
301 dependencies.add(a);
302 const aState = a === atom ? getAtomState(version, a) : readAtomState(version, a);
303 if (aState) {
304 if ("e" in aState) {
305 throw aState.e;
306 }
307 if ("p" in aState) {
308 throw aState.p;
309 }
310 return aState.v;
311 }
312 if (hasInitialValue(a)) {
313 return a.init;
314 }
315 throw new Error("no atom init");
316 });
317 return setAtomPromiseOrValue(version, atom, promiseOrValue, dependencies);
318 } catch (errorOrPromise) {
319 if (errorOrPromise instanceof Promise) {
320 const suspensePromise = createSuspensePromise(errorOrPromise);
321 return setAtomSuspensePromise(version, atom, suspensePromise, dependencies);
322 }
323 return setAtomReadError(version, atom, errorOrPromise, dependencies);
324 }
325 };
326 const readAtom = (readingAtom, version) => {
327 const atomState = readAtomState(version, readingAtom);
328 return atomState;
329 };
330 const addAtom = (version, addingAtom) => {
331 let mounted = mountedMap.get(addingAtom);
332 if (!mounted) {
333 mounted = mountAtom(version, addingAtom);
334 }
335 return mounted;
336 };
337 const canUnmountAtom = (atom, mounted) => !mounted.l.size && (!mounted.t.size || mounted.t.size === 1 && mounted.t.has(atom));
338 const delAtom = (version, deletingAtom) => {
339 const mounted = mountedMap.get(deletingAtom);
340 if (mounted && canUnmountAtom(deletingAtom, mounted)) {
341 unmountAtom(version, deletingAtom);
342 }
343 };
344 const invalidateDependents = (version, atom) => {
345 const mounted = mountedMap.get(atom);
346 mounted == null ? void 0 : mounted.t.forEach((dependent) => {
347 if (dependent !== atom) {
348 setAtomInvalidated(version, dependent);
349 invalidateDependents(version, dependent);
350 }
351 });
352 };
353 const writeAtomState = (version, atom, update) => {
354 let isSync = true;
355 const writeGetter = (a, options) => {
356 const aState = readAtomState(version, a);
357 if ("e" in aState) {
358 throw aState.e;
359 }
360 if ("p" in aState) {
361 if (options == null ? void 0 : options.unstable_promise) {
362 return aState.p.then(() => writeGetter(a, options));
363 }
364 {
365 console.info("Reading pending atom state in write operation. We throw a promise for now.", a);
366 }
367 throw aState.p;
368 }
369 if ("v" in aState) {
370 return aState.v;
371 }
372 {
373 console.warn("[Bug] no value found while reading atom in write operation. This is probably a bug.", a);
374 }
375 throw new Error("no value found");
376 };
377 const setter = (a, v) => {
378 let promiseOrVoid2;
379 if (a === atom) {
380 if (!hasInitialValue(a)) {
381 throw new Error("atom not writable");
382 }
383 const versionSet = cancelAllSuspensePromiseInCache(a);
384 versionSet.forEach((cancelledVersion) => {
385 if (cancelledVersion !== version) {
386 setAtomPromiseOrValue(cancelledVersion, a, v);
387 }
388 });
389 const prevAtomState = getAtomState(version, a);
390 const nextAtomState = setAtomPromiseOrValue(version, a, v);
391 if (prevAtomState !== nextAtomState) {
392 invalidateDependents(version, a);
393 }
394 } else {
395 promiseOrVoid2 = writeAtomState(version, a, v);
396 }
397 if (!isSync) {
398 flushPending(version);
399 }
400 return promiseOrVoid2;
401 };
402 const promiseOrVoid = atom.write(writeGetter, setter, update);
403 isSync = false;
404 return promiseOrVoid;
405 };
406 const writeAtom = (writingAtom, update, version) => {
407 const promiseOrVoid = writeAtomState(version, writingAtom, update);
408 flushPending(version);
409 return promiseOrVoid;
410 };
411 const isActuallyWritableAtom = (atom) => !!atom.write;
412 const mountAtom = (version, atom, initialDependent) => {
413 const mounted = {
414 t: new Set(initialDependent && [initialDependent]),
415 l: /* @__PURE__ */ new Set()
416 };
417 mountedMap.set(atom, mounted);
418 {
419 mountedAtoms.add(atom);
420 }
421 const atomState = readAtomState(void 0, atom);
422 atomState.d.forEach((_, a) => {
423 const aMounted = mountedMap.get(a);
424 if (aMounted) {
425 aMounted.t.add(atom);
426 } else {
427 if (a !== atom) {
428 mountAtom(version, a, atom);
429 }
430 }
431 });
432 if (isActuallyWritableAtom(atom) && atom.onMount) {
433 const setAtom = (update) => writeAtom(atom, update, version);
434 const onUnmount = atom.onMount(setAtom);
435 version = void 0;
436 if (onUnmount) {
437 mounted.u = onUnmount;
438 }
439 }
440 return mounted;
441 };
442 const unmountAtom = (version, atom) => {
443 var _a;
444 const onUnmount = (_a = mountedMap.get(atom)) == null ? void 0 : _a.u;
445 if (onUnmount) {
446 onUnmount();
447 }
448 mountedMap.delete(atom);
449 {
450 mountedAtoms.delete(atom);
451 }
452 const atomState = getAtomState(version, atom);
453 if (atomState) {
454 atomState.d.forEach((_, a) => {
455 if (a !== atom) {
456 const mounted = mountedMap.get(a);
457 if (mounted) {
458 mounted.t.delete(atom);
459 if (canUnmountAtom(a, mounted)) {
460 unmountAtom(version, a);
461 }
462 }
463 }
464 });
465 } else {
466 console.warn("[Bug] could not find atom state to unmount", atom);
467 }
468 };
469 const mountDependencies = (version, atom, atomState, prevReadDependencies) => {
470 const dependencies = new Set(atomState.d.keys());
471 prevReadDependencies == null ? void 0 : prevReadDependencies.forEach((_, a) => {
472 if (dependencies.has(a)) {
473 dependencies.delete(a);
474 return;
475 }
476 const mounted = mountedMap.get(a);
477 if (mounted) {
478 mounted.t.delete(atom);
479 if (canUnmountAtom(a, mounted)) {
480 unmountAtom(version, a);
481 }
482 }
483 });
484 dependencies.forEach((a) => {
485 const mounted = mountedMap.get(a);
486 if (mounted) {
487 mounted.t.add(atom);
488 } else if (mountedMap.has(atom)) {
489 mountAtom(version, a, atom);
490 }
491 });
492 };
493 const flushPending = (version) => {
494 if (version) {
495 const versionedAtomStateMap = getVersionedAtomStateMap(version);
496 versionedAtomStateMap.forEach((atomState, atom) => {
497 const committedAtomState = committedAtomStateMap.get(atom);
498 if (atomState !== committedAtomState) {
499 const mounted = mountedMap.get(atom);
500 mounted == null ? void 0 : mounted.l.forEach((listener) => listener(version));
501 }
502 });
503 return;
504 }
505 while (pendingMap.size) {
506 const pending = Array.from(pendingMap);
507 pendingMap.clear();
508 pending.forEach(([atom, prevAtomState]) => {
509 const atomState = getAtomState(void 0, atom);
510 if (atomState && atomState.d !== (prevAtomState == null ? void 0 : prevAtomState.d)) {
511 mountDependencies(void 0, atom, atomState, prevAtomState == null ? void 0 : prevAtomState.d);
512 }
513 if (prevAtomState && "i" in prevAtomState && atomState && !("i" in atomState)) {
514 return;
515 }
516 const mounted = mountedMap.get(atom);
517 mounted == null ? void 0 : mounted.l.forEach((listener) => listener());
518 });
519 }
520 {
521 stateListeners.forEach((l) => l());
522 }
523 };
524 const commitVersionedAtomStateMap = (version) => {
525 const versionedAtomStateMap = getVersionedAtomStateMap(version);
526 versionedAtomStateMap.forEach((atomState, atom) => {
527 const prevAtomState = committedAtomStateMap.get(atom);
528 if (!prevAtomState || atomState.r > prevAtomState.r || "v" in atomState && atomState.r === prevAtomState.r && atomState.d !== prevAtomState.d) {
529 committedAtomStateMap.set(atom, atomState);
530 if (atomState.d !== (prevAtomState == null ? void 0 : prevAtomState.d)) {
531 mountDependencies(version, atom, atomState, prevAtomState == null ? void 0 : prevAtomState.d);
532 }
533 }
534 });
535 };
536 const commitAtom = (_atom, version) => {
537 if (version) {
538 commitVersionedAtomStateMap(version);
539 }
540 flushPending(void 0);
541 };
542 const subscribeAtom = (atom, callback, version) => {
543 const mounted = addAtom(version, atom);
544 const listeners = mounted.l;
545 listeners.add(callback);
546 return () => {
547 listeners.delete(callback);
548 delAtom(version, atom);
549 };
550 };
551 const restoreAtoms = (values, version) => {
552 for (const [atom, value] of values) {
553 if (hasInitialValue(atom)) {
554 setAtomPromiseOrValue(version, atom, value);
555 invalidateDependents(version, atom);
556 }
557 }
558 flushPending(version);
559 };
560 {
561 return {
562 [READ_ATOM]: readAtom,
563 [WRITE_ATOM]: writeAtom,
564 [COMMIT_ATOM]: commitAtom,
565 [SUBSCRIBE_ATOM]: subscribeAtom,
566 [RESTORE_ATOMS]: restoreAtoms,
567 [DEV_SUBSCRIBE_STATE]: (l) => {
568 stateListeners.add(l);
569 return () => {
570 stateListeners.delete(l);
571 };
572 },
573 [DEV_GET_MOUNTED_ATOMS]: () => mountedAtoms.values(),
574 [DEV_GET_ATOM_STATE]: (a) => committedAtomStateMap.get(a),
575 [DEV_GET_MOUNTED]: (a) => mountedMap.get(a)
576 };
577 }
578 };
579 const createStoreForExport = exports('unstable_createStore', (initialValues) => {
580 const store = createStore(initialValues);
581 const get = (atom) => {
582 const atomState = store[READ_ATOM](atom);
583 if ("e" in atomState) {
584 throw atomState.e;
585 }
586 if ("p" in atomState) {
587 return void 0;
588 }
589 return atomState.v;
590 };
591 const asyncGet = (atom) => new Promise((resolve, reject) => {
592 const atomState = store[READ_ATOM](atom);
593 if ("e" in atomState) {
594 reject(atomState.e);
595 } else if ("p" in atomState) {
596 resolve(atomState.p.then(() => asyncGet(atom)));
597 } else {
598 resolve(atomState.v);
599 }
600 });
601 const set = (atom, update) => store[WRITE_ATOM](atom, update);
602 const sub = (atom, callback) => store[SUBSCRIBE_ATOM](atom, callback);
603 return {
604 get,
605 asyncGet,
606 set,
607 sub,
608 SECRET_INTERNAL_store: store
609 };
610 });
611
612 const createScopeContainer = (initialValues, unstable_createStore) => {
613 const store = unstable_createStore ? unstable_createStore(initialValues).SECRET_INTERNAL_store : createStore(initialValues);
614 return { s: store };
615 };
616 const ScopeContextMap = /* @__PURE__ */ new Map();
617 const getScopeContext = exports('SECRET_INTERNAL_getScopeContext', (scope) => {
618 if (!ScopeContextMap.has(scope)) {
619 ScopeContextMap.set(scope, createContext(createScopeContainer()));
620 }
621 return ScopeContextMap.get(scope);
622 });
623
624 const Provider = exports('Provider', ({
625 children,
626 initialValues,
627 scope,
628 unstable_createStore,
629 unstable_enableVersionedWrite
630 }) => {
631 const [version, setVersion] = useState({});
632 useEffect(() => {
633 const scopeContainer = scopeContainerRef.current;
634 if (scopeContainer.w) {
635 scopeContainer.s[COMMIT_ATOM](null, version);
636 delete version.p;
637 scopeContainer.v = version;
638 }
639 }, [version]);
640 const scopeContainerRef = useRef();
641 if (!scopeContainerRef.current) {
642 const scopeContainer = createScopeContainer(initialValues, unstable_createStore);
643 if (unstable_enableVersionedWrite) {
644 let retrying = 0;
645 scopeContainer.w = (write) => {
646 setVersion((parentVersion) => {
647 const nextVersion = retrying ? parentVersion : { p: parentVersion };
648 write(nextVersion);
649 return nextVersion;
650 });
651 };
652 scopeContainer.v = version;
653 scopeContainer.r = (fn) => {
654 ++retrying;
655 fn();
656 --retrying;
657 };
658 }
659 scopeContainerRef.current = scopeContainer;
660 }
661 const ScopeContainerContext = getScopeContext(scope);
662 return createElement(ScopeContainerContext.Provider, {
663 value: scopeContainerRef.current
664 }, children);
665 });
666
667 let keyCount = 0;
668 function atom(read, write) {
669 const key = `atom${++keyCount}`;
670 const config = {
671 toString: () => key
672 };
673 if (typeof read === "function") {
674 config.read = read;
675 } else {
676 config.init = read;
677 config.read = (get) => get(config);
678 config.write = (get, set, update) => set(config, typeof update === "function" ? update(get(config)) : update);
679 }
680 if (write) {
681 config.write = write;
682 }
683 return config;
684 }
685
686 function useAtomValue(atom, scope) {
687 const ScopeContext = getScopeContext(scope);
688 const scopeContainer = useContext(ScopeContext);
689 const { s: store, v: versionFromProvider } = scopeContainer;
690 const getAtomValue = (version2) => {
691 const atomState = store[READ_ATOM](atom, version2);
692 if ("e" in atomState) {
693 throw atomState.e;
694 }
695 if ("p" in atomState) {
696 throw atomState.p;
697 }
698 if ("v" in atomState) {
699 return atomState.v;
700 }
701 throw new Error("no atom value");
702 };
703 const [[version, valueFromReducer, atomFromReducer], rerenderIfChanged] = useReducer((prev, nextVersion) => {
704 const nextValue = getAtomValue(nextVersion);
705 if (Object.is(prev[1], nextValue) && prev[2] === atom) {
706 return prev;
707 }
708 return [nextVersion, nextValue, atom];
709 }, versionFromProvider, (initialVersion) => {
710 const initialValue = getAtomValue(initialVersion);
711 return [initialVersion, initialValue, atom];
712 });
713 let value = valueFromReducer;
714 if (atomFromReducer !== atom) {
715 rerenderIfChanged(version);
716 value = getAtomValue(version);
717 }
718 useEffect(() => {
719 const { v: versionFromProvider2 } = scopeContainer;
720 if (versionFromProvider2) {
721 store[COMMIT_ATOM](atom, versionFromProvider2);
722 }
723 const unsubscribe = store[SUBSCRIBE_ATOM](atom, rerenderIfChanged, versionFromProvider2);
724 rerenderIfChanged(versionFromProvider2);
725 return unsubscribe;
726 }, [store, atom, scopeContainer]);
727 useEffect(() => {
728 store[COMMIT_ATOM](atom, version);
729 });
730 useDebugValue(value);
731 return value;
732 }
733
734 function useSetAtom(atom, scope) {
735 const ScopeContext = getScopeContext(scope);
736 const { s: store, w: versionedWrite } = useContext(ScopeContext);
737 const setAtom = useCallback((update) => {
738 if (!("write" in atom)) {
739 throw new Error("not writable atom");
740 }
741 const write = (version) => store[WRITE_ATOM](atom, update, version);
742 return versionedWrite ? versionedWrite(write) : write();
743 }, [store, versionedWrite, atom]);
744 return setAtom;
745 }
746
747 function useAtom(atom, scope) {
748 if ("scope" in atom) {
749 console.warn("atom.scope is deprecated. Please do useAtom(atom, scope) instead.");
750 scope = atom.scope;
751 }
752 return [
753 useAtomValue(atom, scope),
754 useSetAtom(atom, scope)
755 ];
756 }
757
758 })
759 };
760}));