UNPKG

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