Comparing version 0.6.2 to 0.7.0
@@ -1,7 +0,9 @@ | ||
import { Getter, Setter, Atom, WritableAtom, PrimitiveAtom, NonPromise, NonFunction } from './types'; | ||
export declare function atom<Value, Update>(read: (get: Getter) => NonPromise<Value>, write: (get: Getter, set: Setter, update: Update) => void | Promise<void>): WritableAtom<Value, Update>; | ||
export declare function atom<Value, Update>(read: NonFunction<NonPromise<Value>>, write: (get: Getter, set: Setter, update: Update) => void | Promise<void>): WritableAtom<Value, Update>; | ||
export declare function atom<Value, Update>(read: (get: Getter) => Promise<Value>, write: (get: Getter, set: Setter, update: Update) => void | Promise<void>): WritableAtom<Value | Promise<Value>, Update>; | ||
export declare function atom<Value>(read: (get: Getter) => NonPromise<Value>): Atom<Value>; | ||
export declare function atom<Value>(read: (get: Getter) => Promise<Value>): Atom<Value | Promise<Value>>; | ||
export declare function atom<Value>(initialValue: NonFunction<NonPromise<Value>>): PrimitiveAtom<Value>; | ||
import { Getter, Setter, Atom, WritableAtom, PrimitiveAtom } from './types'; | ||
export declare function atom<Value, Update>(read: (get: Getter) => Promise<Value>, write: (get: Getter, set: Setter, update: Update) => void | Promise<void>): WritableAtom<Value, Update>; | ||
export declare function atom<Value, Update>(read: (get: Getter) => Value, write: (get: Getter, set: Setter, update: Update) => void | Promise<void>): WritableAtom<Value, Update>; | ||
export declare function atom<Value, Update>(read: Function, write: (get: Getter, set: Setter, update: Update) => void | Promise<void>): never; | ||
export declare function atom<Value, Update>(read: Value, write: (get: Getter, set: Setter, update: Update) => void | Promise<void>): WritableAtom<Value, Update>; | ||
export declare function atom<Value, Update extends never = never>(read: (get: Getter) => Promise<Value>): Atom<Value>; | ||
export declare function atom<Value, Update extends never = never>(read: (get: Getter) => Value): Atom<Value>; | ||
export declare function atom<Value, Update>(read: Function): never; | ||
export declare function atom<Value, Update extends never = never>(initialValue: Value): PrimitiveAtom<Value>; |
291
index.cjs.js
@@ -8,20 +8,2 @@ 'use strict'; | ||
function _extends() { | ||
_extends = Object.assign || function (target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i]; | ||
for (var key in source) { | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
return target; | ||
}; | ||
return _extends.apply(this, arguments); | ||
} | ||
var isSSR = typeof window === 'undefined' || /ServerSideRendering/.test(window.navigator && window.navigator.userAgent); | ||
@@ -41,10 +23,3 @@ var useIsoLayoutEffect = isSSR ? function (fn) { | ||
var concatMap = function concatMap(src1, src2) { | ||
var dst = new Map(); | ||
src1.forEach(function (v, k) { | ||
dst.set(k, v); | ||
}); | ||
src2.forEach(function (v, k) { | ||
dst.set(k, v); | ||
}); | ||
return dst; | ||
return appendMap(new Map(src1), src2); | ||
}; | ||
@@ -72,16 +47,23 @@ | ||
var deleteDependent = function deleteDependent(dependentsMap, atom, dependent) { | ||
var dependents = dependentsMap.get(atom); | ||
if (dependents && dependents.has(dependent)) { | ||
var deleteDependent = function deleteDependent(dependentsMap, dependent) { | ||
dependentsMap.forEach(function (dependents) { | ||
dependents.delete(dependent); | ||
return dependents.size === 0; // empty | ||
} | ||
}); | ||
}; | ||
return false; // not found | ||
var setDependencies = function setDependencies(dependentsMap, atom, dependencies) { | ||
deleteDependent(dependentsMap, atom); | ||
dependencies.forEach(function (dependency) { | ||
addDependent(dependentsMap, dependency, atom); | ||
}); | ||
}; | ||
var listDependents = function listDependents(dependentsMap, atom) { | ||
var dependents = dependentsMap.get(atom); | ||
return dependents || new Set(); | ||
var listDependents = function listDependents(dependentsMap, atom, excludeSelf) { | ||
var dependents = new Set(dependentsMap.get(atom)); | ||
if (excludeSelf) { | ||
dependents.delete(atom); | ||
} | ||
return dependents; | ||
}; | ||
@@ -91,4 +73,4 @@ | ||
var getAtomStateValue = function getAtomStateValue(state, atom) { | ||
var atomState = state.get(atom); | ||
var getAtomStateValue = function getAtomStateValue(atom, state, tmpState) { | ||
var atomState = tmpState && tmpState.get(atom) || state.get(atom); | ||
return atomState ? atomState.value : atom.init; | ||
@@ -98,7 +80,3 @@ }; | ||
var readAtom = function readAtom(state, readingAtom, setState, dependentsMap) { | ||
var readAtomValue = function readAtomValue(prevState, atom, dependent) { | ||
if (dependent) { | ||
addDependent(dependentsMap, atom, dependent); | ||
} | ||
var readAtomValue = function readAtomValue(prevState, atom) { | ||
var partialState = new Map(); | ||
@@ -114,2 +92,3 @@ var atomState = prevState.get(atom); | ||
var value = null; | ||
var dependencies = new Set(); | ||
var isSync = true; | ||
@@ -119,4 +98,10 @@ | ||
var promiseOrValue = atom.read(function (a) { | ||
if (dependencies) { | ||
dependencies.add(a); | ||
} else { | ||
addDependent(dependentsMap, a, atom); | ||
} | ||
if (a !== atom) { | ||
var _readAtomValue = readAtomValue(prevState, a, atom), | ||
var _readAtomValue = readAtomValue(prevState, a), | ||
_nextAtomState = _readAtomValue[0], | ||
@@ -129,3 +114,3 @@ nextPartialState = _readAtomValue[1]; | ||
setState(function (prev) { | ||
return appendMap(new Map(prev), nextPartialState); | ||
return concatMap(prev, nextPartialState); | ||
}); | ||
@@ -143,3 +128,3 @@ } | ||
return _nextAtomState.value; | ||
} // primitive atom | ||
} // a === atom | ||
@@ -162,2 +147,4 @@ | ||
promise = promiseOrValue.then(function (value) { | ||
setDependencies(dependentsMap, atom, dependencies); | ||
dependencies = null; | ||
setState(function (prev) { | ||
@@ -171,3 +158,3 @@ return new Map(prev).set(atom, { | ||
return new Map(prev).set(atom, { | ||
value: getAtomStateValue(prev, atom), | ||
value: getAtomStateValue(atom, prev), | ||
error: e instanceof Error ? e : new Error(e) | ||
@@ -178,2 +165,4 @@ }); | ||
} else { | ||
setDependencies(dependentsMap, atom, dependencies); | ||
dependencies = null; | ||
value = promiseOrValue; | ||
@@ -201,3 +190,3 @@ } | ||
return readAtomValue(state, readingAtom, null); | ||
return readAtomValue(state, readingAtom); | ||
}; | ||
@@ -210,3 +199,3 @@ | ||
setState(function (prev) { | ||
return appendMap(new Map(prev), partialState); | ||
return concatMap(prev, partialState); | ||
}); | ||
@@ -216,14 +205,7 @@ } | ||
var delAtom = function delAtom(id, setState, dependentsMap, gcRequiredRef) { | ||
var deleteAtomState = function deleteAtomState(prevState, dependent) { | ||
prevState.forEach(function (_atomState, atom) { | ||
deleteDependent(dependentsMap, atom, dependent); | ||
}); | ||
return new Map(prevState); // to re-render | ||
}; | ||
gcRequiredRef.current = true; | ||
setState(function (prev) { | ||
return deleteAtomState(prev, id); | ||
}); | ||
var delAtom = function delAtom(id, setGcCount, dependentsMap) { | ||
deleteDependent(dependentsMap, id); | ||
setGcCount(function (c) { | ||
return c + 1; | ||
}); // trigger re-render for gc | ||
}; | ||
@@ -264,41 +246,69 @@ | ||
var writeAtom = function writeAtom(updatingAtom, update, dependentsMap, addWriteThunk) { | ||
var writeAtom = function writeAtom(updatingAtom, update, setState, dependentsMap, addWriteThunk) { | ||
var pendingPromises = []; | ||
var updateDependentsState = function updateDependentsState(prevState, atom) { | ||
var partialState = new Map(); | ||
listDependents(dependentsMap, atom).forEach(function (dependent) { | ||
listDependents(dependentsMap, atom, true).forEach(function (dependent) { | ||
if (typeof dependent === 'symbol') return; | ||
var v = dependent.read(function (a) { | ||
if (a !== dependent) { | ||
addDependent(dependentsMap, a, dependent); | ||
} | ||
var dependencies = new Set(); | ||
return getAtomStateValue(prevState, a); | ||
}); | ||
try { | ||
var v = dependent.read(function (a) { | ||
if (dependencies) { | ||
dependencies.add(a); | ||
} else { | ||
addDependent(dependentsMap, a, dependent); | ||
} | ||
if (v instanceof Promise) { | ||
var promise = v.then(function (vv) { | ||
var nextAtomState = { | ||
value: vv | ||
}; | ||
addWriteThunk(function (prev) { | ||
var nextState = new Map(prev).set(dependent, nextAtomState); | ||
var nextPartialState = updateDependentsState(nextState, dependent); | ||
return appendMap(nextState, nextPartialState); | ||
}); | ||
}).catch(function (e) { | ||
addWriteThunk(function (prev) { | ||
return new Map(prev).set(dependent, { | ||
value: getAtomStateValue(prev, dependent), | ||
error: e instanceof Error ? e : new Error(e) | ||
var s = prevState.get(a); | ||
if (!s) { | ||
throw new Error('atom state not found. possibly a bug.'); | ||
} | ||
if (s.error) { | ||
throw s.error; | ||
} | ||
return s.value; | ||
}); | ||
if (v instanceof Promise) { | ||
var promise = v.then(function (vv) { | ||
setDependencies(dependentsMap, dependent, dependencies); | ||
dependencies = null; | ||
var nextAtomState = { | ||
value: vv | ||
}; | ||
setState(function (prev) { | ||
var nextState = new Map(prev).set(dependent, nextAtomState); | ||
var nextPartialState = updateDependentsState(nextState, dependent); | ||
return appendMap(nextState, nextPartialState); | ||
}); | ||
}).catch(function (e) { | ||
setState(function (prev) { | ||
return new Map(prev).set(dependent, { | ||
value: getAtomStateValue(dependent, prev), | ||
error: e instanceof Error ? e : new Error(e) | ||
}); | ||
}); | ||
}); | ||
}); | ||
partialState.set(dependent, { | ||
value: getAtomStateValue(dependent, prevState), | ||
promise: promise | ||
}); | ||
} else { | ||
setDependencies(dependentsMap, dependent, dependencies); | ||
dependencies = null; | ||
partialState.set(dependent, { | ||
value: v | ||
}); | ||
appendMap(partialState, updateDependentsState(concatMap(prevState, partialState), dependent)); | ||
} | ||
} catch (e) { | ||
partialState.set(dependent, { | ||
value: getAtomStateValue(prevState, dependent), | ||
promise: promise | ||
value: getAtomStateValue(dependent, prevState), | ||
error: e instanceof Error ? e : new Error(e) | ||
}); | ||
} else { | ||
partialState.set(dependent, { | ||
value: v | ||
}); | ||
appendMap(partialState, updateDependentsState(concatMap(prevState, partialState), dependent)); | ||
@@ -316,3 +326,11 @@ } | ||
var promise = atom.write(function (a) { | ||
return getAtomStateValue(concatMap(prevState, partialState), a); | ||
if (process.env.NODE_ENV !== 'production') { | ||
var s = prevState.get(a); | ||
if (s && s.promise) { | ||
console.log('Reading pending atom state in write operation. Not sure how to deal with it. Returning obsolete vaule for', a); | ||
} | ||
} | ||
return getAtomStateValue(a, prevState, partialState); | ||
}, function (a, v) { | ||
@@ -328,3 +346,3 @@ if (a === atom) { | ||
} else { | ||
addWriteThunk(function (prev) { | ||
setState(function (prev) { | ||
var nextState = new Map(prev).set(a, nextAtomState); | ||
@@ -342,3 +360,3 @@ var nextPartialState = updateDependentsState(nextState, a); | ||
var nextPartialState = updateAtomState(prev, a, v); | ||
return appendMap(new Map(prev), nextPartialState); | ||
return concatMap(prev, nextPartialState); | ||
}); | ||
@@ -350,18 +368,12 @@ } | ||
if (promise instanceof Promise) { | ||
pendingPromises.push(promise); // XXX this is write pending (can be confused with read pending) | ||
var nextAtomState = { | ||
value: getAtomStateValue(concatMap(prevState, partialState), atom), | ||
value: getAtomStateValue(atom, prevState, partialState), | ||
promise: promise.then(function () { | ||
addWriteThunk(function (prev) { | ||
return new Map(prev).set(atom, { | ||
value: getAtomStateValue(prev, atom), | ||
promise: undefined | ||
value: getAtomStateValue(atom, prev) | ||
}); | ||
}); | ||
}).catch(function (e) { | ||
addWriteThunk(function (prev) { | ||
return new Map(prev).set(atom, { | ||
value: getAtomStateValue(prev, atom), | ||
error: e instanceof Error ? e : new Error(e) | ||
}); | ||
}); | ||
}) | ||
@@ -372,7 +384,9 @@ }; | ||
} catch (e) { | ||
var _nextAtomState2 = { | ||
value: getAtomStateValue(concatMap(prevState, partialState), atom), | ||
error: e instanceof Error ? e : new Error(e) | ||
}; | ||
partialState.set(atom, _nextAtomState2); | ||
if (pendingPromises.length) { | ||
pendingPromises.push(new Promise(function (_resolve, reject) { | ||
reject(e); | ||
})); | ||
} else { | ||
throw e; | ||
} | ||
} | ||
@@ -385,20 +399,24 @@ | ||
addWriteThunk(function (prevState) { | ||
var updatingAtomState = prevState.get(updatingAtom); | ||
var nextPartialState = updateAtomState(prevState, updatingAtom, update); | ||
return concatMap(prevState, nextPartialState); | ||
}); | ||
if (updatingAtomState && updatingAtomState.promise) { | ||
// schedule update after promise is resolved | ||
var promise = updatingAtomState.promise.then(function () { | ||
var updateState = updateAtomState(prevState, updatingAtom, update); | ||
addWriteThunk(function (prev) { | ||
return appendMap(new Map(prev), updateState); | ||
}); | ||
}); | ||
return new Map(prevState).set(updatingAtom, _extends({}, updatingAtomState, { | ||
promise: promise | ||
})); | ||
} else { | ||
var updateState = updateAtomState(prevState, updatingAtom, update); | ||
return appendMap(new Map(prevState), updateState); | ||
} | ||
}); | ||
if (pendingPromises.length) { | ||
return new Promise(function (resolve, reject) { | ||
var loop = function loop() { | ||
var len = pendingPromises.length; | ||
if (len === 0) { | ||
resolve(); | ||
} else { | ||
Promise.all(pendingPromises).then(function () { | ||
pendingPromises.splice(0, len); | ||
loop(); | ||
}).catch(reject); | ||
} | ||
}; | ||
loop(); | ||
}); | ||
} | ||
}; | ||
@@ -444,14 +462,13 @@ | ||
if (!dependentsMapRef.current) { | ||
dependentsMapRef.current = new WeakMap(); | ||
dependentsMapRef.current = new Map(); | ||
} | ||
var gcRequiredRef = react.useRef(false); | ||
var _useState2 = react.useState(0), | ||
gcCount = _useState2[0], | ||
setGcCount = _useState2[1]; // to trigger gc | ||
react.useEffect(function () { | ||
if (!gcRequiredRef.current) { | ||
return; | ||
} | ||
gcAtom(state, setState, dependentsMapRef.current); | ||
gcRequiredRef.current = false; | ||
}, [state]); | ||
}, [state, gcCount]); | ||
var lastStateRef = react.useRef(null); | ||
@@ -471,3 +488,3 @@ useIsoLayoutEffect(function () { | ||
del: function del(id) { | ||
return delAtom(id, setState, dependentsMapRef.current, gcRequiredRef); | ||
return delAtom(id, setGcCount, dependentsMapRef.current); | ||
}, | ||
@@ -478,3 +495,3 @@ read: function read(state, atom) { | ||
write: function write(atom, update) { | ||
writeAtom(atom, update, dependentsMapRef.current, function (thunk) { | ||
return writeAtom(atom, update, setState, dependentsMapRef.current, function (thunk) { | ||
writeThunkQueueRef.current.push(thunk); | ||
@@ -579,3 +596,3 @@ runWriteThunk(lastStateRef, setState, writeThunkQueueRef.current); | ||
if (isWritable(atom)) { | ||
actions.write(atom, update); | ||
return actions.write(atom, update); | ||
} else { | ||
@@ -582,0 +599,0 @@ throw new Error('not writable atom'); |
var jotai = (function (exports, react, useContextSelector) { | ||
'use strict'; | ||
function _extends() { | ||
_extends = Object.assign || function (target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i]; | ||
for (var key in source) { | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
return target; | ||
}; | ||
return _extends.apply(this, arguments); | ||
} | ||
var isSSR = typeof window === 'undefined' || /ServerSideRendering/.test(window.navigator && window.navigator.userAgent); | ||
@@ -36,10 +18,3 @@ var useIsoLayoutEffect = isSSR ? function (fn) { | ||
var concatMap = function concatMap(src1, src2) { | ||
var dst = new Map(); | ||
src1.forEach(function (v, k) { | ||
dst.set(k, v); | ||
}); | ||
src2.forEach(function (v, k) { | ||
dst.set(k, v); | ||
}); | ||
return dst; | ||
return appendMap(new Map(src1), src2); | ||
}; | ||
@@ -67,16 +42,23 @@ | ||
var deleteDependent = function deleteDependent(dependentsMap, atom, dependent) { | ||
var dependents = dependentsMap.get(atom); | ||
if (dependents && dependents.has(dependent)) { | ||
var deleteDependent = function deleteDependent(dependentsMap, dependent) { | ||
dependentsMap.forEach(function (dependents) { | ||
dependents.delete(dependent); | ||
return dependents.size === 0; // empty | ||
} | ||
}); | ||
}; | ||
return false; // not found | ||
var setDependencies = function setDependencies(dependentsMap, atom, dependencies) { | ||
deleteDependent(dependentsMap, atom); | ||
dependencies.forEach(function (dependency) { | ||
addDependent(dependentsMap, dependency, atom); | ||
}); | ||
}; | ||
var listDependents = function listDependents(dependentsMap, atom) { | ||
var dependents = dependentsMap.get(atom); | ||
return dependents || new Set(); | ||
var listDependents = function listDependents(dependentsMap, atom, excludeSelf) { | ||
var dependents = new Set(dependentsMap.get(atom)); | ||
if (excludeSelf) { | ||
dependents.delete(atom); | ||
} | ||
return dependents; | ||
}; | ||
@@ -86,4 +68,4 @@ | ||
var getAtomStateValue = function getAtomStateValue(state, atom) { | ||
var atomState = state.get(atom); | ||
var getAtomStateValue = function getAtomStateValue(atom, state, tmpState) { | ||
var atomState = tmpState && tmpState.get(atom) || state.get(atom); | ||
return atomState ? atomState.value : atom.init; | ||
@@ -93,7 +75,3 @@ }; | ||
var readAtom = function readAtom(state, readingAtom, setState, dependentsMap) { | ||
var readAtomValue = function readAtomValue(prevState, atom, dependent) { | ||
if (dependent) { | ||
addDependent(dependentsMap, atom, dependent); | ||
} | ||
var readAtomValue = function readAtomValue(prevState, atom) { | ||
var partialState = new Map(); | ||
@@ -109,2 +87,3 @@ var atomState = prevState.get(atom); | ||
var value = null; | ||
var dependencies = new Set(); | ||
var isSync = true; | ||
@@ -114,4 +93,10 @@ | ||
var promiseOrValue = atom.read(function (a) { | ||
if (dependencies) { | ||
dependencies.add(a); | ||
} else { | ||
addDependent(dependentsMap, a, atom); | ||
} | ||
if (a !== atom) { | ||
var _readAtomValue = readAtomValue(prevState, a, atom), | ||
var _readAtomValue = readAtomValue(prevState, a), | ||
_nextAtomState = _readAtomValue[0], | ||
@@ -124,3 +109,3 @@ nextPartialState = _readAtomValue[1]; | ||
setState(function (prev) { | ||
return appendMap(new Map(prev), nextPartialState); | ||
return concatMap(prev, nextPartialState); | ||
}); | ||
@@ -138,3 +123,3 @@ } | ||
return _nextAtomState.value; | ||
} // primitive atom | ||
} // a === atom | ||
@@ -157,2 +142,4 @@ | ||
promise = promiseOrValue.then(function (value) { | ||
setDependencies(dependentsMap, atom, dependencies); | ||
dependencies = null; | ||
setState(function (prev) { | ||
@@ -166,3 +153,3 @@ return new Map(prev).set(atom, { | ||
return new Map(prev).set(atom, { | ||
value: getAtomStateValue(prev, atom), | ||
value: getAtomStateValue(atom, prev), | ||
error: e instanceof Error ? e : new Error(e) | ||
@@ -173,2 +160,4 @@ }); | ||
} else { | ||
setDependencies(dependentsMap, atom, dependencies); | ||
dependencies = null; | ||
value = promiseOrValue; | ||
@@ -196,3 +185,3 @@ } | ||
return readAtomValue(state, readingAtom, null); | ||
return readAtomValue(state, readingAtom); | ||
}; | ||
@@ -205,3 +194,3 @@ | ||
setState(function (prev) { | ||
return appendMap(new Map(prev), partialState); | ||
return concatMap(prev, partialState); | ||
}); | ||
@@ -211,14 +200,7 @@ } | ||
var delAtom = function delAtom(id, setState, dependentsMap, gcRequiredRef) { | ||
var deleteAtomState = function deleteAtomState(prevState, dependent) { | ||
prevState.forEach(function (_atomState, atom) { | ||
deleteDependent(dependentsMap, atom, dependent); | ||
}); | ||
return new Map(prevState); // to re-render | ||
}; | ||
gcRequiredRef.current = true; | ||
setState(function (prev) { | ||
return deleteAtomState(prev, id); | ||
}); | ||
var delAtom = function delAtom(id, setGcCount, dependentsMap) { | ||
deleteDependent(dependentsMap, id); | ||
setGcCount(function (c) { | ||
return c + 1; | ||
}); // trigger re-render for gc | ||
}; | ||
@@ -259,41 +241,69 @@ | ||
var writeAtom = function writeAtom(updatingAtom, update, dependentsMap, addWriteThunk) { | ||
var writeAtom = function writeAtom(updatingAtom, update, setState, dependentsMap, addWriteThunk) { | ||
var pendingPromises = []; | ||
var updateDependentsState = function updateDependentsState(prevState, atom) { | ||
var partialState = new Map(); | ||
listDependents(dependentsMap, atom).forEach(function (dependent) { | ||
listDependents(dependentsMap, atom, true).forEach(function (dependent) { | ||
if (typeof dependent === 'symbol') return; | ||
var v = dependent.read(function (a) { | ||
if (a !== dependent) { | ||
addDependent(dependentsMap, a, dependent); | ||
} | ||
var dependencies = new Set(); | ||
return getAtomStateValue(prevState, a); | ||
}); | ||
try { | ||
var v = dependent.read(function (a) { | ||
if (dependencies) { | ||
dependencies.add(a); | ||
} else { | ||
addDependent(dependentsMap, a, dependent); | ||
} | ||
if (v instanceof Promise) { | ||
var promise = v.then(function (vv) { | ||
var nextAtomState = { | ||
value: vv | ||
}; | ||
addWriteThunk(function (prev) { | ||
var nextState = new Map(prev).set(dependent, nextAtomState); | ||
var nextPartialState = updateDependentsState(nextState, dependent); | ||
return appendMap(nextState, nextPartialState); | ||
}); | ||
}).catch(function (e) { | ||
addWriteThunk(function (prev) { | ||
return new Map(prev).set(dependent, { | ||
value: getAtomStateValue(prev, dependent), | ||
error: e instanceof Error ? e : new Error(e) | ||
var s = prevState.get(a); | ||
if (!s) { | ||
throw new Error('atom state not found. possibly a bug.'); | ||
} | ||
if (s.error) { | ||
throw s.error; | ||
} | ||
return s.value; | ||
}); | ||
if (v instanceof Promise) { | ||
var promise = v.then(function (vv) { | ||
setDependencies(dependentsMap, dependent, dependencies); | ||
dependencies = null; | ||
var nextAtomState = { | ||
value: vv | ||
}; | ||
setState(function (prev) { | ||
var nextState = new Map(prev).set(dependent, nextAtomState); | ||
var nextPartialState = updateDependentsState(nextState, dependent); | ||
return appendMap(nextState, nextPartialState); | ||
}); | ||
}).catch(function (e) { | ||
setState(function (prev) { | ||
return new Map(prev).set(dependent, { | ||
value: getAtomStateValue(dependent, prev), | ||
error: e instanceof Error ? e : new Error(e) | ||
}); | ||
}); | ||
}); | ||
}); | ||
partialState.set(dependent, { | ||
value: getAtomStateValue(dependent, prevState), | ||
promise: promise | ||
}); | ||
} else { | ||
setDependencies(dependentsMap, dependent, dependencies); | ||
dependencies = null; | ||
partialState.set(dependent, { | ||
value: v | ||
}); | ||
appendMap(partialState, updateDependentsState(concatMap(prevState, partialState), dependent)); | ||
} | ||
} catch (e) { | ||
partialState.set(dependent, { | ||
value: getAtomStateValue(prevState, dependent), | ||
promise: promise | ||
value: getAtomStateValue(dependent, prevState), | ||
error: e instanceof Error ? e : new Error(e) | ||
}); | ||
} else { | ||
partialState.set(dependent, { | ||
value: v | ||
}); | ||
appendMap(partialState, updateDependentsState(concatMap(prevState, partialState), dependent)); | ||
@@ -311,3 +321,11 @@ } | ||
var promise = atom.write(function (a) { | ||
return getAtomStateValue(concatMap(prevState, partialState), a); | ||
if (process.env.NODE_ENV !== 'production') { | ||
var s = prevState.get(a); | ||
if (s && s.promise) { | ||
console.log('Reading pending atom state in write operation. Not sure how to deal with it. Returning obsolete vaule for', a); | ||
} | ||
} | ||
return getAtomStateValue(a, prevState, partialState); | ||
}, function (a, v) { | ||
@@ -323,3 +341,3 @@ if (a === atom) { | ||
} else { | ||
addWriteThunk(function (prev) { | ||
setState(function (prev) { | ||
var nextState = new Map(prev).set(a, nextAtomState); | ||
@@ -337,3 +355,3 @@ var nextPartialState = updateDependentsState(nextState, a); | ||
var nextPartialState = updateAtomState(prev, a, v); | ||
return appendMap(new Map(prev), nextPartialState); | ||
return concatMap(prev, nextPartialState); | ||
}); | ||
@@ -345,18 +363,12 @@ } | ||
if (promise instanceof Promise) { | ||
pendingPromises.push(promise); // XXX this is write pending (can be confused with read pending) | ||
var nextAtomState = { | ||
value: getAtomStateValue(concatMap(prevState, partialState), atom), | ||
value: getAtomStateValue(atom, prevState, partialState), | ||
promise: promise.then(function () { | ||
addWriteThunk(function (prev) { | ||
return new Map(prev).set(atom, { | ||
value: getAtomStateValue(prev, atom), | ||
promise: undefined | ||
value: getAtomStateValue(atom, prev) | ||
}); | ||
}); | ||
}).catch(function (e) { | ||
addWriteThunk(function (prev) { | ||
return new Map(prev).set(atom, { | ||
value: getAtomStateValue(prev, atom), | ||
error: e instanceof Error ? e : new Error(e) | ||
}); | ||
}); | ||
}) | ||
@@ -367,7 +379,9 @@ }; | ||
} catch (e) { | ||
var _nextAtomState2 = { | ||
value: getAtomStateValue(concatMap(prevState, partialState), atom), | ||
error: e instanceof Error ? e : new Error(e) | ||
}; | ||
partialState.set(atom, _nextAtomState2); | ||
if (pendingPromises.length) { | ||
pendingPromises.push(new Promise(function (_resolve, reject) { | ||
reject(e); | ||
})); | ||
} else { | ||
throw e; | ||
} | ||
} | ||
@@ -380,20 +394,24 @@ | ||
addWriteThunk(function (prevState) { | ||
var updatingAtomState = prevState.get(updatingAtom); | ||
var nextPartialState = updateAtomState(prevState, updatingAtom, update); | ||
return concatMap(prevState, nextPartialState); | ||
}); | ||
if (updatingAtomState && updatingAtomState.promise) { | ||
// schedule update after promise is resolved | ||
var promise = updatingAtomState.promise.then(function () { | ||
var updateState = updateAtomState(prevState, updatingAtom, update); | ||
addWriteThunk(function (prev) { | ||
return appendMap(new Map(prev), updateState); | ||
}); | ||
}); | ||
return new Map(prevState).set(updatingAtom, _extends({}, updatingAtomState, { | ||
promise: promise | ||
})); | ||
} else { | ||
var updateState = updateAtomState(prevState, updatingAtom, update); | ||
return appendMap(new Map(prevState), updateState); | ||
} | ||
}); | ||
if (pendingPromises.length) { | ||
return new Promise(function (resolve, reject) { | ||
var loop = function loop() { | ||
var len = pendingPromises.length; | ||
if (len === 0) { | ||
resolve(); | ||
} else { | ||
Promise.all(pendingPromises).then(function () { | ||
pendingPromises.splice(0, len); | ||
loop(); | ||
}).catch(reject); | ||
} | ||
}; | ||
loop(); | ||
}); | ||
} | ||
}; | ||
@@ -439,14 +457,13 @@ | ||
if (!dependentsMapRef.current) { | ||
dependentsMapRef.current = new WeakMap(); | ||
dependentsMapRef.current = new Map(); | ||
} | ||
var gcRequiredRef = react.useRef(false); | ||
var _useState2 = react.useState(0), | ||
gcCount = _useState2[0], | ||
setGcCount = _useState2[1]; // to trigger gc | ||
react.useEffect(function () { | ||
if (!gcRequiredRef.current) { | ||
return; | ||
} | ||
gcAtom(state, setState, dependentsMapRef.current); | ||
gcRequiredRef.current = false; | ||
}, [state]); | ||
}, [state, gcCount]); | ||
var lastStateRef = react.useRef(null); | ||
@@ -466,3 +483,3 @@ useIsoLayoutEffect(function () { | ||
del: function del(id) { | ||
return delAtom(id, setState, dependentsMapRef.current, gcRequiredRef); | ||
return delAtom(id, setGcCount, dependentsMapRef.current); | ||
}, | ||
@@ -473,3 +490,3 @@ read: function read(state, atom) { | ||
write: function write(atom, update) { | ||
writeAtom(atom, update, dependentsMapRef.current, function (thunk) { | ||
return writeAtom(atom, update, setState, dependentsMapRef.current, function (thunk) { | ||
writeThunkQueueRef.current.push(thunk); | ||
@@ -574,3 +591,3 @@ runWriteThunk(lastStateRef, setState, writeThunkQueueRef.current); | ||
if (isWritable(atom)) { | ||
actions.write(atom, update); | ||
return actions.write(atom, update); | ||
} else { | ||
@@ -577,0 +594,0 @@ throw new Error('not writable atom'); |
290
index.js
import { useLayoutEffect, useState, useRef, useEffect, useMemo, createElement, useCallback, useDebugValue } from 'react'; | ||
import { createContext, useContext, useContextSelector } from 'use-context-selector'; | ||
function _extends() { | ||
_extends = Object.assign || function (target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i]; | ||
for (var key in source) { | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
return target; | ||
}; | ||
return _extends.apply(this, arguments); | ||
} | ||
const isSSR = typeof window === 'undefined' || /ServerSideRendering/.test(window.navigator && window.navigator.userAgent); | ||
@@ -33,12 +15,3 @@ const useIsoLayoutEffect = isSSR ? fn => fn() : useLayoutEffect; | ||
const concatMap = (src1, src2) => { | ||
const dst = new Map(); | ||
src1.forEach((v, k) => { | ||
dst.set(k, v); | ||
}); | ||
src2.forEach((v, k) => { | ||
dst.set(k, v); | ||
}); | ||
return dst; | ||
}; | ||
const concatMap = (src1, src2) => appendMap(new Map(src1), src2); | ||
@@ -67,16 +40,23 @@ const warningObject = new Proxy({}, { | ||
const deleteDependent = (dependentsMap, atom, dependent) => { | ||
const dependents = dependentsMap.get(atom); | ||
if (dependents && dependents.has(dependent)) { | ||
const deleteDependent = (dependentsMap, dependent) => { | ||
dependentsMap.forEach(dependents => { | ||
dependents.delete(dependent); | ||
return dependents.size === 0; // empty | ||
} | ||
}); | ||
}; | ||
return false; // not found | ||
const setDependencies = (dependentsMap, atom, dependencies) => { | ||
deleteDependent(dependentsMap, atom); | ||
dependencies.forEach(dependency => { | ||
addDependent(dependentsMap, dependency, atom); | ||
}); | ||
}; | ||
const listDependents = (dependentsMap, atom) => { | ||
const dependents = dependentsMap.get(atom); | ||
return dependents || new Set(); | ||
const listDependents = (dependentsMap, atom, excludeSelf) => { | ||
const dependents = new Set(dependentsMap.get(atom)); | ||
if (excludeSelf) { | ||
dependents.delete(atom); | ||
} | ||
return dependents; | ||
}; | ||
@@ -86,4 +66,4 @@ | ||
const getAtomStateValue = (state, atom) => { | ||
const atomState = state.get(atom); | ||
const getAtomStateValue = (atom, state, tmpState) => { | ||
const atomState = tmpState && tmpState.get(atom) || state.get(atom); | ||
return atomState ? atomState.value : atom.init; | ||
@@ -93,7 +73,3 @@ }; | ||
const readAtom = (state, readingAtom, setState, dependentsMap) => { | ||
const readAtomValue = (prevState, atom, dependent) => { | ||
if (dependent) { | ||
addDependent(dependentsMap, atom, dependent); | ||
} | ||
const readAtomValue = (prevState, atom) => { | ||
const partialState = new Map(); | ||
@@ -109,2 +85,3 @@ const atomState = prevState.get(atom); | ||
let value = null; | ||
let dependencies = new Set(); | ||
let isSync = true; | ||
@@ -114,4 +91,10 @@ | ||
const promiseOrValue = atom.read(a => { | ||
if (dependencies) { | ||
dependencies.add(a); | ||
} else { | ||
addDependent(dependentsMap, a, atom); | ||
} | ||
if (a !== atom) { | ||
const [nextAtomState, nextPartialState] = readAtomValue(prevState, a, atom); | ||
const [nextAtomState, nextPartialState] = readAtomValue(prevState, a); | ||
@@ -121,3 +104,3 @@ if (isSync) { | ||
} else { | ||
setState(prev => appendMap(new Map(prev), nextPartialState)); | ||
setState(prev => concatMap(prev, nextPartialState)); | ||
} | ||
@@ -134,3 +117,3 @@ | ||
return nextAtomState.value; | ||
} // primitive atom | ||
} // a === atom | ||
@@ -153,2 +136,4 @@ | ||
promise = promiseOrValue.then(value => { | ||
setDependencies(dependentsMap, atom, dependencies); | ||
dependencies = null; | ||
setState(prev => new Map(prev).set(atom, { | ||
@@ -159,3 +144,3 @@ value | ||
setState(prev => new Map(prev).set(atom, { | ||
value: getAtomStateValue(prev, atom), | ||
value: getAtomStateValue(atom, prev), | ||
error: e instanceof Error ? e : new Error(e) | ||
@@ -165,2 +150,4 @@ })); | ||
} else { | ||
setDependencies(dependentsMap, atom, dependencies); | ||
dependencies = null; | ||
value = promiseOrValue; | ||
@@ -188,3 +175,3 @@ } | ||
return readAtomValue(state, readingAtom, null); | ||
return readAtomValue(state, readingAtom); | ||
}; | ||
@@ -196,16 +183,9 @@ | ||
if (partialState) { | ||
setState(prev => appendMap(new Map(prev), partialState)); | ||
setState(prev => concatMap(prev, partialState)); | ||
} | ||
}; | ||
const delAtom = (id, setState, dependentsMap, gcRequiredRef) => { | ||
const deleteAtomState = (prevState, dependent) => { | ||
prevState.forEach((_atomState, atom) => { | ||
deleteDependent(dependentsMap, atom, dependent); | ||
}); | ||
return new Map(prevState); // to re-render | ||
}; | ||
gcRequiredRef.current = true; | ||
setState(prev => deleteAtomState(prev, id)); | ||
const delAtom = (id, setGcCount, dependentsMap) => { | ||
deleteDependent(dependentsMap, id); | ||
setGcCount(c => c + 1); // trigger re-render for gc | ||
}; | ||
@@ -246,39 +226,67 @@ | ||
const writeAtom = (updatingAtom, update, dependentsMap, addWriteThunk) => { | ||
const writeAtom = (updatingAtom, update, setState, dependentsMap, addWriteThunk) => { | ||
const pendingPromises = []; | ||
const updateDependentsState = (prevState, atom) => { | ||
const partialState = new Map(); | ||
listDependents(dependentsMap, atom).forEach(dependent => { | ||
listDependents(dependentsMap, atom, true).forEach(dependent => { | ||
if (typeof dependent === 'symbol') return; | ||
const v = dependent.read(a => { | ||
if (a !== dependent) { | ||
addDependent(dependentsMap, a, dependent); | ||
} | ||
let dependencies = new Set(); | ||
return getAtomStateValue(prevState, a); | ||
}); | ||
try { | ||
const v = dependent.read(a => { | ||
if (dependencies) { | ||
dependencies.add(a); | ||
} else { | ||
addDependent(dependentsMap, a, dependent); | ||
} | ||
if (v instanceof Promise) { | ||
const promise = v.then(vv => { | ||
const nextAtomState = { | ||
value: vv | ||
}; | ||
addWriteThunk(prev => { | ||
const nextState = new Map(prev).set(dependent, nextAtomState); | ||
const nextPartialState = updateDependentsState(nextState, dependent); | ||
return appendMap(nextState, nextPartialState); | ||
const s = prevState.get(a); | ||
if (!s) { | ||
throw new Error('atom state not found. possibly a bug.'); | ||
} | ||
if (s.error) { | ||
throw s.error; | ||
} | ||
return s.value; | ||
}); | ||
if (v instanceof Promise) { | ||
const promise = v.then(vv => { | ||
setDependencies(dependentsMap, dependent, dependencies); | ||
dependencies = null; | ||
const nextAtomState = { | ||
value: vv | ||
}; | ||
setState(prev => { | ||
const nextState = new Map(prev).set(dependent, nextAtomState); | ||
const nextPartialState = updateDependentsState(nextState, dependent); | ||
return appendMap(nextState, nextPartialState); | ||
}); | ||
}).catch(e => { | ||
setState(prev => new Map(prev).set(dependent, { | ||
value: getAtomStateValue(dependent, prev), | ||
error: e instanceof Error ? e : new Error(e) | ||
})); | ||
}); | ||
}).catch(e => { | ||
addWriteThunk(prev => new Map(prev).set(dependent, { | ||
value: getAtomStateValue(prev, dependent), | ||
error: e instanceof Error ? e : new Error(e) | ||
})); | ||
}); | ||
partialState.set(dependent, { | ||
value: getAtomStateValue(dependent, prevState), | ||
promise | ||
}); | ||
} else { | ||
setDependencies(dependentsMap, dependent, dependencies); | ||
dependencies = null; | ||
partialState.set(dependent, { | ||
value: v | ||
}); | ||
appendMap(partialState, updateDependentsState(concatMap(prevState, partialState), dependent)); | ||
} | ||
} catch (e) { | ||
partialState.set(dependent, { | ||
value: getAtomStateValue(prevState, dependent), | ||
promise | ||
value: getAtomStateValue(dependent, prevState), | ||
error: e instanceof Error ? e : new Error(e) | ||
}); | ||
} else { | ||
partialState.set(dependent, { | ||
value: v | ||
}); | ||
appendMap(partialState, updateDependentsState(concatMap(prevState, partialState), dependent)); | ||
@@ -295,3 +303,13 @@ } | ||
try { | ||
const promise = atom.write(a => getAtomStateValue(concatMap(prevState, partialState), a), (a, v) => { | ||
const promise = atom.write(a => { | ||
if (process.env.NODE_ENV !== 'production') { | ||
const s = prevState.get(a); | ||
if (s && s.promise) { | ||
console.log('Reading pending atom state in write operation. Not sure how to deal with it. Returning obsolete vaule for', a); | ||
} | ||
} | ||
return getAtomStateValue(a, prevState, partialState); | ||
}, (a, v) => { | ||
if (a === atom) { | ||
@@ -306,3 +324,3 @@ const nextAtomState = { | ||
} else { | ||
addWriteThunk(prev => { | ||
setState(prev => { | ||
const nextState = new Map(prev).set(a, nextAtomState); | ||
@@ -320,3 +338,3 @@ const nextPartialState = updateDependentsState(nextState, a); | ||
const nextPartialState = updateAtomState(prev, a, v); | ||
return appendMap(new Map(prev), nextPartialState); | ||
return concatMap(prev, nextPartialState); | ||
}); | ||
@@ -328,14 +346,10 @@ } | ||
if (promise instanceof Promise) { | ||
pendingPromises.push(promise); // XXX this is write pending (can be confused with read pending) | ||
const nextAtomState = { | ||
value: getAtomStateValue(concatMap(prevState, partialState), atom), | ||
value: getAtomStateValue(atom, prevState, partialState), | ||
promise: promise.then(() => { | ||
addWriteThunk(prev => new Map(prev).set(atom, { | ||
value: getAtomStateValue(prev, atom), | ||
promise: undefined | ||
value: getAtomStateValue(atom, prev) | ||
})); | ||
}).catch(e => { | ||
addWriteThunk(prev => new Map(prev).set(atom, { | ||
value: getAtomStateValue(prev, atom), | ||
error: e instanceof Error ? e : new Error(e) | ||
})); | ||
}) | ||
@@ -346,7 +360,9 @@ }; | ||
} catch (e) { | ||
const nextAtomState = { | ||
value: getAtomStateValue(concatMap(prevState, partialState), atom), | ||
error: e instanceof Error ? e : new Error(e) | ||
}; | ||
partialState.set(atom, nextAtomState); | ||
if (pendingPromises.length) { | ||
pendingPromises.push(new Promise((_resolve, reject) => { | ||
reject(e); | ||
})); | ||
} else { | ||
throw e; | ||
} | ||
} | ||
@@ -359,18 +375,24 @@ | ||
addWriteThunk(prevState => { | ||
const updatingAtomState = prevState.get(updatingAtom); | ||
const nextPartialState = updateAtomState(prevState, updatingAtom, update); | ||
return concatMap(prevState, nextPartialState); | ||
}); | ||
if (updatingAtomState && updatingAtomState.promise) { | ||
// schedule update after promise is resolved | ||
const promise = updatingAtomState.promise.then(() => { | ||
const updateState = updateAtomState(prevState, updatingAtom, update); | ||
addWriteThunk(prev => appendMap(new Map(prev), updateState)); | ||
}); | ||
return new Map(prevState).set(updatingAtom, _extends({}, updatingAtomState, { | ||
promise | ||
})); | ||
} else { | ||
const updateState = updateAtomState(prevState, updatingAtom, update); | ||
return appendMap(new Map(prevState), updateState); | ||
} | ||
}); | ||
if (pendingPromises.length) { | ||
return new Promise((resolve, reject) => { | ||
const loop = () => { | ||
const len = pendingPromises.length; | ||
if (len === 0) { | ||
resolve(); | ||
} else { | ||
Promise.all(pendingPromises).then(() => { | ||
pendingPromises.splice(0, len); | ||
loop(); | ||
}).catch(reject); | ||
} | ||
}; | ||
loop(); | ||
}); | ||
} | ||
}; | ||
@@ -414,14 +436,10 @@ | ||
if (!dependentsMapRef.current) { | ||
dependentsMapRef.current = new WeakMap(); | ||
dependentsMapRef.current = new Map(); | ||
} | ||
const gcRequiredRef = useRef(false); | ||
const [gcCount, setGcCount] = useState(0); // to trigger gc | ||
useEffect(() => { | ||
if (!gcRequiredRef.current) { | ||
return; | ||
} | ||
gcAtom(state, setState, dependentsMapRef.current); | ||
gcRequiredRef.current = false; | ||
}, [state]); | ||
}, [state, gcCount]); | ||
const lastStateRef = useRef(null); | ||
@@ -437,10 +455,8 @@ useIsoLayoutEffect(() => { | ||
add: (id, atom, partialState) => addAtom(id, atom, partialState, setState, dependentsMapRef.current), | ||
del: id => delAtom(id, setState, dependentsMapRef.current, gcRequiredRef), | ||
del: id => delAtom(id, setGcCount, dependentsMapRef.current), | ||
read: (state, atom) => readAtom(state, atom, setState, dependentsMapRef.current), | ||
write: (atom, update) => { | ||
writeAtom(atom, update, dependentsMapRef.current, thunk => { | ||
writeThunkQueueRef.current.push(thunk); | ||
runWriteThunk(lastStateRef, setState, writeThunkQueueRef.current); | ||
}); | ||
} | ||
write: (atom, update) => writeAtom(atom, update, setState, dependentsMapRef.current, thunk => { | ||
writeThunkQueueRef.current.push(thunk); | ||
runWriteThunk(lastStateRef, setState, writeThunkQueueRef.current); | ||
}) | ||
}), []); | ||
@@ -532,3 +548,3 @@ return createElement(ActionsContext.Provider, { | ||
if (isWritable(atom)) { | ||
actions.write(atom, update); | ||
return actions.write(atom, update); | ||
} else { | ||
@@ -535,0 +551,0 @@ throw new Error('not writable atom'); |
{ | ||
"name": "jotai", | ||
"private": false, | ||
"version": "0.6.2", | ||
"version": "0.7.0", | ||
"description": "👻 Next gen state management that will spook you", | ||
@@ -6,0 +6,0 @@ "main": "index.cjs.js", |
@@ -14,3 +14,3 @@ import React from 'react'; | ||
read: <Value>(state: State, atom: Atom<Value>) => readonly [AtomState, PartialState]; | ||
write: <Value, Update>(atom: WritableAtom<Value, Update>, update: Update) => void; | ||
write: <Value, Update>(atom: WritableAtom<Value, Update>, update: Update) => void | Promise<void>; | ||
}; | ||
@@ -17,0 +17,0 @@ export declare const ActionsContext: React.Context<Actions>; |
@@ -1,4 +0,2 @@ | ||
export declare type NonPromise<T> = T extends Promise<unknown> ? never : T; | ||
export declare type NonFunction<T> = T extends Function ? never : T; | ||
export declare type SetStateAction<Value> = NonFunction<Value> | ((prev: Value) => NonFunction<Value>); | ||
export declare type SetStateAction<Value> = Value | ((prev: Value) => Value); | ||
export declare type Getter = <Value>(atom: Atom<Value>) => Value; | ||
@@ -5,0 +3,0 @@ export declare type Setter = <Value, Update>(atom: WritableAtom<Value, Update>, update: Update) => void; |
@@ -1,5 +0,5 @@ | ||
import { Atom, WritableAtom, NonPromise } from './types'; | ||
declare type SetAtom<Update> = [Update] extends [never] ? () => void : (update: Update) => void; | ||
export declare function useAtom<Value, Update>(atom: WritableAtom<Value, Update>): [NonPromise<Value>, SetAtom<Update>]; | ||
export declare function useAtom<Value>(atom: Atom<Value>): [NonPromise<Value>, never]; | ||
import { Atom, WritableAtom } from './types'; | ||
declare type SetAtom<Update> = [Update] extends [never] ? () => void | Promise<void> : (update: Update) => void | Promise<void>; | ||
export declare function useAtom<Value, Update>(atom: WritableAtom<Value, Update>): [Value, SetAtom<Update>]; | ||
export declare function useAtom<Value>(atom: Atom<Value>): [Value, never]; | ||
export {}; |
@@ -1,9 +0,21 @@ | ||
import { WritableAtom } from 'jotai'; | ||
import type { NonPromise, NonFunction, SetStateAction, PrimitiveAtom } from './types'; | ||
export declare const useUpdateAtom: <Value, Update>(anAtom: WritableAtom<Value, Update>) => [Update] extends [never] ? () => void : (update: Update) => void; | ||
import { Atom, WritableAtom, PrimitiveAtom } from 'jotai'; | ||
import type { SetStateAction, Getter, Setter } from './types'; | ||
export declare const useUpdateAtom: <Value, Update>(anAtom: WritableAtom<Value, Update>) => [Update] extends [never] ? () => void | Promise<void> : (update: Update) => void | Promise<void>; | ||
declare const RESET: unique symbol; | ||
export declare const atomWithReset: <Value>(initialValue: NonFunction<NonPromise<Value>>) => WritableAtom<Value, typeof RESET | NonFunction<Value> | ((prev: Value) => NonFunction<Value>)>; | ||
export declare const useResetAtom: <Value>(anAtom: WritableAtom<Value, typeof RESET>) => (update: unknown) => void; | ||
export declare const useReducerAtom: <Value, Action>(anAtom: WritableAtom<Value, SetStateAction<Value>>, reducer: (v: Value, a: Action) => NonFunction<Value>) => readonly [NonPromise<Value>, (action: Action) => void]; | ||
export declare const atomWithReducer: <Value, Action>(initialValue: NonFunction<NonPromise<Value>>, reducer: (v: Value, a: Action) => Value) => WritableAtom<Value, Action>; | ||
export declare const atomWithReset: <Value>(initialValue: Value) => WritableAtom<Value, typeof RESET | Value | ((prev: Value) => Value)>; | ||
export declare const useResetAtom: <Value>(anAtom: WritableAtom<Value, typeof RESET>) => (update: unknown) => void | Promise<void>; | ||
export declare const useReducerAtom: <Value, Action>(anAtom: WritableAtom<Value, SetStateAction<Value>>, reducer: (v: Value, a: Action) => Value) => readonly [Value, (action: Action) => void]; | ||
export declare const atomWithReducer: <Value, Action>(initialValue: Value, reducer: (v: Value, a: Action) => Value) => WritableAtom<Value, Action>; | ||
declare type AtomFamily<Param, AtomType> = { | ||
(param: Param): AtomType; | ||
remove(param: Param): void; | ||
}; | ||
export declare function atomFamily<Param, Value, Update>(initializeRead: (param: Param) => (get: Getter) => Promise<Value>, initializeWrite: (param: Param) => (get: Getter, set: Setter, update: Update) => void | Promise<void>, areEqual?: (a: Param, b: Param) => boolean): AtomFamily<Param, WritableAtom<Value, Update>>; | ||
export declare function atomFamily<Param, Value, Update>(initializeRead: (param: Param) => (get: Getter) => Value, initializeWrite: (param: Param) => (get: Getter, set: Setter, update: Update) => void | Promise<void>, areEqual?: (a: Param, b: Param) => boolean): AtomFamily<Param, WritableAtom<Value, Update>>; | ||
export declare function atomFamily<Param, Value, Update>(initializeRead: (param: Param) => Function, initializeWrite: (param: Param) => (get: Getter, set: Setter, update: Update) => void | Promise<void>, areEqual?: (a: Param, b: Param) => boolean): never; | ||
export declare function atomFamily<Param, Value, Update>(initializeRead: (param: Param) => Value, initializeWrite: (param: Param) => (get: Getter, set: Setter, update: Update) => void | Promise<void>, areEqual?: (a: Param, b: Param) => boolean): AtomFamily<Param, WritableAtom<Value, Update>>; | ||
export declare function atomFamily<Param, Value, Update extends never = never>(initializeRead: (param: Param) => (get: Getter) => Promise<Value>, initializeWrite?: null, areEqual?: (a: Param, b: Param) => boolean): AtomFamily<Param, Atom<Value>>; | ||
export declare function atomFamily<Param, Value, Update extends never = never>(initializeRead: (param: Param) => (get: Getter) => Value, initializeWrite?: null, areEqual?: (a: Param, b: Param) => boolean): AtomFamily<Param, Atom<Value>>; | ||
export declare function atomFamily<Param, Value, Update>(initializeRead: (param: Param) => Function, initializeWrite?: null, areEqual?: (a: Param, b: Param) => boolean): never; | ||
export declare function atomFamily<Param, Value, Update extends never = never>(initializeRead: (param: Param) => Value, initializeWrite?: null, areEqual?: (a: Param, b: Param) => boolean): AtomFamily<Param, PrimitiveAtom<Value>>; | ||
export {}; |
36
utils.js
@@ -7,3 +7,4 @@ import { useMemo, useCallback } from 'react'; | ||
return useAtom(writeOnlyAtom)[1]; | ||
}; | ||
}; // ----------------------------------------------------------------------- | ||
const RESET = Symbol(); | ||
@@ -23,3 +24,4 @@ const atomWithReset = initialValue => { | ||
return useAtom(writeOnlyAtom)[1]; | ||
}; | ||
}; // ----------------------------------------------------------------------- | ||
const useReducerAtom = (anAtom, reducer) => { | ||
@@ -31,3 +33,4 @@ const [state, setState] = useAtom(anAtom); | ||
return [state, dispatch]; | ||
}; | ||
}; // ----------------------------------------------------------------------- | ||
const atomWithReducer = (initialValue, reducer) => { | ||
@@ -37,3 +40,28 @@ const anAtom = atom(initialValue, (get, set, action) => set(anAtom, reducer(get(anAtom), action))); | ||
}; | ||
function atomFamily(initializeRead, initializeWrite, areEqual = Object.is) { | ||
const atoms = []; | ||
export { atomWithReducer, atomWithReset, useReducerAtom, useResetAtom, useUpdateAtom }; | ||
const createAtom = param => { | ||
const found = atoms.find(x => areEqual(x[0], param)); | ||
if (found) { | ||
return found[1]; | ||
} | ||
const newAtom = atom(initializeRead(param), initializeWrite && initializeWrite(param)); | ||
atoms.unshift([param, newAtom]); | ||
return newAtom; | ||
}; | ||
createAtom.remove = p => { | ||
const index = atoms.findIndex(x => x[0] === p); | ||
if (index >= 0) { | ||
atoms.splice(index, 1); | ||
} | ||
}; | ||
return createAtom; | ||
} // ----------------------------------------------------------------------- | ||
export { atomFamily, atomWithReducer, atomWithReset, useReducerAtom, useResetAtom, useUpdateAtom }; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
64076
1546
2