jotai
Version:
👻 Next gen state management that will spook you
645 lines (629 loc) • 20.3 kB
JavaScript
var vanilla = require('jotai/vanilla');
var RESET = Symbol();
function atomWithReset(initialValue) {
var anAtom = vanilla.atom(initialValue, function (get, set, update) {
var nextValue = typeof update === 'function' ? update(get(anAtom)) : update;
set(anAtom, nextValue === RESET ? initialValue : nextValue);
});
return anAtom;
}
function atomWithReducer(initialValue, reducer) {
var anAtom = vanilla.atom(initialValue, function (get, set, action) {
return set(anAtom, reducer(get(anAtom), action));
});
return anAtom;
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
function _createForOfIteratorHelperLoose(o, allowArrayLike) {
var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
if (it) return (it = it.call(o)).next.bind(it);
if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
if (it) o = it;
var i = 0;
return function () {
if (i >= o.length) return {
done: true
};
return {
done: false,
value: o[i++]
};
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function atomFamily(initializeAtom, areEqual) {
var shouldRemove = null;
var atoms = new Map();
var createAtom = function createAtom(param) {
var item;
if (areEqual === undefined) {
item = atoms.get(param);
} else {
for (var _iterator = _createForOfIteratorHelperLoose(atoms), _step; !(_step = _iterator()).done;) {
var _step$value = _step.value,
key = _step$value[0],
value = _step$value[1];
if (areEqual(key, param)) {
item = value;
break;
}
}
}
if (item !== undefined) {
if (shouldRemove != null && shouldRemove(item[1], param)) {
createAtom.remove(param);
} else {
return item[0];
}
}
var newAtom = initializeAtom(param);
atoms.set(param, [newAtom, Date.now()]);
return newAtom;
};
createAtom.remove = function (param) {
if (areEqual === undefined) {
atoms.delete(param);
} else {
for (var _iterator2 = _createForOfIteratorHelperLoose(atoms), _step2; !(_step2 = _iterator2()).done;) {
var _step2$value = _step2.value,
key = _step2$value[0];
if (areEqual(key, param)) {
atoms.delete(key);
break;
}
}
}
};
createAtom.setShouldRemove = function (fn) {
shouldRemove = fn;
if (!shouldRemove) return;
for (var _iterator3 = _createForOfIteratorHelperLoose(atoms), _step3; !(_step3 = _iterator3()).done;) {
var _step3$value = _step3.value,
key = _step3$value[0],
value = _step3$value[1];
if (shouldRemove(value[1], key)) {
atoms.delete(key);
}
}
};
return createAtom;
}
var getCached$1 = function getCached(c, m, k) {
return (m.has(k) ? m : m.set(k, c())).get(k);
};
var cache1$4 = new WeakMap();
var memo3 = function memo3(create, dep1, dep2, dep3) {
var cache2 = getCached$1(function () {
return new WeakMap();
}, cache1$4, dep1);
var cache3 = getCached$1(function () {
return new WeakMap();
}, cache2, dep2);
return getCached$1(create, cache3, dep3);
};
function selectAtom(anAtom, selector, equalityFn) {
if (equalityFn === void 0) {
equalityFn = Object.is;
}
return memo3(function () {
var refAtom = vanilla.atom(function () {
return {};
});
var derivedAtom = vanilla.atom(function (get) {
var ref = get(refAtom);
var selectValue = function selectValue(value) {
var slice = selector(value);
if ('prev' in ref && equalityFn(ref.prev, slice)) {
return ref.prev;
}
return ref.prev = slice;
};
var value = get(anAtom);
if (value instanceof Promise) {
return value.then(selectValue);
}
return selectValue(value);
});
return derivedAtom;
}, anAtom, selector, equalityFn);
}
var cache1$3 = new WeakMap();
var memo1$2 = function memo1(create, dep1) {
return (cache1$3.has(dep1) ? cache1$3 : cache1$3.set(dep1, create())).get(dep1);
};
var deepFreeze = function deepFreeze(obj) {
if (typeof obj !== 'object' || obj === null) return;
Object.freeze(obj);
var propNames = Object.getOwnPropertyNames(obj);
for (var _iterator = _createForOfIteratorHelperLoose(propNames), _step; !(_step = _iterator()).done;) {
var name = _step.value;
var value = obj[name];
deepFreeze(value);
}
return obj;
};
function freezeAtom(anAtom) {
return memo1$2(function () {
var frozenAtom = vanilla.atom(function (get) {
return deepFreeze(get(anAtom));
}, function (_get, set, arg) {
return set(anAtom, arg);
});
return frozenAtom;
}, anAtom);
}
function freezeAtomCreator(createAtom) {
return function () {
var anAtom = createAtom.apply(void 0, arguments);
var origRead = anAtom.read;
anAtom.read = function (get, options) {
return deepFreeze(origRead(get, options));
};
return anAtom;
};
}
var getCached = function getCached(c, m, k) {
return (m.has(k) ? m : m.set(k, c())).get(k);
};
var cache1$2 = new WeakMap();
var memo2 = function memo2(create, dep1, dep2) {
var cache2 = getCached(function () {
return new WeakMap();
}, cache1$2, dep1);
return getCached(create, cache2, dep2);
};
var cacheKeyForEmptyKeyExtractor = {};
var isWritable = function isWritable(atom) {
return !!atom.write;
};
var isFunction = function isFunction(x) {
return typeof x === 'function';
};
function splitAtom(arrAtom, keyExtractor) {
return memo2(function () {
var mappingCache = new WeakMap();
var getMapping = function getMapping(arr, prev) {
var mapping = mappingCache.get(arr);
if (mapping) {
return mapping;
}
var prevMapping = prev && mappingCache.get(prev);
var atomList = [];
var keyList = [];
arr.forEach(function (item, index) {
var key = keyExtractor ? keyExtractor(item) : index;
keyList[index] = key;
var cachedAtom = prevMapping && prevMapping.atomList[prevMapping.keyList.indexOf(key)];
if (cachedAtom) {
atomList[index] = cachedAtom;
return;
}
var read = function read(get) {
var ref = get(refAtom);
var currArr = get(arrAtom);
var mapping = getMapping(currArr, ref.prev);
var index = mapping.keyList.indexOf(key);
if (index < 0 || index >= currArr.length) {
var prevItem = arr[getMapping(arr).keyList.indexOf(key)];
if (prevItem) {
return prevItem;
}
throw new Error('splitAtom: index out of bounds for read');
}
return currArr[index];
};
var write = function write(get, set, update) {
var ref = get(refAtom);
var arr = get(arrAtom);
var mapping = getMapping(arr, ref.prev);
var index = mapping.keyList.indexOf(key);
if (index < 0 || index >= arr.length) {
throw new Error('splitAtom: index out of bounds for write');
}
var nextItem = isFunction(update) ? update(arr[index]) : update;
set(arrAtom, [].concat(arr.slice(0, index), [nextItem], arr.slice(index + 1)));
};
atomList[index] = isWritable(arrAtom) ? vanilla.atom(read, write) : vanilla.atom(read);
});
if (prevMapping && prevMapping.keyList.length === keyList.length && prevMapping.keyList.every(function (x, i) {
return x === keyList[i];
})) {
mapping = prevMapping;
} else {
mapping = {
atomList: atomList,
keyList: keyList
};
}
mappingCache.set(arr, mapping);
return mapping;
};
var refAtom = vanilla.atom(function () {
return {};
});
var read = function read(get) {
var ref = get(refAtom);
var arr = get(arrAtom);
var mapping = getMapping(arr, ref.prev);
ref.prev = arr;
return mapping.atomList;
};
var write = function write(get, set, action) {
switch (action.type) {
case 'remove':
{
var index = get(splittedAtom).indexOf(action.atom);
if (index >= 0) {
var arr = get(arrAtom);
set(arrAtom, [].concat(arr.slice(0, index), arr.slice(index + 1)));
}
break;
}
case 'insert':
{
var _index = action.before ? get(splittedAtom).indexOf(action.before) : get(splittedAtom).length;
if (_index >= 0) {
var _arr = get(arrAtom);
set(arrAtom, [].concat(_arr.slice(0, _index), [action.value], _arr.slice(_index)));
}
break;
}
case 'move':
{
var index1 = get(splittedAtom).indexOf(action.atom);
var index2 = action.before ? get(splittedAtom).indexOf(action.before) : get(splittedAtom).length;
if (index1 >= 0 && index2 >= 0) {
var _arr2 = get(arrAtom);
if (index1 < index2) {
set(arrAtom, [].concat(_arr2.slice(0, index1), _arr2.slice(index1 + 1, index2), [_arr2[index1]], _arr2.slice(index2)));
} else {
set(arrAtom, [].concat(_arr2.slice(0, index2), [_arr2[index1]], _arr2.slice(index2, index1), _arr2.slice(index1 + 1)));
}
}
break;
}
}
};
var splittedAtom = isWritable(arrAtom) ? vanilla.atom(read, write) : vanilla.atom(read);
return splittedAtom;
}, arrAtom, keyExtractor || cacheKeyForEmptyKeyExtractor);
}
var updateValue = function updateValue(prevValue, update) {
return typeof update === 'function' ? update(prevValue) : update;
};
function atomWithDefault(getDefault) {
var EMPTY = Symbol();
var overwrittenAtom = vanilla.atom(EMPTY);
var anAtom = vanilla.atom(function (get, options) {
var overwritten = get(overwrittenAtom);
if (overwritten !== EMPTY) {
return overwritten;
}
return getDefault(get, options);
}, function (get, set, update) {
if (update === RESET) {
return set(overwrittenAtom, EMPTY);
}
var prevValue = get(anAtom);
if (prevValue instanceof Promise) {
return prevValue.then(function (v) {
return set(overwrittenAtom, updateValue(v, update));
});
}
return set(overwrittenAtom, updateValue(prevValue, update));
});
return anAtom;
}
var NO_STORAGE_VALUE = Symbol();
function createJSONStorage(getStringStorage) {
var lastStr;
var lastValue;
var storage = {
getItem: function getItem(key) {
var _getStringStorage$get, _getStringStorage;
var parse = function parse(str) {
str = str || '';
if (lastStr !== str) {
try {
lastValue = JSON.parse(str);
} catch (_unused) {
return NO_STORAGE_VALUE;
}
lastStr = str;
}
return lastValue;
};
var str = (_getStringStorage$get = (_getStringStorage = getStringStorage()) == null ? void 0 : _getStringStorage.getItem(key)) != null ? _getStringStorage$get : null;
if (str instanceof Promise) {
return str.then(parse);
}
return parse(str);
},
setItem: function setItem(key, newValue) {
var _getStringStorage2;
return (_getStringStorage2 = getStringStorage()) == null ? void 0 : _getStringStorage2.setItem(key, JSON.stringify(newValue));
},
removeItem: function removeItem(key) {
var _getStringStorage3;
return (_getStringStorage3 = getStringStorage()) == null ? void 0 : _getStringStorage3.removeItem(key);
}
};
if (typeof window !== 'undefined' && typeof window.addEventListener === 'function') {
storage.subscribe = function (key, callback) {
var storageEventCallback = function storageEventCallback(e) {
if (e.key === key && e.newValue) {
callback(JSON.parse(e.newValue));
}
};
window.addEventListener('storage', storageEventCallback);
return function () {
window.removeEventListener('storage', storageEventCallback);
};
};
}
return storage;
}
var defaultStorage = createJSONStorage(function () {
return typeof window !== 'undefined' ? window.localStorage : undefined;
});
function atomWithStorage(key, initialValue, storage) {
if (storage === void 0) {
storage = defaultStorage;
}
var baseAtom = vanilla.atom(initialValue);
baseAtom.onMount = function (setAtom) {
var value = storage.getItem(key);
if (value instanceof Promise) {
value.then(function (v) {
return setAtom(v === NO_STORAGE_VALUE ? initialValue : v);
});
} else {
setAtom(value === NO_STORAGE_VALUE ? initialValue : value);
}
var unsub;
if (storage.subscribe) {
unsub = storage.subscribe(key, setAtom);
}
return unsub;
};
var anAtom = vanilla.atom(function (get) {
return get(baseAtom);
}, function (get, set, update) {
var nextValue = typeof update === 'function' ? update(get(baseAtom)) : update;
if (nextValue === RESET) {
set(baseAtom, initialValue);
return storage.removeItem(key);
}
set(baseAtom, nextValue);
return storage.setItem(key, nextValue);
});
return anAtom;
}
function atomWithObservable(getObservable, options) {
var returnResultData = function returnResultData(result) {
if ('e' in result) {
throw result.e;
}
return result.d;
};
var observableResultAtom = vanilla.atom(function (get) {
var _observable$Symbol$ob, _observable;
var observable = getObservable(get);
var itself = (_observable$Symbol$ob = (_observable = observable)[Symbol.observable]) == null ? void 0 : _observable$Symbol$ob.call(_observable);
if (itself) {
observable = itself;
}
var resolve;
var makePending = function makePending() {
return new Promise(function (r) {
resolve = r;
});
};
var initialResult = options && 'initialValue' in options ? {
d: typeof options.initialValue === 'function' ? options.initialValue() : options.initialValue
} : makePending();
var setResult;
var lastResult;
var listener = function listener(result) {
lastResult = result;
resolve == null ? void 0 : resolve(result);
setResult == null ? void 0 : setResult(result);
};
var subscription;
var timer;
var isNotMounted = function isNotMounted() {
return !setResult;
};
var start = function start() {
if (subscription) {
clearTimeout(timer);
subscription.unsubscribe();
}
subscription = observable.subscribe({
next: function next(d) {
return listener({
d: d
});
},
error: function error(e) {
return listener({
e: e
});
},
complete: function complete() {}
});
if (isNotMounted() && options != null && options.unstable_timeout) {
timer = setTimeout(function () {
if (subscription) {
subscription.unsubscribe();
subscription = undefined;
}
}, options.unstable_timeout);
}
};
start();
var resultAtom = vanilla.atom(lastResult || initialResult);
resultAtom.onMount = function (update) {
setResult = update;
if (lastResult) {
update(lastResult);
}
if (subscription) {
clearTimeout(timer);
} else {
start();
}
return function () {
setResult = undefined;
if (subscription) {
subscription.unsubscribe();
subscription = undefined;
}
};
};
return [resultAtom, observable, makePending, start, isNotMounted];
});
var observableAtom = vanilla.atom(function (get) {
var _get = get(observableResultAtom),
resultAtom = _get[0];
var result = get(resultAtom);
if (result instanceof Promise) {
return result.then(returnResultData);
}
return returnResultData(result);
}, function (get, set, data) {
var _get2 = get(observableResultAtom),
resultAtom = _get2[0],
observable = _get2[1],
makePending = _get2[2],
start = _get2[3],
isNotMounted = _get2[4];
if ('next' in observable) {
if (isNotMounted()) {
set(resultAtom, makePending());
start();
}
observable.next(data);
} else {
throw new Error('observable is not subject');
}
});
return observableAtom;
}
var cache1$1 = new WeakMap();
var memo1$1 = function memo1(create, dep1) {
return (cache1$1.has(dep1) ? cache1$1 : cache1$1.set(dep1, create())).get(dep1);
};
var LOADING = {
state: 'loading'
};
function loadable(anAtom) {
return memo1$1(function () {
var loadableCache = new WeakMap();
var refreshAtom = vanilla.atom(0);
var derivedAtom = vanilla.atom(function (get, _ref) {
var setSelf = _ref.setSelf;
get(refreshAtom);
var promise = get(anAtom);
if (!(promise instanceof Promise)) {
return {
state: 'hasData',
data: promise
};
}
var cached = loadableCache.get(promise);
if (cached) {
return cached;
}
loadableCache.set(promise, LOADING);
promise.then(function (data) {
loadableCache.set(promise, {
state: 'hasData',
data: data
});
}, function (error) {
loadableCache.set(promise, {
state: 'hasError',
error: error
});
}).finally(setSelf);
return LOADING;
}, function (_get, set) {
set(refreshAtom, function (c) {
return c + 1;
});
});
return vanilla.atom(function (get) {
return get(derivedAtom);
});
}, anAtom);
}
var cache1 = new WeakMap();
var memo1 = function memo1(create, dep1) {
return (cache1.has(dep1) ? cache1 : cache1.set(dep1, create())).get(dep1);
};
function unwrap(anAtom, defaultValue) {
return memo1(function () {
var refAtom = vanilla.atom(function () {
return {};
});
var refreshAtom = vanilla.atom(0);
var derivedAtom = vanilla.atom(function (get, _ref) {
var setSelf = _ref.setSelf;
get(refreshAtom);
var ref = get(refAtom);
var promise = get(anAtom);
if (ref.p !== promise) {
promise.then(function (v) {
return ref.v = v;
}, function (e) {
return ref.e = e;
}).finally(setSelf);
ref.p = promise;
}
if ('e' in ref) {
throw ref.e;
}
if ('v' in ref) {
return ref.v;
}
return defaultValue;
}, function (_get, set) {
set(refreshAtom, function (c) {
return c + 1;
});
});
return vanilla.atom(function (get) {
return get(derivedAtom);
});
}, anAtom);
}
exports.RESET = RESET;
exports.atomFamily = atomFamily;
exports.atomWithDefault = atomWithDefault;
exports.atomWithObservable = atomWithObservable;
exports.atomWithReducer = atomWithReducer;
exports.atomWithReset = atomWithReset;
exports.atomWithStorage = atomWithStorage;
exports.createJSONStorage = createJSONStorage;
exports.freezeAtom = freezeAtom;
exports.freezeAtomCreator = freezeAtomCreator;
exports.loadable = loadable;
exports.selectAtom = selectAtom;
exports.splitAtom = splitAtom;
exports.unstable_NO_STORAGE_VALUE = NO_STORAGE_VALUE;
exports.unstable_unwrap = unwrap;
;