Skip to content

Commit 5b576e3

Browse files
committed
Add some methods
1 parent c026b3a commit 5b576e3

File tree

8 files changed

+1006
-100
lines changed

8 files changed

+1006
-100
lines changed

.eslintrc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"root": true,
3+
"extends": ["plugin:react-hooks/recommended"],
4+
"parser": "@typescript-eslint/parser",
5+
"plugins": ["@typescript-eslint", "react-hooks"]
6+
}

example-app/src/App.tsx

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,17 @@ import { render } from "react-dom";
33
import type { ApiType } from "../server-api";
44
import axios from "axios";
55
import { createBifrost } from "bifrost";
6-
import { QueryClient, QueryClientProvider } from "react-query";
6+
import {
7+
QueryClient,
8+
QueryClientProvider,
9+
useMutation,
10+
useQueryClient,
11+
} from "react-query";
712

813
const queryClient = new QueryClient();
914

10-
const { query, useQuery } = createBifrost<ApiType>({
15+
const Bifrost = createBifrost<ApiType>({
16+
queryClient,
1117
doFetch: async ({ argument, path }) => {
1218
return axios
1319
.post(`http://localhost:8000/${path.join("/")}`, { argument })
@@ -25,19 +31,35 @@ function App() {
2531

2632
function AppInner() {
2733
useEffect(() => {
28-
query.accounts.someCoolAccountsFn({ foo: "asdf" }).then((data) => {
34+
Bifrost.sdk.accounts.someCoolAccountsFn({ foo: "asdf" }).then((data) => {
2935
console.log("Fetched data!", data.someValue);
3036
});
3137
}, []);
3238

33-
const r = useQuery().accounts.anotherCoolAccountsFn(
39+
const r2 = Bifrost.useSDKMutation().accounts.someCoolAccountsFn();
40+
41+
const qc = useQueryClient();
42+
43+
const r = Bifrost.useSDK().accounts.anotherCoolAccountsFn(
3444
{ bar: 123, blah: "asdf" },
3545
{
3646
select: (a) => a.waddup,
3747
}
3848
);
3949

40-
return <div>Hello world! {r.data}</div>;
50+
return (
51+
<div
52+
onClick={() => {
53+
const asdf = Bifrost.getSDKQueryKey.accounts.anotherCoolAccountsFn({
54+
blah: "asdf",
55+
bar: 123,
56+
});
57+
qc.invalidateQueries();
58+
}}
59+
>
60+
Hello world! {r.data}
61+
</div>
62+
);
4163
}
4264

4365
render(<App />, document.getElementById("root"));

example-app/yarn.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -845,7 +845,7 @@ fast-redact@^3.0.0:
845845
resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.0.2.tgz#c940ba7162dde3aeeefc522926ae8c5231412904"
846846
integrity sha512-YN+CYfCVRVMUZOUPeinHNKgytM1wPI/C/UCLEi56EsY2dwwvI00kIJHJoI7pMVqGoMew8SMZ2SSfHKHULHXDsg==
847847

848-
fast-safe-stringify@2.1.1, fast-safe-stringify@^2.0.8:
848+
fast-safe-stringify@^2.0.8:
849849
version "2.1.1"
850850
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884"
851851
integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@
1616
"author": "",
1717
"license": "ISC",
1818
"devDependencies": {
19+
"@typescript-eslint/eslint-plugin": "^5.4.0",
20+
"@typescript-eslint/parser": "^5.4.0",
1921
"esbuild": "^0.13.15",
22+
"eslint": "^8.3.0",
23+
"eslint-plugin-react-hooks": "^4.3.0",
2024
"fast-safe-stringify": "2.1.1",
2125
"npm-run-all": "^4.1.5",
2226
"react-query": "^3.33.5",
@@ -25,6 +29,7 @@
2529
},
2630
"dependencies": {},
2731
"peerDependencies": {
32+
"react": "*",
2833
"react-query": "*"
2934
}
3035
}

src/index.ts

Lines changed: 171 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,116 +1,204 @@
11
import safeStringify from "fast-safe-stringify";
22
import {
33
DeepAsyncFnRecord,
4+
TypedGetSDKQueryKey,
45
Opts,
5-
TypedQuery,
6-
TypedUseInfiniteQuery,
7-
TypedUseQuery,
6+
TypedSDK as TypedSDK,
7+
TypedUseInfiniteQuery as TypedUseInfiniteSDK,
8+
TypedUseQuery as TypedUseSDK,
9+
TypedUseSDKMutation,
810
} from "./types";
911
import {
1012
useInfiniteQuery,
1113
UseInfiniteQueryOptions,
14+
useMutation,
15+
UseMutationOptions,
1216
useQuery,
1317
UseQueryOptions,
1418
} from "react-query";
15-
import { createBifrostQuery } from "./server";
16-
17-
export { createBifrostQuery } from "./server";
19+
import { createBifrostSDK } from "./server";
1820

1921
export function createBifrost<Endpoints extends DeepAsyncFnRecord<Endpoints>>(
2022
opts: Opts
2123
): {
22-
query: TypedQuery<Endpoints>;
23-
useQuery: () => TypedUseQuery<Endpoints>;
24-
useInfiniteQuery: () => TypedUseInfiniteQuery<Endpoints>;
25-
// useQuerys: () =>
24+
sdk: TypedSDK<Endpoints>;
25+
sdkPrefetch: TypedSDK<Endpoints>;
26+
getSDKQueryKey: TypedGetSDKQueryKey<Endpoints>;
27+
useSDK: () => TypedUseSDK<Endpoints>;
28+
useInfiniteSDK: () => TypedUseInfiniteSDK<Endpoints>;
29+
useSDKMutation: () => TypedUseSDKMutation<Endpoints>;
2630
} {
2731
return {
28-
query: createBifrostQuery<Endpoints>(opts),
29-
useQuery: createBifrostUseQuery<Endpoints>(opts),
30-
useInfiniteQuery: createBifrostUseInfiniteQuery<Endpoints>(opts),
32+
sdk: createBifrostSDK<Endpoints>(opts),
33+
sdkPrefetch: createBifrostSDKPrefetch<Endpoints>(opts),
34+
getSDKQueryKey: createGetSDKQueryKey<Endpoints>(opts),
35+
useSDK: createBifrostUseSDK<Endpoints>(opts),
36+
useInfiniteSDK: createBifrostUseInfiniteSDK<Endpoints>(opts),
37+
useSDKMutation: createBifrostUseSDKMutation<Endpoints>(opts),
3138
};
3239
}
3340

34-
export function createBifrostUseQuery<
41+
export function createBifrostUseSDK<
3542
Endpoints extends DeepAsyncFnRecord<Endpoints>
36-
>(opts: Opts): () => TypedUseQuery<Endpoints> {
37-
const getNextUseQuery = (p: { path: string[] }): any => {
38-
return new Proxy(
39-
() => {}, //use function as base, so that it can be called...
40-
{
41-
apply(__, ___, args) {
42-
const argument = args[0] as any;
43-
44-
const extraQueryOpts = (args[1] || {}) as UseQueryOptions;
45-
const queryKey = [...p.path, safeStringify.stableStringify(argument)];
46-
47-
const queryOpts: UseQueryOptions = {
48-
queryKey,
49-
queryFn: ({ signal, queryKey, meta, pageParam }) =>
50-
opts.doFetch({
51-
argument,
52-
path: p.path,
53-
signal,
54-
queryKey: queryKey as any,
55-
meta,
56-
pageParam,
57-
}),
58-
...extraQueryOpts,
59-
};
60-
return useQuery(queryOpts);
61-
},
62-
get(__, prop) {
63-
return getNextUseQuery({
64-
path: p.path.concat(prop.toString()),
65-
});
66-
},
67-
}
68-
);
43+
>(opts: Opts): () => TypedUseSDK<Endpoints> {
44+
const getNextUseSDK = (p: { path: string[] }): any => {
45+
return new Proxy(() => {}, {
46+
apply(__, ___, args) {
47+
const argument = args[0] as any;
48+
49+
const extraQueryOpts = (args[1] || {}) as UseQueryOptions;
50+
51+
const queryOpts: UseQueryOptions = {
52+
queryKey: getQueryKey(p.path, argument),
53+
queryFn: ({ signal, queryKey, meta, pageParam }) =>
54+
opts.doFetch({
55+
argument,
56+
path: p.path,
57+
signal,
58+
queryKey: queryKey as any,
59+
meta,
60+
pageParam,
61+
}),
62+
...extraQueryOpts,
63+
};
64+
65+
// eslint-disable-next-line react-hooks/rules-of-hooks
66+
return useQuery(queryOpts);
67+
},
68+
get(__, prop) {
69+
return getNextUseSDK({
70+
path: p.path.concat(prop.toString()),
71+
});
72+
},
73+
});
6974
};
7075

71-
const useQueryRet = () => getNextUseQuery({ path: [] });
76+
const useQueryRet = () => getNextUseSDK({ path: [] });
7277

7378
return useQueryRet;
7479
}
7580

76-
export function createBifrostUseInfiniteQuery<
81+
export function createBifrostUseInfiniteSDK<
7782
Endpoints extends DeepAsyncFnRecord<Endpoints>
78-
>(opts: Opts): () => TypedUseInfiniteQuery<Endpoints> {
79-
const getNextUseQuery = (p: { path: string[] }): any => {
80-
return new Proxy(
81-
() => {}, //use function as base, so that it can be called...
82-
{
83-
apply(__, ___, args) {
84-
const argument = args[0] as any;
85-
86-
const extraQueryOpts = (args[1] || {}) as UseInfiniteQueryOptions;
87-
const queryKey = [...p.path, safeStringify.stableStringify(argument)];
88-
89-
const queryOpts: UseInfiniteQueryOptions = {
90-
queryKey,
91-
queryFn: ({ signal, queryKey, meta, pageParam }) =>
92-
opts.doFetch({
93-
argument,
94-
path: p.path,
95-
signal,
96-
queryKey: queryKey as any,
97-
meta,
98-
pageParam,
99-
}),
100-
...extraQueryOpts,
101-
};
102-
return useInfiniteQuery(queryOpts);
103-
},
104-
get(__, prop) {
105-
return getNextUseQuery({
106-
path: p.path.concat(prop.toString()),
107-
});
108-
},
109-
}
110-
);
83+
>(opts: Opts): () => TypedUseInfiniteSDK<Endpoints> {
84+
const getNextUseInfiniteSDK = (p: { path: string[] }): any => {
85+
return new Proxy(() => {}, {
86+
apply(__, ___, args) {
87+
const argument = args[0] as any;
88+
89+
const extraQueryOpts = (args[1] || {}) as UseInfiniteQueryOptions;
90+
91+
const queryOpts: UseInfiniteQueryOptions = {
92+
queryKey: getQueryKey(p.path, argument),
93+
queryFn: ({ signal, queryKey, meta, pageParam }) =>
94+
opts.doFetch({
95+
argument,
96+
path: p.path,
97+
signal,
98+
queryKey: queryKey as any,
99+
meta,
100+
pageParam,
101+
}),
102+
...extraQueryOpts,
103+
};
104+
// eslint-disable-next-line react-hooks/rules-of-hooks
105+
return useInfiniteQuery(queryOpts);
106+
},
107+
get(__, prop) {
108+
return getNextUseInfiniteSDK({
109+
path: p.path.concat(prop.toString()),
110+
});
111+
},
112+
});
111113
};
112114

113-
const useQueryRet = () => getNextUseQuery({ path: [] });
115+
const useQueryRet = () => getNextUseInfiniteSDK({ path: [] });
114116

115117
return useQueryRet;
116118
}
119+
120+
export function createBifrostUseSDKMutation<
121+
Endpoints extends DeepAsyncFnRecord<Endpoints>
122+
>(opts: Opts): () => TypedUseSDKMutation<Endpoints> {
123+
const getNextUseMutation = (p: { path: string[] }): any => {
124+
return new Proxy(() => {}, {
125+
apply(__, ___, args) {
126+
const argument = args[0] as any;
127+
128+
const extraQueryOpts = (args[1] || {}) as UseMutationOptions;
129+
const mutationKey = getQueryKey(p.path, argument);
130+
131+
const queryOpts: UseMutationOptions = {
132+
mutationKey,
133+
mutationFn: () =>
134+
opts.doFetch({
135+
argument,
136+
path: p.path,
137+
queryKey: mutationKey as any,
138+
}),
139+
...extraQueryOpts,
140+
};
141+
142+
// eslint-disable-next-line react-hooks/rules-of-hooks
143+
return useMutation(queryOpts);
144+
},
145+
get(__, prop) {
146+
return getNextUseMutation({
147+
path: p.path.concat(prop.toString()),
148+
});
149+
},
150+
});
151+
};
152+
153+
const useMutationRet = () => getNextUseMutation({ path: [] });
154+
155+
return useMutationRet;
156+
}
157+
158+
export function createBifrostSDKPrefetch<
159+
Endpoints extends DeepAsyncFnRecord<Endpoints>
160+
>(opts: Opts): TypedSDK<Endpoints> {
161+
const getNextSDK = (path: string[]): any => {
162+
return new Proxy(() => {}, {
163+
apply(__, ___, args) {
164+
const argument = args[0];
165+
const prom = opts.doFetch({ argument, path });
166+
prom.then((resp) => {
167+
opts.queryClient.setQueryData(getQueryKey(path, argument), resp);
168+
});
169+
170+
return prom;
171+
},
172+
get(__, prop) {
173+
return getNextSDK(path.concat(prop.toString()));
174+
},
175+
});
176+
};
177+
178+
return getNextSDK([]);
179+
}
180+
181+
export function createGetSDKQueryKey<
182+
Endpoints extends DeepAsyncFnRecord<Endpoints>
183+
>(opts: Opts): TypedGetSDKQueryKey<Endpoints> {
184+
const getNextGetSDKQueryKey = (path: string[]): any => {
185+
return new Proxy(() => {}, {
186+
apply(__, ___, args) {
187+
return getQueryKey(path, args[0]);
188+
},
189+
get(__, prop) {
190+
return getNextGetSDKQueryKey(path.concat(prop.toString()));
191+
},
192+
});
193+
};
194+
195+
return getNextGetSDKQueryKey([]);
196+
}
197+
198+
function getQueryKey(path: string[], argument: unknown) {
199+
const queryKey = [...path];
200+
if (argument !== "undefined") {
201+
queryKey.push(safeStringify.stableStringify(argument));
202+
}
203+
return queryKey;
204+
}

0 commit comments

Comments
 (0)