@alepha/react 0.7.0 → 0.7.1
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/README.md +1 -1
- package/dist/index.browser.cjs +21 -21
- package/dist/index.browser.js +2 -3
- package/dist/index.cjs +151 -83
- package/dist/index.d.ts +360 -205
- package/dist/index.js +129 -62
- package/dist/{useActive-DjpZBEuB.cjs → useRouterState-AdK-XeM2.cjs} +270 -81
- package/dist/{useActive-BX41CqY8.js → useRouterState-qoMq7Y9J.js} +272 -84
- package/package.json +11 -10
- package/src/components/ClientOnly.tsx +35 -0
- package/src/components/ErrorBoundary.tsx +1 -1
- package/src/components/ErrorViewer.tsx +161 -0
- package/src/components/Link.tsx +9 -3
- package/src/components/NestedView.tsx +18 -3
- package/src/descriptors/$page.ts +139 -30
- package/src/errors/RedirectionError.ts +4 -1
- package/src/hooks/RouterHookApi.ts +42 -5
- package/src/hooks/useAlepha.ts +12 -0
- package/src/hooks/useClient.ts +8 -6
- package/src/hooks/useInject.ts +2 -2
- package/src/hooks/useQueryParams.ts +1 -1
- package/src/hooks/useRouter.ts +6 -0
- package/src/index.browser.ts +1 -1
- package/src/index.shared.ts +11 -5
- package/src/index.ts +3 -4
- package/src/providers/BrowserRouterProvider.ts +1 -1
- package/src/providers/PageDescriptorProvider.ts +72 -21
- package/src/providers/ReactBrowserProvider.ts +5 -8
- package/src/providers/ReactServerProvider.ts +197 -80
- package/dist/index.browser.cjs.map +0 -1
- package/dist/index.browser.js.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/useActive-BX41CqY8.js.map +0 -1
- package/dist/useActive-DjpZBEuB.cjs.map +0 -1
|
@@ -28,27 +28,161 @@ const $page = (options) => {
|
|
|
28
28
|
[core.OPTIONS]: options,
|
|
29
29
|
render: () => {
|
|
30
30
|
throw new core.NotImplementedError(KEY);
|
|
31
|
-
},
|
|
32
|
-
go: () => {
|
|
33
|
-
throw new core.NotImplementedError(KEY);
|
|
34
|
-
},
|
|
35
|
-
createAnchorProps: () => {
|
|
36
|
-
throw new core.NotImplementedError(KEY);
|
|
37
|
-
},
|
|
38
|
-
can: () => {
|
|
39
|
-
if (options.can) {
|
|
40
|
-
return options.can();
|
|
41
|
-
}
|
|
42
|
-
return true;
|
|
43
31
|
}
|
|
44
32
|
};
|
|
45
33
|
};
|
|
46
34
|
$page[core.KIND] = KEY;
|
|
47
35
|
|
|
36
|
+
const ClientOnly = (props) => {
|
|
37
|
+
const [mounted, setMounted] = React.useState(false);
|
|
38
|
+
React.useEffect(() => setMounted(true), []);
|
|
39
|
+
if (props.disabled) {
|
|
40
|
+
return props.children;
|
|
41
|
+
}
|
|
42
|
+
return mounted ? props.children : props.fallback;
|
|
43
|
+
};
|
|
44
|
+
|
|
48
45
|
const RouterContext = React.createContext(
|
|
49
46
|
void 0
|
|
50
47
|
);
|
|
51
48
|
|
|
49
|
+
const useAlepha = () => {
|
|
50
|
+
const routerContext = React.useContext(RouterContext);
|
|
51
|
+
if (!routerContext) {
|
|
52
|
+
throw new Error("useAlepha must be used within a RouterProvider");
|
|
53
|
+
}
|
|
54
|
+
return routerContext.alepha;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const ErrorViewer = ({ error }) => {
|
|
58
|
+
const [expanded, setExpanded] = React.useState(false);
|
|
59
|
+
const isProduction = useAlepha().isProduction();
|
|
60
|
+
if (isProduction) {
|
|
61
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ErrorViewerProduction, {});
|
|
62
|
+
}
|
|
63
|
+
const stackLines = error.stack?.split("\n") ?? [];
|
|
64
|
+
const previewLines = stackLines.slice(0, 5);
|
|
65
|
+
const hiddenLineCount = stackLines.length - previewLines.length;
|
|
66
|
+
const copyToClipboard = (text) => {
|
|
67
|
+
navigator.clipboard.writeText(text).catch((err) => {
|
|
68
|
+
console.error("Clipboard error:", err);
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
const styles = {
|
|
72
|
+
container: {
|
|
73
|
+
padding: "24px",
|
|
74
|
+
backgroundColor: "#FEF2F2",
|
|
75
|
+
color: "#7F1D1D",
|
|
76
|
+
border: "1px solid #FECACA",
|
|
77
|
+
borderRadius: "16px",
|
|
78
|
+
boxShadow: "0 8px 24px rgba(0,0,0,0.05)",
|
|
79
|
+
fontFamily: "monospace",
|
|
80
|
+
maxWidth: "768px",
|
|
81
|
+
margin: "40px auto"
|
|
82
|
+
},
|
|
83
|
+
heading: {
|
|
84
|
+
fontSize: "20px",
|
|
85
|
+
fontWeight: "bold",
|
|
86
|
+
marginBottom: "4px"
|
|
87
|
+
},
|
|
88
|
+
name: {
|
|
89
|
+
fontSize: "16px",
|
|
90
|
+
fontWeight: 600
|
|
91
|
+
},
|
|
92
|
+
message: {
|
|
93
|
+
fontSize: "14px",
|
|
94
|
+
marginBottom: "16px"
|
|
95
|
+
},
|
|
96
|
+
sectionHeader: {
|
|
97
|
+
display: "flex",
|
|
98
|
+
justifyContent: "space-between",
|
|
99
|
+
alignItems: "center",
|
|
100
|
+
fontSize: "12px",
|
|
101
|
+
marginBottom: "4px",
|
|
102
|
+
color: "#991B1B"
|
|
103
|
+
},
|
|
104
|
+
copyButton: {
|
|
105
|
+
fontSize: "12px",
|
|
106
|
+
color: "#DC2626",
|
|
107
|
+
background: "none",
|
|
108
|
+
border: "none",
|
|
109
|
+
cursor: "pointer",
|
|
110
|
+
textDecoration: "underline"
|
|
111
|
+
},
|
|
112
|
+
stackContainer: {
|
|
113
|
+
backgroundColor: "#FEE2E2",
|
|
114
|
+
padding: "12px",
|
|
115
|
+
borderRadius: "8px",
|
|
116
|
+
fontSize: "13px",
|
|
117
|
+
lineHeight: "1.4",
|
|
118
|
+
overflowX: "auto",
|
|
119
|
+
whiteSpace: "pre-wrap"
|
|
120
|
+
},
|
|
121
|
+
expandLine: {
|
|
122
|
+
color: "#F87171",
|
|
123
|
+
cursor: "pointer",
|
|
124
|
+
marginTop: "8px"
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.container, children: [
|
|
128
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
129
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles.heading, children: "\u{1F525} Error" }),
|
|
130
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles.name, children: error.name }),
|
|
131
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles.message, children: error.message })
|
|
132
|
+
] }),
|
|
133
|
+
stackLines.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
134
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.sectionHeader, children: [
|
|
135
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Stack trace" }),
|
|
136
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
137
|
+
"button",
|
|
138
|
+
{
|
|
139
|
+
onClick: () => copyToClipboard(error.stack),
|
|
140
|
+
style: styles.copyButton,
|
|
141
|
+
children: "Copy all"
|
|
142
|
+
}
|
|
143
|
+
)
|
|
144
|
+
] }),
|
|
145
|
+
/* @__PURE__ */ jsxRuntime.jsxs("pre", { style: styles.stackContainer, children: [
|
|
146
|
+
(expanded ? stackLines : previewLines).map((line, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { children: line }, i)),
|
|
147
|
+
!expanded && hiddenLineCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.expandLine, onClick: () => setExpanded(true), children: [
|
|
148
|
+
"+ ",
|
|
149
|
+
hiddenLineCount,
|
|
150
|
+
" more lines..."
|
|
151
|
+
] })
|
|
152
|
+
] })
|
|
153
|
+
] })
|
|
154
|
+
] });
|
|
155
|
+
};
|
|
156
|
+
const ErrorViewerProduction = () => {
|
|
157
|
+
const styles = {
|
|
158
|
+
container: {
|
|
159
|
+
padding: "24px",
|
|
160
|
+
backgroundColor: "#FEF2F2",
|
|
161
|
+
color: "#7F1D1D",
|
|
162
|
+
border: "1px solid #FECACA",
|
|
163
|
+
borderRadius: "16px",
|
|
164
|
+
boxShadow: "0 8px 24px rgba(0,0,0,0.05)",
|
|
165
|
+
fontFamily: "monospace",
|
|
166
|
+
maxWidth: "768px",
|
|
167
|
+
margin: "40px auto",
|
|
168
|
+
textAlign: "center"
|
|
169
|
+
},
|
|
170
|
+
heading: {
|
|
171
|
+
fontSize: "20px",
|
|
172
|
+
fontWeight: "bold",
|
|
173
|
+
marginBottom: "8px"
|
|
174
|
+
},
|
|
175
|
+
message: {
|
|
176
|
+
fontSize: "14px",
|
|
177
|
+
opacity: 0.85
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.container, children: [
|
|
181
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles.heading, children: "\u{1F6A8} An error occurred" }),
|
|
182
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles.message, children: "Something went wrong. Please try again later." })
|
|
183
|
+
] });
|
|
184
|
+
};
|
|
185
|
+
|
|
52
186
|
const RouterLayerContext = React.createContext(void 0);
|
|
53
187
|
|
|
54
188
|
const useRouterEvents = (opts = {}, deps = []) => {
|
|
@@ -146,14 +280,19 @@ const NestedView = (props) => {
|
|
|
146
280
|
};
|
|
147
281
|
|
|
148
282
|
class RedirectionError extends Error {
|
|
283
|
+
page;
|
|
149
284
|
constructor(page) {
|
|
150
285
|
super("Redirection");
|
|
151
286
|
this.page = page;
|
|
152
287
|
}
|
|
153
288
|
}
|
|
154
289
|
|
|
290
|
+
const envSchema$1 = core.t.object({
|
|
291
|
+
REACT_STRICT_MODE: core.t.boolean({ default: true })
|
|
292
|
+
});
|
|
155
293
|
class PageDescriptorProvider {
|
|
156
294
|
log = core.$logger();
|
|
295
|
+
env = core.$inject(envSchema$1);
|
|
157
296
|
alepha = core.$inject(core.Alepha);
|
|
158
297
|
pages = [];
|
|
159
298
|
getPages() {
|
|
@@ -167,8 +306,25 @@ class PageDescriptorProvider {
|
|
|
167
306
|
}
|
|
168
307
|
throw new Error(`Page ${name} not found`);
|
|
169
308
|
}
|
|
309
|
+
url(name, options = {}) {
|
|
310
|
+
const page = this.page(name);
|
|
311
|
+
if (!page) {
|
|
312
|
+
throw new Error(`Page ${name} not found`);
|
|
313
|
+
}
|
|
314
|
+
let url = page.path ?? "";
|
|
315
|
+
let parent = page.parent;
|
|
316
|
+
while (parent) {
|
|
317
|
+
url = `${parent.path ?? ""}/${url}`;
|
|
318
|
+
parent = parent.parent;
|
|
319
|
+
}
|
|
320
|
+
url = this.compile(url, options.params ?? {});
|
|
321
|
+
return new URL(
|
|
322
|
+
url.replace(/\/\/+/g, "/") || "/",
|
|
323
|
+
options.base ?? `http://localhost`
|
|
324
|
+
);
|
|
325
|
+
}
|
|
170
326
|
root(state, context) {
|
|
171
|
-
|
|
327
|
+
const root = React.createElement(
|
|
172
328
|
RouterContext.Provider,
|
|
173
329
|
{
|
|
174
330
|
value: {
|
|
@@ -179,13 +335,17 @@ class PageDescriptorProvider {
|
|
|
179
335
|
},
|
|
180
336
|
React.createElement(NestedView, {}, state.layers[0]?.element)
|
|
181
337
|
);
|
|
338
|
+
if (this.env.REACT_STRICT_MODE) {
|
|
339
|
+
return React.createElement(React.StrictMode, {}, root);
|
|
340
|
+
}
|
|
341
|
+
return root;
|
|
182
342
|
}
|
|
183
343
|
async createLayers(route, request) {
|
|
184
344
|
const { pathname, search } = request.url;
|
|
185
345
|
const layers = [];
|
|
186
346
|
let context = {};
|
|
187
347
|
const stack = [{ route }];
|
|
188
|
-
|
|
348
|
+
request.onError = (error) => this.renderError(error);
|
|
189
349
|
let parent = route.parent;
|
|
190
350
|
while (parent) {
|
|
191
351
|
stack.unshift({ route: parent });
|
|
@@ -285,23 +445,26 @@ class PageDescriptorProvider {
|
|
|
285
445
|
const path = acc.replace(/\/+/, "/");
|
|
286
446
|
const localErrorHandler = this.getErrorHandler(it.route);
|
|
287
447
|
if (localErrorHandler) {
|
|
288
|
-
onError = localErrorHandler;
|
|
448
|
+
request.onError = localErrorHandler;
|
|
289
449
|
}
|
|
290
450
|
if (it.error) {
|
|
291
|
-
|
|
451
|
+
let element2 = await request.onError(it.error);
|
|
452
|
+
if (element2 === null) {
|
|
453
|
+
element2 = this.renderError(it.error);
|
|
454
|
+
}
|
|
292
455
|
layers.push({
|
|
293
456
|
props,
|
|
294
457
|
error: it.error,
|
|
295
458
|
name: it.route.name,
|
|
296
459
|
part: it.route.path,
|
|
297
460
|
config: it.config,
|
|
298
|
-
element: this.renderView(i + 1, path,
|
|
461
|
+
element: this.renderView(i + 1, path, element2, it.route),
|
|
299
462
|
index: i + 1,
|
|
300
463
|
path
|
|
301
464
|
});
|
|
302
465
|
break;
|
|
303
466
|
}
|
|
304
|
-
const
|
|
467
|
+
const element = await this.createElement(it.route, {
|
|
305
468
|
...props,
|
|
306
469
|
...context
|
|
307
470
|
});
|
|
@@ -310,7 +473,7 @@ class PageDescriptorProvider {
|
|
|
310
473
|
props,
|
|
311
474
|
part: it.route.path,
|
|
312
475
|
config: it.config,
|
|
313
|
-
element: this.renderView(i + 1, path,
|
|
476
|
+
element: this.renderView(i + 1, path, element, it.route),
|
|
314
477
|
index: i + 1,
|
|
315
478
|
path
|
|
316
479
|
});
|
|
@@ -366,8 +529,8 @@ class PageDescriptorProvider {
|
|
|
366
529
|
ctx.head.meta = [...ctx.head.meta ?? [], ...head.meta ?? []];
|
|
367
530
|
}
|
|
368
531
|
}
|
|
369
|
-
renderError(
|
|
370
|
-
return React.createElement(
|
|
532
|
+
renderError(error) {
|
|
533
|
+
return React.createElement(ErrorViewer, { error });
|
|
371
534
|
}
|
|
372
535
|
renderEmptyView() {
|
|
373
536
|
return React.createElement(NestedView, {});
|
|
@@ -392,7 +555,13 @@ class PageDescriptorProvider {
|
|
|
392
555
|
}
|
|
393
556
|
return path;
|
|
394
557
|
}
|
|
395
|
-
renderView(index, path, view
|
|
558
|
+
renderView(index, path, view, page) {
|
|
559
|
+
view ??= this.renderEmptyView();
|
|
560
|
+
const element = page.client ? React.createElement(
|
|
561
|
+
ClientOnly,
|
|
562
|
+
typeof page.client === "object" ? page.client : {},
|
|
563
|
+
view
|
|
564
|
+
) : view;
|
|
396
565
|
return React.createElement(
|
|
397
566
|
RouterLayerContext.Provider,
|
|
398
567
|
{
|
|
@@ -401,7 +570,7 @@ class PageDescriptorProvider {
|
|
|
401
570
|
path
|
|
402
571
|
}
|
|
403
572
|
},
|
|
404
|
-
|
|
573
|
+
element
|
|
405
574
|
);
|
|
406
575
|
}
|
|
407
576
|
configure = core.$hook({
|
|
@@ -410,6 +579,8 @@ class PageDescriptorProvider {
|
|
|
410
579
|
const pages = this.alepha.getDescriptorValues($page);
|
|
411
580
|
for (const { value, key } of pages) {
|
|
412
581
|
value[core.OPTIONS].name ??= key;
|
|
582
|
+
}
|
|
583
|
+
for (const { value } of pages) {
|
|
413
584
|
if (value[core.OPTIONS].parent) {
|
|
414
585
|
continue;
|
|
415
586
|
}
|
|
@@ -419,11 +590,6 @@ class PageDescriptorProvider {
|
|
|
419
590
|
});
|
|
420
591
|
map(pages, target) {
|
|
421
592
|
const children = target[core.OPTIONS].children ?? [];
|
|
422
|
-
for (const it of pages) {
|
|
423
|
-
if (it.value[core.OPTIONS].parent === target) {
|
|
424
|
-
children.push(it.value);
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
593
|
return {
|
|
428
594
|
...target[core.OPTIONS],
|
|
429
595
|
parent: void 0,
|
|
@@ -735,7 +901,7 @@ class ReactBrowserProvider {
|
|
|
735
901
|
const hydration = this.getHydrationState();
|
|
736
902
|
const previous = hydration?.layers ?? [];
|
|
737
903
|
if (hydration?.links) {
|
|
738
|
-
for (const link of hydration.links) {
|
|
904
|
+
for (const link of hydration.links.links) {
|
|
739
905
|
this.client.pushLink(link);
|
|
740
906
|
}
|
|
741
907
|
}
|
|
@@ -771,7 +937,8 @@ class ReactBrowserProvider {
|
|
|
771
937
|
}
|
|
772
938
|
|
|
773
939
|
class RouterHookApi {
|
|
774
|
-
constructor(state, layer, browser) {
|
|
940
|
+
constructor(pages, state, layer, browser) {
|
|
941
|
+
this.pages = pages;
|
|
775
942
|
this.state = state;
|
|
776
943
|
this.layer = layer;
|
|
777
944
|
this.browser = browser;
|
|
@@ -825,23 +992,40 @@ class RouterHookApi {
|
|
|
825
992
|
* @param pathname
|
|
826
993
|
* @param layer
|
|
827
994
|
*/
|
|
828
|
-
createHref(pathname, layer = this.layer) {
|
|
995
|
+
createHref(pathname, layer = this.layer, options = {}) {
|
|
829
996
|
if (typeof pathname === "object") {
|
|
830
997
|
pathname = pathname.options.path ?? "";
|
|
831
998
|
}
|
|
999
|
+
if (options.params) {
|
|
1000
|
+
for (const [key, value] of Object.entries(options.params)) {
|
|
1001
|
+
pathname = pathname.replace(`:${key}`, String(value));
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
832
1004
|
return pathname.startsWith("/") ? pathname : `${layer.path}/${pathname}`.replace(/\/\/+/g, "/");
|
|
833
1005
|
}
|
|
834
1006
|
async go(path, options) {
|
|
835
|
-
|
|
1007
|
+
for (const page of this.pages) {
|
|
1008
|
+
if (page.name === path) {
|
|
1009
|
+
path = page.path ?? "";
|
|
1010
|
+
break;
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
await this.browser?.go(this.createHref(path, this.layer, options), options);
|
|
836
1014
|
}
|
|
837
|
-
anchor(path) {
|
|
838
|
-
const
|
|
1015
|
+
anchor(path, options = {}) {
|
|
1016
|
+
for (const page of this.pages) {
|
|
1017
|
+
if (page.name === path) {
|
|
1018
|
+
path = page.path ?? "";
|
|
1019
|
+
break;
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
const href = this.createHref(path, this.layer, options);
|
|
839
1023
|
return {
|
|
840
1024
|
href,
|
|
841
1025
|
onClick: (ev) => {
|
|
842
1026
|
ev.stopPropagation();
|
|
843
1027
|
ev.preventDefault();
|
|
844
|
-
this.go(path).catch(console.error);
|
|
1028
|
+
this.go(path, options).catch(console.error);
|
|
845
1029
|
}
|
|
846
1030
|
};
|
|
847
1031
|
}
|
|
@@ -869,8 +1053,12 @@ const useRouter = () => {
|
|
|
869
1053
|
if (!ctx || !layer) {
|
|
870
1054
|
throw new Error("useRouter must be used within a RouterProvider");
|
|
871
1055
|
}
|
|
1056
|
+
const pages = React.useMemo(() => {
|
|
1057
|
+
return ctx.alepha.get(PageDescriptorProvider).getPages();
|
|
1058
|
+
}, []);
|
|
872
1059
|
return React.useMemo(
|
|
873
1060
|
() => new RouterHookApi(
|
|
1061
|
+
pages,
|
|
874
1062
|
ctx.state,
|
|
875
1063
|
layer,
|
|
876
1064
|
ctx.alepha.isBrowser() ? ctx.alepha.get(ReactBrowserProvider) : void 0
|
|
@@ -881,6 +1069,7 @@ const useRouter = () => {
|
|
|
881
1069
|
|
|
882
1070
|
const Link = (props) => {
|
|
883
1071
|
React.useContext(RouterContext);
|
|
1072
|
+
const router = useRouter();
|
|
884
1073
|
const to = typeof props.to === "string" ? props.to : props.to[core.OPTIONS].path;
|
|
885
1074
|
if (!to) {
|
|
886
1075
|
return null;
|
|
@@ -890,8 +1079,49 @@ const Link = (props) => {
|
|
|
890
1079
|
return null;
|
|
891
1080
|
}
|
|
892
1081
|
const name = typeof props.to === "string" ? void 0 : props.to[core.OPTIONS].name;
|
|
1082
|
+
const anchorProps = {
|
|
1083
|
+
...props,
|
|
1084
|
+
to: void 0
|
|
1085
|
+
};
|
|
1086
|
+
return /* @__PURE__ */ jsxRuntime.jsx("a", { ...router.anchor(to), ...anchorProps, children: props.children ?? name });
|
|
1087
|
+
};
|
|
1088
|
+
|
|
1089
|
+
const useActive = (path) => {
|
|
893
1090
|
const router = useRouter();
|
|
894
|
-
|
|
1091
|
+
const ctx = React.useContext(RouterContext);
|
|
1092
|
+
const layer = React.useContext(RouterLayerContext);
|
|
1093
|
+
if (!ctx || !layer) {
|
|
1094
|
+
throw new Error("useRouter must be used within a RouterProvider");
|
|
1095
|
+
}
|
|
1096
|
+
let name;
|
|
1097
|
+
if (typeof path === "object" && path.options.name) {
|
|
1098
|
+
name = path.options.name;
|
|
1099
|
+
}
|
|
1100
|
+
const [current, setCurrent] = React.useState(ctx.state.pathname);
|
|
1101
|
+
const href = React.useMemo(() => router.createHref(path, layer), [path, layer]);
|
|
1102
|
+
const [isPending, setPending] = React.useState(false);
|
|
1103
|
+
const isActive = current === href;
|
|
1104
|
+
useRouterEvents({
|
|
1105
|
+
onEnd: ({ state }) => setCurrent(state.pathname)
|
|
1106
|
+
});
|
|
1107
|
+
return {
|
|
1108
|
+
name,
|
|
1109
|
+
isPending,
|
|
1110
|
+
isActive,
|
|
1111
|
+
anchorProps: {
|
|
1112
|
+
href,
|
|
1113
|
+
onClick: (ev) => {
|
|
1114
|
+
ev.stopPropagation();
|
|
1115
|
+
ev.preventDefault();
|
|
1116
|
+
if (isActive) return;
|
|
1117
|
+
if (isPending) return;
|
|
1118
|
+
setPending(true);
|
|
1119
|
+
router.go(href).then(() => {
|
|
1120
|
+
setPending(false);
|
|
1121
|
+
});
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
};
|
|
895
1125
|
};
|
|
896
1126
|
|
|
897
1127
|
const useInject = (clazz) => {
|
|
@@ -902,10 +1132,7 @@ const useInject = (clazz) => {
|
|
|
902
1132
|
return React.useMemo(() => ctx.alepha.get(clazz), []);
|
|
903
1133
|
};
|
|
904
1134
|
|
|
905
|
-
const useClient = () => {
|
|
906
|
-
return useInject(server.HttpClient);
|
|
907
|
-
};
|
|
908
|
-
const useApi = () => {
|
|
1135
|
+
const useClient = (_scope) => {
|
|
909
1136
|
return useInject(server.HttpClient).of();
|
|
910
1137
|
};
|
|
911
1138
|
|
|
@@ -939,7 +1166,7 @@ const encode = (alepha, schema, data) => {
|
|
|
939
1166
|
const decode = (alepha, schema, data) => {
|
|
940
1167
|
try {
|
|
941
1168
|
return alepha.parse(schema, JSON.parse(atob(decodeURIComponent(data))));
|
|
942
|
-
} catch (
|
|
1169
|
+
} catch (_error) {
|
|
943
1170
|
return {};
|
|
944
1171
|
}
|
|
945
1172
|
};
|
|
@@ -957,46 +1184,9 @@ const useRouterState = () => {
|
|
|
957
1184
|
return state;
|
|
958
1185
|
};
|
|
959
1186
|
|
|
960
|
-
const useActive = (path) => {
|
|
961
|
-
const router = useRouter();
|
|
962
|
-
const ctx = React.useContext(RouterContext);
|
|
963
|
-
const layer = React.useContext(RouterLayerContext);
|
|
964
|
-
if (!ctx || !layer) {
|
|
965
|
-
throw new Error("useRouter must be used within a RouterProvider");
|
|
966
|
-
}
|
|
967
|
-
let name;
|
|
968
|
-
if (typeof path === "object" && path.options.name) {
|
|
969
|
-
name = path.options.name;
|
|
970
|
-
}
|
|
971
|
-
const [current, setCurrent] = React.useState(ctx.state.pathname);
|
|
972
|
-
const href = React.useMemo(() => router.createHref(path, layer), [path, layer]);
|
|
973
|
-
const [isPending, setPending] = React.useState(false);
|
|
974
|
-
const isActive = current === href;
|
|
975
|
-
useRouterEvents({
|
|
976
|
-
onEnd: ({ state }) => setCurrent(state.pathname)
|
|
977
|
-
});
|
|
978
|
-
return {
|
|
979
|
-
name,
|
|
980
|
-
isPending,
|
|
981
|
-
isActive,
|
|
982
|
-
anchorProps: {
|
|
983
|
-
href,
|
|
984
|
-
onClick: (ev) => {
|
|
985
|
-
ev.stopPropagation();
|
|
986
|
-
ev.preventDefault();
|
|
987
|
-
if (isActive) return;
|
|
988
|
-
if (isPending) return;
|
|
989
|
-
setPending(true);
|
|
990
|
-
router.go(href).then(() => {
|
|
991
|
-
setPending(false);
|
|
992
|
-
});
|
|
993
|
-
}
|
|
994
|
-
}
|
|
995
|
-
};
|
|
996
|
-
};
|
|
997
|
-
|
|
998
1187
|
exports.$page = $page;
|
|
999
1188
|
exports.BrowserRouterProvider = BrowserRouterProvider;
|
|
1189
|
+
exports.ClientOnly = ClientOnly;
|
|
1000
1190
|
exports.ErrorBoundary = ErrorBoundary;
|
|
1001
1191
|
exports.Link = Link;
|
|
1002
1192
|
exports.NestedView = NestedView;
|
|
@@ -1008,11 +1198,10 @@ exports.RouterHookApi = RouterHookApi;
|
|
|
1008
1198
|
exports.RouterLayerContext = RouterLayerContext;
|
|
1009
1199
|
exports.isPageRoute = isPageRoute;
|
|
1010
1200
|
exports.useActive = useActive;
|
|
1011
|
-
exports.
|
|
1201
|
+
exports.useAlepha = useAlepha;
|
|
1012
1202
|
exports.useClient = useClient;
|
|
1013
1203
|
exports.useInject = useInject;
|
|
1014
1204
|
exports.useQueryParams = useQueryParams;
|
|
1015
1205
|
exports.useRouter = useRouter;
|
|
1016
1206
|
exports.useRouterEvents = useRouterEvents;
|
|
1017
1207
|
exports.useRouterState = useRouterState;
|
|
1018
|
-
//# sourceMappingURL=useActive-DjpZBEuB.cjs.map
|