xote 4.3.0 → 4.4.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.
@@ -0,0 +1,356 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Core__Option from "@rescript/core/src/Core__Option.res.mjs";
4
+ import * as Xote__Component from "./Xote__Component.res.mjs";
5
+ import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
6
+
7
+ function jsx(component, props) {
8
+ return component(props);
9
+ }
10
+
11
+ function jsxs(component, props) {
12
+ return component(props);
13
+ }
14
+
15
+ function jsxKeyed(component, props, key, param) {
16
+ return component(props);
17
+ }
18
+
19
+ function jsxsKeyed(component, props, key, param) {
20
+ return component(props);
21
+ }
22
+
23
+ function jsxFragment(props) {
24
+ let child = props.children;
25
+ if (child !== undefined) {
26
+ return child;
27
+ } else {
28
+ return Xote__Component.fragment([]);
29
+ }
30
+ }
31
+
32
+ let array = Xote__Component.fragment;
33
+
34
+ function $$null() {
35
+ return Xote__Component.text("");
36
+ }
37
+
38
+ function signal(s) {
39
+ return s;
40
+ }
41
+
42
+ function computed(f) {
43
+ return f;
44
+ }
45
+
46
+ function convertAttrValue(key, value) {
47
+ if (typeof value === "function") {
48
+ return Xote__Component.computedAttr(key, value);
49
+ } else if (typeof value === "object" && Core__Option.isSome(value.id)) {
50
+ return Xote__Component.signalAttr(key, value);
51
+ } else {
52
+ return Xote__Component.attr(key, value);
53
+ }
54
+ }
55
+
56
+ function propsToAttrs(props) {
57
+ let attrs = [];
58
+ let v = props.id;
59
+ if (v !== undefined) {
60
+ attrs.push(convertAttrValue("id", Primitive_option.valFromOption(v)));
61
+ }
62
+ let v$1 = props.class;
63
+ if (v$1 !== undefined) {
64
+ attrs.push(convertAttrValue("class", Primitive_option.valFromOption(v$1)));
65
+ }
66
+ let v$2 = props.style;
67
+ if (v$2 !== undefined) {
68
+ attrs.push(convertAttrValue("style", Primitive_option.valFromOption(v$2)));
69
+ }
70
+ let v$3 = props.type;
71
+ if (v$3 !== undefined) {
72
+ attrs.push(convertAttrValue("type", Primitive_option.valFromOption(v$3)));
73
+ }
74
+ let v$4 = props.name;
75
+ if (v$4 !== undefined) {
76
+ attrs.push(convertAttrValue("name", Primitive_option.valFromOption(v$4)));
77
+ }
78
+ let v$5 = props.value;
79
+ if (v$5 !== undefined) {
80
+ attrs.push(convertAttrValue("value", Primitive_option.valFromOption(v$5)));
81
+ }
82
+ let v$6 = props.placeholder;
83
+ if (v$6 !== undefined) {
84
+ attrs.push(convertAttrValue("placeholder", Primitive_option.valFromOption(v$6)));
85
+ }
86
+ let match = props.disabled;
87
+ if (match !== undefined && match) {
88
+ attrs.push(Xote__Component.attr("disabled", "true"));
89
+ }
90
+ let match$1 = props.checked;
91
+ if (match$1 !== undefined && match$1) {
92
+ attrs.push(Xote__Component.attr("checked", "true"));
93
+ }
94
+ let match$2 = props.required;
95
+ if (match$2 !== undefined && match$2) {
96
+ attrs.push(Xote__Component.attr("required", "true"));
97
+ }
98
+ let match$3 = props.readOnly;
99
+ if (match$3 !== undefined && match$3) {
100
+ attrs.push(Xote__Component.attr("readonly", "true"));
101
+ }
102
+ let v$7 = props.maxLength;
103
+ if (v$7 !== undefined) {
104
+ attrs.push(Xote__Component.attr("maxlength", v$7.toString()));
105
+ }
106
+ let v$8 = props.minLength;
107
+ if (v$8 !== undefined) {
108
+ attrs.push(Xote__Component.attr("minlength", v$8.toString()));
109
+ }
110
+ let v$9 = props.min;
111
+ if (v$9 !== undefined) {
112
+ attrs.push(convertAttrValue("min", Primitive_option.valFromOption(v$9)));
113
+ }
114
+ let v$10 = props.max;
115
+ if (v$10 !== undefined) {
116
+ attrs.push(convertAttrValue("max", Primitive_option.valFromOption(v$10)));
117
+ }
118
+ let v$11 = props.step;
119
+ if (v$11 !== undefined) {
120
+ attrs.push(convertAttrValue("step", Primitive_option.valFromOption(v$11)));
121
+ }
122
+ let v$12 = props.pattern;
123
+ if (v$12 !== undefined) {
124
+ attrs.push(convertAttrValue("pattern", Primitive_option.valFromOption(v$12)));
125
+ }
126
+ let v$13 = props.autoComplete;
127
+ if (v$13 !== undefined) {
128
+ attrs.push(convertAttrValue("autocomplete", Primitive_option.valFromOption(v$13)));
129
+ }
130
+ let match$4 = props.multiple;
131
+ if (match$4 !== undefined && match$4) {
132
+ attrs.push(Xote__Component.attr("multiple", "true"));
133
+ }
134
+ let v$14 = props.accept;
135
+ if (v$14 !== undefined) {
136
+ attrs.push(convertAttrValue("accept", Primitive_option.valFromOption(v$14)));
137
+ }
138
+ let v$15 = props.rows;
139
+ if (v$15 !== undefined) {
140
+ attrs.push(Xote__Component.attr("rows", v$15.toString()));
141
+ }
142
+ let v$16 = props.cols;
143
+ if (v$16 !== undefined) {
144
+ attrs.push(Xote__Component.attr("cols", v$16.toString()));
145
+ }
146
+ let v$17 = props.for;
147
+ if (v$17 !== undefined) {
148
+ attrs.push(convertAttrValue("for", Primitive_option.valFromOption(v$17)));
149
+ }
150
+ let v$18 = props.href;
151
+ if (v$18 !== undefined) {
152
+ attrs.push(convertAttrValue("href", Primitive_option.valFromOption(v$18)));
153
+ }
154
+ let v$19 = props.target;
155
+ if (v$19 !== undefined) {
156
+ attrs.push(convertAttrValue("target", Primitive_option.valFromOption(v$19)));
157
+ }
158
+ let v$20 = props.src;
159
+ if (v$20 !== undefined) {
160
+ attrs.push(convertAttrValue("src", Primitive_option.valFromOption(v$20)));
161
+ }
162
+ let v$21 = props.alt;
163
+ if (v$21 !== undefined) {
164
+ attrs.push(convertAttrValue("alt", Primitive_option.valFromOption(v$21)));
165
+ }
166
+ let v$22 = props.width;
167
+ if (v$22 !== undefined) {
168
+ attrs.push(convertAttrValue("width", Primitive_option.valFromOption(v$22)));
169
+ }
170
+ let v$23 = props.height;
171
+ if (v$23 !== undefined) {
172
+ attrs.push(convertAttrValue("height", Primitive_option.valFromOption(v$23)));
173
+ }
174
+ let v$24 = props.role;
175
+ if (v$24 !== undefined) {
176
+ attrs.push(convertAttrValue("role", Primitive_option.valFromOption(v$24)));
177
+ }
178
+ let v$25 = props.tabIndex;
179
+ if (v$25 !== undefined) {
180
+ attrs.push(Xote__Component.attr("tabindex", v$25.toString()));
181
+ }
182
+ let v$26 = props["aria-label"];
183
+ if (v$26 !== undefined) {
184
+ attrs.push(convertAttrValue("aria-label", Primitive_option.valFromOption(v$26)));
185
+ }
186
+ let match$5 = props["aria-hidden"];
187
+ if (match$5 !== undefined) {
188
+ if (match$5) {
189
+ attrs.push(Xote__Component.attr("aria-hidden", "true"));
190
+ } else {
191
+ attrs.push(Xote__Component.attr("aria-hidden", "false"));
192
+ }
193
+ }
194
+ let match$6 = props["aria-expanded"];
195
+ if (match$6 !== undefined) {
196
+ if (match$6) {
197
+ attrs.push(Xote__Component.attr("aria-expanded", "true"));
198
+ } else {
199
+ attrs.push(Xote__Component.attr("aria-expanded", "false"));
200
+ }
201
+ }
202
+ let match$7 = props["aria-selected"];
203
+ if (match$7 !== undefined) {
204
+ if (match$7) {
205
+ attrs.push(Xote__Component.attr("aria-selected", "true"));
206
+ } else {
207
+ attrs.push(Xote__Component.attr("aria-selected", "false"));
208
+ }
209
+ }
210
+ let _dataObj = props.data;
211
+ if (_dataObj !== undefined) {
212
+ ((Object.entries(_dataObj).forEach(([key, value]) => {
213
+ attrs.push(convertAttrValue("data-" + key, value))
214
+ })));
215
+ }
216
+ return attrs;
217
+ }
218
+
219
+ function propsToEvents(props) {
220
+ let events = [];
221
+ let handler = props.onClick;
222
+ if (handler !== undefined) {
223
+ events.push([
224
+ "click",
225
+ handler
226
+ ]);
227
+ }
228
+ let handler$1 = props.onInput;
229
+ if (handler$1 !== undefined) {
230
+ events.push([
231
+ "input",
232
+ handler$1
233
+ ]);
234
+ }
235
+ let handler$2 = props.onChange;
236
+ if (handler$2 !== undefined) {
237
+ events.push([
238
+ "change",
239
+ handler$2
240
+ ]);
241
+ }
242
+ let handler$3 = props.onSubmit;
243
+ if (handler$3 !== undefined) {
244
+ events.push([
245
+ "submit",
246
+ handler$3
247
+ ]);
248
+ }
249
+ let handler$4 = props.onFocus;
250
+ if (handler$4 !== undefined) {
251
+ events.push([
252
+ "focus",
253
+ handler$4
254
+ ]);
255
+ }
256
+ let handler$5 = props.onBlur;
257
+ if (handler$5 !== undefined) {
258
+ events.push([
259
+ "blur",
260
+ handler$5
261
+ ]);
262
+ }
263
+ let handler$6 = props.onKeyDown;
264
+ if (handler$6 !== undefined) {
265
+ events.push([
266
+ "keydown",
267
+ handler$6
268
+ ]);
269
+ }
270
+ let handler$7 = props.onKeyUp;
271
+ if (handler$7 !== undefined) {
272
+ events.push([
273
+ "keyup",
274
+ handler$7
275
+ ]);
276
+ }
277
+ let handler$8 = props.onMouseEnter;
278
+ if (handler$8 !== undefined) {
279
+ events.push([
280
+ "mouseenter",
281
+ handler$8
282
+ ]);
283
+ }
284
+ let handler$9 = props.onMouseLeave;
285
+ if (handler$9 !== undefined) {
286
+ events.push([
287
+ "mouseleave",
288
+ handler$9
289
+ ]);
290
+ }
291
+ return events;
292
+ }
293
+
294
+ function getChildren(props) {
295
+ let child = props.children;
296
+ if (child !== undefined) {
297
+ if (child.TAG === "Fragment") {
298
+ return child._0;
299
+ } else {
300
+ return [child];
301
+ }
302
+ } else {
303
+ return [];
304
+ }
305
+ }
306
+
307
+ function createElement(tag, props) {
308
+ return {
309
+ TAG: "Element",
310
+ tag: tag,
311
+ attrs: propsToAttrs(props),
312
+ events: propsToEvents(props),
313
+ children: getChildren(props)
314
+ };
315
+ }
316
+
317
+ let jsx$1 = createElement;
318
+
319
+ let jsxs$1 = createElement;
320
+
321
+ function jsxKeyed$1(tag, props, key, param) {
322
+ return createElement(tag, props);
323
+ }
324
+
325
+ function jsxsKeyed$1(tag, props, key, param) {
326
+ return createElement(tag, props);
327
+ }
328
+
329
+ let Elements = {
330
+ signal: signal,
331
+ computed: computed,
332
+ convertAttrValue: convertAttrValue,
333
+ propsToAttrs: propsToAttrs,
334
+ propsToEvents: propsToEvents,
335
+ getChildren: getChildren,
336
+ createElement: createElement,
337
+ jsx: jsx$1,
338
+ jsxs: jsxs$1,
339
+ jsxKeyed: jsxKeyed$1,
340
+ jsxsKeyed: jsxsKeyed$1
341
+ };
342
+
343
+ let Component;
344
+
345
+ export {
346
+ Component,
347
+ jsx,
348
+ jsxs,
349
+ jsxKeyed,
350
+ jsxsKeyed,
351
+ jsxFragment,
352
+ array,
353
+ $$null,
354
+ Elements,
355
+ }
356
+ /* Xote__Component Not a pure module */
@@ -0,0 +1,62 @@
1
+ // Pure route matching logic (no signals, no DOM)
2
+
3
+ // Route parameter map
4
+ type params = Dict.t<string>
5
+
6
+ // Match result
7
+ type matchResult =
8
+ | Match(params)
9
+ | NoMatch
10
+
11
+ // Route segment - either static or dynamic parameter
12
+ type segment =
13
+ | Static(string)
14
+ | Param(string)
15
+
16
+ // Parse a route pattern like "/users/:id/posts/:postId"
17
+ // Returns array of segments, where dynamic segments are marked
18
+ let parsePattern = (pattern: string): array<segment> => {
19
+ pattern
20
+ ->String.split("/")
21
+ ->Array.filterMap(seg => {
22
+ if seg == "" {
23
+ None
24
+ } else if String.startsWith(seg, ":") {
25
+ Some(Param(String.sliceToEnd(seg, ~start=1)))
26
+ } else {
27
+ Some(Static(seg))
28
+ }
29
+ })
30
+ }
31
+
32
+ // Match a pathname against a parsed pattern
33
+ let matchPath = (pattern: array<segment>, pathname: string): matchResult => {
34
+ let pathSegments =
35
+ pathname
36
+ ->String.split("/")
37
+ ->Array.filter(s => s != "")
38
+
39
+ // Length must match
40
+ if Array.length(pattern) != Array.length(pathSegments) {
41
+ NoMatch
42
+ } else {
43
+ let params = Dict.make()
44
+ let matches = pattern->Array.everyWithIndex((seg, idx) => {
45
+ let pathSeg = pathSegments->Array.getUnsafe(idx)
46
+ switch seg {
47
+ | Static(expected) => pathSeg == expected
48
+ | Param(name) => {
49
+ params->Dict.set(name, pathSeg)
50
+ true
51
+ }
52
+ }
53
+ })
54
+
55
+ matches ? Match(params) : NoMatch
56
+ }
57
+ }
58
+
59
+ // Convenience: match a pattern string against pathname
60
+ let match = (pattern: string, pathname: string): matchResult => {
61
+ matchPath(parsePattern(pattern), pathname)
62
+ }
@@ -0,0 +1,56 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Core__Array from "@rescript/core/src/Core__Array.res.mjs";
4
+
5
+ function parsePattern(pattern) {
6
+ return Core__Array.filterMap(pattern.split("/"), seg => {
7
+ if (seg === "") {
8
+ return;
9
+ } else if (seg.startsWith(":")) {
10
+ return {
11
+ TAG: "Param",
12
+ _0: seg.slice(1)
13
+ };
14
+ } else {
15
+ return {
16
+ TAG: "Static",
17
+ _0: seg
18
+ };
19
+ }
20
+ });
21
+ }
22
+
23
+ function matchPath(pattern, pathname) {
24
+ let pathSegments = pathname.split("/").filter(s => s !== "");
25
+ if (pattern.length !== pathSegments.length) {
26
+ return "NoMatch";
27
+ }
28
+ let params = {};
29
+ let matches = pattern.every((seg, idx) => {
30
+ let pathSeg = pathSegments[idx];
31
+ if (seg.TAG === "Static") {
32
+ return pathSeg === seg._0;
33
+ }
34
+ params[seg._0] = pathSeg;
35
+ return true;
36
+ });
37
+ if (matches) {
38
+ return {
39
+ TAG: "Match",
40
+ _0: params
41
+ };
42
+ } else {
43
+ return "NoMatch";
44
+ }
45
+ }
46
+
47
+ function match(pattern, pathname) {
48
+ return matchPath(parsePattern(pattern), pathname);
49
+ }
50
+
51
+ export {
52
+ parsePattern,
53
+ matchPath,
54
+ match,
55
+ }
56
+ /* No side effect */
@@ -0,0 +1,130 @@
1
+ open Signals
2
+ module Component = Xote__Component
3
+ module Route = Xote__Route
4
+
5
+ // Browser location type
6
+ type location = {
7
+ pathname: string,
8
+ search: string,
9
+ hash: string,
10
+ }
11
+
12
+ // Global location signal - the core router state
13
+ let location: Signal.t<location> = Signal.make({
14
+ pathname: "/",
15
+ search: "",
16
+ hash: "",
17
+ })
18
+
19
+ // External bindings for History API
20
+ type historyState = {.}
21
+
22
+ @val @scope(("window", "history"))
23
+ external pushState: (historyState, string, string) => unit = "pushState"
24
+
25
+ @val @scope(("window", "history"))
26
+ external replaceState: (historyState, string, string) => unit = "replaceState"
27
+
28
+ @val @scope("window")
29
+ external addEventListener: (string, Dom.event => unit) => unit = "addEventListener"
30
+
31
+ @val @scope("window")
32
+ external removeEventListener: (string, Dom.event => unit) => unit = "removeEventListener"
33
+
34
+ // Parse current browser location from window.location
35
+ let getCurrentLocation = (): location => {
36
+ pathname: %raw(`window.location.pathname`),
37
+ search: %raw(`window.location.search`),
38
+ hash: %raw(`window.location.hash`),
39
+ }
40
+
41
+ // Initialize router - call this once at app start
42
+ let init = (): unit => {
43
+ // Set initial location from browser
44
+ Signal.set(location, getCurrentLocation())
45
+
46
+ // Listen for popstate (back/forward buttons)
47
+ let handlePopState = (_evt: Dom.event) => {
48
+ Signal.set(location, getCurrentLocation())
49
+ }
50
+
51
+ addEventListener("popstate", handlePopState)
52
+
53
+ // Note: No cleanup needed for SPA scenarios
54
+ // If cleanup is needed, return a disposer function
55
+ }
56
+
57
+ // Imperative navigation - push new history entry
58
+ let push = (pathname: string, ~search: string="", ~hash: string="", ()): unit => {
59
+ let newLocation = {pathname, search, hash}
60
+ let url = pathname ++ search ++ hash
61
+ let state: historyState = %raw("{}")
62
+ pushState(state, "", url)
63
+ Signal.set(location, newLocation)
64
+ }
65
+
66
+ // Imperative navigation - replace current history entry
67
+ let replace = (pathname: string, ~search: string="", ~hash: string="", ()): unit => {
68
+ let newLocation = {pathname, search, hash}
69
+ let url = pathname ++ search ++ hash
70
+ let state: historyState = %raw("{}")
71
+ replaceState(state, "", url)
72
+ Signal.set(location, newLocation)
73
+ }
74
+
75
+ // Route definition for routes() component
76
+ type routeConfig = {
77
+ pattern: string,
78
+ render: Route.params => Component.node,
79
+ }
80
+
81
+ // Single route component - renders if pattern matches
82
+ let route = (pattern: string, render: Route.params => Component.node): Component.node => {
83
+ let signal = Computed.make(() => {
84
+ let loc = Signal.get(location)
85
+ switch Route.match(pattern, loc.pathname) {
86
+ | Match(params) => [render(params)]
87
+ | NoMatch => []
88
+ }
89
+ })
90
+ Component.signalFragment(signal)
91
+ }
92
+
93
+ // Routes component - renders first matching route
94
+ let routes = (configs: array<routeConfig>): Component.node => {
95
+ let signal = Computed.make(() => {
96
+ let loc = Signal.get(location)
97
+ let matched = configs->Array.findMap(config => {
98
+ switch Route.match(config.pattern, loc.pathname) {
99
+ | Match(params) => Some(config.render(params))
100
+ | NoMatch => None
101
+ }
102
+ })
103
+
104
+ switch matched {
105
+ | Some(node) => [node]
106
+ | None => [] // No matching route - render nothing
107
+ }
108
+ })
109
+ Component.signalFragment(signal)
110
+ }
111
+
112
+ // Link component - handles navigation without page reload
113
+ let link = (
114
+ ~to: string,
115
+ ~attrs: array<(string, Component.attrValue)>=[],
116
+ ~children: array<Component.node>=[],
117
+ (),
118
+ ): Component.node => {
119
+ let handleClick = (_evt: Dom.event) => {
120
+ %raw(`_evt.preventDefault()`)
121
+ push(to, ())
122
+ }
123
+
124
+ Component.a(
125
+ ~attrs=Array.concat(attrs, [Component.attr("href", to)]),
126
+ ~events=[("click", handleClick)],
127
+ ~children,
128
+ (),
129
+ )
130
+ }
@@ -0,0 +1,116 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Signals from "rescript-signals/src/Signals.res.mjs";
4
+ import * as Core__Array from "@rescript/core/src/Core__Array.res.mjs";
5
+ import * as Xote__Route from "./Xote__Route.res.mjs";
6
+ import * as Xote__Component from "./Xote__Component.res.mjs";
7
+
8
+ let location = Signals.Signal.make({
9
+ pathname: "/",
10
+ search: "",
11
+ hash: ""
12
+ }, undefined, undefined);
13
+
14
+ function getCurrentLocation() {
15
+ return {
16
+ pathname: window.location.pathname,
17
+ search: window.location.search,
18
+ hash: window.location.hash
19
+ };
20
+ }
21
+
22
+ function init() {
23
+ Signals.Signal.set(location, getCurrentLocation());
24
+ let handlePopState = _evt => Signals.Signal.set(location, getCurrentLocation());
25
+ window.addEventListener("popstate", handlePopState);
26
+ }
27
+
28
+ function push(pathname, searchOpt, hashOpt, param) {
29
+ let search = searchOpt !== undefined ? searchOpt : "";
30
+ let hash = hashOpt !== undefined ? hashOpt : "";
31
+ let newLocation = {
32
+ pathname: pathname,
33
+ search: search,
34
+ hash: hash
35
+ };
36
+ let url = pathname + search + hash;
37
+ let state = {};
38
+ window.history.pushState(state, "", url);
39
+ Signals.Signal.set(location, newLocation);
40
+ }
41
+
42
+ function replace(pathname, searchOpt, hashOpt, param) {
43
+ let search = searchOpt !== undefined ? searchOpt : "";
44
+ let hash = hashOpt !== undefined ? hashOpt : "";
45
+ let newLocation = {
46
+ pathname: pathname,
47
+ search: search,
48
+ hash: hash
49
+ };
50
+ let url = pathname + search + hash;
51
+ let state = {};
52
+ window.history.replaceState(state, "", url);
53
+ Signals.Signal.set(location, newLocation);
54
+ }
55
+
56
+ function route(pattern, render) {
57
+ return Xote__Component.signalFragment(Signals.Computed.make(() => {
58
+ let loc = Signals.Signal.get(location);
59
+ let params = Xote__Route.match(pattern, loc.pathname);
60
+ if (typeof params !== "object") {
61
+ return [];
62
+ } else {
63
+ return [render(params._0)];
64
+ }
65
+ }, undefined));
66
+ }
67
+
68
+ function routes(configs) {
69
+ return Xote__Component.signalFragment(Signals.Computed.make(() => {
70
+ let loc = Signals.Signal.get(location);
71
+ let matched = Core__Array.findMap(configs, config => {
72
+ let params = Xote__Route.match(config.pattern, loc.pathname);
73
+ if (typeof params !== "object") {
74
+ return;
75
+ } else {
76
+ return config.render(params._0);
77
+ }
78
+ });
79
+ if (matched !== undefined) {
80
+ return [matched];
81
+ } else {
82
+ return [];
83
+ }
84
+ }, undefined));
85
+ }
86
+
87
+ function link(to, attrsOpt, childrenOpt, param) {
88
+ let attrs = attrsOpt !== undefined ? attrsOpt : [];
89
+ let children = childrenOpt !== undefined ? childrenOpt : [];
90
+ let handleClick = _evt => {
91
+ ((_evt.preventDefault()));
92
+ push(to, undefined, undefined, undefined);
93
+ };
94
+ return Xote__Component.a(attrs.concat([Xote__Component.attr("href", to)]), [[
95
+ "click",
96
+ handleClick
97
+ ]], children, undefined);
98
+ }
99
+
100
+ let Component;
101
+
102
+ let Route;
103
+
104
+ export {
105
+ Component,
106
+ Route,
107
+ location,
108
+ getCurrentLocation,
109
+ init,
110
+ push,
111
+ replace,
112
+ route,
113
+ routes,
114
+ link,
115
+ }
116
+ /* location Not a pure module */