UNPKG

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