1 | System.register([], (function (exports) {
|
2 | 'use strict';
|
3 | return {
|
4 | execute: (function () {
|
5 |
|
6 | exports("atom", atom);
|
7 |
|
8 | let keyCount = 0;
|
9 | function atom(read, write) {
|
10 | const key = `atom${++keyCount}`;
|
11 | const config = {
|
12 | toString: () => key
|
13 | };
|
14 | if (typeof read === "function") {
|
15 | config.read = read;
|
16 | } else {
|
17 | config.init = read;
|
18 | config.read = defaultRead;
|
19 | config.write = defaultWrite;
|
20 | }
|
21 | if (write) {
|
22 | config.write = write;
|
23 | }
|
24 | return config;
|
25 | }
|
26 | function defaultRead(get) {
|
27 | return get(this);
|
28 | }
|
29 | function defaultWrite(get, set, arg) {
|
30 | return set(
|
31 | this,
|
32 | typeof arg === "function" ? arg(get(this)) : arg
|
33 | );
|
34 | }
|
35 |
|
36 | const isSelfAtom = (atom, a) => atom.unstable_is ? atom.unstable_is(a) : a === atom;
|
37 | const hasInitialValue = (atom) => "init" in atom;
|
38 | const isActuallyWritableAtom = (atom) => !!atom.write;
|
39 | const cancelPromiseMap = /* @__PURE__ */ new WeakMap();
|
40 | const registerCancelPromise = (promise, cancel) => {
|
41 | cancelPromiseMap.set(promise, cancel);
|
42 | promise.catch(() => {
|
43 | }).finally(() => cancelPromiseMap.delete(promise));
|
44 | };
|
45 | const cancelPromise = (promise, next) => {
|
46 | const cancel = cancelPromiseMap.get(promise);
|
47 | if (cancel) {
|
48 | cancelPromiseMap.delete(promise);
|
49 | cancel(next);
|
50 | }
|
51 | };
|
52 | const resolvePromise = (promise, value) => {
|
53 | promise.status = "fulfilled";
|
54 | promise.value = value;
|
55 | };
|
56 | const rejectPromise = (promise, e) => {
|
57 | promise.status = "rejected";
|
58 | promise.reason = e;
|
59 | };
|
60 | const isPromiseLike = (x) => typeof (x == null ? void 0 : x.then) === "function";
|
61 | const isEqualAtomValue = (a, b) => !!a && "v" in a && "v" in b && Object.is(a.v, b.v);
|
62 | const isEqualAtomError = (a, b) => !!a && "e" in a && "e" in b && Object.is(a.e, b.e);
|
63 | const hasPromiseAtomValue = (a) => !!a && "v" in a && a.v instanceof Promise;
|
64 | const isEqualPromiseAtomValue = (a, b) => "v" in a && "v" in b && a.v.orig && a.v.orig === b.v.orig;
|
65 | const returnAtomValue = (atomState) => {
|
66 | if ("e" in atomState) {
|
67 | throw atomState.e;
|
68 | }
|
69 | return atomState.v;
|
70 | };
|
71 | const createStore$1 = () => {
|
72 | const atomStateMap = new WeakMap();
|
73 | const mountedMap = new WeakMap();
|
74 | const pendingStack = [];
|
75 | const pendingMap = new WeakMap();
|
76 | let devListenersRev2;
|
77 | let mountedAtoms;
|
78 | {
|
79 | devListenersRev2 = new Set();
|
80 | mountedAtoms = new Set();
|
81 | }
|
82 | const getAtomState = (atom) => atomStateMap.get(atom);
|
83 | const addPendingDependent = (atom, atomState) => {
|
84 | atomState.d.forEach((_, a) => {
|
85 | var _a;
|
86 | if (!pendingMap.has(a)) {
|
87 | const aState = getAtomState(a);
|
88 | (_a = pendingStack[pendingStack.length - 1]) == null ? void 0 : _a.add(a);
|
89 | pendingMap.set(a, [aState, new Set()]);
|
90 | if (aState) {
|
91 | addPendingDependent(a, aState);
|
92 | }
|
93 | }
|
94 | pendingMap.get(a)[1].add(atom);
|
95 | });
|
96 | };
|
97 | const setAtomState = (atom, atomState) => {
|
98 | var _a;
|
99 | {
|
100 | Object.freeze(atomState);
|
101 | }
|
102 | const prevAtomState = getAtomState(atom);
|
103 | atomStateMap.set(atom, atomState);
|
104 | if (!pendingMap.has(atom)) {
|
105 | (_a = pendingStack[pendingStack.length - 1]) == null ? void 0 : _a.add(atom);
|
106 | pendingMap.set(atom, [prevAtomState, new Set()]);
|
107 | addPendingDependent(atom, atomState);
|
108 | }
|
109 | if (hasPromiseAtomValue(prevAtomState)) {
|
110 | const next = "v" in atomState ? atomState.v instanceof Promise ? atomState.v : Promise.resolve(atomState.v) : Promise.reject(atomState.e);
|
111 | if (prevAtomState.v !== next) {
|
112 | cancelPromise(prevAtomState.v, next);
|
113 | }
|
114 | }
|
115 | };
|
116 | const updateDependencies = (atom, nextAtomState, nextDependencies, keepPreviousDependencies) => {
|
117 | const dependencies = new Map(
|
118 | keepPreviousDependencies ? nextAtomState.d : null
|
119 | );
|
120 | let changed = false;
|
121 | nextDependencies.forEach((aState, a) => {
|
122 | if (!aState && isSelfAtom(atom, a)) {
|
123 | aState = nextAtomState;
|
124 | }
|
125 | if (aState) {
|
126 | dependencies.set(a, aState);
|
127 | if (nextAtomState.d.get(a) !== aState) {
|
128 | changed = true;
|
129 | }
|
130 | } else {
|
131 | console.warn("[Bug] atom state not found");
|
132 | }
|
133 | });
|
134 | if (changed || nextAtomState.d.size !== dependencies.size) {
|
135 | nextAtomState.d = dependencies;
|
136 | }
|
137 | };
|
138 | const setAtomValue = (atom, value, nextDependencies, keepPreviousDependencies) => {
|
139 | const prevAtomState = getAtomState(atom);
|
140 | const nextAtomState = {
|
141 | d: (prevAtomState == null ? void 0 : prevAtomState.d) || new Map(),
|
142 | v: value
|
143 | };
|
144 | if (nextDependencies) {
|
145 | updateDependencies(
|
146 | atom,
|
147 | nextAtomState,
|
148 | nextDependencies,
|
149 | keepPreviousDependencies
|
150 | );
|
151 | }
|
152 | if (isEqualAtomValue(prevAtomState, nextAtomState) && prevAtomState.d === nextAtomState.d) {
|
153 | return prevAtomState;
|
154 | }
|
155 | if (hasPromiseAtomValue(prevAtomState) && hasPromiseAtomValue(nextAtomState) && isEqualPromiseAtomValue(prevAtomState, nextAtomState)) {
|
156 | if (prevAtomState.d === nextAtomState.d) {
|
157 | return prevAtomState;
|
158 | } else {
|
159 | nextAtomState.v = prevAtomState.v;
|
160 | }
|
161 | }
|
162 | setAtomState(atom, nextAtomState);
|
163 | return nextAtomState;
|
164 | };
|
165 | const setAtomValueOrPromise = (atom, valueOrPromise, nextDependencies, abortPromise) => {
|
166 | if (isPromiseLike(valueOrPromise)) {
|
167 | let continuePromise;
|
168 | const updatePromiseDependencies = () => {
|
169 | const prevAtomState = getAtomState(atom);
|
170 | if (!hasPromiseAtomValue(prevAtomState) || prevAtomState.v !== promise) {
|
171 | return;
|
172 | }
|
173 | const nextAtomState = setAtomValue(
|
174 | atom,
|
175 | promise,
|
176 | nextDependencies
|
177 | );
|
178 | if (mountedMap.has(atom) && prevAtomState.d !== nextAtomState.d) {
|
179 | mountDependencies(atom, nextAtomState, prevAtomState.d);
|
180 | }
|
181 | };
|
182 | const promise = new Promise((resolve, reject) => {
|
183 | let settled = false;
|
184 | valueOrPromise.then(
|
185 | (v) => {
|
186 | if (!settled) {
|
187 | settled = true;
|
188 | resolvePromise(promise, v);
|
189 | resolve(v);
|
190 | updatePromiseDependencies();
|
191 | }
|
192 | },
|
193 | (e) => {
|
194 | if (!settled) {
|
195 | settled = true;
|
196 | rejectPromise(promise, e);
|
197 | reject(e);
|
198 | updatePromiseDependencies();
|
199 | }
|
200 | }
|
201 | );
|
202 | continuePromise = (next) => {
|
203 | if (!settled) {
|
204 | settled = true;
|
205 | next.then(
|
206 | (v) => resolvePromise(promise, v),
|
207 | (e) => rejectPromise(promise, e)
|
208 | );
|
209 | resolve(next);
|
210 | }
|
211 | };
|
212 | });
|
213 | promise.orig = valueOrPromise;
|
214 | promise.status = "pending";
|
215 | registerCancelPromise(promise, (next) => {
|
216 | if (next) {
|
217 | continuePromise(next);
|
218 | }
|
219 | abortPromise == null ? void 0 : abortPromise();
|
220 | });
|
221 | return setAtomValue(atom, promise, nextDependencies, true);
|
222 | }
|
223 | return setAtomValue(atom, valueOrPromise, nextDependencies);
|
224 | };
|
225 | const setAtomError = (atom, error, nextDependencies) => {
|
226 | const prevAtomState = getAtomState(atom);
|
227 | const nextAtomState = {
|
228 | d: (prevAtomState == null ? void 0 : prevAtomState.d) || new Map(),
|
229 | e: error
|
230 | };
|
231 | if (nextDependencies) {
|
232 | updateDependencies(atom, nextAtomState, nextDependencies);
|
233 | }
|
234 | if (isEqualAtomError(prevAtomState, nextAtomState) && prevAtomState.d === nextAtomState.d) {
|
235 | return prevAtomState;
|
236 | }
|
237 | setAtomState(atom, nextAtomState);
|
238 | return nextAtomState;
|
239 | };
|
240 | const readAtomState = (atom, force) => {
|
241 | const atomState = getAtomState(atom);
|
242 | if (!force && atomState) {
|
243 | if (mountedMap.has(atom)) {
|
244 | return atomState;
|
245 | }
|
246 | if (Array.from(atomState.d).every(([a, s]) => {
|
247 | if (a === atom) {
|
248 | return true;
|
249 | }
|
250 | const aState = readAtomState(a);
|
251 | return aState === s || isEqualAtomValue(aState, s);
|
252 | })) {
|
253 | return atomState;
|
254 | }
|
255 | }
|
256 | const nextDependencies = new Map();
|
257 | let isSync = true;
|
258 | const getter = (a) => {
|
259 | if (isSelfAtom(atom, a)) {
|
260 | const aState2 = getAtomState(a);
|
261 | if (aState2) {
|
262 | nextDependencies.set(a, aState2);
|
263 | return returnAtomValue(aState2);
|
264 | }
|
265 | if (hasInitialValue(a)) {
|
266 | nextDependencies.set(a, void 0);
|
267 | return a.init;
|
268 | }
|
269 | throw new Error("no atom init");
|
270 | }
|
271 | const aState = readAtomState(a);
|
272 | nextDependencies.set(a, aState);
|
273 | return returnAtomValue(aState);
|
274 | };
|
275 | let controller;
|
276 | let setSelf;
|
277 | const options = {
|
278 | get signal() {
|
279 | if (!controller) {
|
280 | controller = new AbortController();
|
281 | }
|
282 | return controller.signal;
|
283 | },
|
284 | get setSelf() {
|
285 | if (!isActuallyWritableAtom(atom)) {
|
286 | console.warn("setSelf function cannot be used with read-only atom");
|
287 | }
|
288 | if (!setSelf && isActuallyWritableAtom(atom)) {
|
289 | setSelf = (...args) => {
|
290 | if (isSync) {
|
291 | console.warn("setSelf function cannot be called in sync");
|
292 | }
|
293 | if (!isSync) {
|
294 | return writeAtom(atom, ...args);
|
295 | }
|
296 | };
|
297 | }
|
298 | return setSelf;
|
299 | }
|
300 | };
|
301 | try {
|
302 | const valueOrPromise = atom.read(getter, options);
|
303 | return setAtomValueOrPromise(
|
304 | atom,
|
305 | valueOrPromise,
|
306 | nextDependencies,
|
307 | () => controller == null ? void 0 : controller.abort()
|
308 | );
|
309 | } catch (error) {
|
310 | return setAtomError(atom, error, nextDependencies);
|
311 | } finally {
|
312 | isSync = false;
|
313 | }
|
314 | };
|
315 | const readAtom = (atom) => returnAtomValue(readAtomState(atom));
|
316 | const recomputeDependents = (atom) => {
|
317 | const getDependents = (a) => {
|
318 | var _a, _b;
|
319 | const dependents = new Set((_a = mountedMap.get(a)) == null ? void 0 : _a.t);
|
320 | (_b = pendingMap.get(a)) == null ? void 0 : _b[1].forEach((dependent) => {
|
321 | dependents.add(dependent);
|
322 | });
|
323 | return dependents;
|
324 | };
|
325 | const topsortedAtoms = new Array();
|
326 | const markedAtoms = new Set();
|
327 | const visit = (n) => {
|
328 | if (markedAtoms.has(n)) {
|
329 | return;
|
330 | }
|
331 | markedAtoms.add(n);
|
332 | for (const m of getDependents(n)) {
|
333 | if (n !== m) {
|
334 | visit(m);
|
335 | }
|
336 | }
|
337 | topsortedAtoms.push(n);
|
338 | };
|
339 | visit(atom);
|
340 | const changedAtoms = new Set([atom]);
|
341 | for (let i = topsortedAtoms.length - 1; i >= 0; --i) {
|
342 | const a = topsortedAtoms[i];
|
343 | const prevAtomState = getAtomState(a);
|
344 | if (!prevAtomState) {
|
345 | continue;
|
346 | }
|
347 | let hasChangedDeps = false;
|
348 | for (const dep of prevAtomState.d.keys()) {
|
349 | if (dep !== a && changedAtoms.has(dep)) {
|
350 | hasChangedDeps = true;
|
351 | break;
|
352 | }
|
353 | }
|
354 | if (hasChangedDeps) {
|
355 | const nextAtomState = readAtomState(a, true);
|
356 | if (!isEqualAtomValue(prevAtomState, nextAtomState)) {
|
357 | changedAtoms.add(a);
|
358 | }
|
359 | }
|
360 | }
|
361 | };
|
362 | const writeAtomState = (atom, ...args) => {
|
363 | const getter = (a) => returnAtomValue(readAtomState(a));
|
364 | const setter = (a, ...args2) => {
|
365 | const isSync = pendingStack.length > 0;
|
366 | if (!isSync) {
|
367 | pendingStack.push( new Set([a]));
|
368 | }
|
369 | let r;
|
370 | if (isSelfAtom(atom, a)) {
|
371 | if (!hasInitialValue(a)) {
|
372 | throw new Error("atom not writable");
|
373 | }
|
374 | const prevAtomState = getAtomState(a);
|
375 | const nextAtomState = setAtomValueOrPromise(a, args2[0]);
|
376 | if (!isEqualAtomValue(prevAtomState, nextAtomState)) {
|
377 | recomputeDependents(a);
|
378 | }
|
379 | } else {
|
380 | r = writeAtomState(a, ...args2);
|
381 | }
|
382 | if (!isSync) {
|
383 | const flushed = flushPending(pendingStack.pop());
|
384 | {
|
385 | devListenersRev2.forEach(
|
386 | (l) => l({ type: "async-write", flushed })
|
387 | );
|
388 | }
|
389 | }
|
390 | return r;
|
391 | };
|
392 | const result = atom.write(getter, setter, ...args);
|
393 | return result;
|
394 | };
|
395 | const writeAtom = (atom, ...args) => {
|
396 | pendingStack.push( new Set([atom]));
|
397 | const result = writeAtomState(atom, ...args);
|
398 | const flushed = flushPending(pendingStack.pop());
|
399 | {
|
400 | devListenersRev2.forEach((l) => l({ type: "write", flushed }));
|
401 | }
|
402 | return result;
|
403 | };
|
404 | const mountAtom = (atom, initialDependent, onMountQueue) => {
|
405 | var _a;
|
406 | const existingMount = mountedMap.get(atom);
|
407 | if (existingMount) {
|
408 | if (initialDependent) {
|
409 | existingMount.t.add(initialDependent);
|
410 | }
|
411 | return existingMount;
|
412 | }
|
413 | const queue = onMountQueue || [];
|
414 | (_a = getAtomState(atom)) == null ? void 0 : _a.d.forEach((_, a) => {
|
415 | if (a !== atom) {
|
416 | mountAtom(a, atom, queue);
|
417 | }
|
418 | });
|
419 | readAtomState(atom);
|
420 | const mounted = {
|
421 | t: new Set(initialDependent && [initialDependent]),
|
422 | l: new Set()
|
423 | };
|
424 | mountedMap.set(atom, mounted);
|
425 | {
|
426 | mountedAtoms.add(atom);
|
427 | }
|
428 | if (isActuallyWritableAtom(atom) && atom.onMount) {
|
429 | const { onMount } = atom;
|
430 | queue.push(() => {
|
431 | const onUnmount = onMount((...args) => writeAtom(atom, ...args));
|
432 | if (onUnmount) {
|
433 | mounted.u = onUnmount;
|
434 | }
|
435 | });
|
436 | }
|
437 | if (!onMountQueue) {
|
438 | queue.forEach((f) => f());
|
439 | }
|
440 | return mounted;
|
441 | };
|
442 | const canUnmountAtom = (atom, mounted) => !mounted.l.size && (!mounted.t.size || mounted.t.size === 1 && mounted.t.has(atom));
|
443 | const tryUnmountAtom = (atom, mounted) => {
|
444 | if (!canUnmountAtom(atom, mounted)) {
|
445 | return;
|
446 | }
|
447 | const onUnmount = mounted.u;
|
448 | if (onUnmount) {
|
449 | onUnmount();
|
450 | }
|
451 | mountedMap.delete(atom);
|
452 | {
|
453 | mountedAtoms.delete(atom);
|
454 | }
|
455 | const atomState = getAtomState(atom);
|
456 | if (atomState) {
|
457 | if (hasPromiseAtomValue(atomState)) {
|
458 | cancelPromise(atomState.v);
|
459 | }
|
460 | atomState.d.forEach((_, a) => {
|
461 | if (a !== atom) {
|
462 | const mountedDep = mountedMap.get(a);
|
463 | if (mountedDep) {
|
464 | mountedDep.t.delete(atom);
|
465 | tryUnmountAtom(a, mountedDep);
|
466 | }
|
467 | }
|
468 | });
|
469 | } else {
|
470 | console.warn("[Bug] could not find atom state to unmount", atom);
|
471 | }
|
472 | };
|
473 | const mountDependencies = (atom, atomState, prevDependencies) => {
|
474 | const depSet = new Set(atomState.d.keys());
|
475 | const maybeUnmountAtomSet = new Set();
|
476 | prevDependencies == null ? void 0 : prevDependencies.forEach((_, a) => {
|
477 | if (depSet.has(a)) {
|
478 | depSet.delete(a);
|
479 | return;
|
480 | }
|
481 | maybeUnmountAtomSet.add(a);
|
482 | const mounted = mountedMap.get(a);
|
483 | if (mounted) {
|
484 | mounted.t.delete(atom);
|
485 | }
|
486 | });
|
487 | depSet.forEach((a) => {
|
488 | mountAtom(a, atom);
|
489 | });
|
490 | maybeUnmountAtomSet.forEach((a) => {
|
491 | const mounted = mountedMap.get(a);
|
492 | if (mounted) {
|
493 | tryUnmountAtom(a, mounted);
|
494 | }
|
495 | });
|
496 | };
|
497 | const flushPending = (pendingAtoms) => {
|
498 | let flushed;
|
499 | {
|
500 | flushed = new Set();
|
501 | }
|
502 | const pending = [];
|
503 | const collectPending = (pendingAtom) => {
|
504 | var _a;
|
505 | if (!pendingMap.has(pendingAtom)) {
|
506 | return;
|
507 | }
|
508 | const [prevAtomState, dependents] = pendingMap.get(pendingAtom);
|
509 | pendingMap.delete(pendingAtom);
|
510 | pending.push([pendingAtom, prevAtomState]);
|
511 | dependents.forEach(collectPending);
|
512 | (_a = getAtomState(pendingAtom)) == null ? void 0 : _a.d.forEach((_, a) => collectPending(a));
|
513 | };
|
514 | pendingAtoms.forEach(collectPending);
|
515 | pending.forEach(([atom, prevAtomState]) => {
|
516 | const atomState = getAtomState(atom);
|
517 | if (!atomState) {
|
518 | {
|
519 | console.warn("[Bug] no atom state to flush");
|
520 | }
|
521 | return;
|
522 | }
|
523 | if (atomState !== prevAtomState) {
|
524 | const mounted = mountedMap.get(atom);
|
525 | if (mounted && atomState.d !== (prevAtomState == null ? void 0 : prevAtomState.d)) {
|
526 | mountDependencies(atom, atomState, prevAtomState == null ? void 0 : prevAtomState.d);
|
527 | }
|
528 | if (mounted && !
|
529 |
|
530 | (!hasPromiseAtomValue(prevAtomState) && (isEqualAtomValue(prevAtomState, atomState) || isEqualAtomError(prevAtomState, atomState)))) {
|
531 | mounted.l.forEach((listener) => listener());
|
532 | {
|
533 | flushed.add(atom);
|
534 | }
|
535 | }
|
536 | }
|
537 | });
|
538 | {
|
539 | return flushed;
|
540 | }
|
541 | };
|
542 | const subscribeAtom = (atom, listener) => {
|
543 | const mounted = mountAtom(atom);
|
544 | const flushed = flushPending([atom]);
|
545 | const listeners = mounted.l;
|
546 | listeners.add(listener);
|
547 | {
|
548 | devListenersRev2.forEach(
|
549 | (l) => l({ type: "sub", flushed })
|
550 | );
|
551 | }
|
552 | return () => {
|
553 | listeners.delete(listener);
|
554 | tryUnmountAtom(atom, mounted);
|
555 | {
|
556 | devListenersRev2.forEach((l) => l({ type: "unsub" }));
|
557 | }
|
558 | };
|
559 | };
|
560 | {
|
561 | return {
|
562 | get: readAtom,
|
563 | set: writeAtom,
|
564 | sub: subscribeAtom,
|
565 | // store dev methods (these are tentative and subject to change without notice)
|
566 | dev_subscribe_store: (l) => {
|
567 | devListenersRev2.add(l);
|
568 | return () => {
|
569 | devListenersRev2.delete(l);
|
570 | };
|
571 | },
|
572 | dev_get_mounted_atoms: () => mountedAtoms.values(),
|
573 | dev_get_atom_state: (a) => atomStateMap.get(a),
|
574 | dev_get_mounted: (a) => mountedMap.get(a),
|
575 | dev_restore_atoms: (values) => {
|
576 | pendingStack.push( new Set());
|
577 | for (const [atom, valueOrPromise] of values) {
|
578 | if (hasInitialValue(atom)) {
|
579 | setAtomValueOrPromise(atom, valueOrPromise);
|
580 | recomputeDependents(atom);
|
581 | }
|
582 | }
|
583 | const flushed = flushPending(pendingStack.pop());
|
584 | devListenersRev2.forEach(
|
585 | (l) => l({ type: "restore", flushed })
|
586 | );
|
587 | }
|
588 | };
|
589 | }
|
590 | };
|
591 | let defaultStore;
|
592 | const getDefaultStore$1 = () => {
|
593 | if (!defaultStore) {
|
594 | defaultStore = createStore$1();
|
595 | {
|
596 | globalThis.__JOTAI_DEFAULT_STORE__ || (globalThis.__JOTAI_DEFAULT_STORE__ = defaultStore);
|
597 | if (globalThis.__JOTAI_DEFAULT_STORE__ !== defaultStore) {
|
598 | console.warn(
|
599 | "Detected multiple Jotai instances. It may cause unexpected behavior with the default store. https://github.com/pmndrs/jotai/discussions/2044"
|
600 | );
|
601 | }
|
602 | }
|
603 | }
|
604 | return defaultStore;
|
605 | };
|
606 |
|
607 | const createStore = exports("createStore", createStore$1);
|
608 | const getDefaultStore = exports("getDefaultStore", getDefaultStore$1);
|
609 |
|
610 | })
|
611 | };
|
612 | }));
|