jotai
Version:
👻 Next gen state management that will spook you
839 lines (828 loc) • 31.8 kB
JavaScript
System.register(['react', 'jotai/vanilla'], (function (exports) {
'use strict';
var createContext, useState, useEffect, useRef, createElement, useContext, useReducer, useDebugValue, useCallback, atom$1;
return {
setters: [function (module) {
createContext = module.createContext;
useState = module.useState;
useEffect = module.useEffect;
useRef = module.useRef;
createElement = module.createElement;
useContext = module.useContext;
useReducer = module.useReducer;
useDebugValue = module.useDebugValue;
useCallback = module.useCallback;
}, function (module) {
atom$1 = module.atom;
}],
execute: (function () {
exports({
atom: atom,
useAtom: useAtom,
useAtomValue: useAtomValue,
useSetAtom: useSetAtom
});
const SUSPENSE_PROMISE = Symbol();
const isSuspensePromise = (promise) => !!promise[SUSPENSE_PROMISE];
const isSuspensePromiseAlreadyCancelled = (suspensePromise) => !suspensePromise[SUSPENSE_PROMISE].c;
const cancelSuspensePromise = (suspensePromise) => {
var _a;
const { b: basePromise, c: cancelPromise } = suspensePromise[SUSPENSE_PROMISE];
if (cancelPromise) {
cancelPromise();
(_a = promiseAbortMap.get(basePromise)) == null ? void 0 : _a();
}
};
const isEqualSuspensePromise = (oldSuspensePromise, newSuspensePromise) => {
const oldOriginalPromise = oldSuspensePromise[SUSPENSE_PROMISE].o;
const newOriginalPromise = newSuspensePromise[SUSPENSE_PROMISE].o;
return oldOriginalPromise === newOriginalPromise || oldSuspensePromise === newOriginalPromise || isSuspensePromise(oldOriginalPromise) && isEqualSuspensePromise(oldOriginalPromise, newSuspensePromise);
};
const createSuspensePromise = (basePromise, promise) => {
const suspensePromiseExtra = {
b: basePromise,
o: promise,
c: null
};
const suspensePromise = new Promise((resolve) => {
suspensePromiseExtra.c = () => {
suspensePromiseExtra.c = null;
resolve();
};
promise.finally(suspensePromiseExtra.c);
});
suspensePromise[SUSPENSE_PROMISE] = suspensePromiseExtra;
return suspensePromise;
};
const copySuspensePromise = (suspensePromise) => createSuspensePromise(
suspensePromise[SUSPENSE_PROMISE].b,
suspensePromise[SUSPENSE_PROMISE].o
);
const promiseAbortMap = /* @__PURE__ */ new WeakMap();
const registerPromiseAbort = exports('SECRET_INTERNAL_registerPromiseAbort', (basePromise, abort) => {
promiseAbortMap.set(basePromise, abort);
});
const hasInitialValue = (atom) => "init" in atom;
const READ_ATOM = "r";
const WRITE_ATOM = "w";
const COMMIT_ATOM = "c";
const SUBSCRIBE_ATOM = "s";
const RESTORE_ATOMS = "h";
const DEV_SUBSCRIBE_STATE = "n";
const DEV_GET_MOUNTED_ATOMS = "l";
const DEV_GET_ATOM_STATE = "a";
const DEV_GET_MOUNTED = "m";
const createStore = (initialValues) => {
const committedAtomStateMap = /* @__PURE__ */ new WeakMap();
const mountedMap = /* @__PURE__ */ new WeakMap();
const pendingMap = /* @__PURE__ */ new Map();
let stateListeners;
let mountedAtoms;
{
stateListeners = /* @__PURE__ */ new Set();
mountedAtoms = /* @__PURE__ */ new Set();
}
if (initialValues) {
for (const [atom, value] of initialValues) {
const atomState = {
v: value,
r: 0,
y: true,
d: /* @__PURE__ */ new Map()
};
{
Object.freeze(atomState);
if (!hasInitialValue(atom)) {
console.warn(
"Found initial value for derived atom which can cause unexpected behavior",
atom
);
}
}
committedAtomStateMap.set(atom, atomState);
}
}
const suspensePromiseCacheMap = /* @__PURE__ */ new WeakMap();
const addSuspensePromiseToCache = (version, atom, suspensePromise) => {
let cache = suspensePromiseCacheMap.get(atom);
if (!cache) {
cache = /* @__PURE__ */ new Map();
suspensePromiseCacheMap.set(atom, cache);
}
suspensePromise.then(() => {
if (cache.get(version) === suspensePromise) {
cache.delete(version);
if (!cache.size) {
suspensePromiseCacheMap.delete(atom);
}
}
});
cache.set(version, suspensePromise);
};
const cancelAllSuspensePromiseInCache = (atom) => {
const versionSet = /* @__PURE__ */ new Set();
const cache = suspensePromiseCacheMap.get(atom);
if (cache) {
suspensePromiseCacheMap.delete(atom);
cache.forEach((suspensePromise, version) => {
cancelSuspensePromise(suspensePromise);
versionSet.add(version);
});
}
return versionSet;
};
const versionedAtomStateMapMap = /* @__PURE__ */ new WeakMap();
const getVersionedAtomStateMap = (version) => {
let versionedAtomStateMap = versionedAtomStateMapMap.get(version);
if (!versionedAtomStateMap) {
versionedAtomStateMap = /* @__PURE__ */ new Map();
versionedAtomStateMapMap.set(version, versionedAtomStateMap);
}
return versionedAtomStateMap;
};
const getAtomState = (version, atom) => {
if (version) {
const versionedAtomStateMap = getVersionedAtomStateMap(version);
let atomState = versionedAtomStateMap.get(atom);
if (!atomState) {
atomState = getAtomState(version.p, atom);
if (atomState && "p" in atomState && isSuspensePromiseAlreadyCancelled(atomState.p)) {
atomState = void 0;
}
if (atomState) {
versionedAtomStateMap.set(atom, atomState);
}
}
return atomState;
}
return committedAtomStateMap.get(atom);
};
const setAtomState = (version, atom, atomState) => {
{
Object.freeze(atomState);
}
if (version) {
const versionedAtomStateMap = getVersionedAtomStateMap(version);
versionedAtomStateMap.set(atom, atomState);
} else {
const prevAtomState = committedAtomStateMap.get(atom);
committedAtomStateMap.set(atom, atomState);
if (!pendingMap.has(atom)) {
pendingMap.set(atom, prevAtomState);
}
}
};
const createReadDependencies = (version, prevReadDependencies = /* @__PURE__ */ new Map(), dependencies) => {
if (!dependencies) {
return prevReadDependencies;
}
const readDependencies = /* @__PURE__ */ new Map();
let changed = false;
dependencies.forEach((atom) => {
var _a;
const revision = ((_a = getAtomState(version, atom)) == null ? void 0 : _a.r) || 0;
readDependencies.set(atom, revision);
if (prevReadDependencies.get(atom) !== revision) {
changed = true;
}
});
if (prevReadDependencies.size === readDependencies.size && !changed) {
return prevReadDependencies;
}
return readDependencies;
};
const setAtomValue = (version, atom, value, dependencies, suspensePromise) => {
const atomState = getAtomState(version, atom);
if (atomState) {
if (suspensePromise && (!("p" in atomState) || !isEqualSuspensePromise(atomState.p, suspensePromise))) {
return atomState;
}
if ("p" in atomState) {
cancelSuspensePromise(atomState.p);
}
}
const nextAtomState = {
v: value,
r: (atomState == null ? void 0 : atomState.r) || 0,
y: true,
d: createReadDependencies(version, atomState == null ? void 0 : atomState.d, dependencies)
};
let changed = !(atomState == null ? void 0 : atomState.y);
if (!atomState || !("v" in atomState) || !Object.is(atomState.v, value)) {
changed = true;
++nextAtomState.r;
if (nextAtomState.d.has(atom)) {
nextAtomState.d = new Map(nextAtomState.d).set(atom, nextAtomState.r);
}
} else if (nextAtomState.d !== atomState.d && (nextAtomState.d.size !== atomState.d.size || !Array.from(nextAtomState.d.keys()).every((a) => atomState.d.has(a)))) {
changed = true;
Promise.resolve().then(() => {
flushPending(version);
});
}
if (atomState && !changed) {
return atomState;
}
setAtomState(version, atom, nextAtomState);
return nextAtomState;
};
const setAtomReadError = (version, atom, error, dependencies, suspensePromise) => {
const atomState = getAtomState(version, atom);
if (atomState) {
if (suspensePromise && (!("p" in atomState) || !isEqualSuspensePromise(atomState.p, suspensePromise))) {
return atomState;
}
if ("p" in atomState) {
cancelSuspensePromise(atomState.p);
}
}
const nextAtomState = {
e: error,
r: ((atomState == null ? void 0 : atomState.r) || 0) + 1,
y: true,
d: createReadDependencies(version, atomState == null ? void 0 : atomState.d, dependencies)
};
setAtomState(version, atom, nextAtomState);
return nextAtomState;
};
const setAtomSuspensePromise = (version, atom, suspensePromise, dependencies) => {
const atomState = getAtomState(version, atom);
if (atomState && "p" in atomState) {
if (isEqualSuspensePromise(atomState.p, suspensePromise) && !isSuspensePromiseAlreadyCancelled(atomState.p)) {
if (!atomState.y) {
return { ...atomState, y: true };
}
return atomState;
}
cancelSuspensePromise(atomState.p);
}
addSuspensePromiseToCache(version, atom, suspensePromise);
const nextAtomState = {
p: suspensePromise,
r: ((atomState == null ? void 0 : atomState.r) || 0) + 1,
y: true,
d: createReadDependencies(version, atomState == null ? void 0 : atomState.d, dependencies)
};
setAtomState(version, atom, nextAtomState);
return nextAtomState;
};
const setAtomPromiseOrValue = (version, atom, promiseOrValue, dependencies) => {
if (promiseOrValue instanceof Promise) {
const suspensePromise = createSuspensePromise(
promiseOrValue,
promiseOrValue.then((value) => {
setAtomValue(version, atom, value, dependencies, suspensePromise);
}).catch((e) => {
if (e instanceof Promise) {
if (isSuspensePromise(e)) {
return e.then(() => {
readAtomState(version, atom, true);
});
}
return e;
}
setAtomReadError(version, atom, e, dependencies, suspensePromise);
})
);
return setAtomSuspensePromise(
version,
atom,
suspensePromise,
dependencies
);
}
return setAtomValue(
version,
atom,
promiseOrValue,
dependencies
);
};
const setAtomInvalidated = (version, atom) => {
const atomState = getAtomState(version, atom);
if (atomState) {
const nextAtomState = {
...atomState,
y: false
};
setAtomState(version, atom, nextAtomState);
} else {
console.warn("[Bug] could not invalidate non existing atom", atom);
}
};
const readAtomState = (version, atom, force) => {
if (!force) {
const atomState = getAtomState(version, atom);
if (atomState) {
if (atomState.y && "p" in atomState && !isSuspensePromiseAlreadyCancelled(atomState.p)) {
return atomState;
}
atomState.d.forEach((_, a) => {
if (a !== atom) {
if (!mountedMap.has(a)) {
readAtomState(version, a);
} else {
const aState = getAtomState(version, a);
if (aState && !aState.y) {
readAtomState(version, a);
}
}
}
});
if (Array.from(atomState.d).every(([a, r]) => {
const aState = getAtomState(version, a);
return aState && !("p" in aState) && aState.r === r;
})) {
if (!atomState.y) {
return { ...atomState, y: true };
}
return atomState;
}
}
}
const dependencies = /* @__PURE__ */ new Set();
try {
const promiseOrValue = atom.read((a) => {
dependencies.add(a);
const aState = a === atom ? getAtomState(version, a) : readAtomState(version, a);
if (aState) {
if ("e" in aState) {
throw aState.e;
}
if ("p" in aState) {
throw aState.p;
}
return aState.v;
}
if (hasInitialValue(a)) {
return a.init;
}
throw new Error("no atom init");
});
return setAtomPromiseOrValue(version, atom, promiseOrValue, dependencies);
} catch (errorOrPromise) {
if (errorOrPromise instanceof Promise) {
const suspensePromise = isSuspensePromise(errorOrPromise) && isSuspensePromiseAlreadyCancelled(errorOrPromise) ? copySuspensePromise(errorOrPromise) : createSuspensePromise(errorOrPromise, errorOrPromise);
return setAtomSuspensePromise(
version,
atom,
suspensePromise,
dependencies
);
}
return setAtomReadError(version, atom, errorOrPromise, dependencies);
}
};
const readAtom = (readingAtom, version) => {
const atomState = readAtomState(version, readingAtom);
return atomState;
};
const addAtom = (version, addingAtom) => {
let mounted = mountedMap.get(addingAtom);
if (!mounted) {
mounted = mountAtom(version, addingAtom);
}
return mounted;
};
const canUnmountAtom = (atom, mounted) => !mounted.l.size && (!mounted.t.size || mounted.t.size === 1 && mounted.t.has(atom));
const delAtom = (version, deletingAtom) => {
const mounted = mountedMap.get(deletingAtom);
if (mounted && canUnmountAtom(deletingAtom, mounted)) {
unmountAtom(version, deletingAtom);
}
};
const invalidateDependents = (version, atom) => {
const mounted = mountedMap.get(atom);
mounted == null ? void 0 : mounted.t.forEach((dependent) => {
if (dependent !== atom) {
setAtomInvalidated(version, dependent);
invalidateDependents(version, dependent);
}
});
};
const writeAtomState = (version, atom, update) => {
let isSync = true;
const writeGetter = (a, options) => {
const aState = readAtomState(version, a);
if ("e" in aState) {
throw aState.e;
}
if ("p" in aState) {
if (options == null ? void 0 : options.unstable_promise) {
return aState.p.then(() => {
const s = getAtomState(version, a);
if (s && "p" in s && s.p === aState.p) {
return new Promise((resolve) => setTimeout(resolve)).then(
() => writeGetter(a, options)
);
}
return writeGetter(a, options);
});
}
{
console.info(
"Reading pending atom state in write operation. We throw a promise for now.",
a
);
}
throw aState.p;
}
if ("v" in aState) {
return aState.v;
}
{
console.warn(
"[Bug] no value found while reading atom in write operation. This is probably a bug.",
a
);
}
throw new Error("no value found");
};
const setter = (a, v) => {
let promiseOrVoid2;
if (a === atom) {
if (!hasInitialValue(a)) {
throw new Error("atom not writable");
}
const versionSet = cancelAllSuspensePromiseInCache(a);
versionSet.forEach((cancelledVersion) => {
if (cancelledVersion !== version) {
setAtomPromiseOrValue(cancelledVersion, a, v);
}
});
const prevAtomState = getAtomState(version, a);
const nextAtomState = setAtomPromiseOrValue(version, a, v);
if (prevAtomState !== nextAtomState) {
invalidateDependents(version, a);
}
} else {
promiseOrVoid2 = writeAtomState(version, a, v);
}
if (!isSync) {
flushPending(version);
}
return promiseOrVoid2;
};
const promiseOrVoid = atom.write(writeGetter, setter, update);
isSync = false;
return promiseOrVoid;
};
const writeAtom = (writingAtom, update, version) => {
const promiseOrVoid = writeAtomState(version, writingAtom, update);
flushPending(version);
return promiseOrVoid;
};
const isActuallyWritableAtom = (atom) => !!atom.write;
const mountAtom = (version, atom, initialDependent) => {
const mounted = {
t: new Set(initialDependent && [initialDependent]),
l: /* @__PURE__ */ new Set()
};
mountedMap.set(atom, mounted);
{
mountedAtoms.add(atom);
}
const atomState = readAtomState(void 0, atom);
atomState.d.forEach((_, a) => {
const aMounted = mountedMap.get(a);
if (aMounted) {
aMounted.t.add(atom);
} else {
if (a !== atom) {
mountAtom(version, a, atom);
}
}
});
if (isActuallyWritableAtom(atom) && atom.onMount) {
const setAtom = (update) => writeAtom(atom, update, version);
const onUnmount = atom.onMount(setAtom);
version = void 0;
if (onUnmount) {
mounted.u = onUnmount;
}
}
return mounted;
};
const unmountAtom = (version, atom) => {
var _a;
const onUnmount = (_a = mountedMap.get(atom)) == null ? void 0 : _a.u;
if (onUnmount) {
onUnmount();
}
mountedMap.delete(atom);
{
mountedAtoms.delete(atom);
}
const atomState = getAtomState(version, atom);
if (atomState) {
if ("p" in atomState) {
cancelSuspensePromise(atomState.p);
}
atomState.d.forEach((_, a) => {
if (a !== atom) {
const mounted = mountedMap.get(a);
if (mounted) {
mounted.t.delete(atom);
if (canUnmountAtom(a, mounted)) {
unmountAtom(version, a);
}
}
}
});
} else {
console.warn("[Bug] could not find atom state to unmount", atom);
}
};
const mountDependencies = (version, atom, atomState, prevReadDependencies) => {
const dependencies = new Set(atomState.d.keys());
prevReadDependencies == null ? void 0 : prevReadDependencies.forEach((_, a) => {
if (dependencies.has(a)) {
dependencies.delete(a);
return;
}
const mounted = mountedMap.get(a);
if (mounted) {
mounted.t.delete(atom);
if (canUnmountAtom(a, mounted)) {
unmountAtom(version, a);
}
}
});
dependencies.forEach((a) => {
const mounted = mountedMap.get(a);
if (mounted) {
mounted.t.add(atom);
} else if (mountedMap.has(atom)) {
mountAtom(version, a, atom);
}
});
};
const flushPending = (version) => {
if (version) {
const versionedAtomStateMap = getVersionedAtomStateMap(version);
versionedAtomStateMap.forEach((atomState, atom) => {
const committedAtomState = committedAtomStateMap.get(atom);
if (atomState !== committedAtomState) {
const mounted = mountedMap.get(atom);
mounted == null ? void 0 : mounted.l.forEach((listener) => listener(version));
}
});
return;
}
while (pendingMap.size) {
const pending = Array.from(pendingMap);
pendingMap.clear();
pending.forEach(([atom, prevAtomState]) => {
const atomState = getAtomState(void 0, atom);
if (atomState && atomState.d !== (prevAtomState == null ? void 0 : prevAtomState.d)) {
mountDependencies(void 0, atom, atomState, prevAtomState == null ? void 0 : prevAtomState.d);
}
if (prevAtomState && !prevAtomState.y && (atomState == null ? void 0 : atomState.y)) {
return;
}
const mounted = mountedMap.get(atom);
mounted == null ? void 0 : mounted.l.forEach((listener) => listener());
});
}
{
stateListeners.forEach((l) => l());
}
};
const commitVersionedAtomStateMap = (version) => {
const versionedAtomStateMap = getVersionedAtomStateMap(version);
versionedAtomStateMap.forEach((atomState, atom) => {
const prevAtomState = committedAtomStateMap.get(atom);
if (!prevAtomState || atomState.r > prevAtomState.r || atomState.y !== prevAtomState.y || atomState.r === prevAtomState.r && atomState.d !== prevAtomState.d) {
committedAtomStateMap.set(atom, atomState);
if (atomState.d !== (prevAtomState == null ? void 0 : prevAtomState.d)) {
mountDependencies(version, atom, atomState, prevAtomState == null ? void 0 : prevAtomState.d);
}
}
});
};
const commitAtom = (_atom, version) => {
if (version) {
commitVersionedAtomStateMap(version);
}
flushPending(void 0);
};
const subscribeAtom = (atom, callback, version) => {
const mounted = addAtom(version, atom);
const listeners = mounted.l;
listeners.add(callback);
return () => {
listeners.delete(callback);
delAtom(version, atom);
};
};
const restoreAtoms = (values, version) => {
for (const [atom, value] of values) {
if (hasInitialValue(atom)) {
setAtomPromiseOrValue(version, atom, value);
invalidateDependents(version, atom);
}
}
flushPending(version);
};
{
return {
[READ_ATOM]: readAtom,
[WRITE_ATOM]: writeAtom,
[COMMIT_ATOM]: commitAtom,
[SUBSCRIBE_ATOM]: subscribeAtom,
[RESTORE_ATOMS]: restoreAtoms,
[DEV_SUBSCRIBE_STATE]: (l) => {
stateListeners.add(l);
return () => {
stateListeners.delete(l);
};
},
[DEV_GET_MOUNTED_ATOMS]: () => mountedAtoms.values(),
[DEV_GET_ATOM_STATE]: (a) => committedAtomStateMap.get(a),
[DEV_GET_MOUNTED]: (a) => mountedMap.get(a)
};
}
};
const createStoreForExport = exports('unstable_createStore', (initialValues) => {
const store = createStore(initialValues);
const get = (atom) => {
const atomState = store[READ_ATOM](atom);
if ("e" in atomState) {
throw atomState.e;
}
if ("p" in atomState) {
return void 0;
}
return atomState.v;
};
const asyncGet = (atom) => new Promise((resolve, reject) => {
const atomState = store[READ_ATOM](atom);
if ("e" in atomState) {
reject(atomState.e);
} else if ("p" in atomState) {
resolve(atomState.p.then(() => asyncGet(atom)));
} else {
resolve(atomState.v);
}
});
const set = (atom, update) => store[WRITE_ATOM](atom, update);
const sub = (atom, callback) => store[SUBSCRIBE_ATOM](atom, callback);
return {
get,
asyncGet,
set,
sub,
SECRET_INTERNAL_store: store
};
});
const createScopeContainer = (initialValues, unstable_createStore) => {
const store = unstable_createStore ? unstable_createStore(initialValues).SECRET_INTERNAL_store : createStore(initialValues);
return { s: store };
};
const ScopeContextMap = /* @__PURE__ */ new Map();
const getScopeContext = exports('SECRET_INTERNAL_getScopeContext', (scope) => {
if (!ScopeContextMap.has(scope)) {
ScopeContextMap.set(scope, createContext(createScopeContainer()));
}
return ScopeContextMap.get(scope);
});
const Provider = exports('Provider', ({
children,
initialValues,
scope,
unstable_createStore,
unstable_enableVersionedWrite
}) => {
const [version, setVersion] = useState({});
useEffect(() => {
const scopeContainer = scopeContainerRef.current;
if (scopeContainer.w) {
scopeContainer.s[COMMIT_ATOM](null, version);
delete version.p;
scopeContainer.v = version;
}
}, [version]);
const scopeContainerRef = useRef();
if (!scopeContainerRef.current) {
const scopeContainer = createScopeContainer(
initialValues,
unstable_createStore
);
if (unstable_enableVersionedWrite) {
let retrying = 0;
scopeContainer.w = (write) => {
setVersion((parentVersion) => {
const nextVersion = retrying ? parentVersion : { p: parentVersion };
write(nextVersion);
return nextVersion;
});
};
scopeContainer.v = version;
scopeContainer.r = (fn) => {
++retrying;
fn();
--retrying;
};
}
scopeContainerRef.current = scopeContainer;
}
const ScopeContainerContext = getScopeContext(scope);
return createElement(
ScopeContainerContext.Provider,
{
value: scopeContainerRef.current
},
children
);
});
function atom(read, write) {
return atom$1(read, write);
}
function useAtomValue(atom, scope) {
const ScopeContext = getScopeContext(scope);
const scopeContainer = useContext(ScopeContext);
const { s: store, v: versionFromProvider } = scopeContainer;
const getAtomValue = (version2) => {
const atomState = store[READ_ATOM](atom, version2);
if (!atomState.y) {
throw new Error("should not be invalidated");
}
if ("e" in atomState) {
throw atomState.e;
}
if ("p" in atomState) {
throw atomState.p;
}
if ("v" in atomState) {
return atomState.v;
}
throw new Error("no atom value");
};
const [[version, valueFromReducer, atomFromReducer], rerenderIfChanged] = useReducer(
(prev, nextVersion) => {
const nextValue = getAtomValue(nextVersion);
if (Object.is(prev[1], nextValue) && prev[2] === atom) {
return prev;
}
return [nextVersion, nextValue, atom];
},
versionFromProvider,
(initialVersion) => {
const initialValue = getAtomValue(initialVersion);
return [initialVersion, initialValue, atom];
}
);
let value = valueFromReducer;
if (atomFromReducer !== atom) {
rerenderIfChanged(version);
value = getAtomValue(version);
}
useEffect(() => {
const { v: versionFromProvider2 } = scopeContainer;
if (versionFromProvider2) {
store[COMMIT_ATOM](atom, versionFromProvider2);
}
const unsubscribe = store[SUBSCRIBE_ATOM](
atom,
rerenderIfChanged,
versionFromProvider2
);
rerenderIfChanged(versionFromProvider2);
return unsubscribe;
}, [store, atom, scopeContainer]);
useEffect(() => {
store[COMMIT_ATOM](atom, version);
});
useDebugValue(value);
return value;
}
function useSetAtom(atom, scope) {
const ScopeContext = getScopeContext(scope);
const { s: store, w: versionedWrite } = useContext(ScopeContext);
const setAtom = useCallback(
(update) => {
if (!("write" in atom)) {
throw new Error("not writable atom");
}
const write = (version) => store[WRITE_ATOM](atom, update, version);
return versionedWrite ? versionedWrite(write) : write();
},
[store, versionedWrite, atom]
);
return setAtom;
}
function useAtom(atom, scope) {
if ("scope" in atom) {
console.warn(
"atom.scope is deprecated. Please do useAtom(atom, scope) instead."
);
scope = atom.scope;
}
return [
useAtomValue(atom, scope),
useSetAtom(atom, scope)
];
}
})
};
}));