UNPKG

31.7 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 const s = getAtomState(version, a);
411 if (s && "p" in s && s.p === aState.p) {
412 return new Promise((resolve) => setTimeout(resolve)).then(
413 () => writeGetter(a, options)
414 );
415 }
416 return writeGetter(a, options);
417 });
418 }
419 {
420 console.info(
421 "Reading pending atom state in write operation. We throw a promise for now.",
422 a
423 );
424 }
425 throw aState.p;
426 }
427 if ("v" in aState) {
428 return aState.v;
429 }
430 {
431 console.warn(
432 "[Bug] no value found while reading atom in write operation. This is probably a bug.",
433 a
434 );
435 }
436 throw new Error("no value found");
437 };
438 const setter = (a, v) => {
439 let promiseOrVoid2;
440 if (a === atom) {
441 if (!hasInitialValue(a)) {
442 throw new Error("atom not writable");
443 }
444 const versionSet = cancelAllSuspensePromiseInCache(a);
445 versionSet.forEach((cancelledVersion) => {
446 if (cancelledVersion !== version) {
447 setAtomPromiseOrValue(cancelledVersion, a, v);
448 }
449 });
450 const prevAtomState = getAtomState(version, a);
451 const nextAtomState = setAtomPromiseOrValue(version, a, v);
452 if (prevAtomState !== nextAtomState) {
453 invalidateDependents(version, a);
454 }
455 } else {
456 promiseOrVoid2 = writeAtomState(version, a, v);
457 }
458 if (!isSync) {
459 flushPending(version);
460 }
461 return promiseOrVoid2;
462 };
463 const promiseOrVoid = atom.write(writeGetter, setter, update);
464 isSync = false;
465 return promiseOrVoid;
466 };
467 const writeAtom = (writingAtom, update, version) => {
468 const promiseOrVoid = writeAtomState(version, writingAtom, update);
469 flushPending(version);
470 return promiseOrVoid;
471 };
472 const isActuallyWritableAtom = (atom) => !!atom.write;
473 const mountAtom = (version, atom, initialDependent) => {
474 const mounted = {
475 t: new Set(initialDependent && [initialDependent]),
476 l: /* @__PURE__ */ new Set()
477 };
478 mountedMap.set(atom, mounted);
479 {
480 mountedAtoms.add(atom);
481 }
482 const atomState = readAtomState(void 0, atom);
483 atomState.d.forEach((_, a) => {
484 const aMounted = mountedMap.get(a);
485 if (aMounted) {
486 aMounted.t.add(atom);
487 } else {
488 if (a !== atom) {
489 mountAtom(version, a, atom);
490 }
491 }
492 });
493 if (isActuallyWritableAtom(atom) && atom.onMount) {
494 const setAtom = (update) => writeAtom(atom, update, version);
495 const onUnmount = atom.onMount(setAtom);
496 version = void 0;
497 if (onUnmount) {
498 mounted.u = onUnmount;
499 }
500 }
501 return mounted;
502 };
503 const unmountAtom = (version, atom) => {
504 var _a;
505 const onUnmount = (_a = mountedMap.get(atom)) == null ? void 0 : _a.u;
506 if (onUnmount) {
507 onUnmount();
508 }
509 mountedMap.delete(atom);
510 {
511 mountedAtoms.delete(atom);
512 }
513 const atomState = getAtomState(version, atom);
514 if (atomState) {
515 if ("p" in atomState) {
516 cancelSuspensePromise(atomState.p);
517 }
518 atomState.d.forEach((_, a) => {
519 if (a !== atom) {
520 const mounted = mountedMap.get(a);
521 if (mounted) {
522 mounted.t.delete(atom);
523 if (canUnmountAtom(a, mounted)) {
524 unmountAtom(version, a);
525 }
526 }
527 }
528 });
529 } else {
530 console.warn("[Bug] could not find atom state to unmount", atom);
531 }
532 };
533 const mountDependencies = (version, atom, atomState, prevReadDependencies) => {
534 const dependencies = new Set(atomState.d.keys());
535 prevReadDependencies == null ? void 0 : prevReadDependencies.forEach((_, a) => {
536 if (dependencies.has(a)) {
537 dependencies.delete(a);
538 return;
539 }
540 const mounted = mountedMap.get(a);
541 if (mounted) {
542 mounted.t.delete(atom);
543 if (canUnmountAtom(a, mounted)) {
544 unmountAtom(version, a);
545 }
546 }
547 });
548 dependencies.forEach((a) => {
549 const mounted = mountedMap.get(a);
550 if (mounted) {
551 mounted.t.add(atom);
552 } else if (mountedMap.has(atom)) {
553 mountAtom(version, a, atom);
554 }
555 });
556 };
557 const flushPending = (version) => {
558 if (version) {
559 const versionedAtomStateMap = getVersionedAtomStateMap(version);
560 versionedAtomStateMap.forEach((atomState, atom) => {
561 const committedAtomState = committedAtomStateMap.get(atom);
562 if (atomState !== committedAtomState) {
563 const mounted = mountedMap.get(atom);
564 mounted == null ? void 0 : mounted.l.forEach((listener) => listener(version));
565 }
566 });
567 return;
568 }
569 while (pendingMap.size) {
570 const pending = Array.from(pendingMap);
571 pendingMap.clear();
572 pending.forEach(([atom, prevAtomState]) => {
573 const atomState = getAtomState(void 0, atom);
574 if (atomState && atomState.d !== (prevAtomState == null ? void 0 : prevAtomState.d)) {
575 mountDependencies(void 0, atom, atomState, prevAtomState == null ? void 0 : prevAtomState.d);
576 }
577 if (prevAtomState && !prevAtomState.y && (atomState == null ? void 0 : atomState.y)) {
578 return;
579 }
580 const mounted = mountedMap.get(atom);
581 mounted == null ? void 0 : mounted.l.forEach((listener) => listener());
582 });
583 }
584 {
585 stateListeners.forEach((l) => l());
586 }
587 };
588 const commitVersionedAtomStateMap = (version) => {
589 const versionedAtomStateMap = getVersionedAtomStateMap(version);
590 versionedAtomStateMap.forEach((atomState, atom) => {
591 const prevAtomState = committedAtomStateMap.get(atom);
592 if (!prevAtomState || atomState.r > prevAtomState.r || atomState.y !== prevAtomState.y || atomState.r === prevAtomState.r && atomState.d !== prevAtomState.d) {
593 committedAtomStateMap.set(atom, atomState);
594 if (atomState.d !== (prevAtomState == null ? void 0 : prevAtomState.d)) {
595 mountDependencies(version, atom, atomState, prevAtomState == null ? void 0 : prevAtomState.d);
596 }
597 }
598 });
599 };
600 const commitAtom = (_atom, version) => {
601 if (version) {
602 commitVersionedAtomStateMap(version);
603 }
604 flushPending(void 0);
605 };
606 const subscribeAtom = (atom, callback, version) => {
607 const mounted = addAtom(version, atom);
608 const listeners = mounted.l;
609 listeners.add(callback);
610 return () => {
611 listeners.delete(callback);
612 delAtom(version, atom);
613 };
614 };
615 const restoreAtoms = (values, version) => {
616 for (const [atom, value] of values) {
617 if (hasInitialValue(atom)) {
618 setAtomPromiseOrValue(version, atom, value);
619 invalidateDependents(version, atom);
620 }
621 }
622 flushPending(version);
623 };
624 {
625 return {
626 [READ_ATOM]: readAtom,
627 [WRITE_ATOM]: writeAtom,
628 [COMMIT_ATOM]: commitAtom,
629 [SUBSCRIBE_ATOM]: subscribeAtom,
630 [RESTORE_ATOMS]: restoreAtoms,
631 [DEV_SUBSCRIBE_STATE]: (l) => {
632 stateListeners.add(l);
633 return () => {
634 stateListeners.delete(l);
635 };
636 },
637 [DEV_GET_MOUNTED_ATOMS]: () => mountedAtoms.values(),
638 [DEV_GET_ATOM_STATE]: (a) => committedAtomStateMap.get(a),
639 [DEV_GET_MOUNTED]: (a) => mountedMap.get(a)
640 };
641 }
642 };
643 const createStoreForExport = exports('unstable_createStore', (initialValues) => {
644 const store = createStore(initialValues);
645 const get = (atom) => {
646 const atomState = store[READ_ATOM](atom);
647 if ("e" in atomState) {
648 throw atomState.e;
649 }
650 if ("p" in atomState) {
651 return void 0;
652 }
653 return atomState.v;
654 };
655 const asyncGet = (atom) => new Promise((resolve, reject) => {
656 const atomState = store[READ_ATOM](atom);
657 if ("e" in atomState) {
658 reject(atomState.e);
659 } else if ("p" in atomState) {
660 resolve(atomState.p.then(() => asyncGet(atom)));
661 } else {
662 resolve(atomState.v);
663 }
664 });
665 const set = (atom, update) => store[WRITE_ATOM](atom, update);
666 const sub = (atom, callback) => store[SUBSCRIBE_ATOM](atom, callback);
667 return {
668 get,
669 asyncGet,
670 set,
671 sub,
672 SECRET_INTERNAL_store: store
673 };
674 });
675
676 const createScopeContainer = (initialValues, unstable_createStore) => {
677 const store = unstable_createStore ? unstable_createStore(initialValues).SECRET_INTERNAL_store : createStore(initialValues);
678 return { s: store };
679 };
680 const ScopeContextMap = /* @__PURE__ */ new Map();
681 const getScopeContext = exports('SECRET_INTERNAL_getScopeContext', (scope) => {
682 if (!ScopeContextMap.has(scope)) {
683 ScopeContextMap.set(scope, createContext(createScopeContainer()));
684 }
685 return ScopeContextMap.get(scope);
686 });
687
688 const Provider = exports('Provider', ({
689 children,
690 initialValues,
691 scope,
692 unstable_createStore,
693 unstable_enableVersionedWrite
694 }) => {
695 const [version, setVersion] = useState({});
696 useEffect(() => {
697 const scopeContainer = scopeContainerRef.current;
698 if (scopeContainer.w) {
699 scopeContainer.s[COMMIT_ATOM](null, version);
700 delete version.p;
701 scopeContainer.v = version;
702 }
703 }, [version]);
704 const scopeContainerRef = useRef();
705 if (!scopeContainerRef.current) {
706 const scopeContainer = createScopeContainer(
707 initialValues,
708 unstable_createStore
709 );
710 if (unstable_enableVersionedWrite) {
711 let retrying = 0;
712 scopeContainer.w = (write) => {
713 setVersion((parentVersion) => {
714 const nextVersion = retrying ? parentVersion : { p: parentVersion };
715 write(nextVersion);
716 return nextVersion;
717 });
718 };
719 scopeContainer.v = version;
720 scopeContainer.r = (fn) => {
721 ++retrying;
722 fn();
723 --retrying;
724 };
725 }
726 scopeContainerRef.current = scopeContainer;
727 }
728 const ScopeContainerContext = getScopeContext(scope);
729 return createElement(
730 ScopeContainerContext.Provider,
731 {
732 value: scopeContainerRef.current
733 },
734 children
735 );
736 });
737
738 let keyCount = 0;
739 function atom(read, write) {
740 const key = `atom${++keyCount}`;
741 const config = {
742 toString: () => key
743 };
744 if (typeof read === "function") {
745 config.read = read;
746 } else {
747 config.init = read;
748 config.read = (get) => get(config);
749 config.write = (get, set, update) => set(config, typeof update === "function" ? update(get(config)) : update);
750 }
751 if (write) {
752 config.write = write;
753 }
754 return config;
755 }
756
757 function useAtomValue(atom, scope) {
758 const ScopeContext = getScopeContext(scope);
759 const scopeContainer = useContext(ScopeContext);
760 const { s: store, v: versionFromProvider } = scopeContainer;
761 const getAtomValue = (version2) => {
762 const atomState = store[READ_ATOM](atom, version2);
763 if (!atomState.y) {
764 throw new Error("should not be invalidated");
765 }
766 if ("e" in atomState) {
767 throw atomState.e;
768 }
769 if ("p" in atomState) {
770 throw atomState.p;
771 }
772 if ("v" in atomState) {
773 return atomState.v;
774 }
775 throw new Error("no atom value");
776 };
777 const [[version, valueFromReducer, atomFromReducer], rerenderIfChanged] = useReducer(
778 (prev, nextVersion) => {
779 const nextValue = getAtomValue(nextVersion);
780 if (Object.is(prev[1], nextValue) && prev[2] === atom) {
781 return prev;
782 }
783 return [nextVersion, nextValue, atom];
784 },
785 versionFromProvider,
786 (initialVersion) => {
787 const initialValue = getAtomValue(initialVersion);
788 return [initialVersion, initialValue, atom];
789 }
790 );
791 let value = valueFromReducer;
792 if (atomFromReducer !== atom) {
793 rerenderIfChanged(version);
794 value = getAtomValue(version);
795 }
796 useEffect(() => {
797 const { v: versionFromProvider2 } = scopeContainer;
798 if (versionFromProvider2) {
799 store[COMMIT_ATOM](atom, versionFromProvider2);
800 }
801 const unsubscribe = store[SUBSCRIBE_ATOM](
802 atom,
803 rerenderIfChanged,
804 versionFromProvider2
805 );
806 rerenderIfChanged(versionFromProvider2);
807 return unsubscribe;
808 }, [store, atom, scopeContainer]);
809 useEffect(() => {
810 store[COMMIT_ATOM](atom, version);
811 });
812 useDebugValue(value);
813 return value;
814 }
815
816 function useSetAtom(atom, scope) {
817 const ScopeContext = getScopeContext(scope);
818 const { s: store, w: versionedWrite } = useContext(ScopeContext);
819 const setAtom = useCallback(
820 (update) => {
821 if (!("write" in atom)) {
822 throw new Error("not writable atom");
823 }
824 const write = (version) => store[WRITE_ATOM](atom, update, version);
825 return versionedWrite ? versionedWrite(write) : write();
826 },
827 [store, versionedWrite, atom]
828 );
829 return setAtom;
830 }
831
832 function useAtom(atom, scope) {
833 if ("scope" in atom) {
834 console.warn(
835 "atom.scope is deprecated. Please do useAtom(atom, scope) instead."
836 );
837 scope = atom.scope;
838 }
839 return [
840 useAtomValue(atom, scope),
841 useSetAtom(atom, scope)
842 ];
843 }
844
845 })
846 };
847}));