Skip to content

Commit 343171b

Browse files
committed
Adding hooks and query client config
1 parent ca9a1b8 commit 343171b

10 files changed

Lines changed: 355 additions & 67 deletions

examples/src/App.res

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,21 @@ let fetchTodo = id =>
2525

2626
@react.component
2727
let make = () => {
28-
let result = ReactQuery.useQueries([
29-
ReactQuery.queryOptions(~queryKey="/todo-1", ~queryFn=_ => fetchTodo(1), ()),
30-
ReactQuery.queryOptions(~queryKey="/todo-2", ~queryFn=_ => fetchTodo(2), ()),
31-
])
32-
28+
let client = ReactQuery.useQueryClient()
29+
let isFetching = ReactQuery.useIsFetchingWithKeys("/todo")
30+
let result = ReactQuery.useQuery(
31+
ReactQuery.queryOptions(
32+
~queryKey="/todo-1",
33+
~queryFn=_ => fetchTodo(1),
34+
~refetchIntervalInBackground=false,
35+
(),
36+
),
37+
)
38+
Js.log(client)
3339
switch result {
34-
| [{data: Some(value)}, {data: Some(value2)}] => Js.log2(value, value2)
40+
| {data: Some(value)} => Js.log(value.title)
3541
| _ => Js.log("caboom!")
3642
}
3743

38-
<div />
44+
<div> {isFetching ? `Loading...`->React.string : React.null} </div>
3945
}

examples/src/UseMutation.res

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
module Promise = Js.Promise
2+
3+
type post = {
4+
title: string,
5+
body: string,
6+
userId: int,
7+
}
8+
9+
type response = {id: int}
10+
11+
type todo = {titles: string}
12+
13+
module Decode = {
14+
open Json.Decode
15+
let response = json => {
16+
id: field("id", int, json),
17+
}
18+
}
19+
20+
module Encode = {
21+
open Json.Encode
22+
let post = value =>
23+
object_(list{
24+
("title", string(value.title)),
25+
("body", string(value.body)),
26+
("userId", int(value.userId)),
27+
})
28+
->Js.Json.stringify
29+
->Fetch.BodyInit.make
30+
}
31+
32+
let createTodo = post =>
33+
Fetch.fetchWithInit(
34+
"https://jsonplaceholder.typicode.com/posts",
35+
Fetch.RequestInit.make(~method_=Post, ~body=post->Encode.post, ()),
36+
)
37+
->Promise.then_(Fetch.Response.json, _)
38+
->Promise.then_(value => value->Decode.response->Promise.resolve, _)
39+
40+
@react.component
41+
let make = () => {
42+
let {mutate, isLoading, isSuccess, data, _} =
43+
ReactQuery.mutationOptions(
44+
~mutationKey="create-post",
45+
~mutationFn=createTodo,
46+
(),
47+
)->ReactQuery.useMutation
48+
49+
let handleCreation = React.useCallback1(_ => {
50+
let post = {
51+
title: "Test",
52+
body: "My test",
53+
userId: 1,
54+
}
55+
mutate(. post, None)
56+
}, [mutate])
57+
58+
<div>
59+
{isLoading ? <p> {`Loading...`->React.string} </p> : React.null}
60+
{switch (isSuccess, data) {
61+
| (true, Some({id})) => <p> {j`Post created: $id`->React.string} </p>
62+
| _ => React.null
63+
}}
64+
<button onClick={handleCreation}> {`Click here`->React.string} </button>
65+
</div>
66+
}

