New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

jotai

Package Overview
Dependencies
Maintainers
2
Versions
187
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

jotai - npm Package Compare versions

Comparing version 0.16.3 to 0.16.4

devtools/useAtomsSnapshot.d.ts

23

core/contexts.d.ts
import type { Context } from 'react';
import type { AnyAtom, WritableAtom, Scope } from './types';
import type { NewAtomReceiver } from './vanilla';
import { State } from './vanilla';
import { createMutableSource } from './useMutableSource';
declare type MutableSource = ReturnType<typeof createMutableSource>;
export declare type Store = [
mutableSource: MutableSource,
updateAtom: <Value, Update>(atom: WritableAtom<Value, Update>, update: Update) => void | Promise<void>
declare type MutableSource<_Target> = ReturnType<typeof createMutableSource>;
declare type UpdateAtom = <Value, Update>(atom: WritableAtom<Value, Update>, update: Update) => void | Promise<void>;
declare type StoreForProduction = [
stateMutableSource: MutableSource<State>,
updateAtom: UpdateAtom
];
export declare const createStore: (initialValues?: Iterable<readonly [AnyAtom, unknown]> | undefined, newAtomReceiver?: NewAtomReceiver | undefined) => Store;
export declare type StoreForDevelopment = [
stateMutableSource: MutableSource<State>,
updateAtom: UpdateAtom,
atomsMutableSource: MutableSource<{
atoms: AnyAtom[];
listeners: Set<() => void>;
}>
];
export declare type Store = StoreForProduction | StoreForDevelopment;
declare type CreateStore = (initialValues?: Iterable<readonly [AnyAtom, unknown]>) => Store;
export declare const createStore: CreateStore;
declare type StoreContext = Context<Store>;
export declare const getStoreContext: (scope?: Scope | undefined) => StoreContext;
export {};
import React from 'react';
import type { AnyAtom, Scope } from './types';
import type { AtomState, State } from './vanilla';
export declare const Provider: React.FC<{

@@ -7,1 +8,18 @@ initialValues?: Iterable<readonly [AnyAtom, unknown]>;

}>;
export declare const getDevState: (state: State) => {
n?: ((newAtom: AnyAtom) => void) | undefined;
v: number;
a: WeakMap<AnyAtom, AtomState<unknown>>;
m: WeakMap<AnyAtom, {
l: Set<() => void>;
d: Set<AnyAtom>;
u: void | import("./types").OnUnmount;
}>;
p: Set<AnyAtom>;
};
export declare const getDevAtoms: ({ atoms }: {
atoms: AnyAtom[];
}) => AnyAtom[];
export declare const subscribeDevAtoms: ({ listeners }: {
listeners: Set<() => void>;
}, callback: () => void) => () => boolean;

@@ -31,3 +31,3 @@ import type { Atom, WritableAtom, AnyAtom, OnUnmount } from './types';

declare type MountedMap = WeakMap<AnyAtom, Mounted>;
export declare type NewAtomReceiver = (newAtom: AnyAtom) => void;
declare type NewAtomReceiver = (newAtom: AnyAtom) => void;
declare type StateVersion = number;

@@ -34,0 +34,0 @@ declare type PendingAtoms = Set<AnyAtom>;

export { useAtomDevtools } from './devtools/useAtomDevtools';
export { useAtomsSnapshot } from './devtools/useAtomsSnapshot';

@@ -35,3 +35,3 @@ 'use strict';

var unsubscribe = devtools.current.subscribe(function (message) {
var _message$payload3;
var _message$payload3, _message$payload4;

@@ -50,2 +50,19 @@ if (message.type === 'DISPATCH' && message.state) {

(_devtools$current = devtools.current) == null ? void 0 : _devtools$current.init(lastValue.current);
} else if (message.type === 'DISPATCH' && ((_message$payload4 = message.payload) == null ? void 0 : _message$payload4.type) === 'IMPORT_STATE') {
var _message$payload$next, _message$payload$next2;
var actions = (_message$payload$next = message.payload.nextLiftedState) == null ? void 0 : _message$payload$next.actionsById;
var computedStates = ((_message$payload$next2 = message.payload.nextLiftedState) == null ? void 0 : _message$payload$next2.computedStates) || [];
computedStates.forEach(function (_ref, index) {
var state = _ref.state;
actions[index] || atomName;
if (index === 0) {
var _devtools$current2;
(_devtools$current2 = devtools.current) == null ? void 0 : _devtools$current2.init(state);
} else {
setValue(state);
}
});
}

@@ -73,2 +90,683 @@ });

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 hasInitialValue = function hasInitialValue(atom) {
return 'init' in atom;
};
var IS_EQUAL_PROMISE = Symbol();
var INTERRUPT_PROMISE = Symbol();
var isInterruptablePromise = function isInterruptablePromise(promise) {
return !!promise[INTERRUPT_PROMISE];
};
var createInterruptablePromise = function createInterruptablePromise(promise) {
var interrupt;
var interruptablePromise = new Promise(function (resolve, reject) {
interrupt = resolve;
promise.then(resolve, reject);
});
interruptablePromise[IS_EQUAL_PROMISE] = function (p) {
return p === interruptablePromise || p === promise;
};
interruptablePromise[INTERRUPT_PROMISE] = interrupt;
return interruptablePromise;
};
var getAtomState = function getAtomState(state, atom) {
return state.a.get(atom);
};
var wipAtomState = function wipAtomState(state, atom, dependencies) {
var atomState = getAtomState(state, atom);
var nextAtomState = _extends({
r: 0
}, atomState, {
d: dependencies ? new Map(Array.from(dependencies).map(function (a) {
var _getAtomState$r, _getAtomState;
return [a, (_getAtomState$r = (_getAtomState = getAtomState(state, a)) == null ? void 0 : _getAtomState.r) != null ? _getAtomState$r : 0];
})) : atomState ? atomState.d : new Map()
});
return [nextAtomState, atomState == null ? void 0 : atomState.d];
};
var setAtomValue = function setAtomValue(state, atom, value, dependencies, promise) {
var _atomState$p;
var _wipAtomState = wipAtomState(state, atom, dependencies),
atomState = _wipAtomState[0],
prevDependencies = _wipAtomState[1];
if (promise && !((_atomState$p = atomState.p) != null && _atomState$p[IS_EQUAL_PROMISE](promise))) {
return;
}
atomState.c == null ? void 0 : atomState.c();
delete atomState.e;
delete atomState.p;
delete atomState.c;
delete atomState.i;
if (!('v' in atomState) || !Object.is(atomState.v, value)) {
atomState.v = value;
++atomState.r;
}
commitAtomState(state, atom, atomState);
mountDependencies(state, atom, atomState, prevDependencies);
};
var setAtomReadError = function setAtomReadError(state, atom, error, dependencies, promise) {
var _atomState$p2;
var _wipAtomState2 = wipAtomState(state, atom, dependencies),
atomState = _wipAtomState2[0],
prevDependencies = _wipAtomState2[1];
if (promise && !((_atomState$p2 = atomState.p) != null && _atomState$p2[IS_EQUAL_PROMISE](promise))) {
return;
}
atomState.c == null ? void 0 : atomState.c();
delete atomState.p;
delete atomState.c;
delete atomState.i;
atomState.e = error;
commitAtomState(state, atom, atomState);
mountDependencies(state, atom, atomState, prevDependencies);
};
var setAtomReadPromise = function setAtomReadPromise(state, atom, promise, dependencies) {
var _atomState$p3;
var _wipAtomState3 = wipAtomState(state, atom, dependencies),
atomState = _wipAtomState3[0],
prevDependencies = _wipAtomState3[1];
if ((_atomState$p3 = atomState.p) != null && _atomState$p3[IS_EQUAL_PROMISE](promise)) {
return;
}
atomState.c == null ? void 0 : atomState.c();
if (isInterruptablePromise(promise)) {
atomState.p = promise;
delete atomState.c;
} else {
var interruptablePromise = createInterruptablePromise(promise);
atomState.p = interruptablePromise;
atomState.c = interruptablePromise[INTERRUPT_PROMISE];
}
commitAtomState(state, atom, atomState);
mountDependencies(state, atom, atomState, prevDependencies);
};
var setAtomInvalidated = function setAtomInvalidated(state, atom) {
var _wipAtomState4 = wipAtomState(state, atom),
atomState = _wipAtomState4[0];
atomState.c == null ? void 0 : atomState.c();
delete atomState.p;
delete atomState.c;
atomState.i = atomState.r;
commitAtomState(state, atom, atomState);
};
var setAtomWritePromise = function setAtomWritePromise(state, atom, promise) {
var _wipAtomState5 = wipAtomState(state, atom),
atomState = _wipAtomState5[0];
if (promise) {
atomState.w = promise;
} else {
delete atomState.w;
}
commitAtomState(state, atom, atomState);
};
var scheduleReadAtomState = function scheduleReadAtomState(state, atom, promise) {
promise.finally(function () {
readAtomState(state, atom, true);
});
};
var readAtomState = function readAtomState(state, atom, force) {
if (!force) {
var atomState = getAtomState(state, atom);
if (atomState) {
atomState.d.forEach(function (_, a) {
if (a !== atom) {
var aState = getAtomState(state, a);
if (aState && !aState.e && !aState.p && aState.r === aState.i) {
readAtomState(state, a, true);
}
}
});
if (Array.from(atomState.d.entries()).every(function (_ref) {
var a = _ref[0],
r = _ref[1];
var aState = getAtomState(state, a);
return aState && !aState.e && !aState.p && aState.r !== aState.i && aState.r === r;
})) {
return atomState;
}
}
}
var error;
var promise;
var value;
var dependencies = new Set();
try {
var promiseOrValue = atom.read(function (a) {
dependencies.add(a);
if (a !== atom) {
var _aState = readAtomState(state, a);
if (_aState.e) {
throw _aState.e;
}
if (_aState.p) {
throw _aState.p;
}
return _aState.v;
}
var aState = getAtomState(state, a);
if (aState) {
if (aState.p) {
throw aState.p;
}
return aState.v;
}
if (hasInitialValue(a)) {
return a.init;
}
throw new Error('no atom init');
});
if (promiseOrValue instanceof Promise) {
promise = promiseOrValue.then(function (value) {
setAtomValue(state, atom, value, dependencies, promise);
flushPending(state);
}).catch(function (e) {
if (e instanceof Promise) {
scheduleReadAtomState(state, atom, e);
return e;
}
setAtomReadError(state, atom, e instanceof Error ? e : new Error(e), dependencies, promise);
flushPending(state);
});
} else {
value = promiseOrValue;
}
} catch (errorOrPromise) {
if (errorOrPromise instanceof Promise) {
promise = errorOrPromise;
} else if (errorOrPromise instanceof Error) {
error = errorOrPromise;
} else {
error = new Error(errorOrPromise);
}
}
if (error) {
setAtomReadError(state, atom, error, dependencies);
} else if (promise) {
setAtomReadPromise(state, atom, promise, dependencies);
} else {
setAtomValue(state, atom, value, dependencies);
}
return getAtomState(state, atom);
};
var addAtom = function addAtom(state, addingAtom) {
var mounted = state.m.get(addingAtom);
if (!mounted) {
mounted = mountAtom(state, addingAtom);
}
flushPending(state);
return mounted;
};
var canUnmountAtom = function canUnmountAtom(atom, mounted) {
return !mounted.l.size && (!mounted.d.size || mounted.d.size === 1 && mounted.d.has(atom));
};
var delAtom = function delAtom(state, deletingAtom) {
var mounted = state.m.get(deletingAtom);
if (mounted && canUnmountAtom(deletingAtom, mounted)) {
unmountAtom(state, deletingAtom);
}
flushPending(state);
};
var invalidateDependents = function invalidateDependents(state, atom) {
var mounted = state.m.get(atom);
mounted == null ? void 0 : mounted.d.forEach(function (dependent) {
if (dependent === atom) {
return;
}
setAtomInvalidated(state, dependent);
invalidateDependents(state, dependent);
});
};
var writeAtomState = function writeAtomState(state, atom, update, pendingPromises) {
var isPendingPromisesExpired = !pendingPromises.length;
var atomState = getAtomState(state, atom);
if (atomState && atomState.w) {
var promise = atomState.w.then(function () {
writeAtomState(state, atom, update, pendingPromises);
if (isPendingPromisesExpired) {
flushPending(state);
}
});
if (!isPendingPromisesExpired) {
pendingPromises.push(promise);
}
return;
}
try {
var promiseOrVoid = atom.write(function (a) {
var aState = readAtomState(state, a);
if (aState.e) {
throw aState.e;
}
if (aState.p) {
if (typeof process === 'object' && process.env.NODE_ENV !== 'production') {
console.warn('Reading pending atom state in write operation. We throw a promise for now.', a);
}
throw aState.p;
}
if ('v' in aState) {
return aState.v;
}
if (typeof process === 'object' && process.env.NODE_ENV !== 'production') {
console.warn('[Bug] no value found while reading atom in write operation. This probably a bug.', a);
}
throw new Error('no value found');
}, function (a, v) {
var isPendingPromisesExpired = !pendingPromises.length;
if (a === atom) {
setAtomValue(state, a, v);
invalidateDependents(state, a);
} else {
writeAtomState(state, a, v, pendingPromises);
}
if (isPendingPromisesExpired) {
flushPending(state);
}
}, update);
if (promiseOrVoid instanceof Promise) {
var _promise = promiseOrVoid.finally(function () {
setAtomWritePromise(state, atom);
if (isPendingPromisesExpired) {
flushPending(state);
}
});
if (!isPendingPromisesExpired) {
pendingPromises.push(_promise);
}
setAtomWritePromise(state, atom, _promise);
}
} catch (e) {
if (pendingPromises.length === 1) {
throw e;
} else if (!isPendingPromisesExpired) {
pendingPromises.push(new Promise(function (_resolve, reject) {
reject(e);
}));
} else {
console.error('Uncaught exception: Use promise to catch error', e);
}
}
};
var writeAtom = function writeAtom(state, writingAtom, update) {
var pendingPromises = [Promise.resolve()];
writeAtomState(state, writingAtom, update, pendingPromises);
flushPending(state);
if (pendingPromises.length <= 1) {
pendingPromises.splice(0);
} else {
return new Promise(function (resolve, reject) {
var loop = function loop() {
if (pendingPromises.length <= 1) {
pendingPromises.splice(0);
resolve();
} else {
Promise.all(pendingPromises).then(function () {
pendingPromises.splice(1);
flushPending(state);
loop();
}).catch(reject);
}
};
loop();
});
}
};
var isActuallyWritableAtom = function isActuallyWritableAtom(atom) {
return !!atom.write;
};
var mountAtom = function mountAtom(state, atom, initialDependent) {
var atomState = getAtomState(state, atom);
if (atomState) {
atomState.d.forEach(function (_, a) {
if (a !== atom) {
if (!state.m.has(a)) {
mountAtom(state, a, atom);
}
}
});
} else if (typeof process === 'object' && process.env.NODE_ENV !== 'production') {
console.warn('[Bug] could not find atom state to mount', atom);
}
var mounted = {
d: new Set(initialDependent && [initialDependent]),
l: new Set(),
u: undefined
};
state.m.set(atom, mounted);
if (isActuallyWritableAtom(atom) && atom.onMount) {
var setAtom = function setAtom(update) {
return writeAtom(state, atom, update);
};
mounted.u = atom.onMount(setAtom);
}
return mounted;
};
var unmountAtom = function unmountAtom(state, atom) {
var _state$m$get;
var onUnmount = (_state$m$get = state.m.get(atom)) == null ? void 0 : _state$m$get.u;
if (onUnmount) {
onUnmount();
}
state.m.delete(atom);
var atomState = getAtomState(state, atom);
if (atomState) {
if (atomState.p && typeof process === 'object' && process.env.NODE_ENV !== 'production') {
console.warn('[Bug] deleting atomState with read promise', atom);
}
atomState.d.forEach(function (_, a) {
if (a !== atom) {
var mounted = state.m.get(a);
if (mounted) {
mounted.d.delete(atom);
if (canUnmountAtom(a, mounted)) {
unmountAtom(state, a);
}
}
}
});
} else if (typeof process === 'object' && process.env.NODE_ENV !== 'production') {
console.warn('[Bug] could not find atom state to unmount', atom);
}
};
var mountDependencies = function mountDependencies(state, atom, atomState, prevDependencies) {
if (prevDependencies !== atomState.d) {
var dependencies = new Set(atomState.d.keys());
if (prevDependencies) {
prevDependencies.forEach(function (_, a) {
var mounted = state.m.get(a);
if (dependencies.has(a)) {
dependencies.delete(a);
} else if (mounted) {
mounted.d.delete(atom);
if (canUnmountAtom(a, mounted)) {
unmountAtom(state, a);
}
} else if (typeof process === 'object' && process.env.NODE_ENV !== 'production') {
console.warn('[Bug] a dependency is not mounted', a);
}
});
}
dependencies.forEach(function (a) {
var mounted = state.m.get(a);
if (mounted) {
var dependents = mounted.d;
dependents.add(atom);
} else {
mountAtom(state, a, atom);
}
});
}
};
var commitAtomState = function commitAtomState(state, atom, atomState) {
if (typeof process === 'object' && process.env.NODE_ENV !== 'production') {
Object.freeze(atomState);
}
var isNewAtom = state.n && !state.a.has(atom);
state.a.set(atom, atomState);
if (isNewAtom) {
state.n(atom);
}
++state.v;
state.p.add(atom);
};
var flushPending = function flushPending(state) {
state.p.forEach(function (atom) {
var mounted = state.m.get(atom);
mounted == null ? void 0 : mounted.l.forEach(function (listener) {
return listener();
});
});
state.p.clear();
};
var subscribeAtom = function subscribeAtom(state, atom, callback) {
var mounted = addAtom(state, atom);
var listeners = mounted.l;
listeners.add(callback);
return function () {
listeners.delete(callback);
delAtom(state, atom);
};
};
var TARGET = Symbol();
var GET_VERSION = Symbol();
var useMutableSource = function useMutableSource(source, getSnapshot, subscribe) {
var lastVersion = react.useRef(0);
var currentVersion = source[GET_VERSION](source[TARGET]);
var _useState = react.useState(function () {
return [source, getSnapshot, subscribe, currentVersion, getSnapshot(source[TARGET])];
}),
state = _useState[0],
setState = _useState[1];
var currentSnapshot = state[4];
if (state[0] !== source || state[1] !== getSnapshot || state[2] !== subscribe) {
currentSnapshot = getSnapshot(source[TARGET]);
setState([source, getSnapshot, subscribe, currentVersion, currentSnapshot]);
} else if (currentVersion !== state[3] && currentVersion !== lastVersion.current) {
currentSnapshot = getSnapshot(source[TARGET]);
if (!Object.is(currentSnapshot, state[4])) {
setState([source, getSnapshot, subscribe, currentVersion, currentSnapshot]);
}
}
react.useEffect(function () {
var didUnsubscribe = false;
var checkForUpdates = function checkForUpdates() {
if (didUnsubscribe) {
return;
}
try {
var nextSnapshot = getSnapshot(source[TARGET]);
var nextVersion = source[GET_VERSION](source[TARGET]);
lastVersion.current = nextVersion;
setState(function (prev) {
if (prev[0] !== source || prev[1] !== getSnapshot || prev[2] !== subscribe) {
return prev;
}
if (Object.is(prev[4], nextSnapshot)) {
return prev;
}
return [prev[0], prev[1], prev[2], nextVersion, nextSnapshot];
});
} catch (e) {
setState(function (prev) {
return [].concat(prev);
});
}
};
var unsubscribe = subscribe(source[TARGET], checkForUpdates);
checkForUpdates();
return function () {
didUnsubscribe = true;
unsubscribe();
};
}, [source, getSnapshot, subscribe]);
return currentSnapshot;
};
var getDevState = function getDevState(state) {
return _extends({}, state);
};
var getDevAtoms = function getDevAtoms(_ref3) {
var atoms = _ref3.atoms;
return atoms;
};
var subscribeDevAtoms = function subscribeDevAtoms(_ref4, callback) {
var listeners = _ref4.listeners;
listeners.add(callback);
return function () {
return listeners.delete(callback);
};
};
function useAtomsSnapshot() {
var StoreContext = jotai.SECRET_INTERNAL_getStoreContext();
var _useContext = react.useContext(StoreContext),
mutableSource = _useContext[0],
atomsMutableSource = _useContext[2];
if (atomsMutableSource === undefined) {
throw Error('useAtomsSnapshot can only be used in dev mode.');
}
var atoms = useMutableSource(atomsMutableSource, getDevAtoms, subscribeDevAtoms);
var subscribe = react.useCallback(function (state, callback) {
var unsubs = atoms.map(function (atom) {
return subscribeAtom(state, atom, callback);
});
return function () {
unsubs.forEach(function (unsub) {
return unsub();
});
};
}, [atoms]);
var state = useMutableSource(mutableSource, getDevState, subscribe);
return react.useMemo(function () {
var atomToAtomValueTuples = atoms.filter(function (atom) {
return !!state.m.get(atom);
}).map(function (atom) {
var _state$a$get;
var atomState = (_state$a$get = state.a.get(atom)) != null ? _state$a$get : {};
return [atom, atomState.e || atomState.p || atomState.w || atomState.v];
});
return new Map(atomToAtomValueTuples);
}, [atoms, state]);
}
exports.useAtomDevtools = useAtomDevtools;
exports.useAtomsSnapshot = useAtomsSnapshot;
import type { Context } from 'react';
import type { AnyAtom, WritableAtom, Scope } from './types';
import type { NewAtomReceiver } from './vanilla';
import { State } from './vanilla';
import { createMutableSource } from './useMutableSource';
declare type MutableSource = ReturnType<typeof createMutableSource>;
export declare type Store = [
mutableSource: MutableSource,
updateAtom: <Value, Update>(atom: WritableAtom<Value, Update>, update: Update) => void | Promise<void>
declare type MutableSource<_Target> = ReturnType<typeof createMutableSource>;
declare type UpdateAtom = <Value, Update>(atom: WritableAtom<Value, Update>, update: Update) => void | Promise<void>;
declare type StoreForProduction = [
stateMutableSource: MutableSource<State>,
updateAtom: UpdateAtom
];
export declare const createStore: (initialValues?: Iterable<readonly [AnyAtom, unknown]> | undefined, newAtomReceiver?: NewAtomReceiver | undefined) => Store;
export declare type StoreForDevelopment = [
stateMutableSource: MutableSource<State>,
updateAtom: UpdateAtom,
atomsMutableSource: MutableSource<{
atoms: AnyAtom[];
listeners: Set<() => void>;
}>
];
export declare type Store = StoreForProduction | StoreForDevelopment;
declare type CreateStore = (initialValues?: Iterable<readonly [AnyAtom, unknown]>) => Store;
export declare const createStore: CreateStore;
declare type StoreContext = Context<Store>;
export declare const getStoreContext: (scope?: Scope | undefined) => StoreContext;
export {};
import React from 'react';
import type { AnyAtom, Scope } from './types';
import type { AtomState, State } from './vanilla';
export declare const Provider: React.FC<{

@@ -7,1 +8,18 @@ initialValues?: Iterable<readonly [AnyAtom, unknown]>;

}>;
export declare const getDevState: (state: State) => {
n?: ((newAtom: AnyAtom) => void) | undefined;
v: number;
a: WeakMap<AnyAtom, AtomState<unknown>>;
m: WeakMap<AnyAtom, {
l: Set<() => void>;
d: Set<AnyAtom>;
u: void | import("./types").OnUnmount;
}>;
p: Set<AnyAtom>;
};
export declare const getDevAtoms: ({ atoms }: {
atoms: AnyAtom[];
}) => AnyAtom[];
export declare const subscribeDevAtoms: ({ listeners }: {
listeners: Set<() => void>;
}, callback: () => void) => () => boolean;

@@ -31,3 +31,3 @@ import type { Atom, WritableAtom, AnyAtom, OnUnmount } from './types';

declare type MountedMap = WeakMap<AnyAtom, Mounted>;
export declare type NewAtomReceiver = (newAtom: AnyAtom) => void;
declare type NewAtomReceiver = (newAtom: AnyAtom) => void;
declare type StateVersion = number;

@@ -34,0 +34,0 @@ declare type PendingAtoms = Set<AnyAtom>;

export { useAtomDevtools } from './devtools/useAtomDevtools';
export { useAtomsSnapshot } from './devtools/useAtomsSnapshot';

@@ -1,3 +0,3 @@

import { useRef, useEffect } from 'react';
import { useAtom } from 'jotai';
import { useRef, useEffect, useState, useContext, useCallback, useMemo } from 'react';
import { useAtom, SECRET_INTERNAL_getStoreContext } from 'jotai';

@@ -24,3 +24,3 @@ function useAtomDevtools(anAtom, name) {

const unsubscribe = devtools.current.subscribe((message) => {
var _a, _b, _c, _d;
var _a, _b, _c, _d, _e, _f, _g;
if (message.type === "DISPATCH" && message.state) {

@@ -33,2 +33,14 @@ if (((_a = message.payload) == null ? void 0 : _a.type) === "JUMP_TO_ACTION" || ((_b = message.payload) == null ? void 0 : _b.type) === "JUMP_TO_STATE") {

(_d = devtools.current) == null ? void 0 : _d.init(lastValue.current);
} else if (message.type === "DISPATCH" && ((_e = message.payload) == null ? void 0 : _e.type) === "IMPORT_STATE") {
const actions = (_f = message.payload.nextLiftedState) == null ? void 0 : _f.actionsById;
const computedStates = ((_g = message.payload.nextLiftedState) == null ? void 0 : _g.computedStates) || [];
computedStates.forEach(({state}, index) => {
var _a2;
actions[index] || atomName;
if (index === 0) {
(_a2 = devtools.current) == null ? void 0 : _a2.init(state);
} else {
setValue(state);
}
});
}

@@ -55,2 +67,554 @@ });

export { useAtomDevtools };
var __defProp$1 = Object.defineProperty;
var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, {enumerable: true, configurable: true, writable: true, value}) : obj[key] = value;
var __objSpread$1 = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp$1.call(b, prop))
__defNormalProp$1(a, prop, b[prop]);
if (__getOwnPropSymbols$1)
for (var prop of __getOwnPropSymbols$1(b)) {
if (__propIsEnum$1.call(b, prop))
__defNormalProp$1(a, prop, b[prop]);
}
return a;
};
const hasInitialValue = (atom) => "init" in atom;
const IS_EQUAL_PROMISE = Symbol();
const INTERRUPT_PROMISE = Symbol();
const isInterruptablePromise = (promise) => !!promise[INTERRUPT_PROMISE];
const createInterruptablePromise = (promise) => {
let interrupt;
const interruptablePromise = new Promise((resolve, reject) => {
interrupt = resolve;
promise.then(resolve, reject);
});
interruptablePromise[IS_EQUAL_PROMISE] = (p) => p === interruptablePromise || p === promise;
interruptablePromise[INTERRUPT_PROMISE] = interrupt;
return interruptablePromise;
};
const getAtomState = (state, atom) => state.a.get(atom);
const wipAtomState = (state, atom, dependencies) => {
const atomState = getAtomState(state, atom);
const nextAtomState = __objSpread$1(__objSpread$1({
r: 0
}, atomState), {
d: dependencies ? new Map(Array.from(dependencies).map((a) => {
var _a, _b;
return [
a,
(_b = (_a = getAtomState(state, a)) == null ? void 0 : _a.r) != null ? _b : 0
];
})) : atomState ? atomState.d : new Map()
});
return [nextAtomState, atomState == null ? void 0 : atomState.d];
};
const setAtomValue = (state, atom, value, dependencies, promise) => {
var _a, _b;
const [atomState, prevDependencies] = wipAtomState(state, atom, dependencies);
if (promise && !((_a = atomState.p) == null ? void 0 : _a[IS_EQUAL_PROMISE](promise))) {
return;
}
(_b = atomState.c) == null ? void 0 : _b.call(atomState);
delete atomState.e;
delete atomState.p;
delete atomState.c;
delete atomState.i;
if (!("v" in atomState) || !Object.is(atomState.v, value)) {
atomState.v = value;
++atomState.r;
}
commitAtomState(state, atom, atomState);
mountDependencies(state, atom, atomState, prevDependencies);
};
const setAtomReadError = (state, atom, error, dependencies, promise) => {
var _a, _b;
const [atomState, prevDependencies] = wipAtomState(state, atom, dependencies);
if (promise && !((_a = atomState.p) == null ? void 0 : _a[IS_EQUAL_PROMISE](promise))) {
return;
}
(_b = atomState.c) == null ? void 0 : _b.call(atomState);
delete atomState.p;
delete atomState.c;
delete atomState.i;
atomState.e = error;
commitAtomState(state, atom, atomState);
mountDependencies(state, atom, atomState, prevDependencies);
};
const setAtomReadPromise = (state, atom, promise, dependencies) => {
var _a, _b;
const [atomState, prevDependencies] = wipAtomState(state, atom, dependencies);
if ((_a = atomState.p) == null ? void 0 : _a[IS_EQUAL_PROMISE](promise)) {
return;
}
(_b = atomState.c) == null ? void 0 : _b.call(atomState);
if (isInterruptablePromise(promise)) {
atomState.p = promise;
delete atomState.c;
} else {
const interruptablePromise = createInterruptablePromise(promise);
atomState.p = interruptablePromise;
atomState.c = interruptablePromise[INTERRUPT_PROMISE];
}
commitAtomState(state, atom, atomState);
mountDependencies(state, atom, atomState, prevDependencies);
};
const setAtomInvalidated = (state, atom) => {
var _a;
const [atomState] = wipAtomState(state, atom);
(_a = atomState.c) == null ? void 0 : _a.call(atomState);
delete atomState.p;
delete atomState.c;
atomState.i = atomState.r;
commitAtomState(state, atom, atomState);
};
const setAtomWritePromise = (state, atom, promise) => {
const [atomState] = wipAtomState(state, atom);
if (promise) {
atomState.w = promise;
} else {
delete atomState.w;
}
commitAtomState(state, atom, atomState);
};
const scheduleReadAtomState = (state, atom, promise) => {
promise.finally(() => {
readAtomState(state, atom, true);
});
};
const readAtomState = (state, atom, force) => {
if (!force) {
const atomState = getAtomState(state, atom);
if (atomState) {
atomState.d.forEach((_, a) => {
if (a !== atom) {
const aState = getAtomState(state, a);
if (aState && !aState.e && !aState.p && aState.r === aState.i) {
readAtomState(state, a, true);
}
}
});
if (Array.from(atomState.d.entries()).every(([a, r]) => {
const aState = getAtomState(state, a);
return aState && !aState.e && !aState.p && aState.r !== aState.i && aState.r === r;
})) {
return atomState;
}
}
}
let error;
let promise;
let value;
const dependencies = new Set();
try {
const promiseOrValue = atom.read((a) => {
dependencies.add(a);
if (a !== atom) {
const aState2 = readAtomState(state, a);
if (aState2.e) {
throw aState2.e;
}
if (aState2.p) {
throw aState2.p;
}
return aState2.v;
}
const aState = getAtomState(state, a);
if (aState) {
if (aState.p) {
throw aState.p;
}
return aState.v;
}
if (hasInitialValue(a)) {
return a.init;
}
throw new Error("no atom init");
});
if (promiseOrValue instanceof Promise) {
promise = promiseOrValue.then((value2) => {
setAtomValue(state, atom, value2, dependencies, promise);
flushPending(state);
}).catch((e) => {
if (e instanceof Promise) {
scheduleReadAtomState(state, atom, e);
return e;
}
setAtomReadError(state, atom, e instanceof Error ? e : new Error(e), dependencies, promise);
flushPending(state);
});
} else {
value = promiseOrValue;
}
} catch (errorOrPromise) {
if (errorOrPromise instanceof Promise) {
promise = errorOrPromise;
} else if (errorOrPromise instanceof Error) {
error = errorOrPromise;
} else {
error = new Error(errorOrPromise);
}
}
if (error) {
setAtomReadError(state, atom, error, dependencies);
} else if (promise) {
setAtomReadPromise(state, atom, promise, dependencies);
} else {
setAtomValue(state, atom, value, dependencies);
}
return getAtomState(state, atom);
};
const addAtom = (state, addingAtom) => {
let mounted = state.m.get(addingAtom);
if (!mounted) {
mounted = mountAtom(state, addingAtom);
}
flushPending(state);
return mounted;
};
const canUnmountAtom = (atom, mounted) => !mounted.l.size && (!mounted.d.size || mounted.d.size === 1 && mounted.d.has(atom));
const delAtom = (state, deletingAtom) => {
const mounted = state.m.get(deletingAtom);
if (mounted && canUnmountAtom(deletingAtom, mounted)) {
unmountAtom(state, deletingAtom);
}
flushPending(state);
};
const invalidateDependents = (state, atom) => {
const mounted = state.m.get(atom);
mounted == null ? void 0 : mounted.d.forEach((dependent) => {
if (dependent === atom) {
return;
}
setAtomInvalidated(state, dependent);
invalidateDependents(state, dependent);
});
};
const writeAtomState = (state, atom, update, pendingPromises) => {
const isPendingPromisesExpired = !pendingPromises.length;
const atomState = getAtomState(state, atom);
if (atomState && atomState.w) {
const promise = atomState.w.then(() => {
writeAtomState(state, atom, update, pendingPromises);
if (isPendingPromisesExpired) {
flushPending(state);
}
});
if (!isPendingPromisesExpired) {
pendingPromises.push(promise);
}
return;
}
try {
const promiseOrVoid = atom.write((a) => {
const aState = readAtomState(state, a);
if (aState.e) {
throw aState.e;
}
if (aState.p) {
if (typeof process === "object" && process.env.NODE_ENV !== "production") {
console.warn("Reading pending atom state in write operation. We throw a promise for now.", a);
}
throw aState.p;
}
if ("v" in aState) {
return aState.v;
}
if (typeof process === "object" && process.env.NODE_ENV !== "production") {
console.warn("[Bug] no value found while reading atom in write operation. This probably a bug.", a);
}
throw new Error("no value found");
}, (a, v) => {
const isPendingPromisesExpired2 = !pendingPromises.length;
if (a === atom) {
setAtomValue(state, a, v);
invalidateDependents(state, a);
} else {
writeAtomState(state, a, v, pendingPromises);
}
if (isPendingPromisesExpired2) {
flushPending(state);
}
}, update);
if (promiseOrVoid instanceof Promise) {
const promise = promiseOrVoid.finally(() => {
setAtomWritePromise(state, atom);
if (isPendingPromisesExpired) {
flushPending(state);
}
});
if (!isPendingPromisesExpired) {
pendingPromises.push(promise);
}
setAtomWritePromise(state, atom, promise);
}
} catch (e) {
if (pendingPromises.length === 1) {
throw e;
} else if (!isPendingPromisesExpired) {
pendingPromises.push(new Promise((_resolve, reject) => {
reject(e);
}));
} else {
console.error("Uncaught exception: Use promise to catch error", e);
}
}
};
const writeAtom = (state, writingAtom, update) => {
const pendingPromises = [Promise.resolve()];
writeAtomState(state, writingAtom, update, pendingPromises);
flushPending(state);
if (pendingPromises.length <= 1) {
pendingPromises.splice(0);
} else {
return new Promise((resolve, reject) => {
const loop = () => {
if (pendingPromises.length <= 1) {
pendingPromises.splice(0);
resolve();
} else {
Promise.all(pendingPromises).then(() => {
pendingPromises.splice(1);
flushPending(state);
loop();
}).catch(reject);
}
};
loop();
});
}
};
const isActuallyWritableAtom = (atom) => !!atom.write;
const mountAtom = (state, atom, initialDependent) => {
const atomState = getAtomState(state, atom);
if (atomState) {
atomState.d.forEach((_, a) => {
if (a !== atom) {
if (!state.m.has(a)) {
mountAtom(state, a, atom);
}
}
});
} else if (typeof process === "object" && process.env.NODE_ENV !== "production") {
console.warn("[Bug] could not find atom state to mount", atom);
}
const mounted = {
d: new Set(initialDependent && [initialDependent]),
l: new Set(),
u: void 0
};
state.m.set(atom, mounted);
if (isActuallyWritableAtom(atom) && atom.onMount) {
const setAtom = (update) => writeAtom(state, atom, update);
mounted.u = atom.onMount(setAtom);
}
return mounted;
};
const unmountAtom = (state, atom) => {
var _a;
const onUnmount = (_a = state.m.get(atom)) == null ? void 0 : _a.u;
if (onUnmount) {
onUnmount();
}
state.m.delete(atom);
const atomState = getAtomState(state, atom);
if (atomState) {
if (atomState.p && typeof process === "object" && process.env.NODE_ENV !== "production") {
console.warn("[Bug] deleting atomState with read promise", atom);
}
atomState.d.forEach((_, a) => {
if (a !== atom) {
const mounted = state.m.get(a);
if (mounted) {
mounted.d.delete(atom);
if (canUnmountAtom(a, mounted)) {
unmountAtom(state, a);
}
}
}
});
} else if (typeof process === "object" && process.env.NODE_ENV !== "production") {
console.warn("[Bug] could not find atom state to unmount", atom);
}
};
const mountDependencies = (state, atom, atomState, prevDependencies) => {
if (prevDependencies !== atomState.d) {
const dependencies = new Set(atomState.d.keys());
if (prevDependencies) {
prevDependencies.forEach((_, a) => {
const mounted = state.m.get(a);
if (dependencies.has(a)) {
dependencies.delete(a);
} else if (mounted) {
mounted.d.delete(atom);
if (canUnmountAtom(a, mounted)) {
unmountAtom(state, a);
}
} else if (typeof process === "object" && process.env.NODE_ENV !== "production") {
console.warn("[Bug] a dependency is not mounted", a);
}
});
}
dependencies.forEach((a) => {
const mounted = state.m.get(a);
if (mounted) {
const dependents = mounted.d;
dependents.add(atom);
} else {
mountAtom(state, a, atom);
}
});
}
};
const commitAtomState = (state, atom, atomState) => {
if (typeof process === "object" && process.env.NODE_ENV !== "production") {
Object.freeze(atomState);
}
const isNewAtom = state.n && !state.a.has(atom);
state.a.set(atom, atomState);
if (isNewAtom) {
state.n(atom);
}
++state.v;
state.p.add(atom);
};
const flushPending = (state) => {
state.p.forEach((atom) => {
const mounted = state.m.get(atom);
mounted == null ? void 0 : mounted.l.forEach((listener) => listener());
});
state.p.clear();
};
const subscribeAtom = (state, atom, callback) => {
const mounted = addAtom(state, atom);
const listeners = mounted.l;
listeners.add(callback);
return () => {
listeners.delete(callback);
delAtom(state, atom);
};
};
const TARGET = Symbol();
const GET_VERSION = Symbol();
const useMutableSource = (source, getSnapshot, subscribe) => {
const lastVersion = useRef(0);
const currentVersion = source[GET_VERSION](source[TARGET]);
const [state, setState] = useState(() => [
source,
getSnapshot,
subscribe,
currentVersion,
getSnapshot(source[TARGET])
]);
let currentSnapshot = state[4];
if (state[0] !== source || state[1] !== getSnapshot || state[2] !== subscribe) {
currentSnapshot = getSnapshot(source[TARGET]);
setState([
source,
getSnapshot,
subscribe,
currentVersion,
currentSnapshot
]);
} else if (currentVersion !== state[3] && currentVersion !== lastVersion.current) {
currentSnapshot = getSnapshot(source[TARGET]);
if (!Object.is(currentSnapshot, state[4])) {
setState([
source,
getSnapshot,
subscribe,
currentVersion,
currentSnapshot
]);
}
}
useEffect(() => {
let didUnsubscribe = false;
const checkForUpdates = () => {
if (didUnsubscribe) {
return;
}
try {
const nextSnapshot = getSnapshot(source[TARGET]);
const nextVersion = source[GET_VERSION](source[TARGET]);
lastVersion.current = nextVersion;
setState((prev) => {
if (prev[0] !== source || prev[1] !== getSnapshot || prev[2] !== subscribe) {
return prev;
}
if (Object.is(prev[4], nextSnapshot)) {
return prev;
}
return [
prev[0],
prev[1],
prev[2],
nextVersion,
nextSnapshot
];
});
} catch (e) {
setState((prev) => [...prev]);
}
};
const unsubscribe = subscribe(source[TARGET], checkForUpdates);
checkForUpdates();
return () => {
didUnsubscribe = true;
unsubscribe();
};
}, [source, getSnapshot, subscribe]);
return currentSnapshot;
};
var __defProp = Object.defineProperty;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {enumerable: true, configurable: true, writable: true, value}) : obj[key] = value;
var __objSpread = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
const getDevState = (state) => __objSpread({}, state);
const getDevAtoms = ({atoms}) => atoms;
const subscribeDevAtoms = ({listeners}, callback) => {
listeners.add(callback);
return () => listeners.delete(callback);
};
function useAtomsSnapshot() {
const StoreContext = SECRET_INTERNAL_getStoreContext();
const [mutableSource, , atomsMutableSource] = useContext(StoreContext);
if (atomsMutableSource === void 0) {
throw Error("useAtomsSnapshot can only be used in dev mode.");
}
const atoms = useMutableSource(atomsMutableSource, getDevAtoms, subscribeDevAtoms);
const subscribe = useCallback((state2, callback) => {
const unsubs = atoms.map((atom) => subscribeAtom(state2, atom, callback));
return () => {
unsubs.forEach((unsub) => unsub());
};
}, [atoms]);
const state = useMutableSource(mutableSource, getDevState, subscribe);
return useMemo(() => {
const atomToAtomValueTuples = atoms.filter((atom) => !!state.m.get(atom)).map((atom) => {
var _a;
const atomState = (_a = state.a.get(atom)) != null ? _a : {};
return [atom, atomState.e || atomState.p || atomState.w || atomState.v];
});
return new Map(atomToAtomValueTuples);
}, [atoms, state]);
}
export { useAtomDevtools, useAtomsSnapshot };

