UNPKG

31.2 kBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react')) :
3 typeof define === 'function' && define.amd ? define(['exports', 'react'], factory) :
4 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.jotai = {}, global.React));
5})(this, (function (exports, react) { 'use strict';
6
7 function _extends() {
8 _extends = Object.assign ? Object.assign.bind() : function (target) {
9 for (var i = 1; i < arguments.length; i++) {
10 var source = arguments[i];
11
12 for (var key in source) {
13 if (Object.prototype.hasOwnProperty.call(source, key)) {
14 target[key] = source[key];
15 }
16 }
17 }
18
19 return target;
20 };
21 return _extends.apply(this, arguments);
22 }
23
24 function _unsupportedIterableToArray(o, minLen) {
25 if (!o) return;
26 if (typeof o === "string") return _arrayLikeToArray(o, minLen);
27 var n = Object.prototype.toString.call(o).slice(8, -1);
28 if (n === "Object" && o.constructor) n = o.constructor.name;
29 if (n === "Map" || n === "Set") return Array.from(o);
30 if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
31 }
32
33 function _arrayLikeToArray(arr, len) {
34 if (len == null || len > arr.length) len = arr.length;
35
36 for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
37
38 return arr2;
39 }
40
41 function _createForOfIteratorHelperLoose(o, allowArrayLike) {
42 var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
43 if (it) return (it = it.call(o)).next.bind(it);
44
45 if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
46 if (it) o = it;
47 var i = 0;
48 return function () {
49 if (i >= o.length) return {
50 done: true
51 };
52 return {
53 done: false,
54 value: o[i++]
55 };
56 };
57 }
58
59 throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
60 }
61
62 var SUSPENSE_PROMISE = Symbol();
63 var isSuspensePromise = function isSuspensePromise(promise) {
64 return !!promise[SUSPENSE_PROMISE];
65 };
66 var isSuspensePromiseAlreadyCancelled = function isSuspensePromiseAlreadyCancelled(suspensePromise) {
67 return !suspensePromise[SUSPENSE_PROMISE].c;
68 };
69 var cancelSuspensePromise = function cancelSuspensePromise(suspensePromise) {
70 var _suspensePromise$SUSP, _suspensePromise$SUSP2;
71
72 (_suspensePromise$SUSP = (_suspensePromise$SUSP2 = suspensePromise[SUSPENSE_PROMISE]).c) == null ? void 0 : _suspensePromise$SUSP.call(_suspensePromise$SUSP2);
73 };
74 var isEqualSuspensePromise = function isEqualSuspensePromise(oldSuspensePromise, newSuspensePromise) {
75 var oldOriginalPromise = oldSuspensePromise[SUSPENSE_PROMISE].o;
76 var newOriginalPromise = newSuspensePromise[SUSPENSE_PROMISE].o;
77 return oldOriginalPromise === newOriginalPromise || oldSuspensePromise === newOriginalPromise || isSuspensePromise(oldOriginalPromise) && isEqualSuspensePromise(oldOriginalPromise, newSuspensePromise);
78 };
79 var createSuspensePromise = function createSuspensePromise(promise) {
80 var objectToAttach = {
81 o: promise,
82 c: null
83 };
84 var suspensePromise = new Promise(function (resolve) {
85 objectToAttach.c = function () {
86 objectToAttach.c = null;
87 resolve();
88 };
89
90 promise.then(objectToAttach.c, objectToAttach.c);
91 });
92 suspensePromise[SUSPENSE_PROMISE] = objectToAttach;
93 return suspensePromise;
94 };
95
96 var hasInitialValue = function hasInitialValue(atom) {
97 return 'init' in atom;
98 };
99
100 var READ_ATOM = 'r';
101 var WRITE_ATOM = 'w';
102 var COMMIT_ATOM = 'c';
103 var SUBSCRIBE_ATOM = 's';
104 var RESTORE_ATOMS = 'h';
105 var DEV_SUBSCRIBE_STATE = 'n';
106 var DEV_GET_MOUNTED_ATOMS = 'l';
107 var DEV_GET_ATOM_STATE = 'a';
108 var DEV_GET_MOUNTED = 'm';
109 var createStore = function createStore(initialValues) {
110
111 var committedAtomStateMap = new WeakMap();
112 var mountedMap = new WeakMap();
113 var pendingMap = new Map();
114 var stateListeners;
115 var mountedAtoms;
116
117 {
118 stateListeners = new Set();
119 mountedAtoms = new Set();
120 }
121
122 if (initialValues) {
123 for (var _iterator = _createForOfIteratorHelperLoose(initialValues), _step; !(_step = _iterator()).done;) {
124 var _step$value = _step.value,
125 atom = _step$value[0],
126 value = _step$value[1];
127 var atomState = {
128 v: value,
129 r: 0,
130 d: new Map()
131 };
132
133 {
134 Object.freeze(atomState);
135
136 if (!hasInitialValue(atom)) {
137 console.warn('Found initial value for derived atom which can cause unexpected behavior', atom);
138 }
139 }
140
141 committedAtomStateMap.set(atom, atomState);
142 }
143 }
144
145 var suspensePromiseCacheMap = new WeakMap();
146
147 var addSuspensePromiseToCache = function addSuspensePromiseToCache(version, atom, suspensePromise) {
148 var cache = suspensePromiseCacheMap.get(atom);
149
150 if (!cache) {
151 cache = new Map();
152 suspensePromiseCacheMap.set(atom, cache);
153 }
154
155 suspensePromise.then(function () {
156 if (cache.get(version) === suspensePromise) {
157 cache.delete(version);
158
159 if (!cache.size) {
160 suspensePromiseCacheMap.delete(atom);
161 }
162 }
163 });
164 cache.set(version, suspensePromise);
165 };
166
167 var cancelAllSuspensePromiseInCache = function cancelAllSuspensePromiseInCache(atom) {
168 var versionSet = new Set();
169 var cache = suspensePromiseCacheMap.get(atom);
170
171 if (cache) {
172 suspensePromiseCacheMap.delete(atom);
173 cache.forEach(function (suspensePromise, version) {
174 cancelSuspensePromise(suspensePromise);
175 versionSet.add(version);
176 });
177 }
178
179 return versionSet;
180 };
181
182 var versionedAtomStateMapMap = new WeakMap();
183
184 var getVersionedAtomStateMap = function getVersionedAtomStateMap(version) {
185 var versionedAtomStateMap = versionedAtomStateMapMap.get(version);
186
187 if (!versionedAtomStateMap) {
188 versionedAtomStateMap = new Map();
189 versionedAtomStateMapMap.set(version, versionedAtomStateMap);
190 }
191
192 return versionedAtomStateMap;
193 };
194
195 var getAtomState = function getAtomState(version, atom) {
196 if (version) {
197 var versionedAtomStateMap = getVersionedAtomStateMap(version);
198
199 var _atomState = versionedAtomStateMap.get(atom);
200
201 if (!_atomState) {
202 _atomState = getAtomState(version.p, atom);
203
204 if (_atomState) {
205 versionedAtomStateMap.set(atom, _atomState);
206 }
207 }
208
209 return _atomState;
210 }
211
212 return committedAtomStateMap.get(atom);
213 };
214
215 var setAtomState = function setAtomState(version, atom, atomState) {
216 {
217 Object.freeze(atomState);
218 }
219
220 if (version) {
221 var versionedAtomStateMap = getVersionedAtomStateMap(version);
222 versionedAtomStateMap.set(atom, atomState);
223 } else {
224 var prevAtomState = committedAtomStateMap.get(atom);
225 committedAtomStateMap.set(atom, atomState);
226
227 if (!pendingMap.has(atom)) {
228 pendingMap.set(atom, prevAtomState);
229 }
230 }
231 };
232
233 var createReadDependencies = function createReadDependencies(version, prevReadDependencies, dependencies) {
234 if (prevReadDependencies === void 0) {
235 prevReadDependencies = new Map();
236 }
237
238 if (!dependencies) {
239 return prevReadDependencies;
240 }
241
242 var readDependencies = new Map();
243 var changed = false;
244 dependencies.forEach(function (atom) {
245 var _getAtomState;
246
247 var revision = ((_getAtomState = getAtomState(version, atom)) == null ? void 0 : _getAtomState.r) || 0;
248 readDependencies.set(atom, revision);
249
250 if (prevReadDependencies.get(atom) !== revision) {
251 changed = true;
252 }
253 });
254
255 if (prevReadDependencies.size === readDependencies.size && !changed) {
256 return prevReadDependencies;
257 }
258
259 return readDependencies;
260 };
261
262 var setAtomValue = function setAtomValue(version, atom, value, dependencies, suspensePromise) {
263 var atomState = getAtomState(version, atom);
264
265 if (atomState) {
266 if (suspensePromise && (!('p' in atomState) || !isEqualSuspensePromise(atomState.p, suspensePromise))) {
267 return atomState;
268 }
269
270 if ('p' in atomState) {
271 cancelSuspensePromise(atomState.p);
272 }
273 }
274
275 var nextAtomState = {
276 v: value,
277 r: (atomState == null ? void 0 : atomState.r) || 0,
278 d: createReadDependencies(version, atomState == null ? void 0 : atomState.d, dependencies)
279 };
280 var changed = false;
281
282 if (!atomState || !('v' in atomState) || !Object.is(atomState.v, value)) {
283 changed = true;
284 ++nextAtomState.r;
285
286 if (nextAtomState.d.has(atom)) {
287 nextAtomState.d = new Map(nextAtomState.d).set(atom, nextAtomState.r);
288 }
289 } else if ('i' in atomState || nextAtomState.d !== atomState.d && (nextAtomState.d.size !== atomState.d.size || !Array.from(nextAtomState.d.keys()).every(function (a) {
290 return atomState.d.has(a);
291 }))) {
292 changed = true;
293 Promise.resolve().then(function () {
294 flushPending(version);
295 });
296 }
297
298 if (atomState && !changed) {
299 return atomState;
300 }
301
302 setAtomState(version, atom, nextAtomState);
303 return nextAtomState;
304 };
305
306 var setAtomReadError = function setAtomReadError(version, atom, error, dependencies, suspensePromise) {
307 var atomState = getAtomState(version, atom);
308
309 if (atomState) {
310 if (suspensePromise && (!('p' in atomState) || !isEqualSuspensePromise(atomState.p, suspensePromise))) {
311 return atomState;
312 }
313
314 if ('p' in atomState) {
315 cancelSuspensePromise(atomState.p);
316 }
317 }
318
319 var nextAtomState = {
320 e: error,
321 r: (atomState == null ? void 0 : atomState.r) || 0,
322 d: createReadDependencies(version, atomState == null ? void 0 : atomState.d, dependencies)
323 };
324 setAtomState(version, atom, nextAtomState);
325 return nextAtomState;
326 };
327
328 var setAtomSuspensePromise = function setAtomSuspensePromise(version, atom, suspensePromise, dependencies) {
329 var atomState = getAtomState(version, atom);
330
331 if (atomState && 'p' in atomState) {
332 if (isEqualSuspensePromise(atomState.p, suspensePromise)) {
333 return atomState;
334 }
335
336 cancelSuspensePromise(atomState.p);
337 }
338
339 addSuspensePromiseToCache(version, atom, suspensePromise);
340 var nextAtomState = {
341 p: suspensePromise,
342 r: (atomState == null ? void 0 : atomState.r) || 0,
343 d: createReadDependencies(version, atomState == null ? void 0 : atomState.d, dependencies)
344 };
345 setAtomState(version, atom, nextAtomState);
346 return nextAtomState;
347 };
348
349 var setAtomPromiseOrValue = function setAtomPromiseOrValue(version, atom, promiseOrValue, dependencies) {
350 if (promiseOrValue instanceof Promise) {
351 var suspensePromise = createSuspensePromise(promiseOrValue.then(function (value) {
352 setAtomValue(version, atom, value, dependencies, suspensePromise);
353 }).catch(function (e) {
354 if (e instanceof Promise) {
355 if (isSuspensePromise(e)) {
356 return e.then(function () {
357 readAtomState(version, atom, true);
358 });
359 }
360
361 return e;
362 }
363
364 setAtomReadError(version, atom, e, dependencies, suspensePromise);
365 }));
366 return setAtomSuspensePromise(version, atom, suspensePromise, dependencies);
367 }
368
369 return setAtomValue(version, atom, promiseOrValue, dependencies);
370 };
371
372 var setAtomInvalidated = function setAtomInvalidated(version, atom) {
373 var atomState = getAtomState(version, atom);
374
375 if (atomState) {
376 var nextAtomState = _extends({}, atomState, {
377 i: atomState.r
378 });
379
380 setAtomState(version, atom, nextAtomState);
381 } else {
382 console.warn('[Bug] could not invalidate non existing atom', atom);
383 }
384 };
385
386 var readAtomState = function readAtomState(version, atom, force) {
387 if (!force) {
388 var _atomState2 = getAtomState(version, atom);
389
390 if (_atomState2) {
391 if (_atomState2.r !== _atomState2.i && 'p' in _atomState2 && !isSuspensePromiseAlreadyCancelled(_atomState2.p)) {
392 return _atomState2;
393 }
394
395 _atomState2.d.forEach(function (_, a) {
396 if (a !== atom) {
397 if (!mountedMap.has(a)) {
398 readAtomState(version, a);
399 } else {
400 var aState = getAtomState(version, a);
401
402 if (aState && aState.r === aState.i) {
403 readAtomState(version, a);
404 }
405 }
406 }
407 });
408
409 if (Array.from(_atomState2.d).every(function (_ref) {
410 var a = _ref[0],
411 r = _ref[1];
412 var aState = getAtomState(version, a);
413 return aState && 'v' in aState && aState.r === r;
414 })) {
415 return _atomState2;
416 }
417 }
418 }
419
420 var dependencies = new Set();
421
422 try {
423 var promiseOrValue = atom.read(function (a) {
424 dependencies.add(a);
425 var aState = a === atom ? getAtomState(version, a) : readAtomState(version, a);
426
427 if (aState) {
428 if ('e' in aState) {
429 throw aState.e;
430 }
431
432 if ('p' in aState) {
433 throw aState.p;
434 }
435
436 return aState.v;
437 }
438
439 if (hasInitialValue(a)) {
440 return a.init;
441 }
442
443 throw new Error('no atom init');
444 });
445 return setAtomPromiseOrValue(version, atom, promiseOrValue, dependencies);
446 } catch (errorOrPromise) {
447 if (errorOrPromise instanceof Promise) {
448 var suspensePromise = createSuspensePromise(errorOrPromise);
449 return setAtomSuspensePromise(version, atom, suspensePromise, dependencies);
450 }
451
452 return setAtomReadError(version, atom, errorOrPromise, dependencies);
453 }
454 };
455
456 var readAtom = function readAtom(readingAtom, version) {
457 var atomState = readAtomState(version, readingAtom);
458 return atomState;
459 };
460
461 var addAtom = function addAtom(version, addingAtom) {
462 var mounted = mountedMap.get(addingAtom);
463
464 if (!mounted) {
465 mounted = mountAtom(version, addingAtom);
466 }
467
468 return mounted;
469 };
470
471 var canUnmountAtom = function canUnmountAtom(atom, mounted) {
472 return !mounted.l.size && (!mounted.t.size || mounted.t.size === 1 && mounted.t.has(atom));
473 };
474
475 var delAtom = function delAtom(version, deletingAtom) {
476 var mounted = mountedMap.get(deletingAtom);
477
478 if (mounted && canUnmountAtom(deletingAtom, mounted)) {
479 unmountAtom(version, deletingAtom);
480 }
481 };
482
483 var invalidateDependents = function invalidateDependents(version, atom) {
484 var mounted = mountedMap.get(atom);
485 mounted == null ? void 0 : mounted.t.forEach(function (dependent) {
486 if (dependent !== atom) {
487 setAtomInvalidated(version, dependent);
488 invalidateDependents(version, dependent);
489 }
490 });
491 };
492
493 var writeAtomState = function writeAtomState(version, atom, update) {
494 var isSync = true;
495
496 var writeGetter = function writeGetter(a, options) {
497 var aState = readAtomState(version, a);
498
499 if ('e' in aState) {
500 throw aState.e;
501 }
502
503 if ('p' in aState) {
504 if (options != null && options.unstable_promise) {
505 return aState.p.then(function () {
506 return writeGetter(a, options);
507 });
508 }
509
510 {
511 console.info('Reading pending atom state in write operation. We throw a promise for now.', a);
512 }
513
514 throw aState.p;
515 }
516
517 if ('v' in aState) {
518 return aState.v;
519 }
520
521 {
522 console.warn('[Bug] no value found while reading atom in write operation. This is probably a bug.', a);
523 }
524
525 throw new Error('no value found');
526 };
527
528 var setter = function setter(a, v) {
529 var promiseOrVoid;
530
531 if (a === atom) {
532 if (!hasInitialValue(a)) {
533 throw new Error('atom not writable');
534 }
535
536 var versionSet = cancelAllSuspensePromiseInCache(a);
537 versionSet.forEach(function (cancelledVersion) {
538 if (cancelledVersion !== version) {
539 setAtomPromiseOrValue(cancelledVersion, a, v);
540 }
541 });
542 var prevAtomState = getAtomState(version, a);
543 var nextAtomState = setAtomPromiseOrValue(version, a, v);
544
545 if (prevAtomState !== nextAtomState) {
546 invalidateDependents(version, a);
547 }
548 } else {
549 promiseOrVoid = writeAtomState(version, a, v);
550 }
551
552 if (!isSync) {
553 flushPending(version);
554 }
555
556 return promiseOrVoid;
557 };
558
559 var promiseOrVoid = atom.write(writeGetter, setter, update);
560 isSync = false;
561 return promiseOrVoid;
562 };
563
564 var writeAtom = function writeAtom(writingAtom, update, version) {
565 var promiseOrVoid = writeAtomState(version, writingAtom, update);
566 flushPending(version);
567 return promiseOrVoid;
568 };
569
570 var isActuallyWritableAtom = function isActuallyWritableAtom(atom) {
571 return !!atom.write;
572 };
573
574 var mountAtom = function mountAtom(version, atom, initialDependent) {
575 var mounted = {
576 t: new Set(initialDependent && [initialDependent]),
577 l: new Set()
578 };
579 mountedMap.set(atom, mounted);
580
581 {
582 mountedAtoms.add(atom);
583 }
584
585 var atomState = readAtomState(undefined, atom);
586 atomState.d.forEach(function (_, a) {
587 var aMounted = mountedMap.get(a);
588
589 if (aMounted) {
590 aMounted.t.add(atom);
591 } else {
592 if (a !== atom) {
593 mountAtom(version, a, atom);
594 }
595 }
596 });
597
598 if (isActuallyWritableAtom(atom) && atom.onMount) {
599 var setAtom = function setAtom(update) {
600 return writeAtom(atom, update, version);
601 };
602
603 var onUnmount = atom.onMount(setAtom);
604 version = undefined;
605
606 if (onUnmount) {
607 mounted.u = onUnmount;
608 }
609 }
610
611 return mounted;
612 };
613
614 var unmountAtom = function unmountAtom(version, atom) {
615 var _mountedMap$get;
616
617 var onUnmount = (_mountedMap$get = mountedMap.get(atom)) == null ? void 0 : _mountedMap$get.u;
618
619 if (onUnmount) {
620 onUnmount();
621 }
622
623 mountedMap.delete(atom);
624
625 {
626 mountedAtoms.delete(atom);
627 }
628
629 var atomState = getAtomState(version, atom);
630
631 if (atomState) {
632 atomState.d.forEach(function (_, a) {
633 if (a !== atom) {
634 var mounted = mountedMap.get(a);
635
636 if (mounted) {
637 mounted.t.delete(atom);
638
639 if (canUnmountAtom(a, mounted)) {
640 unmountAtom(version, a);
641 }
642 }
643 }
644 });
645 } else {
646 console.warn('[Bug] could not find atom state to unmount', atom);
647 }
648 };
649
650 var mountDependencies = function mountDependencies(version, atom, atomState, prevReadDependencies) {
651 var dependencies = new Set(atomState.d.keys());
652 prevReadDependencies == null ? void 0 : prevReadDependencies.forEach(function (_, a) {
653 if (dependencies.has(a)) {
654 dependencies.delete(a);
655 return;
656 }
657
658 var mounted = mountedMap.get(a);
659
660 if (mounted) {
661 mounted.t.delete(atom);
662
663 if (canUnmountAtom(a, mounted)) {
664 unmountAtom(version, a);
665 }
666 }
667 });
668 dependencies.forEach(function (a) {
669 var mounted = mountedMap.get(a);
670
671 if (mounted) {
672 mounted.t.add(atom);
673 } else if (mountedMap.has(atom)) {
674 mountAtom(version, a, atom);
675 }
676 });
677 };
678
679 var flushPending = function flushPending(version) {
680 if (version) {
681 var versionedAtomStateMap = getVersionedAtomStateMap(version);
682 versionedAtomStateMap.forEach(function (atomState, atom) {
683 var committedAtomState = committedAtomStateMap.get(atom);
684
685 if (atomState !== committedAtomState) {
686 var mounted = mountedMap.get(atom);
687 mounted == null ? void 0 : mounted.l.forEach(function (listener) {
688 return listener(version);
689 });
690 }
691 });
692 return;
693 }
694
695 while (pendingMap.size) {
696 var pending = Array.from(pendingMap);
697 pendingMap.clear();
698 pending.forEach(function (_ref2) {
699 var atom = _ref2[0],
700 prevAtomState = _ref2[1];
701 var atomState = getAtomState(undefined, atom);
702
703 if (atomState && atomState.d !== (prevAtomState == null ? void 0 : prevAtomState.d)) {
704 mountDependencies(undefined, atom, atomState, prevAtomState == null ? void 0 : prevAtomState.d);
705 }
706
707 if (prevAtomState && 'i' in prevAtomState && atomState && !('i' in atomState)) {
708 return;
709 }
710
711 var mounted = mountedMap.get(atom);
712 mounted == null ? void 0 : mounted.l.forEach(function (listener) {
713 return listener();
714 });
715 });
716 }
717
718 {
719 stateListeners.forEach(function (l) {
720 return l();
721 });
722 }
723 };
724
725 var commitVersionedAtomStateMap = function commitVersionedAtomStateMap(version) {
726 var versionedAtomStateMap = getVersionedAtomStateMap(version);
727 versionedAtomStateMap.forEach(function (atomState, atom) {
728 var prevAtomState = committedAtomStateMap.get(atom);
729
730 if (!prevAtomState || atomState.r > prevAtomState.r || 'v' in atomState && atomState.r === prevAtomState.r && atomState.d !== prevAtomState.d) {
731 committedAtomStateMap.set(atom, atomState);
732
733 if (atomState.d !== (prevAtomState == null ? void 0 : prevAtomState.d)) {
734 mountDependencies(version, atom, atomState, prevAtomState == null ? void 0 : prevAtomState.d);
735 }
736 }
737 });
738 };
739
740 var commitAtom = function commitAtom(_atom, version) {
741 if (version) {
742 commitVersionedAtomStateMap(version);
743 }
744
745 flushPending(undefined);
746 };
747
748 var subscribeAtom = function subscribeAtom(atom, callback, version) {
749 var mounted = addAtom(version, atom);
750 var listeners = mounted.l;
751 listeners.add(callback);
752 return function () {
753 listeners.delete(callback);
754 delAtom(version, atom);
755 };
756 };
757
758 var restoreAtoms = function restoreAtoms(values, version) {
759 for (var _iterator2 = _createForOfIteratorHelperLoose(values), _step2; !(_step2 = _iterator2()).done;) {
760 var _step2$value = _step2.value,
761 _atom2 = _step2$value[0],
762 _value = _step2$value[1];
763
764 if (hasInitialValue(_atom2)) {
765 setAtomPromiseOrValue(version, _atom2, _value);
766 invalidateDependents(version, _atom2);
767 }
768 }
769
770 flushPending(version);
771 };
772
773 {
774 var _ref3;
775
776 return _ref3 = {}, _ref3[READ_ATOM] = readAtom, _ref3[WRITE_ATOM] = writeAtom, _ref3[COMMIT_ATOM] = commitAtom, _ref3[SUBSCRIBE_ATOM] = subscribeAtom, _ref3[RESTORE_ATOMS] = restoreAtoms, _ref3[DEV_SUBSCRIBE_STATE] = function (l) {
777 stateListeners.add(l);
778 return function () {
779 stateListeners.delete(l);
780 };
781 }, _ref3[DEV_GET_MOUNTED_ATOMS] = function () {
782 return mountedAtoms.values();
783 }, _ref3[DEV_GET_ATOM_STATE] = function (a) {
784 return committedAtomStateMap.get(a);
785 }, _ref3[DEV_GET_MOUNTED] = function (a) {
786 return mountedMap.get(a);
787 }, _ref3;
788 }
789 };
790 var createStoreForExport = function createStoreForExport(initialValues) {
791 var store = createStore(initialValues);
792
793 var get = function get(atom) {
794 var atomState = store[READ_ATOM](atom);
795
796 if ('e' in atomState) {
797 throw atomState.e;
798 }
799
800 if ('p' in atomState) {
801 return undefined;
802 }
803
804 return atomState.v;
805 };
806
807 var asyncGet = function asyncGet(atom) {
808 return new Promise(function (resolve, reject) {
809 var atomState = store[READ_ATOM](atom);
810
811 if ('e' in atomState) {
812 reject(atomState.e);
813 } else if ('p' in atomState) {
814 resolve(atomState.p.then(function () {
815 return asyncGet(atom);
816 }));
817 } else {
818 resolve(atomState.v);
819 }
820 });
821 };
822
823 var set = function set(atom, update) {
824 return store[WRITE_ATOM](atom, update);
825 };
826
827 var sub = function sub(atom, callback) {
828 return store[SUBSCRIBE_ATOM](atom, callback);
829 };
830
831 return {
832 get: get,
833 asyncGet: asyncGet,
834 set: set,
835 sub: sub,
836 SECRET_INTERNAL_store: store
837 };
838 };
839
840 var createScopeContainer = function createScopeContainer(initialValues, unstable_createStore) {
841 var store = unstable_createStore ? unstable_createStore(initialValues).SECRET_INTERNAL_store : createStore(initialValues);
842 return {
843 s: store
844 };
845 };
846 var ScopeContextMap = new Map();
847 var getScopeContext = function getScopeContext(scope) {
848 if (!ScopeContextMap.has(scope)) {
849 ScopeContextMap.set(scope, react.createContext(createScopeContainer()));
850 }
851
852 return ScopeContextMap.get(scope);
853 };
854
855 var Provider = function Provider(_ref) {
856 var children = _ref.children,
857 initialValues = _ref.initialValues,
858 scope = _ref.scope,
859 unstable_createStore = _ref.unstable_createStore,
860 unstable_enableVersionedWrite = _ref.unstable_enableVersionedWrite;
861
862 var _useState = react.useState({}),
863 version = _useState[0],
864 setVersion = _useState[1];
865
866 react.useEffect(function () {
867 var scopeContainer = scopeContainerRef.current;
868
869 if (scopeContainer.w) {
870 scopeContainer.s[COMMIT_ATOM](null, version);
871 delete version.p;
872 scopeContainer.v = version;
873 }
874 }, [version]);
875 var scopeContainerRef = react.useRef();
876
877 if (!scopeContainerRef.current) {
878 var scopeContainer = createScopeContainer(initialValues, unstable_createStore);
879
880 if (unstable_enableVersionedWrite) {
881 var retrying = 0;
882
883 scopeContainer.w = function (write) {
884 setVersion(function (parentVersion) {
885 var nextVersion = retrying ? parentVersion : {
886 p: parentVersion
887 };
888 write(nextVersion);
889 return nextVersion;
890 });
891 };
892
893 scopeContainer.v = version;
894
895 scopeContainer.r = function (fn) {
896 ++retrying;
897 fn();
898 --retrying;
899 };
900 }
901
902 scopeContainerRef.current = scopeContainer;
903 }
904
905 var ScopeContainerContext = getScopeContext(scope);
906 return react.createElement(ScopeContainerContext.Provider, {
907 value: scopeContainerRef.current
908 }, children);
909 };
910
911 var keyCount = 0;
912 function atom(read, write) {
913 var key = "atom" + ++keyCount;
914 var config = {
915 toString: function toString() {
916 return key;
917 }
918 };
919
920 if (typeof read === 'function') {
921 config.read = read;
922 } else {
923 config.init = read;
924
925 config.read = function (get) {
926 return get(config);
927 };
928
929 config.write = function (get, set, update) {
930 return set(config, typeof update === 'function' ? update(get(config)) : update);
931 };
932 }
933
934 if (write) {
935 config.write = write;
936 }
937
938 return config;
939 }
940
941 function useAtomValue(atom, scope) {
942 var ScopeContext = getScopeContext(scope);
943 var scopeContainer = react.useContext(ScopeContext);
944 var store = scopeContainer.s,
945 versionFromProvider = scopeContainer.v;
946
947 var getAtomValue = function getAtomValue(version) {
948 var atomState = store[READ_ATOM](atom, version);
949
950 if ('e' in atomState) {
951 throw atomState.e;
952 }
953
954 if ('p' in atomState) {
955 throw atomState.p;
956 }
957
958 if ('v' in atomState) {
959 return atomState.v;
960 }
961
962 throw new Error('no atom value');
963 };
964
965 var _useReducer = react.useReducer(function (prev, nextVersion) {
966 var nextValue = getAtomValue(nextVersion);
967
968 if (Object.is(prev[1], nextValue) && prev[2] === atom) {
969 return prev;
970 }
971
972 return [nextVersion, nextValue, atom];
973 }, versionFromProvider, function (initialVersion) {
974 var initialValue = getAtomValue(initialVersion);
975 return [initialVersion, initialValue, atom];
976 }),
977 _useReducer$ = _useReducer[0],
978 version = _useReducer$[0],
979 valueFromReducer = _useReducer$[1],
980 atomFromReducer = _useReducer$[2],
981 rerenderIfChanged = _useReducer[1];
982
983 var value = valueFromReducer;
984
985 if (atomFromReducer !== atom) {
986 rerenderIfChanged(version);
987 value = getAtomValue(version);
988 }
989
990 react.useEffect(function () {
991 var versionFromProvider = scopeContainer.v;
992
993 if (versionFromProvider) {
994 store[COMMIT_ATOM](atom, versionFromProvider);
995 }
996
997 var unsubscribe = store[SUBSCRIBE_ATOM](atom, rerenderIfChanged, versionFromProvider);
998 rerenderIfChanged(versionFromProvider);
999 return unsubscribe;
1000 }, [store, atom, scopeContainer]);
1001 react.useEffect(function () {
1002 store[COMMIT_ATOM](atom, version);
1003 });
1004 react.useDebugValue(value);
1005 return value;
1006 }
1007
1008 function useSetAtom(atom, scope) {
1009 var ScopeContext = getScopeContext(scope);
1010
1011 var _useContext = react.useContext(ScopeContext),
1012 store = _useContext.s,
1013 versionedWrite = _useContext.w;
1014
1015 var setAtom = react.useCallback(function (update) {
1016 if (!('write' in atom)) {
1017 throw new Error('not writable atom');
1018 }
1019
1020 var write = function write(version) {
1021 return store[WRITE_ATOM](atom, update, version);
1022 };
1023
1024 return versionedWrite ? versionedWrite(write) : write();
1025 }, [store, versionedWrite, atom]);
1026 return setAtom;
1027 }
1028
1029 function useAtom(atom, scope) {
1030 if ('scope' in atom) {
1031 console.warn('atom.scope is deprecated. Please do useAtom(atom, scope) instead.');
1032 scope = atom.scope;
1033 }
1034
1035 return [useAtomValue(atom, scope), useSetAtom(atom, scope)];
1036 }
1037
1038 exports.Provider = Provider;
1039 exports.SECRET_INTERNAL_getScopeContext = getScopeContext;
1040 exports.atom = atom;
1041 exports.unstable_createStore = createStoreForExport;
1042 exports.useAtom = useAtom;
1043 exports.useAtomValue = useAtomValue;
1044 exports.useSetAtom = useSetAtom;
1045
1046 Object.defineProperty(exports, '__esModule', { value: true });
1047
1048}));