@alepha/react 0.14.2 → 0.14.4
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/dist/auth/index.browser.js +29 -14
- package/dist/auth/index.browser.js.map +1 -1
- package/dist/auth/index.js +960 -195
- package/dist/auth/index.js.map +1 -1
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +7 -4
- package/dist/core/index.js.map +1 -1
- package/dist/head/index.browser.js +59 -19
- package/dist/head/index.browser.js.map +1 -1
- package/dist/head/index.d.ts +99 -560
- package/dist/head/index.d.ts.map +1 -1
- package/dist/head/index.js +92 -87
- package/dist/head/index.js.map +1 -1
- package/dist/router/index.browser.js +30 -15
- package/dist/router/index.browser.js.map +1 -1
- package/dist/router/index.d.ts +616 -192
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +961 -196
- package/dist/router/index.js.map +1 -1
- package/package.json +4 -4
- package/src/auth/__tests__/$auth.spec.ts +188 -0
- package/src/core/__tests__/Router.spec.tsx +169 -0
- package/src/core/hooks/useAction.browser.spec.tsx +569 -0
- package/src/core/hooks/useAction.ts +11 -0
- package/src/form/hooks/useForm.browser.spec.tsx +366 -0
- package/src/head/helpers/SeoExpander.spec.ts +203 -0
- package/src/head/hooks/useHead.spec.tsx +288 -0
- package/src/head/index.ts +11 -28
- package/src/head/providers/BrowserHeadProvider.browser.spec.ts +196 -0
- package/src/head/providers/BrowserHeadProvider.ts +25 -19
- package/src/head/providers/HeadProvider.ts +76 -10
- package/src/head/providers/ServerHeadProvider.ts +22 -138
- package/src/i18n/__tests__/integration.spec.tsx +239 -0
- package/src/i18n/components/Localize.spec.tsx +357 -0
- package/src/i18n/hooks/useI18n.browser.spec.tsx +438 -0
- package/src/i18n/providers/I18nProvider.spec.ts +389 -0
- package/src/router/__tests__/page-head-browser.browser.spec.ts +91 -0
- package/src/router/__tests__/page-head.spec.ts +44 -0
- package/src/router/__tests__/seo-head.spec.ts +121 -0
- package/src/router/atoms/ssrManifestAtom.ts +60 -0
- package/src/router/constants/PAGE_PRELOAD_KEY.ts +6 -0
- package/src/router/errors/Redirection.ts +1 -1
- package/src/router/index.shared.ts +1 -0
- package/src/router/index.ts +16 -2
- package/src/router/primitives/$page.browser.spec.tsx +702 -0
- package/src/router/primitives/$page.spec.tsx +702 -0
- package/src/router/primitives/$page.ts +46 -10
- package/src/router/providers/ReactBrowserProvider.ts +14 -29
- package/src/router/providers/ReactBrowserRouterProvider.ts +5 -0
- package/src/router/providers/ReactPageProvider.ts +11 -4
- package/src/router/providers/ReactServerProvider.spec.tsx +316 -0
- package/src/router/providers/ReactServerProvider.ts +331 -315
- package/src/router/providers/ReactServerTemplateProvider.ts +775 -0
- package/src/router/providers/SSRManifestProvider.ts +365 -0
- package/src/router/services/ReactPageServerService.ts +5 -3
- package/src/router/services/ReactRouter.ts +3 -3
|
@@ -2,6 +2,7 @@ import { $atom, $env, $hook, $inject, $module, $use, Alepha, AlephaError, KIND,
|
|
|
2
2
|
import { AlephaDateTime, DateTimeProvider } from "alepha/datetime";
|
|
3
3
|
import { $logger } from "alepha/logger";
|
|
4
4
|
import { AlephaServerLinks, LinkProvider } from "alepha/server/links";
|
|
5
|
+
import { BrowserHeadProvider } from "@alepha/react/head";
|
|
5
6
|
import { RouterProvider } from "alepha/router";
|
|
6
7
|
import { StrictMode, createContext, createElement, memo, use, useRef, useState } from "react";
|
|
7
8
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -23,6 +24,15 @@ var ReactPageService = class {
|
|
|
23
24
|
}
|
|
24
25
|
};
|
|
25
26
|
|
|
27
|
+
//#endregion
|
|
28
|
+
//#region ../../src/router/constants/PAGE_PRELOAD_KEY.ts
|
|
29
|
+
/**
|
|
30
|
+
* Symbol key for SSR module preloading path.
|
|
31
|
+
* Using Symbol.for() allows the Vite plugin to inject this at build time.
|
|
32
|
+
* @internal
|
|
33
|
+
*/
|
|
34
|
+
const PAGE_PRELOAD_KEY = Symbol.for("alepha.page.preload");
|
|
35
|
+
|
|
26
36
|
//#endregion
|
|
27
37
|
//#region ../../src/router/primitives/$page.ts
|
|
28
38
|
/**
|
|
@@ -37,7 +47,7 @@ var ReactPageService = class {
|
|
|
37
47
|
* - Type-safe URL parameter and query string validation
|
|
38
48
|
*
|
|
39
49
|
* **Data Loading**
|
|
40
|
-
* - Server-side data fetching with the `
|
|
50
|
+
* - Server-side data fetching with the `loader` function
|
|
41
51
|
* - Automatic serialization and hydration for SSR
|
|
42
52
|
* - Access to request context, URL params, and parent data
|
|
43
53
|
*
|
|
@@ -74,7 +84,7 @@ var ReactPageService = class {
|
|
|
74
84
|
* params: t.object({ id: t.integer() }),
|
|
75
85
|
* query: t.object({ tab: t.optional(t.text()) })
|
|
76
86
|
* },
|
|
77
|
-
*
|
|
87
|
+
* loader: async ({ params }) => {
|
|
78
88
|
* const user = await userApi.getUser(params.id);
|
|
79
89
|
* return { user };
|
|
80
90
|
* },
|
|
@@ -87,7 +97,7 @@ var ReactPageService = class {
|
|
|
87
97
|
* const projectSection = $page({
|
|
88
98
|
* path: "/projects/:id",
|
|
89
99
|
* children: () => [projectBoard, projectSettings],
|
|
90
|
-
*
|
|
100
|
+
* loader: async ({ params }) => {
|
|
91
101
|
* const project = await projectApi.get(params.id);
|
|
92
102
|
* return { project };
|
|
93
103
|
* },
|
|
@@ -106,7 +116,7 @@ var ReactPageService = class {
|
|
|
106
116
|
* static: {
|
|
107
117
|
* entries: posts.map(p => ({ params: { slug: p.slug } }))
|
|
108
118
|
* },
|
|
109
|
-
*
|
|
119
|
+
* loader: async ({ params }) => {
|
|
110
120
|
* const post = await loadPost(params.slug);
|
|
111
121
|
* return { post };
|
|
112
122
|
* }
|
|
@@ -587,7 +597,7 @@ const RouterLayerContext = createContext(void 0);
|
|
|
587
597
|
* import { Redirection } from "@alepha/react";
|
|
588
598
|
*
|
|
589
599
|
* const MyPage = $page({
|
|
590
|
-
*
|
|
600
|
+
* loader: async () => {
|
|
591
601
|
* if (needRedirect) {
|
|
592
602
|
* throw new Redirection("/new-path");
|
|
593
603
|
* }
|
|
@@ -743,13 +753,13 @@ function parseAnimation(animationLike, state, type = "enter") {
|
|
|
743
753
|
|
|
744
754
|
//#endregion
|
|
745
755
|
//#region ../../src/router/providers/ReactPageProvider.ts
|
|
746
|
-
const envSchema
|
|
756
|
+
const envSchema = t.object({ REACT_STRICT_MODE: t.boolean({ default: true }) });
|
|
747
757
|
/**
|
|
748
758
|
* Handle page routes for React applications. (Browser and Server)
|
|
749
759
|
*/
|
|
750
760
|
var ReactPageProvider = class {
|
|
751
761
|
log = $logger();
|
|
752
|
-
env = $env(envSchema
|
|
762
|
+
env = $env(envSchema);
|
|
753
763
|
alepha = $inject(Alepha);
|
|
754
764
|
pages = [];
|
|
755
765
|
getPages() {
|
|
@@ -869,11 +879,11 @@ var ReactPageProvider = class {
|
|
|
869
879
|
}
|
|
870
880
|
forceRefresh = true;
|
|
871
881
|
}
|
|
872
|
-
if (!route$1.
|
|
882
|
+
if (!route$1.loader) continue;
|
|
873
883
|
try {
|
|
874
884
|
const args = Object.create(state);
|
|
875
885
|
Object.assign(args, config, context);
|
|
876
|
-
const props = await route$1.
|
|
886
|
+
const props = await route$1.loader?.(args) ?? {};
|
|
877
887
|
it.props = { ...props };
|
|
878
888
|
context = {
|
|
879
889
|
...context,
|
|
@@ -881,7 +891,7 @@ var ReactPageProvider = class {
|
|
|
881
891
|
};
|
|
882
892
|
} catch (e) {
|
|
883
893
|
if (e instanceof Redirection) return { redirect: e.redirect };
|
|
884
|
-
this.log.error("Page
|
|
894
|
+
this.log.error("Page loader has failed", e);
|
|
885
895
|
it.error = e;
|
|
886
896
|
break;
|
|
887
897
|
}
|
|
@@ -1076,6 +1086,7 @@ var ReactBrowserRouterProvider = class extends RouterProvider {
|
|
|
1076
1086
|
log = $logger();
|
|
1077
1087
|
alepha = $inject(Alepha);
|
|
1078
1088
|
pageApi = $inject(ReactPageProvider);
|
|
1089
|
+
browserHeadProvider = $inject(BrowserHeadProvider);
|
|
1079
1090
|
add(entry) {
|
|
1080
1091
|
this.pageApi.add(entry);
|
|
1081
1092
|
}
|
|
@@ -1146,6 +1157,7 @@ var ReactBrowserRouterProvider = class extends RouterProvider {
|
|
|
1146
1157
|
this.alepha.store.set("alepha.react.router.state", state);
|
|
1147
1158
|
await this.alepha.events.emit("react:action:end", { type: "transition" });
|
|
1148
1159
|
await this.alepha.events.emit("react:transition:end", { state });
|
|
1160
|
+
this.browserHeadProvider.fillAndRenderHead(state);
|
|
1149
1161
|
}
|
|
1150
1162
|
root(state) {
|
|
1151
1163
|
return this.pageApi.root(state);
|
|
@@ -1154,7 +1166,6 @@ var ReactBrowserRouterProvider = class extends RouterProvider {
|
|
|
1154
1166
|
|
|
1155
1167
|
//#endregion
|
|
1156
1168
|
//#region ../../src/router/providers/ReactBrowserProvider.ts
|
|
1157
|
-
const envSchema = t.object({ REACT_ROOT_ID: t.text({ default: "root" }) });
|
|
1158
1169
|
/**
|
|
1159
1170
|
* React browser renderer configuration atom
|
|
1160
1171
|
*/
|
|
@@ -1164,18 +1175,21 @@ const reactBrowserOptions = $atom({
|
|
|
1164
1175
|
default: { scrollRestoration: "top" }
|
|
1165
1176
|
});
|
|
1166
1177
|
var ReactBrowserProvider = class {
|
|
1167
|
-
env = $env(envSchema);
|
|
1168
1178
|
log = $logger();
|
|
1169
1179
|
client = $inject(LinkProvider);
|
|
1170
1180
|
alepha = $inject(Alepha);
|
|
1171
1181
|
router = $inject(ReactBrowserRouterProvider);
|
|
1172
1182
|
dateTimeProvider = $inject(DateTimeProvider);
|
|
1183
|
+
browserHeadProvider = $inject(BrowserHeadProvider);
|
|
1173
1184
|
options = $use(reactBrowserOptions);
|
|
1185
|
+
get rootId() {
|
|
1186
|
+
return "root";
|
|
1187
|
+
}
|
|
1174
1188
|
getRootElement() {
|
|
1175
|
-
const root = this.document.getElementById(this.
|
|
1189
|
+
const root = this.document.getElementById(this.rootId);
|
|
1176
1190
|
if (root) return root;
|
|
1177
1191
|
const div = this.document.createElement("div");
|
|
1178
|
-
div.id = this.
|
|
1192
|
+
div.id = this.rootId;
|
|
1179
1193
|
this.document.body.prepend(div);
|
|
1180
1194
|
return div;
|
|
1181
1195
|
}
|
|
@@ -1308,6 +1322,7 @@ var ReactBrowserProvider = class {
|
|
|
1308
1322
|
hydration,
|
|
1309
1323
|
state: this.state
|
|
1310
1324
|
});
|
|
1325
|
+
this.browserHeadProvider.fillAndRenderHead(this.state);
|
|
1311
1326
|
window.addEventListener("popstate", () => {
|
|
1312
1327
|
if (this.base + this.state.url.pathname === this.location.pathname) return;
|
|
1313
1328
|
this.log.debug("Popstate event triggered - rendering new state", { url: this.location.pathname + this.location.search });
|