1 | var jotai = (function (exports, react, useContextSelector) {
|
2 | 'use strict';
|
3 |
|
4 | function _extends() {
|
5 | _extends = Object.assign || function (target) {
|
6 | for (var i = 1; i < arguments.length; i++) {
|
7 | var source = arguments[i];
|
8 |
|
9 | for (var key in source) {
|
10 | if (Object.prototype.hasOwnProperty.call(source, key)) {
|
11 | target[key] = source[key];
|
12 | }
|
13 | }
|
14 | }
|
15 |
|
16 | return target;
|
17 | };
|
18 |
|
19 | return _extends.apply(this, arguments);
|
20 | }
|
21 |
|
22 | var isSSR = typeof window === 'undefined' || /ServerSideRendering/.test(window.navigator && window.navigator.userAgent);
|
23 | var useIsoLayoutEffect = isSSR ? function (fn) {
|
24 | return fn();
|
25 | } : react.useLayoutEffect;
|
26 |
|
27 | var appendMap = function appendMap(dst, src) {
|
28 | src.forEach(function (v, k) {
|
29 | dst.set(k, v);
|
30 | });
|
31 | return dst;
|
32 | };
|
33 |
|
34 |
|
35 | var concatMap = function concatMap(src1, src2) {
|
36 | return appendMap(new Map(src1), src2);
|
37 | };
|
38 |
|
39 |
|
40 | var deleteMapItem = function deleteMapItem(src, key) {
|
41 | var dst = new Map(src);
|
42 | dst.delete(key);
|
43 | return dst;
|
44 | };
|
45 |
|
46 | var warningObject = new Proxy({}, {
|
47 | get: function get() {
|
48 | throw new Error('Please use <Provider>');
|
49 | },
|
50 | apply: function apply() {
|
51 | throw new Error('Please use <Provider>');
|
52 | }
|
53 | });
|
54 |
|
55 | var addDependent = function addDependent(dependentsMap, atom, dependent) {
|
56 | var dependents = dependentsMap.get(atom);
|
57 |
|
58 | if (!dependents) {
|
59 | dependents = new Set();
|
60 | dependentsMap.set(atom, dependents);
|
61 | }
|
62 |
|
63 | dependents.add(dependent);
|
64 | };
|
65 |
|
66 | var deleteDependent = function deleteDependent(dependentsMap, dependent) {
|
67 | dependentsMap.forEach(function (dependents) {
|
68 | dependents.delete(dependent);
|
69 | });
|
70 | };
|
71 |
|
72 | var setDependencies = function setDependencies(dependentsMap, atom, dependencies) {
|
73 | deleteDependent(dependentsMap, atom);
|
74 | dependencies.forEach(function (dependency) {
|
75 | addDependent(dependentsMap, dependency, atom);
|
76 | });
|
77 | };
|
78 |
|
79 | var listDependents = function listDependents(dependentsMap, atom, excludeSelf) {
|
80 | var dependents = new Set(dependentsMap.get(atom));
|
81 |
|
82 | if (excludeSelf) {
|
83 | dependents.delete(atom);
|
84 | }
|
85 |
|
86 | return dependents;
|
87 | };
|
88 |
|
89 | var initialState = new Map();
|
90 |
|
91 | var getAtomState = function getAtomState(atom, state, tmpState) {
|
92 | var atomState = tmpState && tmpState.get(atom) || state.get(atom);
|
93 |
|
94 | if (!atomState) {
|
95 | throw new Error('atom state not found. possibly a bug.');
|
96 | }
|
97 |
|
98 | return atomState;
|
99 | };
|
100 |
|
101 | var getAtomStateValue = function getAtomStateValue(atom, state, tmpState) {
|
102 | var atomState = tmpState && tmpState.get(atom) || state.get(atom);
|
103 | return atomState ? atomState.value : atom.init;
|
104 | };
|
105 |
|
106 | var readAtom = function readAtom(state, readingAtom, setState, dependentsMap, readPendingMap) {
|
107 | var readAtomValue = function readAtomValue(prevState, atom) {
|
108 | var partialState = new Map();
|
109 | var atomState = prevState.get(atom);
|
110 |
|
111 | if (atomState) {
|
112 | return [atomState, partialState];
|
113 | }
|
114 |
|
115 | var error = undefined;
|
116 | var promise = undefined;
|
117 | var value = null;
|
118 | var dependencies = new Set();
|
119 | var isSync = true;
|
120 |
|
121 | try {
|
122 | var promiseOrValue = atom.read(function (a) {
|
123 | if (dependencies) {
|
124 | dependencies.add(a);
|
125 | } else {
|
126 | addDependent(dependentsMap, a, atom);
|
127 | }
|
128 |
|
129 | if (a !== atom) {
|
130 | var _readAtomValue = readAtomValue(concatMap(prevState, partialState), a),
|
131 | _nextAtomState = _readAtomValue[0],
|
132 | nextPartialState = _readAtomValue[1];
|
133 |
|
134 | if (isSync) {
|
135 | appendMap(partialState, nextPartialState);
|
136 | } else {
|
137 | setState(function (prev) {
|
138 | return concatMap(prev, nextPartialState);
|
139 | });
|
140 | }
|
141 |
|
142 | if (_nextAtomState.readE) {
|
143 | throw _nextAtomState.readE;
|
144 | }
|
145 |
|
146 | if (_nextAtomState.readP) {
|
147 | throw _nextAtomState.readP;
|
148 | }
|
149 |
|
150 | return _nextAtomState.value;
|
151 | }
|
152 |
|
153 |
|
154 | var aState = partialState.get(a) || prevState.get(a);
|
155 |
|
156 | if (aState) {
|
157 | if (aState.readP) {
|
158 | throw aState.readP;
|
159 | }
|
160 |
|
161 | return aState.value;
|
162 | }
|
163 |
|
164 | return a.init;
|
165 | });
|
166 |
|
167 | if (promiseOrValue instanceof Promise) {
|
168 | promise = promiseOrValue.then(function (value) {
|
169 | var _prev$get;
|
170 |
|
171 | setDependencies(dependentsMap, atom, dependencies);
|
172 | dependencies = null;
|
173 | var prev = readPendingMap.get(atom);
|
174 |
|
175 | if (prev && ((_prev$get = prev.get(atom)) == null ? void 0 : _prev$get.readP) === promise) {
|
176 | readPendingMap.set(atom, deleteMapItem(prev, atom));
|
177 | }
|
178 |
|
179 | setState(function (prev) {
|
180 | return new Map(prev).set(atom, {
|
181 | value: value
|
182 | });
|
183 | });
|
184 | }).catch(function (e) {
|
185 | var _prev$get2;
|
186 |
|
187 | var prev = readPendingMap.get(atom);
|
188 |
|
189 | if (prev && ((_prev$get2 = prev.get(atom)) == null ? void 0 : _prev$get2.readP) === promise) {
|
190 | readPendingMap.set(atom, deleteMapItem(prev, atom));
|
191 | }
|
192 |
|
193 | setState(function (prev) {
|
194 | return new Map(prev).set(atom, {
|
195 | value: getAtomStateValue(atom, prev),
|
196 | readE: e instanceof Error ? e : new Error(e)
|
197 | });
|
198 | });
|
199 | });
|
200 | } else {
|
201 | setDependencies(dependentsMap, atom, dependencies);
|
202 | dependencies = null;
|
203 | value = promiseOrValue;
|
204 | }
|
205 | } catch (errorOrPromise) {
|
206 | if (errorOrPromise instanceof Promise) {
|
207 | promise = errorOrPromise;
|
208 | } else if (errorOrPromise instanceof Error) {
|
209 | error = errorOrPromise;
|
210 | } else {
|
211 | error = new Error(errorOrPromise);
|
212 | }
|
213 | }
|
214 |
|
215 | var nextAtomState = {
|
216 | readE: error,
|
217 | readP: promise,
|
218 | value: promise ? atom.init : value
|
219 | };
|
220 | partialState.set(atom, nextAtomState);
|
221 | isSync = false;
|
222 | return [nextAtomState, partialState];
|
223 | };
|
224 |
|
225 | var prevPartialState = readPendingMap.get(readingAtom);
|
226 |
|
227 | var _readAtomValue2 = readAtomValue(prevPartialState ? concatMap(state, prevPartialState) : state, readingAtom),
|
228 | atomState = _readAtomValue2[0],
|
229 | partialState = _readAtomValue2[1];
|
230 |
|
231 | readPendingMap.set(readingAtom, prevPartialState ? concatMap(prevPartialState, partialState) : partialState);
|
232 | return atomState;
|
233 | };
|
234 |
|
235 | var addAtom = function addAtom(id, atom, setState, dependentsMap, readPendingMap) {
|
236 | addDependent(dependentsMap, atom, id);
|
237 | var partialState = readPendingMap.get(atom);
|
238 |
|
239 | if (partialState) {
|
240 | readPendingMap.delete(atom);
|
241 | setState(function (prev) {
|
242 | return concatMap(prev, partialState);
|
243 | });
|
244 | }
|
245 | };
|
246 |
|
247 | var delAtom = function delAtom(id, setGcCount, dependentsMap) {
|
248 | deleteDependent(dependentsMap, id);
|
249 | setGcCount(function (c) {
|
250 | return c + 1;
|
251 | });
|
252 | };
|
253 |
|
254 | var gcAtom = function gcAtom(state, setState, dependentsMap) {
|
255 | var nextState = new Map(state);
|
256 | var deleted;
|
257 |
|
258 | do {
|
259 | deleted = false;
|
260 | nextState.forEach(function (_atomState, atom) {
|
261 | var _dependentsMap$get;
|
262 |
|
263 | var isEmpty = ((_dependentsMap$get = dependentsMap.get(atom)) == null ? void 0 : _dependentsMap$get.size) === 0;
|
264 |
|
265 | if (isEmpty) {
|
266 | nextState.delete(atom);
|
267 | dependentsMap.delete(atom);
|
268 | deleted = true;
|
269 | }
|
270 | });
|
271 | } while (deleted);
|
272 |
|
273 | if (nextState.size !== state.size) {
|
274 | setState(nextState);
|
275 | }
|
276 | };
|
277 |
|
278 | var writeAtom = function writeAtom(updatingAtom, update, setState, dependentsMap, addWriteThunk) {
|
279 | var pendingPromises = [];
|
280 |
|
281 | var updateDependentsState = function updateDependentsState(prevState, atom) {
|
282 | var partialState = new Map();
|
283 | listDependents(dependentsMap, atom, true).forEach(function (dependent) {
|
284 | if (typeof dependent === 'symbol') return;
|
285 | var dependencies = new Set();
|
286 |
|
287 | try {
|
288 | var promiseOrValue = dependent.read(function (a) {
|
289 | if (dependencies) {
|
290 | dependencies.add(a);
|
291 | } else {
|
292 | addDependent(dependentsMap, a, dependent);
|
293 | }
|
294 |
|
295 | var s = getAtomState(a, prevState);
|
296 |
|
297 | if (s.readE) {
|
298 | throw s.readE;
|
299 | }
|
300 |
|
301 | return s.value;
|
302 | });
|
303 |
|
304 | if (promiseOrValue instanceof Promise) {
|
305 | var promise = promiseOrValue.then(function (value) {
|
306 | setDependencies(dependentsMap, dependent, dependencies);
|
307 | dependencies = null;
|
308 | var nextAtomState = {
|
309 | value: value
|
310 | };
|
311 | setState(function (prev) {
|
312 | var _prev$get3;
|
313 |
|
314 | var prevPromise = (_prev$get3 = prev.get(dependent)) == null ? void 0 : _prev$get3.readP;
|
315 |
|
316 | if (prevPromise && prevPromise !== promise) {
|
317 |
|
318 | return prev;
|
319 | }
|
320 |
|
321 | var nextState = new Map(prev).set(dependent, nextAtomState);
|
322 | var nextPartialState = updateDependentsState(nextState, dependent);
|
323 | return appendMap(nextState, nextPartialState);
|
324 | });
|
325 | }).catch(function (e) {
|
326 | setState(function (prev) {
|
327 | return new Map(prev).set(dependent, {
|
328 | value: getAtomStateValue(dependent, prev),
|
329 | readE: e instanceof Error ? e : new Error(e)
|
330 | });
|
331 | });
|
332 | });
|
333 | partialState.set(dependent, {
|
334 | value: getAtomStateValue(dependent, prevState),
|
335 | readP: promise
|
336 | });
|
337 | } else {
|
338 | setDependencies(dependentsMap, dependent, dependencies);
|
339 | dependencies = null;
|
340 | partialState.set(dependent, {
|
341 | value: promiseOrValue
|
342 | });
|
343 | appendMap(partialState, updateDependentsState(concatMap(prevState, partialState), dependent));
|
344 | }
|
345 | } catch (e) {
|
346 | partialState.set(dependent, {
|
347 | value: getAtomStateValue(dependent, prevState),
|
348 | readE: e instanceof Error ? e : new Error(e)
|
349 | });
|
350 | appendMap(partialState, updateDependentsState(concatMap(prevState, partialState), dependent));
|
351 | }
|
352 | });
|
353 | return partialState;
|
354 | };
|
355 |
|
356 | var updateAtomState = function updateAtomState(prevState, atom, update) {
|
357 | var prevAtomState = prevState.get(atom);
|
358 |
|
359 | if (prevAtomState && prevAtomState.writeP) {
|
360 | var promise = prevAtomState.writeP.then(function () {
|
361 | addWriteThunk(function (prev) {
|
362 | var nextPartialState = updateAtomState(prev, atom, update);
|
363 |
|
364 | if (nextPartialState) {
|
365 | return concatMap(prevState, nextPartialState);
|
366 | }
|
367 |
|
368 | return prev;
|
369 | });
|
370 | });
|
371 | pendingPromises.push(promise);
|
372 | return null;
|
373 | }
|
374 |
|
375 | var partialState = new Map();
|
376 | var isSync = true;
|
377 |
|
378 | try {
|
379 | var promiseOrVoid = atom.write(function (a) {
|
380 | if (process.env.NODE_ENV !== 'production') {
|
381 | var s = prevState.get(a);
|
382 |
|
383 | if (s && s.readP) {
|
384 | console.log('Reading pending atom state in write operation. Not sure how to deal with it. Returning stale vaule for', a);
|
385 | }
|
386 | }
|
387 |
|
388 | return getAtomStateValue(a, prevState, partialState);
|
389 | }, function (a, v) {
|
390 | if (a === atom) {
|
391 | var nextAtomState = {
|
392 | value: v
|
393 | };
|
394 |
|
395 | if (isSync) {
|
396 | partialState.set(a, nextAtomState);
|
397 | appendMap(partialState, updateDependentsState(concatMap(prevState, partialState), a));
|
398 | } else {
|
399 | setState(function (prev) {
|
400 | var nextState = new Map(prev).set(a, nextAtomState);
|
401 | var nextPartialState = updateDependentsState(nextState, a);
|
402 | return appendMap(nextState, nextPartialState);
|
403 | });
|
404 | }
|
405 | } else {
|
406 | if (isSync) {
|
407 | var nextPartialState = updateAtomState(concatMap(prevState, partialState), a, v);
|
408 |
|
409 | if (nextPartialState) {
|
410 | appendMap(partialState, nextPartialState);
|
411 | }
|
412 | } else {
|
413 | addWriteThunk(function (prev) {
|
414 | var nextPartialState = updateAtomState(prev, a, v);
|
415 |
|
416 | if (nextPartialState) {
|
417 | return concatMap(prev, nextPartialState);
|
418 | }
|
419 |
|
420 | return prev;
|
421 | });
|
422 | }
|
423 | }
|
424 | }, update);
|
425 |
|
426 | if (promiseOrVoid instanceof Promise) {
|
427 | pendingPromises.push(promiseOrVoid);
|
428 |
|
429 | var nextAtomState = _extends({}, getAtomState(atom, prevState, partialState), {
|
430 | writeP: promiseOrVoid.then(function () {
|
431 | addWriteThunk(function (prev) {
|
432 | return new Map(prev).set(atom, _extends({}, getAtomState(atom, prev), {
|
433 | writeP: undefined
|
434 | }));
|
435 | });
|
436 | })
|
437 | });
|
438 |
|
439 | partialState.set(atom, nextAtomState);
|
440 | }
|
441 | } catch (e) {
|
442 | if (pendingPromises.length) {
|
443 | pendingPromises.push(new Promise(function (_resolve, reject) {
|
444 | reject(e);
|
445 | }));
|
446 | } else {
|
447 | throw e;
|
448 | }
|
449 | }
|
450 |
|
451 | isSync = false;
|
452 | return partialState;
|
453 | };
|
454 |
|
455 | addWriteThunk(function (prevState) {
|
456 | var nextPartialState = updateAtomState(prevState, updatingAtom, update);
|
457 |
|
458 | if (nextPartialState) {
|
459 | return concatMap(prevState, nextPartialState);
|
460 | }
|
461 |
|
462 | return prevState;
|
463 | });
|
464 |
|
465 | if (pendingPromises.length) {
|
466 | return new Promise(function (resolve, reject) {
|
467 | var loop = function loop() {
|
468 | var len = pendingPromises.length;
|
469 |
|
470 | if (len === 0) {
|
471 | resolve();
|
472 | } else {
|
473 | Promise.all(pendingPromises).then(function () {
|
474 | pendingPromises.splice(0, len);
|
475 | loop();
|
476 | }).catch(reject);
|
477 | }
|
478 | };
|
479 |
|
480 | loop();
|
481 | });
|
482 | }
|
483 | };
|
484 |
|
485 | var runWriteThunk = function runWriteThunk(lastStateRef, setState, writeThunkQueue) {
|
486 | while (true) {
|
487 | if (!lastStateRef.current) {
|
488 | return;
|
489 | }
|
490 |
|
491 | if (writeThunkQueue.length === 0) {
|
492 | return;
|
493 | }
|
494 |
|
495 | var thunk = writeThunkQueue.shift();
|
496 | var lastState = lastStateRef.current;
|
497 | var nextState = thunk(lastState);
|
498 |
|
499 | if (nextState !== lastState) {
|
500 | setState(nextState);
|
501 | return;
|
502 | }
|
503 | }
|
504 | };
|
505 |
|
506 | var ActionsContext = useContextSelector.createContext(warningObject);
|
507 | var StateContext = useContextSelector.createContext(warningObject);
|
508 | var Provider = function Provider(_ref) {
|
509 | var children = _ref.children;
|
510 | var dependentsMapRef = react.useRef();
|
511 |
|
512 | if (!dependentsMapRef.current) {
|
513 | dependentsMapRef.current = new Map();
|
514 | }
|
515 |
|
516 | var readPendingMapRef = react.useRef();
|
517 |
|
518 | if (!readPendingMapRef.current) {
|
519 | readPendingMapRef.current = new WeakMap();
|
520 | }
|
521 |
|
522 | var _useState = react.useState(initialState),
|
523 | state = _useState[0],
|
524 | setStateOrig = _useState[1];
|
525 |
|
526 | var lastStateRef = react.useRef(null);
|
527 |
|
528 | var setState = function setState(setStateAction) {
|
529 | lastStateRef.current = null;
|
530 | setStateOrig(setStateAction);
|
531 | };
|
532 |
|
533 | useIsoLayoutEffect(function () {
|
534 | if (state !== initialState) {
|
535 | lastStateRef.current = state;
|
536 | }
|
537 | });
|
538 |
|
539 | var _useState2 = react.useState(0),
|
540 | gcCount = _useState2[0],
|
541 | setGcCount = _useState2[1];
|
542 |
|
543 |
|
544 | react.useEffect(function () {
|
545 | gcAtom(state, setState, dependentsMapRef.current);
|
546 | }, [state, gcCount]);
|
547 | var writeThunkQueueRef = react.useRef([]);
|
548 | react.useEffect(function () {
|
549 | runWriteThunk(lastStateRef, setState, writeThunkQueueRef.current);
|
550 | }, [state]);
|
551 | var actions = react.useMemo(function () {
|
552 | return {
|
553 | add: function add(id, atom) {
|
554 | return addAtom(id, atom, setState, dependentsMapRef.current, readPendingMapRef.current);
|
555 | },
|
556 | del: function del(id) {
|
557 | return delAtom(id, setGcCount, dependentsMapRef.current);
|
558 | },
|
559 | read: function read(state, atom) {
|
560 | return readAtom(state, atom, setState, dependentsMapRef.current, readPendingMapRef.current);
|
561 | },
|
562 | write: function write(atom, update) {
|
563 | return writeAtom(atom, update, setState, dependentsMapRef.current, function (thunk) {
|
564 | writeThunkQueueRef.current.push(thunk);
|
565 | runWriteThunk(lastStateRef, setState, writeThunkQueueRef.current);
|
566 | });
|
567 | }
|
568 | };
|
569 | }, []);
|
570 | return react.createElement(ActionsContext.Provider, {
|
571 | value: actions
|
572 | }, react.createElement(StateContext.Provider, {
|
573 | value: state
|
574 | }, children));
|
575 | };
|
576 |
|
577 | var keyCount = 0;
|
578 |
|
579 | function atom(read, write) {
|
580 | var config = {
|
581 | key: ++keyCount
|
582 | };
|
583 |
|
584 | if (typeof read === 'function') {
|
585 | config.read = read;
|
586 | } else {
|
587 | config.init = read;
|
588 |
|
589 | config.read = function (get) {
|
590 | return get(config);
|
591 | };
|
592 |
|
593 | config.write = function (get, set, update) {
|
594 | set(config, typeof update === 'function' ? update(get(config)) : update);
|
595 | };
|
596 | }
|
597 |
|
598 | if (write) {
|
599 | config.write = write;
|
600 | }
|
601 |
|
602 | return config;
|
603 | }
|
604 |
|
605 | var isWritable = function isWritable(atom) {
|
606 | return !!atom.write;
|
607 | };
|
608 |
|
609 | function useAtom(atom) {
|
610 | var actions = useContextSelector.useContext(ActionsContext);
|
611 | var value = useContextSelector.useContextSelector(StateContext, react.useCallback(function (state) {
|
612 | var atomState = actions.read(state, atom);
|
613 |
|
614 | if (atomState.readE) {
|
615 | throw atomState.readE;
|
616 | }
|
617 |
|
618 | if (atomState.readP) {
|
619 | throw atomState.readP;
|
620 | }
|
621 |
|
622 | if (atomState.writeP) {
|
623 | throw atomState.writeP;
|
624 | }
|
625 |
|
626 | return atomState.value;
|
627 | }, [atom, actions]));
|
628 | useIsoLayoutEffect(function () {
|
629 | var id = Symbol();
|
630 | actions.add(id, atom);
|
631 | return function () {
|
632 | actions.del(id);
|
633 | };
|
634 | }, [actions, atom]);
|
635 | var setAtom = react.useCallback(function (update) {
|
636 | if (isWritable(atom)) {
|
637 | return actions.write(atom, update);
|
638 | } else {
|
639 | throw new Error('not writable atom');
|
640 | }
|
641 | }, [atom, actions]);
|
642 | react.useDebugValue(value);
|
643 | return [value, setAtom];
|
644 | }
|
645 |
|
646 | var useBridge = function useBridge() {
|
647 | var actions = useContextSelector.useContext(ActionsContext);
|
648 | var state = useContextSelector.useContext(StateContext);
|
649 | return react.useMemo(function () {
|
650 | return [actions, state];
|
651 | }, [actions, state]);
|
652 | };
|
653 | var Bridge = function Bridge(_ref) {
|
654 | var value = _ref.value,
|
655 | children = _ref.children;
|
656 | var actions = value[0],
|
657 | state = value[1];
|
658 | return react.createElement(useContextSelector.BridgeProvider, {
|
659 | context: ActionsContext,
|
660 | value: actions
|
661 | }, react.createElement(useContextSelector.BridgeProvider, {
|
662 | context: StateContext,
|
663 | value: state
|
664 | }, children));
|
665 | };
|
666 |
|
667 | exports.Bridge = Bridge;
|
668 | exports.Provider = Provider;
|
669 | exports.atom = atom;
|
670 | exports.useAtom = useAtom;
|
671 | exports.useBridge = useBridge;
|
672 |
|
673 | return exports;
|
674 |
|
675 | }({}, React, useContextSelector));
|