rescript-relay 1.1.1 → 2.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/package.json +7 -7
- package/postinstall.js +4 -0
- package/ppx-linux +0 -0
- package/ppx-macos-arm64 +0 -0
- package/ppx-macos-latest +0 -0
- package/ppx-windows-latest +0 -0
- package/relay-compiler-linux-musl/relay +0 -0
- package/relay-compiler-linux-x64/relay +0 -0
- package/relay-compiler-macos-arm64/relay +0 -0
- package/relay-compiler-macos-x64/relay +0 -0
- package/relay-compiler-win-x64/relay.exe +0 -0
- package/src/ReactExperimental.bs.js +5 -3
- package/src/ReactExperimental.res +1 -1
- package/src/ReactExperimental.resi +1 -1
- package/src/RescriptRelay.bs.js +14 -43
- package/src/RescriptRelay.res +23 -37
- package/src/RescriptRelay.resi +35 -24
- package/src/RescriptRelayUtils.bs.js +3 -3
- package/src/RescriptRelay_Fragment.bs.js +115 -0
- package/src/RescriptRelay_Fragment.res +239 -0
- package/src/RescriptRelay_Fragment.resi +86 -0
- package/src/RescriptRelay_Internal.bs.js +2 -3
- package/src/RescriptRelay_Mutation.bs.js +57 -0
- package/src/RescriptRelay_Mutation.res +146 -0
- package/src/RescriptRelay_Mutation.resi +54 -0
- package/src/RescriptRelay_Query.bs.js +101 -0
- package/src/RescriptRelay_Query.res +185 -0
- package/src/RescriptRelay_Query.resi +70 -0
- package/src/RescriptRelay_RelayResolvers.bs.js +13 -0
- package/src/RescriptRelay_RelayResolvers.res +21 -0
- package/src/RescriptRelay_RelayResolvers.resi +10 -0
- package/src/RescriptRelay_Subscriptions.bs.js +24 -0
- package/src/RescriptRelay_Subscriptions.res +51 -0
- package/src/RescriptRelay_Subscriptions.resi +15 -0
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
open RescriptRelay
|
|
2
|
+
|
|
3
|
+
@module("react-relay")
|
|
4
|
+
external useFragment_: (fragmentNode<'node>, 'fragmentRef) => 'fragment = "useFragment"
|
|
5
|
+
|
|
6
|
+
let useFragment = (~node, ~convertFragment: 'fragment => 'fragment, ~fRef) => {
|
|
7
|
+
/** React hook for getting the data of this fragment. Pass \
|
|
8
|
+
the `fragmentRefs` of any object where you've spread your \
|
|
9
|
+
fragment into this and get the fragment data back.\n\n\
|
|
10
|
+
### Fragment data outside of React's render\n\
|
|
11
|
+
If you're looking for a way to use fragments _outside_ of \
|
|
12
|
+
render (for regular function calls for instance, like for \
|
|
13
|
+
logging etc), look in to adding `@inline` to your \
|
|
14
|
+
fragment definition (like `fragment SomeFragment_user on \
|
|
15
|
+
User @inline {...}`) and then use `Fragment.readInline`. \
|
|
16
|
+
This will allow you to get the fragment data, but outside \
|
|
17
|
+
of React's render.*/
|
|
18
|
+
(
|
|
19
|
+
useFragment_(node, fRef)
|
|
20
|
+
->(RescriptRelay_Internal.internal_useConvertedValue(convertFragment, _))
|
|
21
|
+
)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@module("react-relay")
|
|
25
|
+
external useFragmentOpt_: (fragmentNode<'node>, option<'fragmentRef>) => Js.Nullable.t<'fragment> =
|
|
26
|
+
"useFragment"
|
|
27
|
+
|
|
28
|
+
let useFragmentOpt = (~fRef, ~node, ~convertFragment: 'fragment => 'fragment) => {
|
|
29
|
+
// TODO(v11) can convert to Nullable pattern match.
|
|
30
|
+
|
|
31
|
+
/** A version of `Fragment.use` that'll allow you to pass \
|
|
32
|
+
`option<fragmentRefs>` and get `option<'fragmentData>` \
|
|
33
|
+
back. Useful for scenarios where you don't have the \
|
|
34
|
+
fragmentRefs yet.*/
|
|
35
|
+
let data =
|
|
36
|
+
useFragmentOpt_(node, fRef)->Js.Nullable.toOption
|
|
37
|
+
React.useMemo1(() => {
|
|
38
|
+
switch data {
|
|
39
|
+
| Some(data) => Some(convertFragment(data))
|
|
40
|
+
| None => None
|
|
41
|
+
}
|
|
42
|
+
}, [data])
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@module("react-relay")
|
|
46
|
+
external readInlineData_: (fragmentNode<'node>, 'fragmentRef) => 'fragment = "readInlineData"
|
|
47
|
+
|
|
48
|
+
let readInlineData = (~node, ~convertFragment: 'fragment => 'fragment, ~fRef) => {
|
|
49
|
+
/** This lets you get the data for this fragment _outside \
|
|
50
|
+
of React's render_. Useful for letting functions with \
|
|
51
|
+
with fragments too, for things like logging etc.*/
|
|
52
|
+
(readInlineData_(node, fRef)->convertFragment)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
type refetchableFnOpts = {
|
|
56
|
+
fetchPolicy?: fetchPolicy,
|
|
57
|
+
onComplete?: Js.Nullable.t<Js.Exn.t> => unit,
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let internal_makeRefetchableFnOpts = (~fetchPolicy=?, ~onComplete=?, ()) => {
|
|
61
|
+
?fetchPolicy,
|
|
62
|
+
onComplete: ?onComplete->RescriptRelay_Internal.internal_nullableToOptionalExnHandler,
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
type paginationLoadMoreOptions = {onComplete?: Js.Nullable.t<Js.Exn.t> => unit}
|
|
66
|
+
type paginationLoadMoreFn = (
|
|
67
|
+
~count: int,
|
|
68
|
+
~onComplete: option<Js.Exn.t> => unit=?,
|
|
69
|
+
unit,
|
|
70
|
+
) => Disposable.t
|
|
71
|
+
type paginationFragmentReturnRaw<'fragment, 'refetchVariables> = {
|
|
72
|
+
data: 'fragment,
|
|
73
|
+
loadNext: (int, paginationLoadMoreOptions) => Disposable.t,
|
|
74
|
+
loadPrevious: (int, paginationLoadMoreOptions) => Disposable.t,
|
|
75
|
+
hasNext: bool,
|
|
76
|
+
hasPrevious: bool,
|
|
77
|
+
isLoadingNext: bool,
|
|
78
|
+
isLoadingPrevious: bool,
|
|
79
|
+
refetch: ('refetchVariables, refetchableFnOpts) => Disposable.t,
|
|
80
|
+
}
|
|
81
|
+
type paginationBlockingFragmentReturn<'fragment, 'refetchVariables> = {
|
|
82
|
+
data: 'fragment,
|
|
83
|
+
loadNext: paginationLoadMoreFn,
|
|
84
|
+
loadPrevious: paginationLoadMoreFn,
|
|
85
|
+
hasNext: bool,
|
|
86
|
+
hasPrevious: bool,
|
|
87
|
+
refetch: (
|
|
88
|
+
~variables: 'refetchVariables,
|
|
89
|
+
~fetchPolicy: fetchPolicy=?,
|
|
90
|
+
~onComplete: option<Js.Exn.t> => unit=?,
|
|
91
|
+
unit,
|
|
92
|
+
) => Disposable.t,
|
|
93
|
+
}
|
|
94
|
+
type paginationFragmentReturn<'fragment, 'refetchVariables> = {
|
|
95
|
+
data: 'fragment,
|
|
96
|
+
loadNext: paginationLoadMoreFn,
|
|
97
|
+
loadPrevious: paginationLoadMoreFn,
|
|
98
|
+
hasNext: bool,
|
|
99
|
+
hasPrevious: bool,
|
|
100
|
+
isLoadingNext: bool,
|
|
101
|
+
isLoadingPrevious: bool,
|
|
102
|
+
refetch: (
|
|
103
|
+
~variables: 'refetchVariables,
|
|
104
|
+
~fetchPolicy: fetchPolicy=?,
|
|
105
|
+
~onComplete: option<Js.Exn.t> => unit=?,
|
|
106
|
+
unit,
|
|
107
|
+
) => Disposable.t,
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
@module("react-relay")
|
|
111
|
+
external usePaginationFragment_: (
|
|
112
|
+
fragmentNode<'node>,
|
|
113
|
+
'fragmentRef,
|
|
114
|
+
) => paginationFragmentReturnRaw<'fragment, 'refetchVariables> = "usePaginationFragment"
|
|
115
|
+
|
|
116
|
+
/** React hook for paginating a fragment. Paginating with \
|
|
117
|
+
this hook will _not_ cause your component to suspend. \
|
|
118
|
+
If you want pagination to trigger suspense, look into \
|
|
119
|
+
using `Fragment.useBlockingPagination`.*/
|
|
120
|
+
let usePaginationFragment = (
|
|
121
|
+
~node,
|
|
122
|
+
~fRef,
|
|
123
|
+
~convertFragment: 'fragment => 'fragment,
|
|
124
|
+
~convertRefetchVariables: 'refetchVariables => 'refetchVariables,
|
|
125
|
+
) => {
|
|
126
|
+
let p = usePaginationFragment_(node, fRef)
|
|
127
|
+
let data = RescriptRelay_Internal.internal_useConvertedValue(convertFragment, p.data)
|
|
128
|
+
{
|
|
129
|
+
data,
|
|
130
|
+
loadNext: React.useMemo1(() => (~count, ~onComplete=?, ()) => {
|
|
131
|
+
p.loadNext(
|
|
132
|
+
count,
|
|
133
|
+
{onComplete: ?onComplete->RescriptRelay_Internal.internal_nullableToOptionalExnHandler},
|
|
134
|
+
)
|
|
135
|
+
}, [p.loadNext]),
|
|
136
|
+
loadPrevious: React.useMemo1(() => (~count, ~onComplete=?, ()) => {
|
|
137
|
+
p.loadPrevious(
|
|
138
|
+
count,
|
|
139
|
+
{onComplete: ?onComplete->RescriptRelay_Internal.internal_nullableToOptionalExnHandler},
|
|
140
|
+
)
|
|
141
|
+
}, [p.loadPrevious]),
|
|
142
|
+
hasNext: p.hasNext,
|
|
143
|
+
hasPrevious: p.hasPrevious,
|
|
144
|
+
isLoadingNext: p.isLoadingNext,
|
|
145
|
+
isLoadingPrevious: p.isLoadingPrevious,
|
|
146
|
+
refetch: React.useMemo1(() => (~variables, ~fetchPolicy=?, ~onComplete=?, ()) => {
|
|
147
|
+
p.refetch(
|
|
148
|
+
RescriptRelay_Internal.internal_cleanObjectFromUndefinedRaw(
|
|
149
|
+
variables->convertRefetchVariables,
|
|
150
|
+
),
|
|
151
|
+
internal_makeRefetchableFnOpts(~onComplete?, ~fetchPolicy?, ()),
|
|
152
|
+
)
|
|
153
|
+
}, [p.refetch]),
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
@module("react-relay")
|
|
158
|
+
external useBlockingPaginationFragment_: (
|
|
159
|
+
fragmentNode<'node>,
|
|
160
|
+
'fragmentRef,
|
|
161
|
+
) => paginationFragmentReturnRaw<'fragment, 'refetchVariables> = "useBlockingPaginationFragment"
|
|
162
|
+
|
|
163
|
+
/** Like `Fragment.usePagination`, but calling the \
|
|
164
|
+
pagination function will trigger suspense. Useful for \
|
|
165
|
+
all-at-once pagination.*/
|
|
166
|
+
let useBlockingPaginationFragment = (
|
|
167
|
+
~node,
|
|
168
|
+
~fRef,
|
|
169
|
+
~convertFragment: 'fragment => 'fragment,
|
|
170
|
+
~convertRefetchVariables: 'refetchVariables => 'refetchVariables,
|
|
171
|
+
) => {
|
|
172
|
+
let p = useBlockingPaginationFragment_(node, fRef)
|
|
173
|
+
let data = RescriptRelay_Internal.internal_useConvertedValue(convertFragment, p.data)
|
|
174
|
+
{
|
|
175
|
+
data,
|
|
176
|
+
loadNext: React.useMemo1(() => (~count, ~onComplete=?, ()) => {
|
|
177
|
+
p.loadNext(
|
|
178
|
+
count,
|
|
179
|
+
{onComplete: ?onComplete->RescriptRelay_Internal.internal_nullableToOptionalExnHandler},
|
|
180
|
+
)
|
|
181
|
+
}, [p.loadNext]),
|
|
182
|
+
loadPrevious: React.useMemo1(() => (~count, ~onComplete=?, ()) => {
|
|
183
|
+
p.loadPrevious(
|
|
184
|
+
count,
|
|
185
|
+
{onComplete: ?onComplete->RescriptRelay_Internal.internal_nullableToOptionalExnHandler},
|
|
186
|
+
)
|
|
187
|
+
}, [p.loadPrevious]),
|
|
188
|
+
hasNext: p.hasNext,
|
|
189
|
+
hasPrevious: p.hasPrevious,
|
|
190
|
+
refetch: React.useMemo1(() => (~variables, ~fetchPolicy=?, ~onComplete=?, ()) => {
|
|
191
|
+
p.refetch(
|
|
192
|
+
RescriptRelay_Internal.internal_cleanObjectFromUndefinedRaw(
|
|
193
|
+
variables->convertRefetchVariables,
|
|
194
|
+
),
|
|
195
|
+
internal_makeRefetchableFnOpts(~onComplete?, ~fetchPolicy?, ()),
|
|
196
|
+
)
|
|
197
|
+
}, [p.refetch]),
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
@module("react-relay")
|
|
202
|
+
external useRefetchableFragment_: (
|
|
203
|
+
fragmentNode<'node>,
|
|
204
|
+
'fragmentRef,
|
|
205
|
+
) => ('fragment, ('refetchVariables, refetchableFnOpts) => Disposable.t) = "useRefetchableFragment"
|
|
206
|
+
|
|
207
|
+
/**React hook for using a fragment that you want to refetch. Returns \
|
|
208
|
+
a tuple of `(fragmentData, refetchFn)`.\n\n\
|
|
209
|
+
### Refetching and variables\n\
|
|
210
|
+
You supply a _diff_ of your variables to Relay when refetching. \
|
|
211
|
+
Diffed variables here means that any new value you supply when \
|
|
212
|
+
refetching will be merged with the variables you last used when \
|
|
213
|
+
fetching data for this fragment.\n\n\
|
|
214
|
+
### `Fragment.makeRefetchVariables` - helper for making the \
|
|
215
|
+
refetch variables\n\
|
|
216
|
+
There's a helper generated for you to create those diffed \
|
|
217
|
+
variables more easily at `Fragment.makeRefetchVariables`.*/
|
|
218
|
+
let useRefetchableFragment = (
|
|
219
|
+
~node,
|
|
220
|
+
~convertFragment: 'fragment => 'fragment,
|
|
221
|
+
~convertRefetchVariables: 'refetchVariables => 'refetchVariables,
|
|
222
|
+
~fRef,
|
|
223
|
+
) => {
|
|
224
|
+
let (fragmentData, refetchFn) = useRefetchableFragment_(node, fRef)
|
|
225
|
+
let data = RescriptRelay_Internal.internal_useConvertedValue(convertFragment, fragmentData)
|
|
226
|
+
(
|
|
227
|
+
data,
|
|
228
|
+
React.useMemo1(
|
|
229
|
+
() => (~variables: 'refetchVariables, ~fetchPolicy=?, ~onComplete=?, ()) =>
|
|
230
|
+
refetchFn(
|
|
231
|
+
RescriptRelay_Internal.internal_removeUndefinedAndConvertNullsRaw(
|
|
232
|
+
variables->convertRefetchVariables,
|
|
233
|
+
),
|
|
234
|
+
internal_makeRefetchableFnOpts(~fetchPolicy?, ~onComplete?, ()),
|
|
235
|
+
),
|
|
236
|
+
[refetchFn],
|
|
237
|
+
),
|
|
238
|
+
)
|
|
239
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
open RescriptRelay
|
|
2
|
+
|
|
3
|
+
let useFragment: (
|
|
4
|
+
~node: fragmentNode<'a>,
|
|
5
|
+
~convertFragment: 'fragment => 'fragment,
|
|
6
|
+
~fRef: 'b,
|
|
7
|
+
) => 'fragment
|
|
8
|
+
|
|
9
|
+
let useFragmentOpt: (
|
|
10
|
+
~fRef: option<'a>,
|
|
11
|
+
~node: fragmentNode<'b>,
|
|
12
|
+
~convertFragment: 'fragment => 'fragment,
|
|
13
|
+
) => option<'fragment>
|
|
14
|
+
|
|
15
|
+
let readInlineData: (
|
|
16
|
+
~node: fragmentNode<'a>,
|
|
17
|
+
~convertFragment: 'fragment => 'fragment,
|
|
18
|
+
~fRef: 'b,
|
|
19
|
+
) => 'fragment
|
|
20
|
+
|
|
21
|
+
type paginationLoadMoreOptions = {onComplete?: Js.Nullable.t<Js.Exn.t> => unit}
|
|
22
|
+
|
|
23
|
+
type paginationLoadMoreFn = (
|
|
24
|
+
~count: int,
|
|
25
|
+
~onComplete: option<Js.Exn.t> => unit=?,
|
|
26
|
+
unit,
|
|
27
|
+
) => Disposable.t
|
|
28
|
+
|
|
29
|
+
type paginationBlockingFragmentReturn<'fragment, 'refetchVariables> = {
|
|
30
|
+
data: 'fragment,
|
|
31
|
+
loadNext: paginationLoadMoreFn,
|
|
32
|
+
loadPrevious: paginationLoadMoreFn,
|
|
33
|
+
hasNext: bool,
|
|
34
|
+
hasPrevious: bool,
|
|
35
|
+
refetch: (
|
|
36
|
+
~variables: 'refetchVariables,
|
|
37
|
+
~fetchPolicy: fetchPolicy=?,
|
|
38
|
+
~onComplete: option<Js.Exn.t> => unit=?,
|
|
39
|
+
unit,
|
|
40
|
+
) => Disposable.t,
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
type paginationFragmentReturn<'fragment, 'refetchVariables> = {
|
|
44
|
+
data: 'fragment,
|
|
45
|
+
loadNext: paginationLoadMoreFn,
|
|
46
|
+
loadPrevious: paginationLoadMoreFn,
|
|
47
|
+
hasNext: bool,
|
|
48
|
+
hasPrevious: bool,
|
|
49
|
+
isLoadingNext: bool,
|
|
50
|
+
isLoadingPrevious: bool,
|
|
51
|
+
refetch: (
|
|
52
|
+
~variables: 'refetchVariables,
|
|
53
|
+
~fetchPolicy: fetchPolicy=?,
|
|
54
|
+
~onComplete: option<Js.Exn.t> => unit=?,
|
|
55
|
+
unit,
|
|
56
|
+
) => Disposable.t,
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
let usePaginationFragment: (
|
|
60
|
+
~node: fragmentNode<'a>,
|
|
61
|
+
~fRef: 'b,
|
|
62
|
+
~convertFragment: 'fragment => 'fragment,
|
|
63
|
+
~convertRefetchVariables: 'refetchVariables => 'refetchVariables,
|
|
64
|
+
) => paginationFragmentReturn<'fragment, 'refetchVariables>
|
|
65
|
+
|
|
66
|
+
let useBlockingPaginationFragment: (
|
|
67
|
+
~node: fragmentNode<'a>,
|
|
68
|
+
~fRef: 'b,
|
|
69
|
+
~convertFragment: 'fragment => 'fragment,
|
|
70
|
+
~convertRefetchVariables: 'refetchVariables => 'refetchVariables,
|
|
71
|
+
) => paginationBlockingFragmentReturn<'fragment, 'refetchVariables>
|
|
72
|
+
|
|
73
|
+
let useRefetchableFragment: (
|
|
74
|
+
~node: fragmentNode<'a>,
|
|
75
|
+
~convertFragment: 'fragment => 'fragment,
|
|
76
|
+
~convertRefetchVariables: 'refetchVariables => 'refetchVariables,
|
|
77
|
+
~fRef: 'b,
|
|
78
|
+
) => (
|
|
79
|
+
'fragment,
|
|
80
|
+
(
|
|
81
|
+
~variables: 'refetchVariables,
|
|
82
|
+
~fetchPolicy: fetchPolicy=?,
|
|
83
|
+
~onComplete: option<Js.Exn.t> => unit=?,
|
|
84
|
+
unit,
|
|
85
|
+
) => Disposable.t,
|
|
86
|
+
)
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var Curry = require("rescript/lib/js/curry.js");
|
|
5
4
|
var React = require("react");
|
|
6
5
|
var Js_dict = require("rescript/lib/js/js_dict.js");
|
|
7
6
|
var Caml_obj = require("rescript/lib/js/caml_obj.js");
|
|
@@ -56,14 +55,14 @@ function internal_removeUndefinedAndConvertNullsRaw(record) {
|
|
|
56
55
|
|
|
57
56
|
function internal_useConvertedValue(convert, v) {
|
|
58
57
|
return React.useMemo((function () {
|
|
59
|
-
return
|
|
58
|
+
return convert(v);
|
|
60
59
|
}), [v]);
|
|
61
60
|
}
|
|
62
61
|
|
|
63
62
|
function internal_nullableToOptionalExnHandler(x) {
|
|
64
63
|
if (x !== undefined) {
|
|
65
64
|
return (function (maybeExn) {
|
|
66
|
-
return
|
|
65
|
+
return x((maybeExn == null) ? undefined : Caml_option.some(maybeExn));
|
|
67
66
|
});
|
|
68
67
|
}
|
|
69
68
|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var React = require("react");
|
|
5
|
+
var Caml_option = require("rescript/lib/js/caml_option.js");
|
|
6
|
+
var ReactRelay = require("react-relay");
|
|
7
|
+
var RelayRuntime = require("relay-runtime");
|
|
8
|
+
|
|
9
|
+
function commitMutation(convertVariables, node, convertResponse, convertWrapRawResponse) {
|
|
10
|
+
return function (environment, variables, optimisticUpdater, optimisticResponse, updater, onCompleted, onError, uploadables, param) {
|
|
11
|
+
return RelayRuntime.commitMutation(environment, {
|
|
12
|
+
mutation: node,
|
|
13
|
+
variables: convertVariables(variables),
|
|
14
|
+
onCompleted: onCompleted !== undefined ? (function (res, err) {
|
|
15
|
+
onCompleted(convertResponse(res), (err == null) ? undefined : Caml_option.some(err));
|
|
16
|
+
}) : undefined,
|
|
17
|
+
onError: onError,
|
|
18
|
+
optimisticResponse: optimisticResponse !== undefined ? Caml_option.some(convertWrapRawResponse(Caml_option.valFromOption(optimisticResponse))) : undefined,
|
|
19
|
+
optimisticUpdater: optimisticUpdater,
|
|
20
|
+
updater: updater !== undefined ? (function (store, response) {
|
|
21
|
+
updater(store, convertResponse(response));
|
|
22
|
+
}) : undefined,
|
|
23
|
+
uploadables: uploadables
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function useMutation(convertVariables, node, convertResponse, convertWrapRawResponse) {
|
|
29
|
+
return function () {
|
|
30
|
+
var match = ReactRelay.useMutation(node);
|
|
31
|
+
var mutate = match[0];
|
|
32
|
+
return [
|
|
33
|
+
React.useMemo((function () {
|
|
34
|
+
return function (variables, optimisticUpdater, optimisticResponse, updater, onCompleted, onError, uploadables, param) {
|
|
35
|
+
return mutate({
|
|
36
|
+
onError: onError,
|
|
37
|
+
onCompleted: onCompleted !== undefined ? (function (res, err) {
|
|
38
|
+
onCompleted(convertResponse(res), (err == null) ? undefined : Caml_option.some(err));
|
|
39
|
+
}) : undefined,
|
|
40
|
+
optimisticResponse: optimisticResponse !== undefined ? Caml_option.some(convertWrapRawResponse(Caml_option.valFromOption(optimisticResponse))) : undefined,
|
|
41
|
+
optimisticUpdater: optimisticUpdater,
|
|
42
|
+
updater: updater !== undefined ? (function (store, response) {
|
|
43
|
+
updater(store, convertResponse(response));
|
|
44
|
+
}) : undefined,
|
|
45
|
+
variables: convertVariables(variables),
|
|
46
|
+
uploadables: uploadables
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
}), [mutate]),
|
|
50
|
+
match[1]
|
|
51
|
+
];
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
exports.commitMutation = commitMutation;
|
|
56
|
+
exports.useMutation = useMutation;
|
|
57
|
+
/* react Not a pure module */
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
open RescriptRelay
|
|
2
|
+
|
|
3
|
+
type updaterFn<'response> = (RecordSourceSelectorProxy.t, 'response) => unit
|
|
4
|
+
type optimisticUpdaterFn = RecordSourceSelectorProxy.t => unit
|
|
5
|
+
type useMutationConfig<'response, 'rawResponse, 'variables> = {
|
|
6
|
+
onError?: mutationError => unit,
|
|
7
|
+
onCompleted?: ('response, option<array<mutationError>>) => unit,
|
|
8
|
+
onUnsubscribe?: unit => unit,
|
|
9
|
+
optimisticResponse?: 'rawResponse,
|
|
10
|
+
optimisticUpdater?: optimisticUpdaterFn,
|
|
11
|
+
updater?: updaterFn<'response>,
|
|
12
|
+
variables: 'variables,
|
|
13
|
+
uploadables?: uploadables,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
type commitMutationConfigRaw<'m, 'variables, 'response, 'rawResponse> = {
|
|
17
|
+
mutation: mutationNode<'m>,
|
|
18
|
+
variables: 'variables,
|
|
19
|
+
onCompleted?: ('response, Js.Nullable.t<array<mutationError>>) => unit,
|
|
20
|
+
onError?: mutationError => unit,
|
|
21
|
+
optimisticResponse?: 'rawResponse,
|
|
22
|
+
optimisticUpdater?: optimisticUpdaterFn,
|
|
23
|
+
updater?: updaterFn<'response>,
|
|
24
|
+
uploadables?: uploadables,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
type useMutationConfigRaw<'m, 'variables, 'response, 'rawResponse> = {
|
|
28
|
+
onError?: mutationError => unit,
|
|
29
|
+
onCompleted?: ('response, Js.Nullable.t<array<mutationError>>) => unit,
|
|
30
|
+
onUnsubscribe?: unit => unit,
|
|
31
|
+
optimisticResponse?: 'rawResponse,
|
|
32
|
+
optimisticUpdater?: optimisticUpdaterFn,
|
|
33
|
+
updater?: updaterFn<'response>,
|
|
34
|
+
variables: 'variables,
|
|
35
|
+
uploadables?: uploadables,
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@module("relay-runtime")
|
|
39
|
+
external commitMutation_: (
|
|
40
|
+
Environment.t,
|
|
41
|
+
commitMutationConfigRaw<'m, 'variables, 'response, 'rawResponse>,
|
|
42
|
+
) => Disposable.t = "commitMutation"
|
|
43
|
+
|
|
44
|
+
@module("react-relay")
|
|
45
|
+
external useMutation_: 'm => (
|
|
46
|
+
useMutationConfigRaw<'m, 'variables, 'response, 'rawResponse> => Disposable.t,
|
|
47
|
+
bool,
|
|
48
|
+
) = "useMutation"
|
|
49
|
+
|
|
50
|
+
let commitMutation = (
|
|
51
|
+
~convertVariables: 'variables => 'variables,
|
|
52
|
+
~node: 'm,
|
|
53
|
+
~convertResponse: 'response => 'response,
|
|
54
|
+
~convertWrapRawResponse: 'rawResponse => 'rawResponse,
|
|
55
|
+
) => {
|
|
56
|
+
/**Commits the current mutation. Use this outside of React's \
|
|
57
|
+
render. If you're inside render, you should use `Mutation.use` \
|
|
58
|
+
instead, which is more convenient.\n\n\
|
|
59
|
+
### Optimistic updates\n\
|
|
60
|
+
Remember to annotate your mutation with `@raw_response_type` if \
|
|
61
|
+
you want to do optimistic updates. That'll make Relay emit the \
|
|
62
|
+
required type information for covering everything needed when \
|
|
63
|
+
doing optimistic updates.*/
|
|
64
|
+
(
|
|
65
|
+
~environment: Environment.t,
|
|
66
|
+
~variables: 'variables,
|
|
67
|
+
~optimisticUpdater=?,
|
|
68
|
+
~optimisticResponse: option<'rawResponse>=?,
|
|
69
|
+
~updater=?,
|
|
70
|
+
~onCompleted=?,
|
|
71
|
+
~onError=?,
|
|
72
|
+
~uploadables=?,
|
|
73
|
+
(),
|
|
74
|
+
) => {
|
|
75
|
+
commitMutation_(
|
|
76
|
+
environment,
|
|
77
|
+
{
|
|
78
|
+
mutation: node,
|
|
79
|
+
onCompleted: ?switch onCompleted {
|
|
80
|
+
| Some(cb) => Some((res, err) => cb(res->convertResponse, err->Js.Nullable.toOption))
|
|
81
|
+
| None => None
|
|
82
|
+
},
|
|
83
|
+
?onError,
|
|
84
|
+
optimisticResponse: ?switch optimisticResponse {
|
|
85
|
+
| Some(optimisticResponse) => Some(optimisticResponse->convertWrapRawResponse)
|
|
86
|
+
| None => None
|
|
87
|
+
},
|
|
88
|
+
?optimisticUpdater,
|
|
89
|
+
updater: ?switch updater {
|
|
90
|
+
| Some(updater) => Some((store, response) => updater(store, response->convertResponse))
|
|
91
|
+
| None => None
|
|
92
|
+
},
|
|
93
|
+
?uploadables,
|
|
94
|
+
variables: variables->convertVariables,
|
|
95
|
+
},
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
let useMutation = (
|
|
101
|
+
~convertVariables: 'variables => 'variables,
|
|
102
|
+
~node: 'm,
|
|
103
|
+
~convertResponse: 'response => 'response,
|
|
104
|
+
~convertWrapRawResponse: 'rawResponse => 'rawResponse,
|
|
105
|
+
) => {
|
|
106
|
+
/**React hook for commiting this mutation.\n\n\
|
|
107
|
+
### Optimistic updates\n\
|
|
108
|
+
Remember to annotate your mutation with `@raw_response_type` if \
|
|
109
|
+
you want to do optimistic updates. That'll make Relay emit the \
|
|
110
|
+
required type information for covering everything needed when \
|
|
111
|
+
doing optimistic updates.*/
|
|
112
|
+
() => {
|
|
113
|
+
let (mutate, mutating) = useMutation_(node)
|
|
114
|
+
(React.useMemo1(() => {
|
|
115
|
+
(
|
|
116
|
+
~variables: 'variables,
|
|
117
|
+
~optimisticUpdater=?,
|
|
118
|
+
~optimisticResponse: option<'rawResponse>=?,
|
|
119
|
+
~updater=?,
|
|
120
|
+
~onCompleted=?,
|
|
121
|
+
~onError=?,
|
|
122
|
+
~uploadables=?,
|
|
123
|
+
(),
|
|
124
|
+
) => {
|
|
125
|
+
mutate({
|
|
126
|
+
onCompleted: ?switch onCompleted {
|
|
127
|
+
| Some(cb) => Some((res, err) => cb(res->convertResponse, err->Js.Nullable.toOption))
|
|
128
|
+
| None => None
|
|
129
|
+
},
|
|
130
|
+
?onError,
|
|
131
|
+
optimisticResponse: ?switch optimisticResponse {
|
|
132
|
+
| Some(optimisticResponse) => Some(optimisticResponse->convertWrapRawResponse)
|
|
133
|
+
| None => None
|
|
134
|
+
},
|
|
135
|
+
?optimisticUpdater,
|
|
136
|
+
updater: ?switch updater {
|
|
137
|
+
| Some(updater) => Some((store, response) => updater(store, response->convertResponse))
|
|
138
|
+
| None => None
|
|
139
|
+
},
|
|
140
|
+
?uploadables,
|
|
141
|
+
variables: variables->convertVariables,
|
|
142
|
+
})
|
|
143
|
+
}
|
|
144
|
+
}, [mutate]), mutating)
|
|
145
|
+
}
|
|
146
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/*** Internal file, do not use directly.*/
|
|
2
|
+
|
|
3
|
+
open RescriptRelay
|
|
4
|
+
|
|
5
|
+
type updaterFn<'response> = (RecordSourceSelectorProxy.t, 'response) => unit
|
|
6
|
+
type optimisticUpdaterFn = RecordSourceSelectorProxy.t => unit
|
|
7
|
+
|
|
8
|
+
@live
|
|
9
|
+
type useMutationConfig<'response, 'rawResponse, 'variables> = {
|
|
10
|
+
onError?: mutationError => unit,
|
|
11
|
+
onCompleted?: ('response, option<array<mutationError>>) => unit,
|
|
12
|
+
onUnsubscribe?: unit => unit,
|
|
13
|
+
optimisticResponse?: 'rawResponse,
|
|
14
|
+
optimisticUpdater?: optimisticUpdaterFn,
|
|
15
|
+
updater?: updaterFn<'response>,
|
|
16
|
+
variables: 'variables,
|
|
17
|
+
uploadables?: uploadables,
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
let commitMutation: (
|
|
21
|
+
~convertVariables: 'variables => 'variables,
|
|
22
|
+
~node: mutationNode<'a>,
|
|
23
|
+
~convertResponse: 'response => 'response,
|
|
24
|
+
~convertWrapRawResponse: 'rawResponse => 'rawResponse,
|
|
25
|
+
) => (
|
|
26
|
+
~environment: Environment.t,
|
|
27
|
+
~variables: 'variables,
|
|
28
|
+
~optimisticUpdater: optimisticUpdaterFn=?,
|
|
29
|
+
~optimisticResponse: 'rawResponse=?,
|
|
30
|
+
~updater: (RecordSourceSelectorProxy.t, 'response) => unit=?,
|
|
31
|
+
~onCompleted: ('response, option<array<mutationError>>) => unit=?,
|
|
32
|
+
~onError: mutationError => unit=?,
|
|
33
|
+
~uploadables: uploadables=?,
|
|
34
|
+
unit,
|
|
35
|
+
) => Disposable.t
|
|
36
|
+
|
|
37
|
+
let useMutation: (
|
|
38
|
+
~convertVariables: 'variables => 'variables,
|
|
39
|
+
~node: mutationNode<'node>,
|
|
40
|
+
~convertResponse: 'response => 'response,
|
|
41
|
+
~convertWrapRawResponse: 'rawResponse => 'rawResponse,
|
|
42
|
+
) => unit => (
|
|
43
|
+
(
|
|
44
|
+
~variables: 'variables,
|
|
45
|
+
~optimisticUpdater: optimisticUpdaterFn=?,
|
|
46
|
+
~optimisticResponse: 'rawResponse=?,
|
|
47
|
+
~updater: (RecordSourceSelectorProxy.t, 'response) => unit=?,
|
|
48
|
+
~onCompleted: ('response, option<array<mutationError>>) => unit=?,
|
|
49
|
+
~onError: mutationError => unit=?,
|
|
50
|
+
~uploadables: uploadables=?,
|
|
51
|
+
unit,
|
|
52
|
+
) => Disposable.t,
|
|
53
|
+
bool,
|
|
54
|
+
)
|