UNPKG

6.48 kBJavaScriptView Raw
1import { QueryClient, QueryObserver, InfiniteQueryObserver, isCancelledError } from 'react-query';
2import { atom } from 'jotai';
3
4const queryClientAtom = atom(new QueryClient());
5
6function atomWithQuery(createQuery, getQueryClient = (get) => get(queryClientAtom)) {
7 const queryDataAtom = atom((get) => {
8 const queryClient = getQueryClient(get);
9 const options = typeof createQuery === "function" ? createQuery(get) : createQuery;
10 let settlePromise = null;
11 const getInitialData = () => {
12 let data = queryClient.getQueryData(options.queryKey);
13 if (data === void 0 && options.initialData) {
14 data = typeof options.initialData === "function" ? options.initialData() : options.initialData;
15 }
16 return data;
17 };
18 const initialData = getInitialData();
19 const dataAtom = atom(initialData === void 0 && options.enabled !== false ? new Promise((resolve, reject) => {
20 settlePromise = (data, err) => {
21 if (err) {
22 reject(err);
23 } else {
24 resolve(data);
25 }
26 };
27 }) : initialData);
28 let setData = () => {
29 throw new Error("atomWithQuery: setting data without mount");
30 };
31 const listener = (result) => {
32 if (result.error) {
33 if (settlePromise) {
34 settlePromise(void 0, result.error);
35 settlePromise = null;
36 } else {
37 setData(Promise.reject(result.error));
38 }
39 return;
40 }
41 if (result.data === void 0) {
42 return;
43 }
44 if (settlePromise) {
45 settlePromise(result.data);
46 settlePromise = null;
47 } else {
48 setData(result.data);
49 }
50 };
51 const defaultedOptions = queryClient.defaultQueryObserverOptions(options);
52 if (initialData === void 0 && options.enabled !== false) {
53 if (typeof defaultedOptions.staleTime !== "number") {
54 defaultedOptions.staleTime = 1e3;
55 }
56 }
57 const observer = new QueryObserver(queryClient, defaultedOptions);
58 if (initialData === void 0 && options.enabled !== false) {
59 observer.fetchOptimistic(defaultedOptions).then(listener).catch((error) => listener({ error }));
60 }
61 dataAtom.onMount = (update) => {
62 setData = update;
63 if (options.enabled !== false) {
64 return observer.subscribe(listener);
65 }
66 };
67 return { dataAtom, observer };
68 }, (get, set, action) => {
69 switch (action.type) {
70 case "refetch": {
71 const { dataAtom, observer } = get(queryDataAtom);
72 set(dataAtom, new Promise(() => {
73 }));
74 const p = Promise.resolve().then(() => observer.refetch({ cancelRefetch: true })).then(() => {
75 });
76 return p;
77 }
78 default:
79 throw new Error("no action");
80 }
81 });
82 const queryAtom = atom((get) => {
83 const { dataAtom } = get(queryDataAtom);
84 return get(dataAtom);
85 }, (_get, set, action) => set(queryDataAtom, action));
86 return queryAtom;
87}
88
89var __getOwnPropSymbols = Object.getOwnPropertySymbols;
90var __hasOwnProp = Object.prototype.hasOwnProperty;
91var __propIsEnum = Object.prototype.propertyIsEnumerable;
92var __objRest = (source, exclude) => {
93 var target = {};
94 for (var prop in source)
95 if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
96 target[prop] = source[prop];
97 if (source != null && __getOwnPropSymbols)
98 for (var prop of __getOwnPropSymbols(source)) {
99 if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
100 target[prop] = source[prop];
101 }
102 return target;
103};
104function atomWithInfiniteQuery(createQuery, getQueryClient = (get) => get(queryClientAtom)) {
105 const queryDataAtom = atom((get) => {
106 const queryClient = getQueryClient(get);
107 const options = typeof createQuery === "function" ? createQuery(get) : createQuery;
108 let settlePromise = null;
109 const getInitialData = () => {
110 let data = queryClient.getQueryData(options.queryKey);
111 if (data === void 0 && options.initialData) {
112 data = typeof options.initialData === "function" ? options.initialData() : options.initialData;
113 }
114 return data;
115 };
116 const initialData = getInitialData();
117 const dataAtom = atom(initialData === void 0 && options.enabled !== false ? new Promise((resolve, reject) => {
118 settlePromise = (data, err) => {
119 if (err) {
120 reject(err);
121 } else {
122 resolve(data);
123 }
124 };
125 }) : initialData);
126 let setData = () => {
127 throw new Error("atomWithInfiniteQuery: setting data without mount");
128 };
129 const listener = (result) => {
130 if (result.error && !isCancelledError(result.error)) {
131 if (settlePromise) {
132 settlePromise(void 0, result.error);
133 settlePromise = null;
134 } else {
135 setData(Promise.reject(result.error));
136 }
137 return;
138 }
139 if (result.data === void 0) {
140 return;
141 }
142 if (settlePromise) {
143 settlePromise(result.data);
144 settlePromise = null;
145 } else {
146 setData(result.data);
147 }
148 };
149 const defaultedOptions = queryClient.defaultQueryObserverOptions(options);
150 if (initialData === void 0 && options.enabled !== false) {
151 if (typeof defaultedOptions.staleTime !== "number") {
152 defaultedOptions.staleTime = 1e3;
153 }
154 }
155 const observer = new InfiniteQueryObserver(queryClient, defaultedOptions);
156 if (initialData === void 0 && options.enabled !== false) {
157 observer.fetchOptimistic(defaultedOptions).then(listener).catch((error) => listener({ error }));
158 }
159 dataAtom.onMount = (update) => {
160 setData = update;
161 if (options.enabled !== false) {
162 return observer.subscribe(listener);
163 }
164 };
165 return { dataAtom, observer, options };
166 }, (get, _set, action) => {
167 const { observer } = get(queryDataAtom);
168 switch (action.type) {
169 case "refetch": {
170 const _a = action, options = __objRest(_a, ["type"]);
171 void observer.refetch(options);
172 break;
173 }
174 case "fetchPreviousPage": {
175 void observer.fetchPreviousPage();
176 break;
177 }
178 case "fetchNextPage": {
179 void observer.fetchNextPage();
180 break;
181 }
182 }
183 });
184 const queryAtom = atom((get) => {
185 const { dataAtom } = get(queryDataAtom);
186 return get(dataAtom);
187 }, (_get, set, action) => set(queryDataAtom, action));
188 return queryAtom;
189}
190
191export { atomWithInfiniteQuery, atomWithQuery, queryClientAtom };