rescript-relay 1.0.0-rc.4 → 1.0.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 +32 -5
- package/package.json +1 -1
- package/ppx-linux +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/RescriptRelay.res +6 -8
- package/src/experimental-router/RescriptRelayRouter.bs.js +0 -424
- package/src/experimental-router/RescriptRelayRouter.res +0 -379
- package/src/experimental-router/RescriptRelayRouter.resi +0 -77
package/CHANGELOG.md
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# master
|
|
2
2
|
|
|
3
|
-
# 1.0.0
|
|
3
|
+
# 1.0.0
|
|
4
4
|
|
|
5
5
|
_[Here's a commit showing a project being upgraded to this version](https://github.com/zth/rescript-relay/commit/5831c2f1f0f13eedc1cb60468c32fd32b2dc01d3)_
|
|
6
6
|
|
|
7
|
-
The time has finally come - RescriptRelay `1.0.0` is
|
|
7
|
+
The time has finally come - RescriptRelay `1.0.0` is released! This version brings a ton of new features and improvements. One of the the big major things this release brings is that the ReScript type generation for the Relay compiler has been completely rewritten, and fully integrated into the new Relay Rust compiler. The RescriptRelay fork of the compiler is available and maintained [here])(https://github.com/zth/relay/tree/rescript-relay).
|
|
8
8
|
|
|
9
9
|
## Upgrade versions
|
|
10
10
|
|
|
11
|
-
- `react-relay` and `relay-runtime` to
|
|
12
|
-
- `react` and `react-dom` to
|
|
11
|
+
- `react-relay` and `relay-runtime` to `>=14.1.0`
|
|
12
|
+
- `react` and `react-dom` to `>=18.0.0`
|
|
13
13
|
|
|
14
14
|
## Remove Packages
|
|
15
15
|
|
|
@@ -29,6 +29,15 @@ You can go ahead and remove these packages, that are no longer needed, as the co
|
|
|
29
29
|
- Bindings for `requiredFieldLogger` for logging when missing fields are encountered (kudos [Emilios1995](https://github.com/Emilios1995)).
|
|
30
30
|
- Improved utils for [dealing with enums](https://rescript-relay-documentation.vercel.app/docs/enums).
|
|
31
31
|
- `recordSourceRecords` is now typed as `Js.Json.t` rather than being abstract.
|
|
32
|
+
- Project now works in `"type": "module"` mode in `package.json` (kudos [cometkim](https://github.com/cometkim))
|
|
33
|
+
- The field name of the `id` field of the `Node` interface is now configurable via `schemaConfig: {nodeInterfaceIdField: "idNameHere"}`.
|
|
34
|
+
- Add support for experimental [Relay Resolvers](https://relay.dev/docs/next/guides/relay-resolvers). Undocumented so far, but looking at the [test](https://github.com/zth/rescript-relay/blob/master/packages/rescript-relay/__tests__/Test_relayResolvers.res) and [definition file](https://github.com/zth/rescript-relay/blob/master/packages/rescript-relay/__tests__/TestRelayUserResolver.res) should give you a hint of how it works.
|
|
35
|
+
- Support `@rescriptRelayIgnoreUnused` directive on fragment definitions to insert annotations that makes `reanalyze` consider all fields in the fragment used, even if they aren't.
|
|
36
|
+
- Support `@rescriptRelayAllowUnsafeEnum` directive on fields selecting enums, which will ignore safety measures for enums, meaning you won't need to add a catch all clause, etc. It'll essentially output the enum as an _input_ enum (as desribed in the docs).
|
|
37
|
+
- Support [provided variables](https://relay.dev/docs/api-reference/graphql-and-directives/#provided-variables). More info in the docs.
|
|
38
|
+
- Windows support! :tada:
|
|
39
|
+
- A `RelaySchemaAssets_graphql.res` is now emitted, containing type definitions for all enums and all input objects. This is designed to help with accessing and using enums and input objects outside of Relay's context. This means it'll be much easier to share makers for input objects, pass enums around, etc.
|
|
40
|
+
- Each fragment with a `@connection` now emits a `makeConnectionId` function that allows you to generate _type safe_ connection IDs. More on why this is useful in the documentation.
|
|
32
41
|
|
|
33
42
|
## Breaking changes
|
|
34
43
|
|
|
@@ -45,8 +54,27 @@ You can go ahead and remove these packages, that are no longer needed, as the co
|
|
|
45
54
|
|
|
46
55
|
More details on this [in the docs](https://rescript-relay-documentation.vercel.app/docs/refetching-and-loading-more-data#makerefetchvariables). Thanks to [@tsnobip](https://github.com/tsnobip) for fixing this!
|
|
47
56
|
|
|
57
|
+
- All enum type definitions now reside in `RelaySchemaAssets_graphql.enum_<yourEnumName>`, and are _not_ generated on the operation itself anymore. So, if you previously referred to the actual enum _type_, like `Fragment.Types.enum_MyFineEnum`, you'll now need to refer to that enum type as `RelaySchemaAssets_graphql.enum_MyFineEnum`.
|
|
58
|
+
- Input object fields with illegal names in ReScript previously had their maker function argument names suffixed with `_`, like `~type_: string`. This is now instead _prefixed_, like `~_type: string`. Prefixing like this instead of suffixing means we can ship fully zero cost maker functions, which we couldn't before for input objects with illegal field names.
|
|
59
|
+
|
|
60
|
+
## Assorted Changes and Fixes
|
|
61
|
+
|
|
62
|
+
- Add Environment isServer option @MoOx
|
|
63
|
+
- Remove rescript from dependencies @anmonteiro
|
|
64
|
+
- Add undocumented holdGC method on relay store @MoOx
|
|
65
|
+
- Fixed `setLinkedRecordToNull`, `setLinkedRecordToUndefined`, `setLinkedRecordsToNull` and `setLinkedRecordsToUndefined` methods by binding them to `setValue` instead of `setLinkedRecord/s`. Previously they were throwing an error because `setLinkedRecord/s` did not support "deleting" values using them. (@reck753)
|
|
66
|
+
- Fix long standing bug that would make whether connection helpers were emitted or not unreliable.
|
|
67
|
+
|
|
48
68
|
## 1.0.0 development changelog
|
|
49
69
|
|
|
70
|
+
- Fix bug in the new type safe connection ID makers where null default values wouldn't turn the variable into a `Js.Null.t<t>`, leading to type errors.
|
|
71
|
+
- Fix bug with connection handling where connections behind a `@include` or `@skip` directive would not be found.
|
|
72
|
+
- Move `getConnectionNodes` back into generated and auto included `Utils` module. This means that failing to generate `getConnectionNodes`, which can happen for various reasons, won't break the build, but rather not just emit the helper.
|
|
73
|
+
|
|
74
|
+
### rc.5
|
|
75
|
+
|
|
76
|
+
- Fix compat with `rescript@10.1.0-alpha.1`.
|
|
77
|
+
|
|
50
78
|
### rc.4
|
|
51
79
|
|
|
52
80
|
- _potentially breaking_ All enum type definitions now reside in `RelaySchemaAssets_graphql.enum_<yourEnumName>`, and are _not_ generated on the operation itself anymore. So, if you previously referred to the actual enum _type_, like `Fragment.Types.enum_MyFineEnum`, you'll now need to refer to that enum type as `RelaySchemaAssets_graphql.enum_MyFineEnum`.
|
|
@@ -63,7 +91,6 @@ You can go ahead and remove these packages, that are no longer needed, as the co
|
|
|
63
91
|
### rc.1
|
|
64
92
|
|
|
65
93
|
- Restore half-broken connection helper function inlining.
|
|
66
|
-
-
|
|
67
94
|
|
|
68
95
|
### rc.0
|
|
69
96
|
|
package/package.json
CHANGED
package/ppx-linux
CHANGED
|
Binary file
|
package/ppx-macos-latest
CHANGED
|
Binary file
|
package/ppx-windows-latest
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/src/RescriptRelay.res
CHANGED
|
@@ -573,8 +573,8 @@ module Store = {
|
|
|
573
573
|
make(
|
|
574
574
|
source,
|
|
575
575
|
{
|
|
576
|
-
gcReleaseBufferSize
|
|
577
|
-
queryCacheExpirationTime
|
|
576
|
+
gcReleaseBufferSize,
|
|
577
|
+
queryCacheExpirationTime,
|
|
578
578
|
},
|
|
579
579
|
)
|
|
580
580
|
|
|
@@ -751,9 +751,9 @@ module MakeLoadQuery = (C: MakeLoadQueryConfig) => {
|
|
|
751
751
|
C.query,
|
|
752
752
|
variables->C.convertVariables,
|
|
753
753
|
{
|
|
754
|
-
fetchKey
|
|
754
|
+
fetchKey,
|
|
755
755
|
fetchPolicy: fetchPolicy->mapFetchPolicy,
|
|
756
|
-
networkCacheConfig
|
|
756
|
+
networkCacheConfig,
|
|
757
757
|
},
|
|
758
758
|
)
|
|
759
759
|
|
|
@@ -770,10 +770,8 @@ module MakeLoadQuery = (C: MakeLoadQueryConfig) => {
|
|
|
770
770
|
switch token->queryRefToObservable {
|
|
771
771
|
| None => resolve(. Error())
|
|
772
772
|
| Some(o) =>
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
subscribe(makeObserver(~complete=() => resolve(. Ok()), ()))
|
|
776
|
-
}
|
|
773
|
+
open Observable
|
|
774
|
+
let _: subscription = o->subscribe(makeObserver(~complete=() => resolve(. Ok()), ()))
|
|
777
775
|
}
|
|
778
776
|
})
|
|
779
777
|
}
|
|
@@ -1,424 +0,0 @@
|
|
|
1
|
-
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
var Curry = require("rescript/lib/js/curry.js");
|
|
5
|
-
var React = require("react");
|
|
6
|
-
var Js_dict = require("rescript/lib/js/js_dict.js");
|
|
7
|
-
var Caml_obj = require("rescript/lib/js/caml_obj.js");
|
|
8
|
-
var Belt_Array = require("rescript/lib/js/belt_Array.js");
|
|
9
|
-
var Belt_Option = require("rescript/lib/js/belt_Option.js");
|
|
10
|
-
var Caml_option = require("rescript/lib/js/caml_option.js");
|
|
11
|
-
var Caml_exceptions = require("rescript/lib/js/caml_exceptions.js");
|
|
12
|
-
var ReactExperimental = require("../ReactExperimental.bs.js");
|
|
13
|
-
var RescriptReactRouter = require("@rescript/react/src/RescriptReactRouter.bs.js");
|
|
14
|
-
|
|
15
|
-
function matchesUrl(t, url) {
|
|
16
|
-
return Curry._1(t.matchesUrl, url);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function preload(t, url) {
|
|
20
|
-
return Curry._1(t.preload, url);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function render(t, url) {
|
|
24
|
-
return Curry._1(t.render, url);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function make(matchUrl, prepare, render) {
|
|
28
|
-
return {
|
|
29
|
-
preload: (function (url) {
|
|
30
|
-
var params = Curry._1(matchUrl, url);
|
|
31
|
-
if (params !== undefined) {
|
|
32
|
-
Curry._1(prepare, Caml_option.valFromOption(params));
|
|
33
|
-
return ;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
}),
|
|
37
|
-
matchesUrl: (function (url) {
|
|
38
|
-
return Curry._1(matchUrl, url) !== undefined;
|
|
39
|
-
}),
|
|
40
|
-
render: (function (url) {
|
|
41
|
-
var params = Curry._1(matchUrl, url);
|
|
42
|
-
if (params !== undefined) {
|
|
43
|
-
return Curry._1(render, Curry._1(prepare, Caml_option.valFromOption(params)));
|
|
44
|
-
} else {
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
47
|
-
})
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
var RouteFamily = {
|
|
52
|
-
matchesUrl: matchesUrl,
|
|
53
|
-
preload: preload,
|
|
54
|
-
render: render,
|
|
55
|
-
make: make
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
function getHash(url) {
|
|
59
|
-
var index = url.indexOf("#");
|
|
60
|
-
if (index >= 0) {
|
|
61
|
-
return url.slice(index + 1 | 0);
|
|
62
|
-
} else {
|
|
63
|
-
return String("");
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function pathParse(str) {
|
|
68
|
-
switch (str) {
|
|
69
|
-
case "" :
|
|
70
|
-
case "/" :
|
|
71
|
-
return /* [] */0;
|
|
72
|
-
default:
|
|
73
|
-
var raw = str.slice(1);
|
|
74
|
-
var match = raw[raw.length - 1 | 0];
|
|
75
|
-
var raw$1 = match === "/" ? raw.slice(0, -1) : raw;
|
|
76
|
-
var match$1 = raw$1.split("?", 2);
|
|
77
|
-
var raw$2 = match$1.length !== 2 ? raw$1 : match$1[0];
|
|
78
|
-
var a = raw$2.split("/").filter(function (item) {
|
|
79
|
-
return item.length !== 0;
|
|
80
|
-
});
|
|
81
|
-
var _i = a.length - 1 | 0;
|
|
82
|
-
var _res = /* [] */0;
|
|
83
|
-
while(true) {
|
|
84
|
-
var res = _res;
|
|
85
|
-
var i = _i;
|
|
86
|
-
if (i < 0) {
|
|
87
|
-
return res;
|
|
88
|
-
}
|
|
89
|
-
_res = {
|
|
90
|
-
hd: a[i],
|
|
91
|
-
tl: res
|
|
92
|
-
};
|
|
93
|
-
_i = i - 1 | 0;
|
|
94
|
-
continue ;
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function searchParse(str) {
|
|
100
|
-
switch (str) {
|
|
101
|
-
case "" :
|
|
102
|
-
case "?" :
|
|
103
|
-
return "";
|
|
104
|
-
default:
|
|
105
|
-
var match = str.split("?", 2);
|
|
106
|
-
if (match.length !== 2) {
|
|
107
|
-
return "";
|
|
108
|
-
} else {
|
|
109
|
-
return match[1];
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function parseUrl(url) {
|
|
115
|
-
return {
|
|
116
|
-
path: pathParse(url),
|
|
117
|
-
hash: getHash(url),
|
|
118
|
-
search: searchParse(url)
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
var context = React.createContext(undefined);
|
|
123
|
-
|
|
124
|
-
var make$1 = context.Provider;
|
|
125
|
-
|
|
126
|
-
function makeProps(value, children, param) {
|
|
127
|
-
return {
|
|
128
|
-
value: value,
|
|
129
|
-
children: children
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
var No_router_in_context = /* @__PURE__ */Caml_exceptions.create("RescriptRelayRouter.No_router_in_context");
|
|
134
|
-
|
|
135
|
-
function replaceShallow(path) {
|
|
136
|
-
var match = typeof history === "undefined" ? undefined : history;
|
|
137
|
-
var match$1 = typeof window === "undefined" ? undefined : window;
|
|
138
|
-
if (match !== undefined && match$1 !== undefined) {
|
|
139
|
-
match.replaceState(null, "", path);
|
|
140
|
-
return ;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
function pushShallow(path) {
|
|
146
|
-
var match = typeof history === "undefined" ? undefined : history;
|
|
147
|
-
var match$1 = typeof window === "undefined" ? undefined : window;
|
|
148
|
-
if (match !== undefined && match$1 !== undefined) {
|
|
149
|
-
match.pushState(null, "", path);
|
|
150
|
-
return ;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
var NavigationUtils = {
|
|
156
|
-
replaceShallow: replaceShallow,
|
|
157
|
-
pushShallow: pushShallow
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
function make$2(routes) {
|
|
161
|
-
var initialUrl = RescriptReactRouter.dangerouslyGetInitialUrl(undefined, undefined);
|
|
162
|
-
var matchRoutes = function (routes, url) {
|
|
163
|
-
return Belt_Array.getBy(routes, (function (r) {
|
|
164
|
-
return Curry._1(r.matchesUrl, url);
|
|
165
|
-
}));
|
|
166
|
-
};
|
|
167
|
-
var currentRoute = {
|
|
168
|
-
contents: {
|
|
169
|
-
route: matchRoutes(routes, initialUrl),
|
|
170
|
-
url: initialUrl
|
|
171
|
-
}
|
|
172
|
-
};
|
|
173
|
-
var subscribers = {};
|
|
174
|
-
var subId = {
|
|
175
|
-
contents: 0
|
|
176
|
-
};
|
|
177
|
-
var getNextId = function (param) {
|
|
178
|
-
subId.contents = subId.contents + 1 | 0;
|
|
179
|
-
return String(subId.contents);
|
|
180
|
-
};
|
|
181
|
-
RescriptReactRouter.watchUrl(function (url) {
|
|
182
|
-
if (!Caml_obj.caml_notequal(url.path, currentRoute.contents.url.path)) {
|
|
183
|
-
return ;
|
|
184
|
-
}
|
|
185
|
-
var route = matchRoutes(routes, url);
|
|
186
|
-
if (route !== undefined) {
|
|
187
|
-
Curry._1(route.preload, url);
|
|
188
|
-
}
|
|
189
|
-
var nextEntry = {
|
|
190
|
-
route: route,
|
|
191
|
-
url: url
|
|
192
|
-
};
|
|
193
|
-
currentRoute.contents = nextEntry;
|
|
194
|
-
return Belt_Array.forEach(Js_dict.values(subscribers), (function (x) {
|
|
195
|
-
if (x !== undefined) {
|
|
196
|
-
return Curry._1(x, nextEntry);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
}));
|
|
200
|
-
});
|
|
201
|
-
return {
|
|
202
|
-
get: (function (param) {
|
|
203
|
-
return currentRoute.contents;
|
|
204
|
-
}),
|
|
205
|
-
preload: (function (url) {
|
|
206
|
-
var asRouterUrl = parseUrl(url);
|
|
207
|
-
var r = matchRoutes(routes, asRouterUrl);
|
|
208
|
-
if (r !== undefined) {
|
|
209
|
-
return Curry._1(r.preload, asRouterUrl);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
}),
|
|
213
|
-
subscribe: (function (cb) {
|
|
214
|
-
var id = getNextId(undefined);
|
|
215
|
-
subscribers[id] = cb;
|
|
216
|
-
return function (param) {
|
|
217
|
-
subscribers[id] = undefined;
|
|
218
|
-
|
|
219
|
-
};
|
|
220
|
-
})
|
|
221
|
-
};
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
function useRouter(param) {
|
|
225
|
-
var router = React.useContext(context);
|
|
226
|
-
return React.useMemo((function () {
|
|
227
|
-
return {
|
|
228
|
-
push: RescriptReactRouter.push,
|
|
229
|
-
pushShallow: pushShallow,
|
|
230
|
-
replace: RescriptReactRouter.replace,
|
|
231
|
-
replaceShallow: pushShallow,
|
|
232
|
-
preload: router.preload
|
|
233
|
-
};
|
|
234
|
-
}), [router.preload]);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
function RescriptRelayRouter$RouteRenderer(Props) {
|
|
238
|
-
var renderPending = Props.renderPending;
|
|
239
|
-
var renderFallback = Props.renderFallback;
|
|
240
|
-
var renderNotFound = Props.renderNotFound;
|
|
241
|
-
var match = React.useState(function () {
|
|
242
|
-
return false;
|
|
243
|
-
});
|
|
244
|
-
var initialized = match[0];
|
|
245
|
-
var router = React.useContext(context);
|
|
246
|
-
var match$1 = ReactExperimental.useTransition(undefined);
|
|
247
|
-
var startTransition = match$1[1];
|
|
248
|
-
var match$2 = React.useState(function () {
|
|
249
|
-
return Curry._1(router.get, undefined);
|
|
250
|
-
});
|
|
251
|
-
var setRouteEntry = match$2[1];
|
|
252
|
-
var routeEntry = match$2[0];
|
|
253
|
-
var match$3 = routeEntry.route;
|
|
254
|
-
if (initialized || match$3 === undefined) {
|
|
255
|
-
|
|
256
|
-
} else {
|
|
257
|
-
Curry._1(match$3.preload, routeEntry.url);
|
|
258
|
-
Curry._1(match[1], (function (param) {
|
|
259
|
-
return true;
|
|
260
|
-
}));
|
|
261
|
-
}
|
|
262
|
-
React.useEffect((function () {
|
|
263
|
-
var currentEntry = Curry._1(router.get, undefined);
|
|
264
|
-
if (Caml_obj.caml_notequal(routeEntry.url, currentEntry.url)) {
|
|
265
|
-
Curry._1(setRouteEntry, (function (param) {
|
|
266
|
-
return currentEntry;
|
|
267
|
-
}));
|
|
268
|
-
return ;
|
|
269
|
-
} else {
|
|
270
|
-
return Curry._1(router.subscribe, (function (nextRoute) {
|
|
271
|
-
return Curry._1(startTransition, (function (param) {
|
|
272
|
-
return Curry._1(setRouteEntry, (function (param) {
|
|
273
|
-
return nextRoute;
|
|
274
|
-
}));
|
|
275
|
-
}));
|
|
276
|
-
}));
|
|
277
|
-
}
|
|
278
|
-
}), [
|
|
279
|
-
router,
|
|
280
|
-
startTransition
|
|
281
|
-
]);
|
|
282
|
-
var match$4 = routeEntry.route;
|
|
283
|
-
var renderedContent = initialized && match$4 !== undefined ? Caml_option.some(Curry._1(match$4.render, routeEntry.url)) : undefined;
|
|
284
|
-
if (initialized) {
|
|
285
|
-
return React.createElement(React.Fragment, undefined, renderPending !== undefined ? Curry._1(renderPending, match$1[0]) : null, React.createElement(React.Suspense, {
|
|
286
|
-
children: renderedContent !== undefined ? Caml_option.valFromOption(renderedContent) : (
|
|
287
|
-
renderNotFound !== undefined ? Curry._1(renderNotFound, routeEntry.url) : null
|
|
288
|
-
),
|
|
289
|
-
fallback: renderFallback !== undefined ? Curry._1(renderFallback, undefined) : null
|
|
290
|
-
}));
|
|
291
|
-
} else {
|
|
292
|
-
return null;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
var RouteRenderer = {
|
|
297
|
-
make: RescriptRelayRouter$RouteRenderer
|
|
298
|
-
};
|
|
299
|
-
|
|
300
|
-
function isModifiedEvent(e) {
|
|
301
|
-
var match = e.metaKey;
|
|
302
|
-
var match$1 = e.altKey;
|
|
303
|
-
var match$2 = e.ctrlKey;
|
|
304
|
-
var match$3 = e.shiftKey;
|
|
305
|
-
if (match$2 || match$3 || match$1 || match) {
|
|
306
|
-
return true;
|
|
307
|
-
} else {
|
|
308
|
-
return false;
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
function RescriptRelayRouter$Link(Props) {
|
|
313
|
-
var to_ = Props.to_;
|
|
314
|
-
var title = Props.title;
|
|
315
|
-
var id = Props.id;
|
|
316
|
-
var className = Props.className;
|
|
317
|
-
var classNameDynamic = Props.classNameDynamic;
|
|
318
|
-
var browserTarget = Props.target;
|
|
319
|
-
var tabIndex = Props.tabIndex;
|
|
320
|
-
var mode = Props.mode;
|
|
321
|
-
var render = Props.render;
|
|
322
|
-
var preloadOnHover = Props.preloadOnHover;
|
|
323
|
-
var children = Props.children;
|
|
324
|
-
var onClick = Props.onClick;
|
|
325
|
-
var router = React.useContext(context);
|
|
326
|
-
var url = RescriptReactRouter.useUrl(undefined, undefined);
|
|
327
|
-
var changeRoute = React.useCallback((function (e) {
|
|
328
|
-
var match = e.isDefaultPrevented();
|
|
329
|
-
var match$1 = e.button;
|
|
330
|
-
var match$2 = isModifiedEvent(e);
|
|
331
|
-
if (match) {
|
|
332
|
-
return ;
|
|
333
|
-
}
|
|
334
|
-
if (match$1 !== 0) {
|
|
335
|
-
return ;
|
|
336
|
-
}
|
|
337
|
-
if (browserTarget !== undefined && browserTarget !== "self") {
|
|
338
|
-
return ;
|
|
339
|
-
}
|
|
340
|
-
if (match$2) {
|
|
341
|
-
return ;
|
|
342
|
-
}
|
|
343
|
-
e.preventDefault();
|
|
344
|
-
var navigate = function (param) {
|
|
345
|
-
if (mode === "replace") {
|
|
346
|
-
return RescriptReactRouter.replace(to_);
|
|
347
|
-
} else {
|
|
348
|
-
return RescriptReactRouter.push(to_);
|
|
349
|
-
}
|
|
350
|
-
};
|
|
351
|
-
navigate(undefined);
|
|
352
|
-
|
|
353
|
-
}), [
|
|
354
|
-
to_,
|
|
355
|
-
router
|
|
356
|
-
]);
|
|
357
|
-
var preload = React.useCallback((function (param) {
|
|
358
|
-
return Curry._1(router.preload, to_);
|
|
359
|
-
}), [
|
|
360
|
-
to_,
|
|
361
|
-
router
|
|
362
|
-
]);
|
|
363
|
-
if (render !== undefined) {
|
|
364
|
-
var linkUrl = parseUrl(to_);
|
|
365
|
-
return Curry._4(render, preload, changeRoute, url, linkUrl);
|
|
366
|
-
}
|
|
367
|
-
var tmp = {
|
|
368
|
-
className: Belt_Option.getWithDefault(className, "") + (
|
|
369
|
-
classNameDynamic !== undefined ? " " + Curry._2(classNameDynamic, url, parseUrl(to_)) : ""
|
|
370
|
-
),
|
|
371
|
-
href: to_,
|
|
372
|
-
target: browserTarget !== undefined ? (
|
|
373
|
-
browserTarget === "blank" ? "_blank" : "_self"
|
|
374
|
-
) : "",
|
|
375
|
-
onClick: (function (e) {
|
|
376
|
-
Curry._1(changeRoute, e);
|
|
377
|
-
if (onClick !== undefined) {
|
|
378
|
-
return Curry._1(onClick, undefined);
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
}),
|
|
382
|
-
onMouseDown: (function (param) {
|
|
383
|
-
return Curry._1(preload, undefined);
|
|
384
|
-
}),
|
|
385
|
-
onMouseEnter: (function (param) {
|
|
386
|
-
if (preloadOnHover !== undefined && preloadOnHover) {
|
|
387
|
-
return Curry._1(preload, undefined);
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
}),
|
|
391
|
-
onTouchStart: (function (param) {
|
|
392
|
-
return Curry._1(preload, undefined);
|
|
393
|
-
})
|
|
394
|
-
};
|
|
395
|
-
if (id !== undefined) {
|
|
396
|
-
tmp.id = Caml_option.valFromOption(id);
|
|
397
|
-
}
|
|
398
|
-
if (tabIndex !== undefined) {
|
|
399
|
-
tmp.tabIndex = Caml_option.valFromOption(tabIndex);
|
|
400
|
-
}
|
|
401
|
-
if (title !== undefined) {
|
|
402
|
-
tmp.title = Caml_option.valFromOption(title);
|
|
403
|
-
}
|
|
404
|
-
return React.createElement("a", tmp, children);
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
var Link = {
|
|
408
|
-
make: RescriptRelayRouter$Link
|
|
409
|
-
};
|
|
410
|
-
|
|
411
|
-
var Provider = {
|
|
412
|
-
makeProps: makeProps,
|
|
413
|
-
make: make$1
|
|
414
|
-
};
|
|
415
|
-
|
|
416
|
-
exports.RouteFamily = RouteFamily;
|
|
417
|
-
exports.Provider = Provider;
|
|
418
|
-
exports.No_router_in_context = No_router_in_context;
|
|
419
|
-
exports.useRouter = useRouter;
|
|
420
|
-
exports.make = make$2;
|
|
421
|
-
exports.RouteRenderer = RouteRenderer;
|
|
422
|
-
exports.Link = Link;
|
|
423
|
-
exports.NavigationUtils = NavigationUtils;
|
|
424
|
-
/* context Not a pure module */
|
|
@@ -1,379 +0,0 @@
|
|
|
1
|
-
module RouteFamily = {
|
|
2
|
-
type t = {
|
|
3
|
-
preload: RescriptReactRouter.url => unit,
|
|
4
|
-
matchesUrl: RescriptReactRouter.url => bool,
|
|
5
|
-
render: RescriptReactRouter.url => React.element,
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
let matchesUrl = (t, url) => t.matchesUrl(url)
|
|
9
|
-
let preload = (t, url) => t.preload(url)
|
|
10
|
-
let render = (t, url) => t.render(url)
|
|
11
|
-
|
|
12
|
-
let make = (~matchUrl, ~prepare, ~render) => {
|
|
13
|
-
preload: url =>
|
|
14
|
-
switch matchUrl(url) {
|
|
15
|
-
| Some(params) =>
|
|
16
|
-
let _ = prepare(params)
|
|
17
|
-
| None => ()
|
|
18
|
-
},
|
|
19
|
-
matchesUrl: url =>
|
|
20
|
-
switch matchUrl(url) {
|
|
21
|
-
| Some(_) => true
|
|
22
|
-
| None => false
|
|
23
|
-
},
|
|
24
|
-
render: url =>
|
|
25
|
-
switch matchUrl(url) {
|
|
26
|
-
| Some(params) => params->prepare->render
|
|
27
|
-
| None => React.null
|
|
28
|
-
},
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
module Url = {
|
|
33
|
-
type t = RescriptReactRouter.url
|
|
34
|
-
|
|
35
|
-
let getHash = url => {
|
|
36
|
-
switch url->Js.String2.indexOf("#") {
|
|
37
|
-
| index if index >= 0 => url->Js.String2.sliceToEnd(~from=index + 1)
|
|
38
|
-
| _ => Js.String2.make("")
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Start - taken from RescriptReactRouter
|
|
43
|
-
let arrayToList = a => {
|
|
44
|
-
let rec tolist = (i, res) =>
|
|
45
|
-
if i < 0 {
|
|
46
|
-
res
|
|
47
|
-
} else {
|
|
48
|
-
tolist(i - 1, list{Js.Array.unsafe_get(a, i), ...res})
|
|
49
|
-
}
|
|
50
|
-
tolist(Js.Array.length(a) - 1, list{})
|
|
51
|
-
}
|
|
52
|
-
let pathParse = str =>
|
|
53
|
-
switch str {
|
|
54
|
-
| ""
|
|
55
|
-
| "/" => list{}
|
|
56
|
-
| raw =>
|
|
57
|
-
/* remove the preceeding /, which every pathname seems to have */
|
|
58
|
-
let raw = Js.String.sliceToEnd(~from=1, raw)
|
|
59
|
-
/* remove the trailing /, which some pathnames might have. Ugh */
|
|
60
|
-
let raw = switch Js.String.get(raw, Js.String.length(raw) - 1) {
|
|
61
|
-
| "/" => Js.String.slice(~from=0, ~to_=-1, raw)
|
|
62
|
-
| _ => raw
|
|
63
|
-
}
|
|
64
|
-
/* remove search portion if present in string */
|
|
65
|
-
let raw = switch raw |> Js.String.splitAtMost("?", ~limit=2) {
|
|
66
|
-
| [path, _] => path
|
|
67
|
-
| _ => raw
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
raw
|
|
71
|
-
|> Js.String.split("/")
|
|
72
|
-
|> Js.Array.filter(item => String.length(item) != 0)
|
|
73
|
-
|> arrayToList
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
let searchParse = str =>
|
|
77
|
-
switch str {
|
|
78
|
-
| ""
|
|
79
|
-
| "?" => ""
|
|
80
|
-
| raw =>
|
|
81
|
-
switch raw |> Js.String.splitAtMost("?", ~limit=2) {
|
|
82
|
-
| [_, search] => search
|
|
83
|
-
| _ => ""
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
// End - taken from RescriptReactRouter
|
|
87
|
-
|
|
88
|
-
let parseUrl = (url: string): t => {
|
|
89
|
-
path: url->pathParse,
|
|
90
|
-
hash: url->getHash,
|
|
91
|
-
search: url->searchParse,
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
let make = url => url->parseUrl
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
type routeEntry = {
|
|
98
|
-
route: option<RouteFamily.t>,
|
|
99
|
-
url: RescriptReactRouter.url,
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
type subscriberCallback = routeEntry => unit
|
|
103
|
-
type disposeSubscriber = unit => unit
|
|
104
|
-
|
|
105
|
-
type routerContext = {
|
|
106
|
-
get: unit => routeEntry,
|
|
107
|
-
preload: string => unit,
|
|
108
|
-
subscribe: subscriberCallback => disposeSubscriber,
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
let context = React.createContext(Obj.magic())
|
|
112
|
-
|
|
113
|
-
module Provider = {
|
|
114
|
-
let make = React.Context.provider(context)
|
|
115
|
-
|
|
116
|
-
let makeProps = (~value, ~children, ()) =>
|
|
117
|
-
{
|
|
118
|
-
"value": value,
|
|
119
|
-
"children": children,
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
exception No_router_in_context
|
|
124
|
-
|
|
125
|
-
module NavigationUtils = {
|
|
126
|
-
@send
|
|
127
|
-
external replaceShallow: (Dom.history, @as(json`null`) _, @as("") _, ~href: string) => unit =
|
|
128
|
-
"replaceState"
|
|
129
|
-
|
|
130
|
-
let replaceShallow = path =>
|
|
131
|
-
switch (%external(history), %external(window)) {
|
|
132
|
-
| (None, _)
|
|
133
|
-
| (_, None) => ()
|
|
134
|
-
| (Some(history: Dom.history), Some(_window: Dom.window)) => replaceShallow(history, ~href=path)
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
@send
|
|
138
|
-
external pushShallow: (Dom.history, @as(json`null`) _, @as("") _, ~href: string) => unit =
|
|
139
|
-
"pushState"
|
|
140
|
-
|
|
141
|
-
let pushShallow = path =>
|
|
142
|
-
switch (%external(history), %external(window)) {
|
|
143
|
-
| (None, _)
|
|
144
|
-
| (_, None) => ()
|
|
145
|
-
| (Some(history: Dom.history), Some(_window: Dom.window)) => pushShallow(history, ~href=path)
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
let use = (): routerContext => React.useContext(context)
|
|
150
|
-
|
|
151
|
-
let make = routes => {
|
|
152
|
-
let initialUrl = RescriptReactRouter.dangerouslyGetInitialUrl()
|
|
153
|
-
|
|
154
|
-
let matchRoutes = (routes, url): option<RouteFamily.t> =>
|
|
155
|
-
routes->Belt.Array.getBy(r => r->RouteFamily.matchesUrl(url))
|
|
156
|
-
|
|
157
|
-
let currentRoute: ref<routeEntry> = ref({url: initialUrl, route: matchRoutes(routes, initialUrl)})
|
|
158
|
-
|
|
159
|
-
let subscribers: Js.Dict.t<option<subscriberCallback>> = Js.Dict.empty()
|
|
160
|
-
let subId = ref(0)
|
|
161
|
-
|
|
162
|
-
let getNextId = () => {
|
|
163
|
-
subId := subId.contents + 1
|
|
164
|
-
subId.contents->string_of_int
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
let _ = RescriptReactRouter.watchUrl(url =>
|
|
168
|
-
if url.path != currentRoute.contents.url.path {
|
|
169
|
-
let route = matchRoutes(routes, url)
|
|
170
|
-
|
|
171
|
-
switch route {
|
|
172
|
-
| Some(r) => r->RouteFamily.preload(url)
|
|
173
|
-
| None => ()
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
let nextEntry = {route: route, url: url}
|
|
177
|
-
|
|
178
|
-
currentRoute := nextEntry
|
|
179
|
-
subscribers
|
|
180
|
-
->Js.Dict.values
|
|
181
|
-
->Belt.Array.forEach(x =>
|
|
182
|
-
switch x {
|
|
183
|
-
| Some(cb) => cb(nextEntry)
|
|
184
|
-
| None => ()
|
|
185
|
-
}
|
|
186
|
-
)
|
|
187
|
-
}
|
|
188
|
-
)
|
|
189
|
-
|
|
190
|
-
let router = {
|
|
191
|
-
get: () => currentRoute.contents,
|
|
192
|
-
preload: url => {
|
|
193
|
-
let asRouterUrl = url->Url.make
|
|
194
|
-
|
|
195
|
-
switch routes->matchRoutes(asRouterUrl) {
|
|
196
|
-
| Some(r) => r->RouteFamily.preload(asRouterUrl)
|
|
197
|
-
| None => ()
|
|
198
|
-
}
|
|
199
|
-
},
|
|
200
|
-
subscribe: cb => {
|
|
201
|
-
let id = getNextId()
|
|
202
|
-
subscribers->Js.Dict.set(id, Some(cb))
|
|
203
|
-
() => subscribers->Js.Dict.set(id, None)
|
|
204
|
-
},
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
router
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
type router = {
|
|
211
|
-
push: string => unit,
|
|
212
|
-
pushShallow: string => unit,
|
|
213
|
-
replace: string => unit,
|
|
214
|
-
replaceShallow: string => unit,
|
|
215
|
-
preload: string => unit,
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
let useRouter = () => {
|
|
219
|
-
let router = use()
|
|
220
|
-
|
|
221
|
-
React.useMemo1(() => {
|
|
222
|
-
push: RescriptReactRouter.push,
|
|
223
|
-
pushShallow: NavigationUtils.pushShallow,
|
|
224
|
-
replace: RescriptReactRouter.replace,
|
|
225
|
-
replaceShallow: NavigationUtils.pushShallow,
|
|
226
|
-
preload: router.preload,
|
|
227
|
-
}, [router.preload])
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
module RouteRenderer = {
|
|
231
|
-
@react.component
|
|
232
|
-
let make = (~renderPending=?, ~renderFallback=?, ~renderNotFound=?, ()) => {
|
|
233
|
-
let (initialized, setInitialized) = React.useState(() => false)
|
|
234
|
-
let router = use()
|
|
235
|
-
|
|
236
|
-
let (isPending, startTransition) = ReactExperimental.useTransition()
|
|
237
|
-
|
|
238
|
-
let (routeEntry, setRouteEntry) = React.useState(() => router.get())
|
|
239
|
-
|
|
240
|
-
switch (initialized, routeEntry.route) {
|
|
241
|
-
| (false, Some(r)) =>
|
|
242
|
-
r->RouteFamily.preload(routeEntry.url)
|
|
243
|
-
setInitialized(_ => true)
|
|
244
|
-
| _ => ()
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
React.useEffect2(() => {
|
|
248
|
-
let currentEntry = router.get()
|
|
249
|
-
if routeEntry.url != currentEntry.url {
|
|
250
|
-
setRouteEntry(_ => currentEntry)
|
|
251
|
-
None
|
|
252
|
-
} else {
|
|
253
|
-
let dispose = router.subscribe(nextRoute =>
|
|
254
|
-
startTransition(() => setRouteEntry(_ => nextRoute))
|
|
255
|
-
)
|
|
256
|
-
|
|
257
|
-
Some(dispose)
|
|
258
|
-
}
|
|
259
|
-
}, (router, startTransition))
|
|
260
|
-
|
|
261
|
-
let renderedContent = switch (initialized, routeEntry.route) {
|
|
262
|
-
| (false, Some(_) | None) => None
|
|
263
|
-
| (true, Some(r)) => Some(r->RouteFamily.render(routeEntry.url))
|
|
264
|
-
| (true, None) => None
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
initialized
|
|
268
|
-
? <>
|
|
269
|
-
{switch renderPending {
|
|
270
|
-
| Some(renderPending) => renderPending(isPending)
|
|
271
|
-
| None => React.null
|
|
272
|
-
}}
|
|
273
|
-
<React.Suspense
|
|
274
|
-
fallback={switch renderFallback {
|
|
275
|
-
| Some(renderFallback) => renderFallback()
|
|
276
|
-
| None => React.null
|
|
277
|
-
}}>
|
|
278
|
-
{switch (renderedContent, renderNotFound) {
|
|
279
|
-
| (Some(content), _) => content
|
|
280
|
-
| (None, Some(renderNotFound)) => renderNotFound(routeEntry.url)
|
|
281
|
-
| (None, None) => React.null
|
|
282
|
-
}}
|
|
283
|
-
</React.Suspense>
|
|
284
|
-
</>
|
|
285
|
-
: React.null
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
let isModifiedEvent = e => {
|
|
290
|
-
open ReactEvent.Mouse
|
|
291
|
-
switch (e->metaKey, e->altKey, e->ctrlKey, e->shiftKey) {
|
|
292
|
-
| (true, _, _, _)
|
|
293
|
-
| (_, true, _, _) => true
|
|
294
|
-
| (_, _, true, _) => true
|
|
295
|
-
| (_, _, _, true) => true
|
|
296
|
-
| _ => false
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
module Link = {
|
|
301
|
-
@react.component
|
|
302
|
-
let make = (
|
|
303
|
-
~to_,
|
|
304
|
-
~title=?,
|
|
305
|
-
~id=?,
|
|
306
|
-
~className=?,
|
|
307
|
-
~classNameDynamic=?,
|
|
308
|
-
~target as browserTarget=?,
|
|
309
|
-
~tabIndex=?,
|
|
310
|
-
~mode=?,
|
|
311
|
-
~render=?,
|
|
312
|
-
~preloadOnHover=?,
|
|
313
|
-
~children,
|
|
314
|
-
~onClick=?,
|
|
315
|
-
(),
|
|
316
|
-
) => {
|
|
317
|
-
let router = use()
|
|
318
|
-
let url = RescriptReactRouter.useUrl()
|
|
319
|
-
|
|
320
|
-
let changeRoute = React.useCallback2(e => {
|
|
321
|
-
open ReactEvent.Mouse
|
|
322
|
-
switch (e->isDefaultPrevented, e->button, browserTarget, e->isModifiedEvent) {
|
|
323
|
-
| (false, 0, None | Some(#self), false) =>
|
|
324
|
-
e->preventDefault
|
|
325
|
-
let navigate = () =>
|
|
326
|
-
switch mode {
|
|
327
|
-
| None
|
|
328
|
-
| Some(#push) =>
|
|
329
|
-
RescriptReactRouter.push(to_)
|
|
330
|
-
| Some(#replace) => RescriptReactRouter.replace(to_)
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
navigate()
|
|
334
|
-
()
|
|
335
|
-
| _ => ()
|
|
336
|
-
}
|
|
337
|
-
}, (to_, router))
|
|
338
|
-
|
|
339
|
-
let preload = React.useCallback2(() => router.preload(to_), (to_, router))
|
|
340
|
-
|
|
341
|
-
switch render {
|
|
342
|
-
| Some(render) =>
|
|
343
|
-
let linkUrl = to_->Url.make
|
|
344
|
-
render(~preload, ~changeRoute, ~currentUrl=url, ~linkUrl)
|
|
345
|
-
| None =>
|
|
346
|
-
<a
|
|
347
|
-
href=to_
|
|
348
|
-
target={switch browserTarget {
|
|
349
|
-
| Some(#self) => "_self"
|
|
350
|
-
| Some(#blank) => "_blank"
|
|
351
|
-
| None => ""
|
|
352
|
-
}}
|
|
353
|
-
?title
|
|
354
|
-
?id
|
|
355
|
-
?tabIndex
|
|
356
|
-
className={className->Belt.Option.getWithDefault("") ++
|
|
357
|
-
switch classNameDynamic {
|
|
358
|
-
| Some(f) => " " ++ f(url, to_->Url.make)
|
|
359
|
-
| None => ""
|
|
360
|
-
}}
|
|
361
|
-
onClick={e => {
|
|
362
|
-
changeRoute(e)
|
|
363
|
-
switch onClick {
|
|
364
|
-
| None => ()
|
|
365
|
-
| Some(onClick) => onClick()
|
|
366
|
-
}
|
|
367
|
-
}}
|
|
368
|
-
onMouseDown={_ => preload()}
|
|
369
|
-
onTouchStart={_ => preload()}
|
|
370
|
-
onMouseEnter={_ =>
|
|
371
|
-
switch preloadOnHover {
|
|
372
|
-
| Some(true) => preload()
|
|
373
|
-
| Some(false) | None => ()
|
|
374
|
-
}}>
|
|
375
|
-
children
|
|
376
|
-
</a>
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
module RouteFamily: {
|
|
2
|
-
type t
|
|
3
|
-
|
|
4
|
-
let matchesUrl: (t, RescriptReactRouter.url) => bool
|
|
5
|
-
let preload: (t, RescriptReactRouter.url) => unit
|
|
6
|
-
let render: (t, RescriptReactRouter.url) => React.element
|
|
7
|
-
let make: (
|
|
8
|
-
~matchUrl: RescriptReactRouter.url => option<'routeVariables>,
|
|
9
|
-
~prepare: 'routeVariables => 'prepared,
|
|
10
|
-
~render: 'prepared => React.element,
|
|
11
|
-
) => t
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
type routerContext
|
|
15
|
-
|
|
16
|
-
module Provider: {
|
|
17
|
-
let makeProps: (
|
|
18
|
-
~value: routerContext,
|
|
19
|
-
~children: React.element,
|
|
20
|
-
unit,
|
|
21
|
-
) => {"value": routerContext, "children": React.element}
|
|
22
|
-
|
|
23
|
-
let make: React.component<{"value": routerContext, "children": React.element}>
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
exception No_router_in_context
|
|
27
|
-
|
|
28
|
-
type router = {
|
|
29
|
-
push: string => unit,
|
|
30
|
-
pushShallow: string => unit,
|
|
31
|
-
replace: string => unit,
|
|
32
|
-
replaceShallow: string => unit,
|
|
33
|
-
preload: string => unit,
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
let useRouter: unit => router
|
|
37
|
-
|
|
38
|
-
let make: array<RouteFamily.t> => routerContext
|
|
39
|
-
|
|
40
|
-
module RouteRenderer: {
|
|
41
|
-
@react.component
|
|
42
|
-
let make: (
|
|
43
|
-
~renderPending: bool => React.element=?,
|
|
44
|
-
~renderFallback: unit => React.element=?,
|
|
45
|
-
~renderNotFound: RescriptReactRouter.url => React.element=?,
|
|
46
|
-
unit,
|
|
47
|
-
) => React.element
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
module Link: {
|
|
51
|
-
@react.component
|
|
52
|
-
let make: (
|
|
53
|
-
~to_: string,
|
|
54
|
-
~title: string=?,
|
|
55
|
-
~id: string=?,
|
|
56
|
-
~className: string=?,
|
|
57
|
-
~classNameDynamic: (RescriptReactRouter.url, RescriptReactRouter.url) => string=?,
|
|
58
|
-
~target: [#self | #blank]=?,
|
|
59
|
-
~tabIndex: int=?,
|
|
60
|
-
~mode: [#push | #replace]=?,
|
|
61
|
-
~render: (
|
|
62
|
-
~preload: unit => unit,
|
|
63
|
-
~changeRoute: ReactEvent.Mouse.t => unit,
|
|
64
|
-
~currentUrl: RescriptReactRouter.url,
|
|
65
|
-
~linkUrl: RescriptReactRouter.url,
|
|
66
|
-
) => React.element=?,
|
|
67
|
-
~preloadOnHover: bool=?,
|
|
68
|
-
~children: React.element,
|
|
69
|
-
~onClick: unit => unit=?,
|
|
70
|
-
unit,
|
|
71
|
-
) => React.element
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
module NavigationUtils: {
|
|
75
|
-
let replaceShallow: string => unit
|
|
76
|
-
let pushShallow: string => unit
|
|
77
|
-
}
|