UNPKG

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