UNPKG

23.1 kBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('jotai/vanilla')) :
3 typeof define === 'function' && define.amd ? define(['exports', 'jotai/vanilla'], factory) :
4 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.jotaiUtils = {}, global.vanilla));
5})(this, (function (exports, vanilla) { 'use strict';
6
7 var RESET = Symbol();
8
9 function atomWithReset(initialValue) {
10 var anAtom = vanilla.atom(initialValue, function (get, set, update) {
11 var nextValue = typeof update === 'function' ? update(get(anAtom)) : update;
12 set(anAtom, nextValue === RESET ? initialValue : nextValue);
13 });
14 return anAtom;
15 }
16
17 function atomWithReducer(initialValue, reducer) {
18 var anAtom = vanilla.atom(initialValue, function (get, set, action) {
19 return set(anAtom, reducer(get(anAtom), action));
20 });
21 return anAtom;
22 }
23
24 function _unsupportedIterableToArray(o, minLen) {
25 if (!o) return;
26 if (typeof o === "string") return _arrayLikeToArray(o, minLen);
27 var n = Object.prototype.toString.call(o).slice(8, -1);
28 if (n === "Object" && o.constructor) n = o.constructor.name;
29 if (n === "Map" || n === "Set") return Array.from(o);
30 if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
31 }
32 function _arrayLikeToArray(arr, len) {
33 if (len == null || len > arr.length) len = arr.length;
34 for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
35 return arr2;
36 }
37 function _createForOfIteratorHelperLoose(o, allowArrayLike) {
38 var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
39 if (it) return (it = it.call(o)).next.bind(it);
40 if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
41 if (it) o = it;
42 var i = 0;
43 return function () {
44 if (i >= o.length) return {
45 done: true
46 };
47 return {
48 done: false,
49 value: o[i++]
50 };
51 };
52 }
53 throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
54 }
55
56 function atomFamily(initializeAtom, areEqual) {
57 var shouldRemove = null;
58 var atoms = new Map();
59 var createAtom = function createAtom(param) {
60 var item;
61 if (areEqual === undefined) {
62 item = atoms.get(param);
63 } else {
64 for (var _iterator = _createForOfIteratorHelperLoose(atoms), _step; !(_step = _iterator()).done;) {
65 var _step$value = _step.value,
66 key = _step$value[0],
67 value = _step$value[1];
68 if (areEqual(key, param)) {
69 item = value;
70 break;
71 }
72 }
73 }
74 if (item !== undefined) {
75 if (shouldRemove != null && shouldRemove(item[1], param)) {
76 createAtom.remove(param);
77 } else {
78 return item[0];
79 }
80 }
81 var newAtom = initializeAtom(param);
82 atoms.set(param, [newAtom, Date.now()]);
83 return newAtom;
84 };
85 createAtom.remove = function (param) {
86 if (areEqual === undefined) {
87 atoms.delete(param);
88 } else {
89 for (var _iterator2 = _createForOfIteratorHelperLoose(atoms), _step2; !(_step2 = _iterator2()).done;) {
90 var _step2$value = _step2.value,
91 key = _step2$value[0];
92 if (areEqual(key, param)) {
93 atoms.delete(key);
94 break;
95 }
96 }
97 }
98 };
99 createAtom.setShouldRemove = function (fn) {
100 shouldRemove = fn;
101 if (!shouldRemove) return;
102 for (var _iterator3 = _createForOfIteratorHelperLoose(atoms), _step3; !(_step3 = _iterator3()).done;) {
103 var _step3$value = _step3.value,
104 key = _step3$value[0],
105 value = _step3$value[1];
106 if (shouldRemove(value[1], key)) {
107 atoms.delete(key);
108 }
109 }
110 };
111 return createAtom;
112 }
113
114 var getCached$2 = function getCached(c, m, k) {
115 return (m.has(k) ? m : m.set(k, c())).get(k);
116 };
117 var cache1$4 = new WeakMap();
118 var memo3 = function memo3(create, dep1, dep2, dep3) {
119 var cache2 = getCached$2(function () {
120 return new WeakMap();
121 }, cache1$4, dep1);
122 var cache3 = getCached$2(function () {
123 return new WeakMap();
124 }, cache2, dep2);
125 return getCached$2(create, cache3, dep3);
126 };
127 function selectAtom(anAtom, selector, equalityFn) {
128 if (equalityFn === void 0) {
129 equalityFn = Object.is;
130 }
131 return memo3(function () {
132 var EMPTY = Symbol();
133 var selectValue = function selectValue(_ref) {
134 var value = _ref[0],
135 prevSlice = _ref[1];
136 var slice = selector(value);
137 if (prevSlice !== EMPTY && equalityFn(prevSlice, slice)) {
138 return prevSlice;
139 }
140 return slice;
141 };
142 var derivedAtom = vanilla.atom(function (get) {
143 var prev = get(derivedAtom);
144 var value = get(anAtom);
145 if (value instanceof Promise || prev instanceof Promise) {
146 return Promise.all([value, prev]).then(selectValue);
147 }
148 return selectValue([value, prev]);
149 });
150 derivedAtom.init = EMPTY;
151 return derivedAtom;
152 }, anAtom, selector, equalityFn);
153 }
154
155 var cache1$3 = new WeakMap();
156 var memo1$1 = function memo1(create, dep1) {
157 return (cache1$3.has(dep1) ? cache1$3 : cache1$3.set(dep1, create())).get(dep1);
158 };
159 var deepFreeze = function deepFreeze(obj) {
160 if (typeof obj !== 'object' || obj === null) return;
161 Object.freeze(obj);
162 var propNames = Object.getOwnPropertyNames(obj);
163 for (var _iterator = _createForOfIteratorHelperLoose(propNames), _step; !(_step = _iterator()).done;) {
164 var name = _step.value;
165 var value = obj[name];
166 deepFreeze(value);
167 }
168 return obj;
169 };
170 function freezeAtom(anAtom) {
171 return memo1$1(function () {
172 var frozenAtom = vanilla.atom(function (get) {
173 return deepFreeze(get(anAtom));
174 }, function (_get, set, arg) {
175 return set(anAtom, arg);
176 });
177 return frozenAtom;
178 }, anAtom);
179 }
180 function freezeAtomCreator(createAtom) {
181 return function () {
182 var anAtom = createAtom.apply(void 0, arguments);
183 var origRead = anAtom.read;
184 anAtom.read = function (get, options) {
185 return deepFreeze(origRead(get, options));
186 };
187 return anAtom;
188 };
189 }
190
191 var getCached$1 = function getCached(c, m, k) {
192 return (m.has(k) ? m : m.set(k, c())).get(k);
193 };
194 var cache1$2 = new WeakMap();
195 var memo2$1 = function memo2(create, dep1, dep2) {
196 var cache2 = getCached$1(function () {
197 return new WeakMap();
198 }, cache1$2, dep1);
199 return getCached$1(create, cache2, dep2);
200 };
201 var cacheKeyForEmptyKeyExtractor = {};
202 var isWritable = function isWritable(atom) {
203 return !!atom.write;
204 };
205 var isFunction = function isFunction(x) {
206 return typeof x === 'function';
207 };
208 function splitAtom(arrAtom, keyExtractor) {
209 return memo2$1(function () {
210 var mappingCache = new WeakMap();
211 var getMapping = function getMapping(arr, prev) {
212 var mapping = mappingCache.get(arr);
213 if (mapping) {
214 return mapping;
215 }
216 var prevMapping = prev && mappingCache.get(prev);
217 var atomList = [];
218 var keyList = [];
219 arr.forEach(function (item, index) {
220 var key = keyExtractor ? keyExtractor(item) : index;
221 keyList[index] = key;
222 var cachedAtom = prevMapping && prevMapping.atomList[prevMapping.keyList.indexOf(key)];
223 if (cachedAtom) {
224 atomList[index] = cachedAtom;
225 return;
226 }
227 var read = function read(get) {
228 var prev = get(mappingAtom);
229 var currArr = get(arrAtom);
230 var mapping = getMapping(currArr, prev == null ? void 0 : prev.arr);
231 var index = mapping.keyList.indexOf(key);
232 if (index < 0 || index >= currArr.length) {
233 var prevItem = arr[getMapping(arr).keyList.indexOf(key)];
234 if (prevItem) {
235 return prevItem;
236 }
237 throw new Error('splitAtom: index out of bounds for read');
238 }
239 return currArr[index];
240 };
241 var write = function write(get, set, update) {
242 var prev = get(mappingAtom);
243 var arr = get(arrAtom);
244 var mapping = getMapping(arr, prev == null ? void 0 : prev.arr);
245 var index = mapping.keyList.indexOf(key);
246 if (index < 0 || index >= arr.length) {
247 throw new Error('splitAtom: index out of bounds for write');
248 }
249 var nextItem = isFunction(update) ? update(arr[index]) : update;
250 set(arrAtom, [].concat(arr.slice(0, index), [nextItem], arr.slice(index + 1)));
251 };
252 atomList[index] = isWritable(arrAtom) ? vanilla.atom(read, write) : vanilla.atom(read);
253 });
254 if (prevMapping && prevMapping.keyList.length === keyList.length && prevMapping.keyList.every(function (x, i) {
255 return x === keyList[i];
256 })) {
257 mapping = prevMapping;
258 } else {
259 mapping = {
260 arr: arr,
261 atomList: atomList,
262 keyList: keyList
263 };
264 }
265 mappingCache.set(arr, mapping);
266 return mapping;
267 };
268 var mappingAtom = vanilla.atom(function (get) {
269 var prev = get(mappingAtom);
270 var arr = get(arrAtom);
271 var mapping = getMapping(arr, prev == null ? void 0 : prev.arr);
272 return mapping;
273 });
274 mappingAtom.init = undefined;
275 var splittedAtom = isWritable(arrAtom) ? vanilla.atom(function (get) {
276 return get(mappingAtom).atomList;
277 }, function (get, set, action) {
278 switch (action.type) {
279 case 'remove':
280 {
281 var index = get(splittedAtom).indexOf(action.atom);
282 if (index >= 0) {
283 var arr = get(arrAtom);
284 set(arrAtom, [].concat(arr.slice(0, index), arr.slice(index + 1)));
285 }
286 break;
287 }
288 case 'insert':
289 {
290 var _index = action.before ? get(splittedAtom).indexOf(action.before) : get(splittedAtom).length;
291 if (_index >= 0) {
292 var _arr = get(arrAtom);
293 set(arrAtom, [].concat(_arr.slice(0, _index), [action.value], _arr.slice(_index)));
294 }
295 break;
296 }
297 case 'move':
298 {
299 var index1 = get(splittedAtom).indexOf(action.atom);
300 var index2 = action.before ? get(splittedAtom).indexOf(action.before) : get(splittedAtom).length;
301 if (index1 >= 0 && index2 >= 0) {
302 var _arr2 = get(arrAtom);
303 if (index1 < index2) {
304 set(arrAtom, [].concat(_arr2.slice(0, index1), _arr2.slice(index1 + 1, index2), [_arr2[index1]], _arr2.slice(index2)));
305 } else {
306 set(arrAtom, [].concat(_arr2.slice(0, index2), [_arr2[index1]], _arr2.slice(index2, index1), _arr2.slice(index1 + 1)));
307 }
308 }
309 break;
310 }
311 }
312 }) : vanilla.atom(function (get) {
313 return get(mappingAtom).atomList;
314 });
315 return splittedAtom;
316 }, arrAtom, keyExtractor || cacheKeyForEmptyKeyExtractor);
317 }
318
319 var updateValue = function updateValue(prevValue, update) {
320 return typeof update === 'function' ? update(prevValue) : update;
321 };
322 function atomWithDefault(getDefault) {
323 var EMPTY = Symbol();
324 var overwrittenAtom = vanilla.atom(EMPTY);
325 var anAtom = vanilla.atom(function (get, options) {
326 var overwritten = get(overwrittenAtom);
327 if (overwritten !== EMPTY) {
328 return overwritten;
329 }
330 return getDefault(get, options);
331 }, function (get, set, update) {
332 if (update === RESET) {
333 return set(overwrittenAtom, EMPTY);
334 }
335 var prevValue = get(anAtom);
336 if (prevValue instanceof Promise) {
337 return prevValue.then(function (v) {
338 return set(overwrittenAtom, updateValue(v, update));
339 });
340 }
341 return set(overwrittenAtom, updateValue(prevValue, update));
342 });
343 return anAtom;
344 }
345
346 var NO_STORAGE_VALUE = Symbol();
347 function createJSONStorage(getStringStorage) {
348 var lastStr;
349 var lastValue;
350 var storage = {
351 getItem: function getItem(key) {
352 var _getStringStorage$get, _getStringStorage;
353 var parse = function parse(str) {
354 str = str || '';
355 if (lastStr !== str) {
356 try {
357 lastValue = JSON.parse(str);
358 } catch (_unused) {
359 return NO_STORAGE_VALUE;
360 }
361 lastStr = str;
362 }
363 return lastValue;
364 };
365 var str = (_getStringStorage$get = (_getStringStorage = getStringStorage()) == null ? void 0 : _getStringStorage.getItem(key)) != null ? _getStringStorage$get : null;
366 if (str instanceof Promise) {
367 return str.then(parse);
368 }
369 return parse(str);
370 },
371 setItem: function setItem(key, newValue) {
372 var _getStringStorage2;
373 return (_getStringStorage2 = getStringStorage()) == null ? void 0 : _getStringStorage2.setItem(key, JSON.stringify(newValue));
374 },
375 removeItem: function removeItem(key) {
376 var _getStringStorage3;
377 return (_getStringStorage3 = getStringStorage()) == null ? void 0 : _getStringStorage3.removeItem(key);
378 }
379 };
380 if (typeof window !== 'undefined' && typeof window.addEventListener === 'function') {
381 storage.subscribe = function (key, callback) {
382 var storageEventCallback = function storageEventCallback(e) {
383 if (e.key === key && e.newValue) {
384 callback(JSON.parse(e.newValue));
385 }
386 };
387 window.addEventListener('storage', storageEventCallback);
388 return function () {
389 window.removeEventListener('storage', storageEventCallback);
390 };
391 };
392 }
393 return storage;
394 }
395 var defaultStorage = createJSONStorage(function () {
396 return typeof window !== 'undefined' ? window.localStorage : undefined;
397 });
398 function atomWithStorage(key, initialValue, storage) {
399 if (storage === void 0) {
400 storage = defaultStorage;
401 }
402 var baseAtom = vanilla.atom(initialValue);
403 baseAtom.onMount = function (setAtom) {
404 var value = storage.getItem(key);
405 if (value instanceof Promise) {
406 value.then(function (v) {
407 return setAtom(v === NO_STORAGE_VALUE ? initialValue : v);
408 });
409 } else {
410 setAtom(value === NO_STORAGE_VALUE ? initialValue : value);
411 }
412 var unsub;
413 if (storage.subscribe) {
414 unsub = storage.subscribe(key, setAtom);
415 }
416 return unsub;
417 };
418 var anAtom = vanilla.atom(function (get) {
419 return get(baseAtom);
420 }, function (get, set, update) {
421 var nextValue = typeof update === 'function' ? update(get(baseAtom)) : update;
422 if (nextValue === RESET) {
423 set(baseAtom, initialValue);
424 return storage.removeItem(key);
425 }
426 set(baseAtom, nextValue);
427 return storage.setItem(key, nextValue);
428 });
429 return anAtom;
430 }
431
432 function atomWithObservable(getObservable, options) {
433 var returnResultData = function returnResultData(result) {
434 if ('e' in result) {
435 throw result.e;
436 }
437 return result.d;
438 };
439 var observableResultAtom = vanilla.atom(function (get) {
440 var _observable$Symbol$ob, _observable;
441 var observable = getObservable(get);
442 var itself = (_observable$Symbol$ob = (_observable = observable)[Symbol.observable]) == null ? void 0 : _observable$Symbol$ob.call(_observable);
443 if (itself) {
444 observable = itself;
445 }
446 var resolve;
447 var makePending = function makePending() {
448 return new Promise(function (r) {
449 resolve = r;
450 });
451 };
452 var initialResult = options && 'initialValue' in options ? {
453 d: typeof options.initialValue === 'function' ? options.initialValue() : options.initialValue
454 } : makePending();
455 var setResult;
456 var lastResult;
457 var listener = function listener(result) {
458 lastResult = result;
459 resolve == null ? void 0 : resolve(result);
460 setResult == null ? void 0 : setResult(result);
461 };
462 var subscription;
463 var timer;
464 var isNotMounted = function isNotMounted() {
465 return !setResult;
466 };
467 var start = function start() {
468 if (subscription) {
469 clearTimeout(timer);
470 subscription.unsubscribe();
471 }
472 subscription = observable.subscribe({
473 next: function next(d) {
474 return listener({
475 d: d
476 });
477 },
478 error: function error(e) {
479 return listener({
480 e: e
481 });
482 },
483 complete: function complete() {}
484 });
485 if (isNotMounted() && options != null && options.unstable_timeout) {
486 timer = setTimeout(function () {
487 if (subscription) {
488 subscription.unsubscribe();
489 subscription = undefined;
490 }
491 }, options.unstable_timeout);
492 }
493 };
494 start();
495 var resultAtom = vanilla.atom(lastResult || initialResult);
496 resultAtom.onMount = function (update) {
497 setResult = update;
498 if (lastResult) {
499 update(lastResult);
500 }
501 if (subscription) {
502 clearTimeout(timer);
503 } else {
504 start();
505 }
506 return function () {
507 setResult = undefined;
508 if (subscription) {
509 subscription.unsubscribe();
510 subscription = undefined;
511 }
512 };
513 };
514 return [resultAtom, observable, makePending, start, isNotMounted];
515 });
516 var observableAtom = vanilla.atom(function (get) {
517 var _get = get(observableResultAtom),
518 resultAtom = _get[0];
519 var result = get(resultAtom);
520 if (result instanceof Promise) {
521 return result.then(returnResultData);
522 }
523 return returnResultData(result);
524 }, function (get, set, data) {
525 var _get2 = get(observableResultAtom),
526 resultAtom = _get2[0],
527 observable = _get2[1],
528 makePending = _get2[2],
529 start = _get2[3],
530 isNotMounted = _get2[4];
531 if ('next' in observable) {
532 if (isNotMounted()) {
533 set(resultAtom, makePending());
534 start();
535 }
536 observable.next(data);
537 } else {
538 throw new Error('observable is not subject');
539 }
540 });
541 return observableAtom;
542 }
543
544 var cache1$1 = new WeakMap();
545 var memo1 = function memo1(create, dep1) {
546 return (cache1$1.has(dep1) ? cache1$1 : cache1$1.set(dep1, create())).get(dep1);
547 };
548 var LOADING = {
549 state: 'loading'
550 };
551 function loadable(anAtom) {
552 return memo1(function () {
553 var loadableCache = new WeakMap();
554 var refreshAtom = vanilla.atom(0);
555 var derivedAtom = vanilla.atom(function (get, _ref) {
556 var setSelf = _ref.setSelf;
557 get(refreshAtom);
558 var promise = get(anAtom);
559 if (!(promise instanceof Promise)) {
560 return {
561 state: 'hasData',
562 data: promise
563 };
564 }
565 var cached = loadableCache.get(promise);
566 if (cached) {
567 return cached;
568 }
569 loadableCache.set(promise, LOADING);
570 promise.then(function (data) {
571 loadableCache.set(promise, {
572 state: 'hasData',
573 data: data
574 });
575 }, function (error) {
576 loadableCache.set(promise, {
577 state: 'hasError',
578 error: error
579 });
580 }).finally(setSelf);
581 return LOADING;
582 }, function (_get, set) {
583 set(refreshAtom, function (c) {
584 return c + 1;
585 });
586 });
587 return vanilla.atom(function (get) {
588 return get(derivedAtom);
589 });
590 }, anAtom);
591 }
592
593 var getCached = function getCached(c, m, k) {
594 return (m.has(k) ? m : m.set(k, c())).get(k);
595 };
596 var cache1 = new WeakMap();
597 var memo2 = function memo2(create, dep1, dep2) {
598 var cache2 = getCached(function () {
599 return new WeakMap();
600 }, cache1, dep1);
601 return getCached(create, cache2, dep2);
602 };
603 var defaultFallback = function defaultFallback() {
604 return undefined;
605 };
606 function unwrap(anAtom, fallback) {
607 if (fallback === void 0) {
608 fallback = defaultFallback;
609 }
610 return memo2(function () {
611 var promiseErrorCache = new WeakMap();
612 var promiseResultCache = new WeakMap();
613 var refreshAtom = vanilla.atom(0);
614 var promiseAndValueAtom = vanilla.atom(function (get, _ref) {
615 var setSelf = _ref.setSelf;
616 get(refreshAtom);
617 var prev = get(promiseAndValueAtom);
618 var promise = get(anAtom);
619 if (promise === (prev == null ? void 0 : prev.p)) {
620 if (promiseErrorCache.has(promise)) {
621 throw promiseErrorCache.get(promise);
622 }
623 if (promiseResultCache.has(promise)) {
624 return {
625 p: promise,
626 v: promiseResultCache.get(promise)
627 };
628 }
629 }
630 if (promise !== (prev == null ? void 0 : prev.p)) {
631 promise.then(function (v) {
632 return promiseResultCache.set(promise, v);
633 }, function (e) {
634 return promiseErrorCache.set(promise, e);
635 }).finally(setSelf);
636 }
637 if (prev && 'v' in prev) {
638 return {
639 p: promise,
640 f: fallback(prev.v)
641 };
642 }
643 return {
644 p: promise,
645 f: fallback()
646 };
647 }, function (_get, set) {
648 set(refreshAtom, function (c) {
649 return c + 1;
650 });
651 });
652 promiseAndValueAtom.init = undefined;
653 return vanilla.atom(function (get) {
654 var state = get(promiseAndValueAtom);
655 if ('v' in state) {
656 return state.v;
657 }
658 return state.f;
659 });
660 }, anAtom, fallback);
661 }
662
663 exports.RESET = RESET;
664 exports.atomFamily = atomFamily;
665 exports.atomWithDefault = atomWithDefault;
666 exports.atomWithObservable = atomWithObservable;
667 exports.atomWithReducer = atomWithReducer;
668 exports.atomWithReset = atomWithReset;
669 exports.atomWithStorage = atomWithStorage;
670 exports.createJSONStorage = createJSONStorage;
671 exports.freezeAtom = freezeAtom;
672 exports.freezeAtomCreator = freezeAtomCreator;
673 exports.loadable = loadable;
674 exports.selectAtom = selectAtom;
675 exports.splitAtom = splitAtom;
676 exports.unstable_NO_STORAGE_VALUE = NO_STORAGE_VALUE;
677 exports.unstable_unwrap = unwrap;
678
679}));