@@ -207,3 +207,2 @@ import { useRef, useState, useEffect, createContext, createElement, useCallback, useDebugValue, useContext } from 'react';

if (errorOrPromise instanceof Promise) {
scheduleReadAtomState(state, atom, errorOrPromise);
promise = errorOrPromise;

@@ -539,8 +538,23 @@ } else if (errorOrPromise instanceof Error) {

const createStore = (initialValues, newAtomReceiver) => {
const state = createState(initialValues, newAtomReceiver);
const mutableSource = createMutableSource(state, () => state.v);
const createStoreForProduction = (initialValues) => {
const state = createState(initialValues);
const stateMutableSource = createMutableSource(state, () => state.v);
const updateAtom = (atom, update) => writeAtom(state, atom, update);
return [mutableSource, updateAtom];
return [stateMutableSource, updateAtom];
};
const createStoreForDevelopment = (initialValues) => {
const atomsStore = {
atoms: [],
listeners: new Set()
};
const state = createState(initialValues, (newAtom) => {
atomsStore.atoms = [...atomsStore.atoms, newAtom];
atomsStore.listeners.forEach((listener) => listener());
});
const stateMutableSource = createMutableSource(state, () => state.v);
const updateAtom = (atom, update) => writeAtom(state, atom, update);
const atomsMutableSource = createMutableSource(atomsStore, () => atomsStore.atoms);
return [stateMutableSource, updateAtom, atomsMutableSource];
};
const createStore = typeof process === "object" && process.env.NODE_ENV !== "production" ? createStoreForDevelopment : createStoreForProduction;
const StoreContextMap = new Map();

@@ -572,15 +586,8 @@ const getStoreContext = (scope) => {

const storeRef = useRef(null);
if (typeof process === "object" && process.env.NODE_ENV !== "production") {
const atomsRef = useRef([]);
if (storeRef.current === null) {
storeRef.current = createStore(initialValues, (newAtom) => {
atomsRef.current.push(newAtom);
});
}
useDebugState(storeRef.current, atomsRef.current);
} else {
if (storeRef.current === null) {
storeRef.current = createStore(initialValues);
}
if (storeRef.current === null) {
storeRef.current = createStore(initialValues);
}
if (typeof process === "object" && process.env.NODE_ENV !== "production" && isDevStore(storeRef.current)) {
useDebugState(storeRef.current);
}
const StoreContext = getStoreContext(scope);

@@ -607,4 +614,14 @@ return createElement(StoreContext.Provider, {value: storeRef.current}, children);

}));
const getState = (state) => __objSpread({}, state);
const useDebugState = (store, atoms) => {
const isDevStore = (store) => {
return store.length > 2;
};
const getDevState = (state) => __objSpread({}, state);
const getDevAtoms = ({atoms}) => atoms;
const subscribeDevAtoms = ({listeners}, callback) => {
listeners.add(callback);
return () => listeners.delete(callback);
};
const useDebugState = (store) => {
const [stateMutableSource, , atomsMutableSource] = store;
const atoms = useMutableSource(atomsMutableSource, getDevAtoms, subscribeDevAtoms);
const subscribe = useCallback((state2, callback) => {

@@ -616,3 +633,3 @@ const unsubs = atoms.map((atom) => subscribeAtom(state2, atom, callback));

}, [atoms]);
const state = useMutableSource(store[0], getState, subscribe);
const state = useMutableSource(stateMutableSource, getDevState, subscribe);
useDebugValue([state, atoms], stateToPrintable);

@@ -619,0 +636,0 @@ };

@@ -10,5 +10,7 @@ export { useUpdateAtom } from './utils/useUpdateAtom';

export { useAtomCallback } from './utils/useAtomCallback';
export { freezeAtom, atomFrozenInDev } from './utils/freezeAtom';
export { freezeAtom, freezeAtomCreator } from './utils/freezeAtom';
export { splitAtom } from './utils/splitAtom';
export { atomWithDefault } from './utils/atomWithDefault';
export { waitForAll } from './utils/waitForAll';
export { atomWithHash } from './utils/atomWithHash';
export { atomWithStorage } from './utils/atomWithStorage';

@@ -167,2 +167,3 @@ import { useContext, useCallback, useMemo } from 'react';

const freezeAtomCache = new WeakMap();
const deepFreeze = (obj) => {

@@ -180,13 +181,20 @@ if (typeof obj !== "object" || obj === null)

function freezeAtom(anAtom) {
const deps = [anAtom];
const cachedAtom = getWeakCacheItem(freezeAtomCache, deps);
if (cachedAtom) {
return cachedAtom;
}
const frozenAtom = atom((get) => deepFreeze(get(anAtom)), (_get, set, arg) => set(anAtom, arg));
frozenAtom.scope = anAtom.scope;
setWeakCacheItem(freezeAtomCache, deps, frozenAtom);
return frozenAtom;
}
const atomFrozen = (read, write) => {
const anAtom = atom(read, write);
const origRead = anAtom.read;
anAtom.read = (get) => deepFreeze(origRead(get));
return anAtom;
};
const atomFrozenInDev = typeof process === "object" && process.env.NODE_ENV === "development" ? atomFrozen : atom;
function freezeAtomCreator(createAtom) {
return (...params) => {
const anAtom = createAtom(...params);
const origRead = anAtom.read;
anAtom.read = (get) => deepFreeze(origRead(get));
return anAtom;
};
}

@@ -338,2 +346,59 @@ const splitAtomCache = new WeakMap();

export { RESET, atomFamily, atomFrozenInDev, atomWithDefault, atomWithReducer, atomWithReset, freezeAtom, selectAtom, splitAtom, useAtomCallback, useAtomValue, useReducerAtom, useResetAtom, useUpdateAtom, waitForAll };
function atomWithHash(key, initialValue, serialize = JSON.stringify, deserialize = JSON.parse) {
const anAtom = atom(initialValue, (get, set, update) => {
const newValue = typeof update === "function" ? update(get(anAtom)) : update;
set(anAtom, newValue);
const searchParams = new URLSearchParams(location.hash.slice(1));
searchParams.set(key, serialize(newValue));
location.hash = searchParams.toString();
});
anAtom.onMount = (setAtom) => {
const callback = () => {
const searchParams = new URLSearchParams(location.hash.slice(1));
const str = searchParams.get(key);
if (str !== null) {
setAtom(deserialize(str));
}
};
window.addEventListener("hashchange", callback);
callback();
return () => {
window.removeEventListener("hashchange", callback);
};
};
return anAtom;
}
const defaultStorage = {
getItem: (key) => {
const storedValue = localStorage.getItem(key);
if (storedValue === null) {
throw new Error("no value stored");
}
return JSON.parse(storedValue);
},
setItem: (key, newValue) => {
localStorage.setItem(key, JSON.stringify(newValue));
}
};
function atomWithStorage(key, initialValue, storage = defaultStorage) {
const getInitialValue = () => {
try {
return storage.getItem(key);
} catch {
return initialValue;
}
};
const baseAtom = atom(initialValue);
baseAtom.onMount = (setAtom) => {
Promise.resolve(getInitialValue()).then(setAtom);
};
const anAtom = atom((get) => get(baseAtom), (get, set, update) => {
const newValue = typeof update === "function" ? update(get(baseAtom)) : update;
set(baseAtom, newValue);
storage.setItem(key, newValue);
});
return anAtom;
}
export { RESET, atomFamily, atomWithDefault, atomWithHash, atomWithReducer, atomWithReset, atomWithStorage, freezeAtom, freezeAtomCreator, selectAtom, splitAtom, useAtomCallback, useAtomValue, useReducerAtom, useResetAtom, useUpdateAtom, waitForAll };

@@ -1,3 +0,3 @@

import { atom, Atom } from 'jotai';
export declare function freezeAtom<T extends Atom<any>>(anAtom: T): T;
export declare const atomFrozenInDev: typeof atom;
import { Atom } from 'jotai';
export declare function freezeAtom<AtomType extends Atom<any>>(anAtom: AtomType): AtomType;
export declare function freezeAtomCreator<CreateAtom extends (...params: any[]) => Atom<any>>(createAtom: CreateAtom): CreateAtom;

@@ -330,3 +330,2 @@ 'use strict';

if (errorOrPromise instanceof Promise) {
scheduleReadAtomState(state, atom, errorOrPromise);
promise = errorOrPromise;

@@ -723,5 +722,5 @@ } else if (errorOrPromise instanceof Error) {

var createStore = function createStore(initialValues, newAtomReceiver) {
var state = createState(initialValues, newAtomReceiver);
var mutableSource = createMutableSource(state, function () {
var createStoreForProduction = function createStoreForProduction(initialValues) {
var state = createState(initialValues);
var stateMutableSource = createMutableSource(state, function () {
return state.v;

@@ -734,4 +733,31 @@ });

return [mutableSource, updateAtom];
return [stateMutableSource, updateAtom];
};
var createStoreForDevelopment = function createStoreForDevelopment(initialValues) {
var atomsStore = {
atoms: [],
listeners: new Set()
};
var state = createState(initialValues, function (newAtom) {
atomsStore.atoms = [].concat(atomsStore.atoms, [newAtom]);
atomsStore.listeners.forEach(function (listener) {
return listener();
});
});
var stateMutableSource = createMutableSource(state, function () {
return state.v;
});
var updateAtom = function updateAtom(atom, update) {
return writeAtom(state, atom, update);
};
var atomsMutableSource = createMutableSource(atomsStore, function () {
return atomsStore.atoms;
});
return [stateMutableSource, updateAtom, atomsMutableSource];
};
var createStore = typeof process === 'object' && process.env.NODE_ENV !== 'production' ? createStoreForDevelopment : createStoreForProduction;
var StoreContextMap = new Map();

@@ -752,16 +778,8 @@ var getStoreContext = function getStoreContext(scope) {

if (typeof process === 'object' && process.env.NODE_ENV !== 'production') {
var atomsRef = react.useRef([]);
if (storeRef.current === null) {
storeRef.current = createStore(initialValues);
}
if (storeRef.current === null) {
storeRef.current = createStore(initialValues, function (newAtom) {
atomsRef.current.push(newAtom);
});
}
useDebugState(storeRef.current, atomsRef.current);
} else {
if (storeRef.current === null) {
storeRef.current = createStore(initialValues);
}
if (typeof process === 'object' && process.env.NODE_ENV !== 'production' && isDevStore(storeRef.current)) {
useDebugState(storeRef.current);
}

@@ -798,7 +816,25 @@

var getState = function getState(state) {
var isDevStore = function isDevStore(store) {
return store.length > 2;
};
var getDevState = function getDevState(state) {
return _extends({}, state);
};
var getDevAtoms = function getDevAtoms(_ref3) {
var atoms = _ref3.atoms;
return atoms;
};
var subscribeDevAtoms = function subscribeDevAtoms(_ref4, callback) {
var listeners = _ref4.listeners;
listeners.add(callback);
return function () {
return listeners.delete(callback);
};
};
var useDebugState = function useDebugState(store, atoms) {
var useDebugState = function useDebugState(store) {
var stateMutableSource = store[0],
atomsMutableSource = store[2];
var atoms = useMutableSource(atomsMutableSource, getDevAtoms, subscribeDevAtoms);
var subscribe = react.useCallback(function (state, callback) {

@@ -814,3 +850,3 @@ var unsubs = atoms.map(function (atom) {

}, [atoms]);
var state = useMutableSource(store[0], getState, subscribe);
var state = useMutableSource(stateMutableSource, getDevState, subscribe);
react.useDebugValue([state, atoms], stateToPrintable);

@@ -817,0 +853,0 @@ };

{
"name": "jotai",
"private": false,
"version": "0.16.3",
"version": "0.16.4",
"description": "👻 Next gen state management that will spook you",

@@ -6,0 +6,0 @@ "main": "index.js",

@@ -171,8 +171,10 @@ <p align="center">

- Introduction
- [Concepts](https://docs.pmnd.rs/jotai/concepts)
- [Getting Started](https://docs.pmnd.rs/jotai/getting-started)
- [Async](https://docs.pmnd.rs/jotai/async)
- [Comparison](https://docs.pmnd.rs/jotai/comparison)
- [Showcase](https://docs.pmnd.rs/jotai/showcase)
- Overview
- [Introduction](https://docs.pmnd.rs/jotai/introduction)
- Basics
- [Concepts](https://docs.pmnd.rs/jotai/basics/concepts)
- [Primitives](https://docs.pmnd.rs/jotai/basics/primitives)
- [Async](https://docs.pmnd.rs/jotai/basics/async)
- [Comparison](https://docs.pmnd.rs/jotai/basics/comparison)
- [Showcase](https://docs.pmnd.rs/jotai/basics/showcase)
- Guides

@@ -189,10 +191,10 @@ - [TypeScript](https://docs.pmnd.rs/jotai/guides/typescript)

- [Devtools](https://docs.pmnd.rs/jotai/api/devtools)
- [Immer](https://docs.pmnd.rs/jotai/api/immer) ([immer](https://github.com/immerjs/immer) integration)
- [Optics](https://docs.pmnd.rs/jotai/api/optics) ([optics-ts](https://github.com/akheron/optics-ts) integration)
- [Query](https://docs.pmnd.rs/jotai/api/query) ([react-query](https://github.com/tannerlinsley/react-query) integration)
- [XState](https://docs.pmnd.rs/jotai/api/xstate) ([xstate](https://github.com/davidkpiano/xstate) integration)
- [Valtio](https://docs.pmnd.rs/jotai/api/valtio) ([valtio](https://github.com/pmndrs/valtio) integration)
- [Zustand](https://docs.pmnd.rs/jotai/api/zustand) ([zustand](https://github.com/pmndrs/zustand) integration)
- [Redux](https://docs.pmnd.rs/jotai/api/redux) ([redux](https://github.com/reduxjs/redux) integration)
- [Immer](https://docs.pmnd.rs/jotai/integrations/immer) ([immer](https://github.com/immerjs/immer) integration)
- [Optics](https://docs.pmnd.rs/jotai/integrations/optics) ([optics-ts](https://github.com/akheron/optics-ts) integration)
- [Query](https://docs.pmnd.rs/jotai/integrations/query) ([react-query](https://github.com/tannerlinsley/react-query) integration)
- [XState](https://docs.pmnd.rs/jotai/integrations/xstate) ([xstate](https://github.com/davidkpiano/xstate) integration)
- [Valtio](https://docs.pmnd.rs/jotai/integrations/valtio) ([valtio](https://github.com/pmndrs/valtio) integration)
- [Zustand](https://docs.pmnd.rs/jotai/integrations/zustand) ([zustand](https://github.com/pmndrs/zustand) integration)
- [Redux](https://docs.pmnd.rs/jotai/integrations/redux) ([redux](https://github.com/reduxjs/redux) integration)
- Advanced Recipes
- [Large Objects](https://docs.pmnd.rs/jotai/advanced-recipes/large-objects)
import { Context } from 'react';
import { AnyAtom, WritableAtom, Scope } from './types';
import { NewAtomReceiver } from './vanilla';
import { State } from './vanilla';
import { createMutableSource } from './useMutableSource';
declare type MutableSource = ReturnType<typeof createMutableSource>;
export declare type Store = [
/*mutableSource*/ MutableSource,
/*updateAtom*/ <Value, Update>(atom: WritableAtom<Value, Update>, update: Update) => void | Promise<void>
declare type MutableSource<_Target> = ReturnType<typeof createMutableSource>;
declare type UpdateAtom = <Value, Update>(atom: WritableAtom<Value, Update>, update: Update) => void | Promise<void>;
declare type StoreForProduction = [
/*stateMutableSource*/ MutableSource<State>,
/*updateAtom*/ UpdateAtom
];
export declare const createStore: (initialValues?: Iterable<readonly [
export declare type StoreForDevelopment = [
/*stateMutableSource*/ MutableSource<State>,
/*updateAtom*/ UpdateAtom,
/*atomsMutableSource*/ MutableSource<{
atoms: AnyAtom[];
listeners: Set<() => void>;
}>
];
export declare type Store = StoreForProduction | StoreForDevelopment;
declare type CreateStore = (initialValues?: Iterable<readonly [
AnyAtom,
unknown
]> | undefined, newAtomReceiver?: NewAtomReceiver | undefined) => Store;
]>) => Store;
export declare const createStore: CreateStore;
declare type StoreContext = Context<Store>;
export declare const getStoreContext: (scope?: Scope | undefined) => StoreContext;
export {};
import React from 'react';
import { AnyAtom, Scope } from './types';
import { AtomState, State } from './vanilla';
export declare const Provider: React.FC<{

@@ -10,1 +11,18 @@ initialValues?: Iterable<readonly [

}>;
export declare const getDevState: (state: State) => {
n?: ((newAtom: AnyAtom) => void) | undefined;
v: number;
a: WeakMap<AnyAtom, AtomState<unknown>>;
m: WeakMap<AnyAtom, {
l: Set<() => void>;
d: Set<AnyAtom>;
u: void | import("./types").OnUnmount;
}>;
p: Set<AnyAtom>;
};
export declare const getDevAtoms: ({ atoms }: {
atoms: AnyAtom[];
}) => AnyAtom[];
export declare const subscribeDevAtoms: ({ listeners }: {
listeners: Set<() => void>;
}, callback: () => void) => () => boolean;

@@ -31,3 +31,3 @@ import { Atom, WritableAtom, AnyAtom, OnUnmount } from './types';

declare type MountedMap = WeakMap<AnyAtom, Mounted>;
export declare type NewAtomReceiver = (newAtom: AnyAtom) => void;
declare type NewAtomReceiver = (newAtom: AnyAtom) => void;
declare type StateVersion = number;

@@ -34,0 +34,0 @@ declare type PendingAtoms = Set<AnyAtom>;

export { useAtomDevtools } from './devtools/useAtomDevtools';
export { useAtomsSnapshot } from './devtools/useAtomsSnapshot';
import { Context } from 'react';
import { AnyAtom, WritableAtom, Scope } from './types';
import { NewAtomReceiver } from './vanilla';
import { State } from './vanilla';
import { createMutableSource } from './useMutableSource';
declare type MutableSource = ReturnType<typeof createMutableSource>;
export declare type Store = [
/*mutableSource*/ MutableSource,
/*updateAtom*/ <Value, Update>(atom: WritableAtom<Value, Update>, update: Update) => void | Promise<void>
declare type MutableSource<_Target> = ReturnType<typeof createMutableSource>;
declare type UpdateAtom = <Value, Update>(atom: WritableAtom<Value, Update>, update: Update) => void | Promise<void>;
declare type StoreForProduction = [
/*stateMutableSource*/ MutableSource<State>,
/*updateAtom*/ UpdateAtom
];
export declare const createStore: (initialValues?: Iterable<readonly [
export declare type StoreForDevelopment = [
/*stateMutableSource*/ MutableSource<State>,
/*updateAtom*/ UpdateAtom,
/*atomsMutableSource*/ MutableSource<{
atoms: AnyAtom[];
listeners: Set<() => void>;
}>
];
export declare type Store = StoreForProduction | StoreForDevelopment;
declare type CreateStore = (initialValues?: Iterable<readonly [
AnyAtom,
unknown
]> | undefined, newAtomReceiver?: NewAtomReceiver | undefined) => Store;
]>) => Store;
export declare const createStore: CreateStore;
declare type StoreContext = Context<Store>;
export declare const getStoreContext: (scope?: Scope | undefined) => StoreContext;
export {};
import React from 'react';
import { AnyAtom, Scope } from './types';
import { AtomState, State } from './vanilla';
export declare const Provider: React.FC<{

@@ -10,1 +11,18 @@ initialValues?: Iterable<readonly [

}>;
export declare const getDevState: (state: State) => {
n?: ((newAtom: AnyAtom) => void) | undefined;
v: number;
a: WeakMap<AnyAtom, AtomState<unknown>>;
m: WeakMap<AnyAtom, {
l: Set<() => void>;
d: Set<AnyAtom>;
u: void | import("./types").OnUnmount;
}>;
p: Set<AnyAtom>;
};
export declare const getDevAtoms: ({ atoms }: {
atoms: AnyAtom[];
}) => AnyAtom[];
export declare const subscribeDevAtoms: ({ listeners }: {
listeners: Set<() => void>;
}, callback: () => void) => () => boolean;

@@ -31,3 +31,3 @@ import { Atom, WritableAtom, AnyAtom, OnUnmount } from './types';

declare type MountedMap = WeakMap<AnyAtom, Mounted>;
export declare type NewAtomReceiver = (newAtom: AnyAtom) => void;
declare type NewAtomReceiver = (newAtom: AnyAtom) => void;
declare type StateVersion = number;

@@ -34,0 +34,0 @@ declare type PendingAtoms = Set<AnyAtom>;

export { useAtomDevtools } from './devtools/useAtomDevtools';
export { useAtomsSnapshot } from './devtools/useAtomsSnapshot';

@@ -10,5 +10,7 @@ export { useUpdateAtom } from './utils/useUpdateAtom';

export { useAtomCallback } from './utils/useAtomCallback';
export { freezeAtom, atomFrozenInDev } from './utils/freezeAtom';
export { freezeAtom, freezeAtomCreator } from './utils/freezeAtom';
export { splitAtom } from './utils/splitAtom';
export { atomWithDefault } from './utils/atomWithDefault';
export { waitForAll } from './utils/waitForAll';
export { atomWithHash } from './utils/atomWithHash';
export { atomWithStorage } from './utils/atomWithStorage';

@@ -1,3 +0,3 @@

import { atom, Atom } from 'jotai';
export declare function freezeAtom<T extends Atom<any>>(anAtom: T): T;
export declare const atomFrozenInDev: typeof atom;
import { Atom } from 'jotai';
export declare function freezeAtom<AtomType extends Atom<any>>(anAtom: AtomType): AtomType;
export declare function freezeAtomCreator<CreateAtom extends (...params: any[]) => Atom<any>>(createAtom: CreateAtom): CreateAtom;

@@ -10,5 +10,7 @@ export { useUpdateAtom } from './utils/useUpdateAtom';

export { useAtomCallback } from './utils/useAtomCallback';
export { freezeAtom, atomFrozenInDev } from './utils/freezeAtom';
export { freezeAtom, freezeAtomCreator } from './utils/freezeAtom';
export { splitAtom } from './utils/splitAtom';
export { atomWithDefault } from './utils/atomWithDefault';
export { waitForAll } from './utils/waitForAll';
export { atomWithHash } from './utils/atomWithHash';
export { atomWithStorage } from './utils/atomWithStorage';

@@ -1,3 +0,3 @@

import { atom, Atom } from 'jotai';
export declare function freezeAtom<T extends Atom<any>>(anAtom: T): T;
export declare const atomFrozenInDev: typeof atom;
import { Atom } from 'jotai';
export declare function freezeAtom<AtomType extends Atom<any>>(anAtom: AtomType): AtomType;
export declare function freezeAtomCreator<CreateAtom extends (...params: any[]) => Atom<any>>(createAtom: CreateAtom): CreateAtom;

@@ -10,5 +10,7 @@ export { useUpdateAtom } from './utils/useUpdateAtom';

export { useAtomCallback } from './utils/useAtomCallback';
export { freezeAtom, atomFrozenInDev } from './utils/freezeAtom';
export { freezeAtom, freezeAtomCreator } from './utils/freezeAtom';
export { splitAtom } from './utils/splitAtom';
export { atomWithDefault } from './utils/atomWithDefault';
export { waitForAll } from './utils/waitForAll';
export { atomWithHash } from './utils/atomWithHash';
export { atomWithStorage } from './utils/atomWithStorage';

@@ -287,2 +287,4 @@ 'use strict';

var freezeAtomCache = new WeakMap();
var deepFreeze = function deepFreeze(obj) {

@@ -303,2 +305,9 @@ if (typeof obj !== 'object' || obj === null) return;

function freezeAtom(anAtom) {
var deps = [anAtom];
var cachedAtom = getWeakCacheItem(freezeAtomCache, deps);
if (cachedAtom) {
return cachedAtom;
}
var frozenAtom = jotai.atom(function (get) {

@@ -310,18 +319,18 @@ return deepFreeze(get(anAtom));

frozenAtom.scope = anAtom.scope;
setWeakCacheItem(freezeAtomCache, deps, frozenAtom);
return frozenAtom;
}
function freezeAtomCreator(createAtom) {
return function () {
var anAtom = createAtom.apply(void 0, arguments);
var origRead = anAtom.read;
var atomFrozen = function atomFrozen(read, write) {
var anAtom = jotai.atom(read, write);
var origRead = anAtom.read;
anAtom.read = function (get) {
return deepFreeze(origRead(get));
};
anAtom.read = function (get) {
return deepFreeze(origRead(get));
return anAtom;
};
}
return anAtom;
};
var atomFrozenInDev = typeof process === 'object' && process.env.NODE_ENV === 'development' ? atomFrozen : jotai.atom;
var splitAtomCache = new WeakMap();

@@ -508,9 +517,91 @@

function atomWithHash(key, initialValue, serialize, deserialize) {
if (serialize === void 0) {
serialize = JSON.stringify;
}
if (deserialize === void 0) {
deserialize = JSON.parse;
}
var anAtom = jotai.atom(initialValue, function (get, set, update) {
var newValue = typeof update === 'function' ? update(get(anAtom)) : update;
set(anAtom, newValue);
var searchParams = new URLSearchParams(location.hash.slice(1));
searchParams.set(key, serialize(newValue));
location.hash = searchParams.toString();
});
anAtom.onMount = function (setAtom) {
var callback = function callback() {
var searchParams = new URLSearchParams(location.hash.slice(1));
var str = searchParams.get(key);
if (str !== null) {
setAtom(deserialize(str));
}
};
window.addEventListener('hashchange', callback);
callback();
return function () {
window.removeEventListener('hashchange', callback);
};
};
return anAtom;
}
var defaultStorage = {
getItem: function getItem(key) {
var storedValue = localStorage.getItem(key);
if (storedValue === null) {
throw new Error('no value stored');
}
return JSON.parse(storedValue);
},
setItem: function setItem(key, newValue) {
localStorage.setItem(key, JSON.stringify(newValue));
}
};
function atomWithStorage(key, initialValue, storage) {
if (storage === void 0) {
storage = defaultStorage;
}
var getInitialValue = function getInitialValue() {
try {
return storage.getItem(key);
} catch (_unused) {
return initialValue;
}
};
var baseAtom = jotai.atom(initialValue);
baseAtom.onMount = function (setAtom) {
Promise.resolve(getInitialValue()).then(setAtom);
};
var anAtom = jotai.atom(function (get) {
return get(baseAtom);
}, function (get, set, update) {
var newValue = typeof update === 'function' ? update(get(baseAtom)) : update;
set(baseAtom, newValue);
storage.setItem(key, newValue);
});
return anAtom;
}
exports.RESET = RESET;
exports.atomFamily = atomFamily;
exports.atomFrozenInDev = atomFrozenInDev;
exports.atomWithDefault = atomWithDefault;
exports.atomWithHash = atomWithHash;
exports.atomWithReducer = atomWithReducer;
exports.atomWithReset = atomWithReset;
exports.atomWithStorage = atomWithStorage;
exports.freezeAtom = freezeAtom;
exports.freezeAtomCreator = freezeAtomCreator;
exports.selectAtom = selectAtom;

@@ -517,0 +608,0 @@ exports.splitAtom = splitAtom;

@@ -1,3 +0,3 @@

import { atom, Atom } from 'jotai';
export declare function freezeAtom<T extends Atom<any>>(anAtom: T): T;
export declare const atomFrozenInDev: typeof atom;
import { Atom } from 'jotai';
export declare function freezeAtom<AtomType extends Atom<any>>(anAtom: AtomType): AtomType;
export declare function freezeAtomCreator<CreateAtom extends (...params: any[]) => Atom<any>>(createAtom: CreateAtom): CreateAtom;
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc