UNPKG

5.51 kBJavaScriptView Raw
1import { createClient } from '@urql/core';
2import { atom } from 'jotai';
3import { pipe, subscribe } from 'wonka';
4
5const DEFAULT_URL = (() => {
6 try {
7 return process.env.JOTAI_URQL_DEFAULT_URL;
8 } catch {
9 return void 0;
10 }
11})() || "/graphql";
12const clientAtom = atom(createClient({ url: DEFAULT_URL }));
13
14const isOperationResultWithData$1 = (result) => "data" in result && !result.error;
15function atomWithQuery(createQueryArgs, getClient = (get) => get(clientAtom)) {
16 const queryResultAtom = atom((get) => {
17 const args = createQueryArgs(get);
18 if (args.pause) {
19 return null;
20 }
21 const client = getClient(get);
22 let resolve = null;
23 const baseResultAtom = atom(new Promise((r) => {
24 resolve = r;
25 }));
26 let setResult = () => {
27 throw new Error("setting result without mount");
28 };
29 const listener = (result) => {
30 if (result instanceof Promise) {
31 setResult(result);
32 return;
33 }
34 if (!isOperationResultWithData$1(result)) {
35 throw new Error("result does not have data");
36 }
37 if (resolve) {
38 resolve(result);
39 resolve = null;
40 } else {
41 setResult(result);
42 }
43 };
44 client.query(args.query, args.variables, {
45 ...args.requestPolicy && { requestPolicy: args.requestPolicy },
46 ...args.context
47 }).toPromise().then(listener).catch(() => {
48 });
49 baseResultAtom.onMount = (update) => {
50 setResult = update;
51 };
52 const subscriptionAtom = atom(null);
53 const resultAtom = atom((get2) => get2(baseResultAtom), (get2, set, callback) => {
54 const subscription = pipe(client.query(args.query, args.variables, {
55 ...args.requestPolicy && { requestPolicy: args.requestPolicy },
56 ...args.context
57 }), subscribe(listener));
58 set(subscriptionAtom, subscription);
59 callback(() => {
60 var _a;
61 return (_a = get2(subscriptionAtom)) == null ? void 0 : _a.unsubscribe();
62 });
63 });
64 resultAtom.onMount = (init) => {
65 let cleanup;
66 init((c) => {
67 cleanup = c;
68 });
69 return cleanup;
70 };
71 return { args, client, resultAtom, subscriptionAtom, listener };
72 });
73 const queryAtom = atom((get) => {
74 const queryResult = get(queryResultAtom);
75 if (!queryResult) {
76 return null;
77 }
78 const { resultAtom } = queryResult;
79 return get(resultAtom);
80 }, (get, set, action) => {
81 switch (action.type) {
82 case "reexecute": {
83 const queryResult = get(queryResultAtom);
84 if (!queryResult) {
85 throw new Error("query is paused");
86 }
87 const { args, client, subscriptionAtom, listener } = queryResult;
88 listener(new Promise(() => {
89 }));
90 const newSubscription = pipe(client.query(args.query, args.variables, {
91 ...args.requestPolicy && { requestPolicy: args.requestPolicy },
92 ...args.context,
93 ...action.opts
94 }), subscribe(listener));
95 const oldSubscription = get(subscriptionAtom);
96 oldSubscription == null ? void 0 : oldSubscription.unsubscribe();
97 set(subscriptionAtom, newSubscription);
98 }
99 }
100 });
101 return queryAtom;
102}
103
104function atomWithMutation(createQuery, getClient = (get) => get(clientAtom)) {
105 const operationResultAtom = atom(new Promise(() => {
106 }));
107 const queryResultAtom = atom((get) => get(operationResultAtom), (get, set, action) => {
108 set(operationResultAtom, new Promise(() => {
109 }));
110 const client = getClient(get);
111 const query = createQuery(get);
112 client.mutation(query, action.variables, action.context).toPromise().then((result) => {
113 var _a;
114 set(operationResultAtom, result);
115 (_a = action.callback) == null ? void 0 : _a.call(action, result);
116 }).catch(() => {
117 });
118 });
119 return queryResultAtom;
120}
121
122const isOperationResultWithData = (result) => "data" in result;
123function atomWithSubscription(createSubscriptionArgs, getClient = (get) => get(clientAtom)) {
124 const queryResultAtom = atom((get) => {
125 const args = createSubscriptionArgs(get);
126 if (args.pause) {
127 return { args };
128 }
129 const client = getClient(get);
130 let resolve = null;
131 const resultAtom = atom(new Promise((r) => {
132 resolve = r;
133 }));
134 let setResult = () => {
135 throw new Error("setting result without mount");
136 };
137 let isMounted = false;
138 const listener = (result) => {
139 if (!isOperationResultWithData(result)) {
140 throw new Error("result does not have data");
141 }
142 if (resolve) {
143 if (!isMounted) {
144 subscription == null ? void 0 : subscription.unsubscribe();
145 subscription = null;
146 }
147 resolve(result);
148 resolve = null;
149 } else {
150 setResult(result);
151 }
152 };
153 let subscription = pipe(client.subscription(args.query, args.variables, args.context), subscribe(listener));
154 resultAtom.onMount = (update) => {
155 setResult = update;
156 isMounted = true;
157 if (!subscription) {
158 subscription = pipe(client.subscription(args.query, args.variables, args.context), subscribe(listener));
159 }
160 return () => subscription == null ? void 0 : subscription.unsubscribe();
161 };
162 return { resultAtom, args };
163 });
164 const queryAtom = atom((get) => {
165 const { resultAtom } = get(queryResultAtom);
166 return resultAtom ? get(resultAtom) : null;
167 });
168 return queryAtom;
169}
170
171export { atomWithMutation, atomWithQuery, atomWithSubscription, clientAtom };