UNPKG

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