examples/src/UseQuery.res

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
module Promise = Js.Promise
2+
3+
type todo = {
4+
completed: bool,
5+
id: int,
6+
title: string,
7+
userId: int,
8+
}
9+
10+
module Decode = {
11+
open Json.Decode
12+
let todo = json => {
13+
completed: field("completed", bool, json),
14+
id: field("id", int, json),
15+
title: field("title", string, json),
16+
userId: field("userId", int, json),
17+
}
18+
}
19+
20+
let fetchTodo = id =>
21+
j`https://jsonplaceholder.typicode.com/todos/$id`
22+
->Fetch.fetch
23+
->Promise.then_(Fetch.Response.json, _)
24+
->Promise.then_(value => Promise.resolve(Decode.todo(value)), _)
25+
26+
@react.component
27+
let make = () => {
28+
let result = ReactQuery.useQuery(
29+
ReactQuery.queryOptions(
30+
~queryKey="/todo-1",
31+
~queryFn=_ => fetchTodo(1),
32+
~refetchIntervalInBackground=false,
33+
(),
34+
),
35+
)
36+
37+
switch result {
38+
| {data: Some(value)} => Js.log(value.title)
39+
| _ => Js.log("caboom!")
40+
}
41+
42+
<div />
43+
}
Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
1-
type queryClient
2-
31
include ReactQuery_Query
2+
include ReactQuery_Mutation
3+
include ReactQuery_Hooks
44
include ReactQuery_Utils
5-
6-
module Provider = {
7-
@new @module("react-query")
8-
external createClient: unit => queryClient = "QueryClient"
9-
10-
@module("react-query") @react.component
11-
external make: (~client: queryClient, ~children: React.element) => React.element =
12-
"QueryClientProvider"
13-
}
5+
include ReactQuery_Client
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
type queryClientValue
2+
type fetchMeta
3+
4+
type queryState<'queryData, 'queryError> = {
5+
data: option<'queryData>,
6+
dataUpdateCount: int,
7+
dataUpdatedAt: int,
8+
error: Js.Nullable.t<'queryError>,
9+
errorUpdateCount: int,
10+
errorUpdatedAt: int,
11+
fetchFailureCount: int,
12+
fetchMeta: fetchMeta,
13+
isFetching: bool,
14+
isInvalidated: bool,
15+
isPaused: bool,
16+
status: ReactQuery_Types.queryStatus,
17+
}
18+
19+
@deriving(abstract)
20+
type fetchQueryOptions<'queryKey, 'queryData, 'queryError> = {
21+
@optional queryKey: 'queryKey,
22+
@optional queryFn: ReactQuery_Types.queryFunctionContext => Js.Promise.t<'queryData>,
23+
@optional retry: ReactQuery_Types.retryValue<'queryError>,
24+
@optional retryOnMount: bool,
25+
@optional retryDelay: ReactQuery_Types.retryDelayValue<'queryError>,
26+
@optional staleTime: ReactQuery_Types.timeValue,
27+
@optional queryKeyHashFn: 'queryKey => string,
28+
@optional refetchOnMount: ReactQuery_Types.boolOrAlwaysValue,
29+
@optional structuralSharing: bool,
30+
@optional initialData: 'queryData => 'queryData,
31+
@optional initialDataUpdatedAt: unit => int,
32+
}
33+
34+
type queryClient<'queryKey, 'queryData, 'queryError, 'pageParams> = {
35+
fetchQuery: fetchQueryOptions<'queryKey, 'queryData, 'queryError> => Js.Promise.t<'queryData>,
36+
fetchInfiniteQuery: fetchQueryOptions<'queryKey, 'queryData, 'queryError> => Js.Promise.t<
37+
ReactQuery_Types.infiniteData<'queryData, 'pageParams>,
38+
>,
39+
prefetchQuery: fetchQueryOptions<'queryKey, 'queryData, 'queryError> => Js.Promise.t<unit>,
40+
prefetchInfiniteQuery: fetchQueryOptions<'queryKey, 'queryData, 'queryError> => Js.Promise.t<
41+
unit,
42+
>,
43+
getQueryData: 'queryKey => option<'queryData>,
44+
setQueryData: ('queryKey, option<'queryData>) => 'queryData,
45+
getQueryState: (
46+
'queryKey,
47+
ReactQuery_Types.queryFilter<'queryKey>,
48+
) => queryState<'queryData, 'queryError>,
49+
setQueriesData: (
50+
ReactQuery_Types.queryDataKeyOrFilterValue<'queryKey>,
51+
option<'queryData> => 'queryData,
52+
) => unit,
53+
}
54+
55+
@module("react-query")
56+
external useQueryClient: unit => queryClient<'queryKey, 'queryData, 'queryError, 'pageParams> =
57+
"useQueryClient"
58+
59+
module Provider = {
60+
@new @module("react-query")
61+
external createClient: unit => queryClientValue = "QueryClient"
62+
63+
@module("react-query") @react.component
64+
external make: (
65+
~client: queryClientValue,
66+
~contextSharing: bool=?,
67+
~children: React.element,
68+
) => React.element = "QueryClientProvider"
69+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
type resetErrorBoundary = {reset: unit => unit}
2+
3+
@module("react-query")
4+
external useIsFetching: unit => bool = "useIsFetching"
5+
6+
@module("react-query") external useIsFetchingWithKeys: 'queryKey => bool = "useIsFetching"
7+
8+
@module("react-query")
9+
external useIsMutating: unit => bool = "useIsMutating"
10+
11+
@module("react-query") external useIsMutatingWithKeys: 'queryKey => bool = "useIsMutating"
12+
13+
@module("react-query")
14+
external useQueryErrorResetBoundary: unit => resetErrorBoundary = "useQueryErrorResetBoundary"
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
type mutationContext
2+
3+
type mutationStatus = [#loading | #success | #idle | #error]
4+
5+
type mutateParams<'mutationVariables, 'mutationData, 'mutationError, 'unknown> = {
6+
onSuccess: option<
7+
('mutationData, 'mutationVariables, Js.Nullable.t<mutationContext>) => Js.Promise.t<'unknown>,
8+
>,
9+
onError: option<
10+
('mutationError, 'mutationVariables, Js.Nullable.t<mutationContext>) => Js.Promise.t<'unknown>,
11+
>,
12+
onSettled: option<
13+
(
14+
'mutationData,
15+
'mutationError,
16+
'mutationVariables,
17+
Js.Nullable.t<mutationContext>,
18+
) => Js.Promise.t<'unknown>,
19+
>,
20+
}
21+
22+
@deriving(abstract)
23+
type mutationOptions<'mutationVariables, 'mutationData, 'mutationError, 'unknown> = {
24+
mutationKey: string,
25+
mutationFn: 'mutationVariables => Js.Promise.t<'mutationData>,
26+
@optional onMutate: 'mutationVariables => Js.Promise.t<mutationContext>,
27+
@optional
28+
onSuccess: (
29+
'mutationData,
30+
'mutationVariables,
31+
Js.Nullable.t<mutationContext>,
32+
) => Js.Promise.t<'unknown>,
33+
@optional
34+
onError: (
35+
'mutationError,
36+
'mutationVariables,
37+
Js.Nullable.t<mutationContext>,
38+
) => Js.Promise.t<'unknown>,
39+
@optional
40+
onSettled: (
41+
'mutationData,
42+
'mutationError,
43+
'mutationVariables,
44+
Js.Nullable.t<mutationContext>,
45+
) => Js.Promise.t<'unknown>,
46+
@optional retry: ReactQuery_Types.retryValue<'mutationError>,
47+
@optional retryDelay: ReactQuery_Types.retryDelayValue<'mutationError>,
48+
@optional useErrorBoundary: bool,
49+
}
50+
51+
type mutationResult<'mutationVariables, 'mutationData, 'mutationError, 'unknown> = {
52+
mutate: (
53+
. 'mutationVariables,
54+
option<mutateParams<'mutationVariables, 'mutationData, 'mutationError, 'unknown>>,
55+
) => unit,
56+
mutateAsync: (
57+
'mutationVariables,
58+
mutateParams<'mutationVariables, 'mutationData, 'mutationError, 'unknown>,
59+
) => Js.Promise.t<'mutationData>,
60+
status: mutationStatus,
61+
isIdle: bool,
62+
isError: bool,
63+
isLoading: bool,
64+
isSuccess: bool,
65+
data: option<'mutationData>,
66+
error: Js.Nullable.t<'mutationError>,
67+
reset: unit => unit,
68+
}
69+
70+
@module("react-query")
71+
external useMutation: mutationOptions<
72+
'mutationVariables,
73+
'mutationData,
74+
'mutationError,
75+
'unknown,
76+
> => mutationResult<'mutationVariables, 'mutationData, 'mutationError, 'unknown> = "useMutation"

examples/src/bindings/ReactQuery_Query.res

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,3 @@
1-
type queryFunctionContext
2-
type queryKey
3-
4-
type timeValue
5-
type boolOrAlwaysValue
6-
type refetchIntervalValue
7-
type notifyOnChangePropsValue
8-
type retryValue<'queryError>
9-
type retryDelayValue<'queryError>
10-
11-
type retryParam<'queryError> = [#bool(bool) | #number(int) | #fn((int, 'queryError) => bool)]
12-
type retryDelayParam<'queryError> = [#number(int) | #fn((int, 'queryError) => int)]
13-
type time = [#number(int) | #infinity]
14-
type refetchInterval = [#bool(bool) | #number(int)]
15-
type boolOrAlways = [#bool(bool) | #always]
16-
type notifyOnChangeProps = [#array(array<string>) | #tracked]
17-
18-
type queryStatus = [#loading | #success | #idle | #error | #initialData]
19-
201
type refetchOptions = {
212
throwOnError: bool,
223
cancelRefetch: bool,
@@ -25,19 +6,19 @@ type refetchOptions = {
256
@deriving(abstract)
267
type queryOptions<'queryKey, 'queryData, 'queryError> = {
278
@optional queryKey: 'queryKey,
28-
@optional queryFn: queryFunctionContext => Js.Promise.t<'queryData>,
9+
@optional queryFn: ReactQuery_Types.queryFunctionContext => Js.Promise.t<'queryData>,
2910
@optional enabled: bool,
30-
@optional retry: retryValue<'queryError>,
11+
@optional retry: ReactQuery_Types.retryValue<'queryError>,
3112
@optional retryOnMount: bool,
32-
@optional retryDelay: retryDelayValue<'queryError>,
33-
@optional staleTime: timeValue,
34-
@optional queryKeyHashFn: queryKey => string,
35-
@optional refetchInterval: refetchIntervalValue,
13+
@optional retryDelay: ReactQuery_Types.retryDelayValue<'queryError>,
14+
@optional staleTime: ReactQuery_Types.timeValue,
15+
@optional queryKeyHashFn: 'queryKey => string,
16+
@optional refetchInterval: ReactQuery_Types.refetchIntervalValue,
3617
@optional refetchIntervalInBackground: bool,
37-
@optional refetchOnMount: boolOrAlwaysValue,
38-
@optional refetchOnWindowFocus: boolOrAlwaysValue,
39-
@optional refetchOnReconnect: boolOrAlwaysValue,
40-
@optional notifyOnChangeProps: notifyOnChangePropsValue,
18+
@optional refetchOnMount: ReactQuery_Types.boolOrAlwaysValue,
19+
@optional refetchOnWindowFocus: ReactQuery_Types.boolOrAlwaysValue,
20+
@optional refetchOnReconnect: ReactQuery_Types.boolOrAlwaysValue,
21+
@optional notifyOnChangeProps: ReactQuery_Types.notifyOnChangePropsValue,
4122
@optional notifyOnChangePropsExclusions: array<string>,
4223
@optional onSuccess: 'queryData => unit,
4324
@optional onError: 'queryError => unit,
@@ -53,7 +34,7 @@ type queryOptions<'queryKey, 'queryData, 'queryError> = {
5334
}
5435

5536
type rec queryResult<'queryError, 'queryData> = {
56-
status: queryStatus,
37+
status: ReactQuery_Types.queryStatus,
5738
isIdle: bool,
5839
isError: bool,
5940
isFetched: bool,

0 commit comments

Comments
 (0)