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