UNPKG

2.88 kBJavaScriptView Raw
1import ReactExports, { createContext, useContext, useRef, createElement, useReducer, useEffect, useDebugValue, useCallback } from 'react';
2import { getDefaultStore, createStore } from 'jotai/vanilla';
3
4const StoreContext = createContext(void 0);
5const useStore = (options) => {
6 const store = useContext(StoreContext);
7 return (options == null ? void 0 : options.store) || store || getDefaultStore();
8};
9const Provider = ({
10 children,
11 store
12}) => {
13 const storeRef = useRef();
14 if (!store && !storeRef.current) {
15 storeRef.current = createStore();
16 }
17 return createElement(
18 StoreContext.Provider,
19 {
20 value: store || storeRef.current
21 },
22 children
23 );
24};
25
26const isPromiseLike = (x) => typeof (x == null ? void 0 : x.then) === "function";
27const use = ReactExports.use || ((promise) => {
28 if (promise.status === "pending") {
29 throw promise;
30 } else if (promise.status === "fulfilled") {
31 return promise.value;
32 } else if (promise.status === "rejected") {
33 throw promise.reason;
34 } else {
35 promise.status = "pending";
36 promise.then(
37 (v) => {
38 promise.status = "fulfilled";
39 promise.value = v;
40 },
41 (e) => {
42 promise.status = "rejected";
43 promise.reason = e;
44 }
45 );
46 throw promise;
47 }
48});
49function useAtomValue(atom, options) {
50 const store = useStore(options);
51 const [[valueFromReducer, storeFromReducer, atomFromReducer], rerender] = useReducer(
52 (prev) => {
53 const nextValue = store.get(atom);
54 if (Object.is(prev[0], nextValue) && prev[1] === store && prev[2] === atom) {
55 return prev;
56 }
57 return [nextValue, store, atom];
58 },
59 void 0,
60 () => [store.get(atom), store, atom]
61 );
62 let value = valueFromReducer;
63 if (storeFromReducer !== store || atomFromReducer !== atom) {
64 rerender();
65 value = store.get(atom);
66 }
67 const delay = options == null ? void 0 : options.delay;
68 useEffect(() => {
69 const unsub = store.sub(atom, () => {
70 if (typeof delay === "number") {
71 setTimeout(rerender, delay);
72 return;
73 }
74 rerender();
75 });
76 rerender();
77 return unsub;
78 }, [store, atom, delay]);
79 useDebugValue(value);
80 return isPromiseLike(value) ? use(value) : value;
81}
82
83function useSetAtom(atom, options) {
84 const store = useStore(options);
85 const setAtom = useCallback(
86 (...args) => {
87 if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production" && !("write" in atom)) {
88 throw new Error("not writable atom");
89 }
90 return store.set(atom, ...args);
91 },
92 [store, atom]
93 );
94 return setAtom;
95}
96
97function useAtom(atom, options) {
98 return [
99 useAtomValue(atom, options),
100 // We do wrong type assertion here, which results in throwing an error.
101 useSetAtom(atom, options)
102 ];
103}
104
105export { Provider, useAtom, useAtomValue, useSetAtom, useStore };