@alepha/react 0.14.3 → 0.15.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/README.md +10 -0
- package/dist/auth/index.browser.js +29 -14
- package/dist/auth/index.browser.js.map +1 -1
- package/dist/auth/index.d.ts +4 -4
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +950 -194
- package/dist/auth/index.js.map +1 -1
- package/dist/core/index.d.ts +118 -118
- package/dist/core/index.d.ts.map +1 -1
- package/dist/form/index.d.ts +27 -28
- package/dist/form/index.d.ts.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 +105 -576
- package/dist/head/index.d.ts.map +1 -1
- package/dist/head/index.js +91 -87
- package/dist/head/index.js.map +1 -1
- package/dist/i18n/index.d.ts +33 -33
- package/dist/i18n/index.d.ts.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 +827 -403
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +951 -195
- package/dist/router/index.js.map +1 -1
- package/dist/websocket/index.d.ts +38 -39
- package/dist/websocket/index.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/auth/__tests__/$auth.spec.ts +10 -11
- package/src/core/__tests__/Router.spec.tsx +4 -4
- package/src/head/{__tests__/expandSeo.spec.ts → helpers/SeoExpander.spec.ts} +1 -1
- package/src/head/index.ts +10 -28
- package/src/head/providers/BrowserHeadProvider.browser.spec.ts +1 -76
- 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/router/__tests__/page-head-browser.browser.spec.ts +91 -0
- package/src/router/__tests__/page-head.spec.ts +44 -0
- package/src/{head → router}/__tests__/seo-head.spec.ts +2 -2
- 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 +15 -15
- package/src/router/primitives/$page.spec.tsx +18 -18
- 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.ts +321 -316
- package/src/router/providers/ReactServerTemplateProvider.ts +793 -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
- package/src/head/__tests__/page-head.spec.ts +0 -39
- package/src/head/providers/ServerHeadProvider.spec.ts +0 -163
|
@@ -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, useEffect, useRef, useState } from "react";
|
|
7
8
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -22,6 +23,15 @@ var ReactPageService = class {
|
|
|
22
23
|
}
|
|
23
24
|
};
|
|
24
25
|
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region ../../src/router/constants/PAGE_PRELOAD_KEY.ts
|
|
28
|
+
/**
|
|
29
|
+
* Symbol key for SSR module preloading path.
|
|
30
|
+
* Using Symbol.for() allows the Vite plugin to inject this at build time.
|
|
31
|
+
* @internal
|
|
32
|
+
*/
|
|
33
|
+
const PAGE_PRELOAD_KEY = Symbol.for("alepha.page.preload");
|
|
34
|
+
|
|
25
35
|
//#endregion
|
|
26
36
|
//#region ../../src/router/primitives/$page.ts
|
|
27
37
|
/**
|
|
@@ -36,7 +46,7 @@ var ReactPageService = class {
|
|
|
36
46
|
* - Type-safe URL parameter and query string validation
|
|
37
47
|
*
|
|
38
48
|
* **Data Loading**
|
|
39
|
-
* - Server-side data fetching with the `
|
|
49
|
+
* - Server-side data fetching with the `loader` function
|
|
40
50
|
* - Automatic serialization and hydration for SSR
|
|
41
51
|
* - Access to request context, URL params, and parent data
|
|
42
52
|
*
|
|
@@ -73,7 +83,7 @@ var ReactPageService = class {
|
|
|
73
83
|
* params: t.object({ id: t.integer() }),
|
|
74
84
|
* query: t.object({ tab: t.optional(t.text()) })
|
|
75
85
|
* },
|
|
76
|
-
*
|
|
86
|
+
* loader: async ({ params }) => {
|
|
77
87
|
* const user = await userApi.getUser(params.id);
|
|
78
88
|
* return { user };
|
|
79
89
|
* },
|
|
@@ -86,7 +96,7 @@ var ReactPageService = class {
|
|
|
86
96
|
* const projectSection = $page({
|
|
87
97
|
* path: "/projects/:id",
|
|
88
98
|
* children: () => [projectBoard, projectSettings],
|
|
89
|
-
*
|
|
99
|
+
* loader: async ({ params }) => {
|
|
90
100
|
* const project = await projectApi.get(params.id);
|
|
91
101
|
* return { project };
|
|
92
102
|
* },
|
|
@@ -105,7 +115,7 @@ var ReactPageService = class {
|
|
|
105
115
|
* static: {
|
|
106
116
|
* entries: posts.map(p => ({ params: { slug: p.slug } }))
|
|
107
117
|
* },
|
|
108
|
-
*
|
|
118
|
+
* loader: async ({ params }) => {
|
|
109
119
|
* const post = await loadPost(params.slug);
|
|
110
120
|
* return { post };
|
|
111
121
|
* }
|
|
@@ -586,7 +596,7 @@ const RouterLayerContext = createContext(void 0);
|
|
|
586
596
|
* import { Redirection } from "@alepha/react";
|
|
587
597
|
*
|
|
588
598
|
* const MyPage = $page({
|
|
589
|
-
*
|
|
599
|
+
* loader: async () => {
|
|
590
600
|
* if (needRedirect) {
|
|
591
601
|
* throw new Redirection("/new-path");
|
|
592
602
|
* }
|
|
@@ -742,13 +752,13 @@ function parseAnimation(animationLike, state, type = "enter") {
|
|
|
742
752
|
|
|
743
753
|
//#endregion
|
|
744
754
|
//#region ../../src/router/providers/ReactPageProvider.ts
|
|
745
|
-
const envSchema
|
|
755
|
+
const envSchema = t.object({ REACT_STRICT_MODE: t.boolean({ default: true }) });
|
|
746
756
|
/**
|
|
747
757
|
* Handle page routes for React applications. (Browser and Server)
|
|
748
758
|
*/
|
|
749
759
|
var ReactPageProvider = class {
|
|
750
760
|
log = $logger();
|
|
751
|
-
env = $env(envSchema
|
|
761
|
+
env = $env(envSchema);
|
|
752
762
|
alepha = $inject(Alepha);
|
|
753
763
|
pages = [];
|
|
754
764
|
getPages() {
|
|
@@ -868,11 +878,11 @@ var ReactPageProvider = class {
|
|
|
868
878
|
}
|
|
869
879
|
forceRefresh = true;
|
|
870
880
|
}
|
|
871
|
-
if (!route$1.
|
|
881
|
+
if (!route$1.loader) continue;
|
|
872
882
|
try {
|
|
873
883
|
const args = Object.create(state);
|
|
874
884
|
Object.assign(args, config, context);
|
|
875
|
-
const props = await route$1.
|
|
885
|
+
const props = await route$1.loader?.(args) ?? {};
|
|
876
886
|
it.props = { ...props };
|
|
877
887
|
context = {
|
|
878
888
|
...context,
|
|
@@ -880,7 +890,7 @@ var ReactPageProvider = class {
|
|
|
880
890
|
};
|
|
881
891
|
} catch (e) {
|
|
882
892
|
if (e instanceof Redirection) return { redirect: e.redirect };
|
|
883
|
-
this.log.error("Page
|
|
893
|
+
this.log.error("Page loader has failed", e);
|
|
884
894
|
it.error = e;
|
|
885
895
|
break;
|
|
886
896
|
}
|
|
@@ -1075,6 +1085,7 @@ var ReactBrowserRouterProvider = class extends RouterProvider {
|
|
|
1075
1085
|
log = $logger();
|
|
1076
1086
|
alepha = $inject(Alepha);
|
|
1077
1087
|
pageApi = $inject(ReactPageProvider);
|
|
1088
|
+
browserHeadProvider = $inject(BrowserHeadProvider);
|
|
1078
1089
|
add(entry) {
|
|
1079
1090
|
this.pageApi.add(entry);
|
|
1080
1091
|
}
|
|
@@ -1145,6 +1156,7 @@ var ReactBrowserRouterProvider = class extends RouterProvider {
|
|
|
1145
1156
|
this.alepha.store.set("alepha.react.router.state", state);
|
|
1146
1157
|
await this.alepha.events.emit("react:action:end", { type: "transition" });
|
|
1147
1158
|
await this.alepha.events.emit("react:transition:end", { state });
|
|
1159
|
+
this.browserHeadProvider.fillAndRenderHead(state);
|
|
1148
1160
|
}
|
|
1149
1161
|
root(state) {
|
|
1150
1162
|
return this.pageApi.root(state);
|
|
@@ -1153,7 +1165,6 @@ var ReactBrowserRouterProvider = class extends RouterProvider {
|
|
|
1153
1165
|
|
|
1154
1166
|
//#endregion
|
|
1155
1167
|
//#region ../../src/router/providers/ReactBrowserProvider.ts
|
|
1156
|
-
const envSchema = t.object({ REACT_ROOT_ID: t.text({ default: "root" }) });
|
|
1157
1168
|
/**
|
|
1158
1169
|
* React browser renderer configuration atom
|
|
1159
1170
|
*/
|
|
@@ -1163,18 +1174,21 @@ const reactBrowserOptions = $atom({
|
|
|
1163
1174
|
default: { scrollRestoration: "top" }
|
|
1164
1175
|
});
|
|
1165
1176
|
var ReactBrowserProvider = class {
|
|
1166
|
-
env = $env(envSchema);
|
|
1167
1177
|
log = $logger();
|
|
1168
1178
|
client = $inject(LinkProvider);
|
|
1169
1179
|
alepha = $inject(Alepha);
|
|
1170
1180
|
router = $inject(ReactBrowserRouterProvider);
|
|
1171
1181
|
dateTimeProvider = $inject(DateTimeProvider);
|
|
1182
|
+
browserHeadProvider = $inject(BrowserHeadProvider);
|
|
1172
1183
|
options = $use(reactBrowserOptions);
|
|
1184
|
+
get rootId() {
|
|
1185
|
+
return "root";
|
|
1186
|
+
}
|
|
1173
1187
|
getRootElement() {
|
|
1174
|
-
const root = this.document.getElementById(this.
|
|
1188
|
+
const root = this.document.getElementById(this.rootId);
|
|
1175
1189
|
if (root) return root;
|
|
1176
1190
|
const div = this.document.createElement("div");
|
|
1177
|
-
div.id = this.
|
|
1191
|
+
div.id = this.rootId;
|
|
1178
1192
|
this.document.body.prepend(div);
|
|
1179
1193
|
return div;
|
|
1180
1194
|
}
|
|
@@ -1307,6 +1321,7 @@ var ReactBrowserProvider = class {
|
|
|
1307
1321
|
hydration,
|
|
1308
1322
|
state: this.state
|
|
1309
1323
|
});
|
|
1324
|
+
this.browserHeadProvider.fillAndRenderHead(this.state);
|
|
1310
1325
|
window.addEventListener("popstate", () => {
|
|
1311
1326
|
if (this.base + this.state.url.pathname === this.location.pathname) return;
|
|
1312
1327
|
this.log.debug("Popstate event triggered - rendering new state", { url: this.location.pathname + this.location.search });
|
|
@@ -1596,5 +1611,5 @@ const AlephaReactRouter = $module({
|
|
|
1596
1611
|
});
|
|
1597
1612
|
|
|
1598
1613
|
//#endregion
|
|
1599
|
-
export { $page, AlephaReactRouter, ErrorViewer_default as ErrorViewer, Link_default as Link, NestedView_default as NestedView, NotFound_default as NotFound, PagePrimitive, ReactBrowserProvider, ReactBrowserRendererProvider, ReactBrowserRouterProvider, ReactPageProvider, ReactPageService, ReactRouter, Redirection, RouterLayerContext, isPageRoute, reactBrowserOptions, useActive, useQueryParams, useRouter, useRouterState };
|
|
1614
|
+
export { $page, AlephaReactRouter, ErrorViewer_default as ErrorViewer, Link_default as Link, NestedView_default as NestedView, NotFound_default as NotFound, PAGE_PRELOAD_KEY, PagePrimitive, ReactBrowserProvider, ReactBrowserRendererProvider, ReactBrowserRouterProvider, ReactPageProvider, ReactPageService, ReactRouter, Redirection, RouterLayerContext, isPageRoute, reactBrowserOptions, useActive, useQueryParams, useRouter, useRouterState };
|
|
1600
1615
|
//# sourceMappingURL=index.browser.js.map
|