@alepha/react 0.15.0 → 0.15.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/dist/auth/index.browser.js +603 -242
- package/dist/auth/index.browser.js.map +1 -1
- package/dist/auth/index.d.ts +6 -6
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +1296 -922
- package/dist/auth/index.js.map +1 -1
- package/dist/core/index.d.ts +128 -128
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +20 -20
- package/dist/core/index.js.map +1 -1
- package/dist/form/index.d.ts +36 -36
- package/dist/form/index.d.ts.map +1 -1
- package/dist/form/index.js +15 -15
- package/dist/form/index.js.map +1 -1
- package/dist/head/index.browser.js +20 -0
- package/dist/head/index.browser.js.map +1 -1
- package/dist/head/index.d.ts +73 -65
- package/dist/head/index.d.ts.map +1 -1
- package/dist/head/index.js +20 -0
- package/dist/head/index.js.map +1 -1
- package/dist/i18n/index.d.ts +37 -37
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/i18n/index.js.map +1 -1
- package/dist/router/index.browser.js +605 -244
- package/dist/router/index.browser.js.map +1 -1
- package/dist/router/index.d.ts +539 -550
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +1296 -922
- package/dist/router/index.js.map +1 -1
- package/dist/websocket/index.d.ts +38 -38
- package/dist/websocket/index.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/auth/__tests__/$auth.spec.ts +162 -147
- package/src/auth/index.ts +9 -3
- package/src/auth/services/ReactAuth.ts +15 -5
- package/src/core/hooks/useAction.ts +1 -2
- package/src/core/index.ts +4 -4
- package/src/form/errors/FormValidationError.ts +4 -6
- package/src/form/hooks/useFormState.ts +1 -1
- package/src/form/index.ts +1 -1
- package/src/form/services/FormModel.ts +31 -25
- package/src/head/helpers/SeoExpander.ts +2 -1
- package/src/head/hooks/useHead.spec.tsx +2 -2
- package/src/head/index.browser.ts +2 -2
- package/src/head/index.ts +4 -4
- package/src/head/interfaces/Head.ts +15 -3
- package/src/head/primitives/$head.ts +2 -5
- package/src/head/providers/BrowserHeadProvider.ts +55 -0
- package/src/head/providers/HeadProvider.ts +4 -1
- package/src/i18n/__tests__/integration.spec.tsx +1 -1
- package/src/i18n/components/Localize.spec.tsx +2 -2
- package/src/i18n/hooks/useI18n.browser.spec.tsx +2 -2
- package/src/i18n/index.ts +1 -1
- package/src/i18n/primitives/$dictionary.ts +1 -1
- package/src/i18n/providers/I18nProvider.spec.ts +1 -1
- package/src/i18n/providers/I18nProvider.ts +1 -1
- package/src/router/__tests__/page-head-browser.browser.spec.ts +5 -1
- package/src/router/__tests__/page-head.spec.ts +11 -7
- package/src/router/__tests__/seo-head.spec.ts +7 -3
- package/src/router/atoms/ssrManifestAtom.ts +2 -11
- package/src/router/components/ErrorViewer.tsx +626 -167
- package/src/router/components/Link.tsx +4 -2
- package/src/router/components/NestedView.tsx +7 -9
- package/src/router/components/NotFound.tsx +2 -2
- package/src/router/hooks/useQueryParams.ts +1 -1
- package/src/router/hooks/useRouter.ts +1 -1
- package/src/router/hooks/useRouterState.ts +1 -1
- package/src/router/index.browser.ts +10 -11
- package/src/router/index.shared.ts +7 -7
- package/src/router/index.ts +10 -7
- package/src/router/primitives/$page.browser.spec.tsx +6 -1
- package/src/router/primitives/$page.spec.tsx +7 -1
- package/src/router/primitives/$page.ts +5 -9
- package/src/router/providers/ReactBrowserProvider.ts +17 -6
- package/src/router/providers/ReactBrowserRouterProvider.ts +1 -1
- package/src/router/providers/ReactPageProvider.ts +4 -3
- package/src/router/providers/ReactServerProvider.ts +29 -37
- package/src/router/providers/ReactServerTemplateProvider.ts +300 -137
- package/src/router/providers/SSRManifestProvider.ts +17 -60
- package/src/router/services/ReactPageService.ts +4 -1
- package/src/router/services/ReactRouter.ts +6 -5
|
@@ -14,8 +14,10 @@ const Link = (props: LinkProps) => {
|
|
|
14
14
|
const router = useRouter();
|
|
15
15
|
|
|
16
16
|
return createElement(
|
|
17
|
-
"a",
|
|
18
|
-
|
|
17
|
+
"a",
|
|
18
|
+
{ ...props, ...router.anchor(props.href) },
|
|
19
|
+
props.children,
|
|
20
|
+
);
|
|
19
21
|
};
|
|
20
22
|
|
|
21
23
|
export default Link;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
import { ErrorBoundary, useAlepha, useEvents } from "@alepha/react";
|
|
1
2
|
import { memo, type ReactNode, use, useRef, useState } from "react";
|
|
2
|
-
import type { ReactRouterState } from "../providers/ReactPageProvider.ts";
|
|
3
3
|
import { RouterLayerContext } from "../contexts/RouterLayerContext.ts";
|
|
4
4
|
import { Redirection } from "../errors/Redirection.ts";
|
|
5
5
|
import { useRouterState } from "../hooks/useRouterState.ts";
|
|
6
6
|
import type { PageAnimation } from "../primitives/$page.ts";
|
|
7
|
+
import type { ReactRouterState } from "../providers/ReactPageProvider.ts";
|
|
7
8
|
import ErrorViewer from "./ErrorViewer.tsx";
|
|
8
|
-
import { ErrorBoundary, useAlepha, useEvents } from "@alepha/react";
|
|
9
9
|
|
|
10
10
|
export interface NestedViewProps {
|
|
11
11
|
children?: ReactNode;
|
|
@@ -152,18 +152,16 @@ const NestedView = (props: NestedViewProps) => {
|
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
const fallback = (error: Error) => {
|
|
155
|
-
const result = onError?.(error, state) ??
|
|
155
|
+
const result = onError?.(error, state) ?? (
|
|
156
|
+
<ErrorViewer error={error} alepha={alepha} />
|
|
157
|
+
);
|
|
156
158
|
if (result instanceof Redirection) {
|
|
157
159
|
return "Redirection inside ErrorBoundary is not allowed.";
|
|
158
160
|
}
|
|
159
161
|
return result as ReactNode;
|
|
160
|
-
}
|
|
162
|
+
};
|
|
161
163
|
|
|
162
|
-
return
|
|
163
|
-
<ErrorBoundary fallback={fallback}>
|
|
164
|
-
{element}
|
|
165
|
-
</ErrorBoundary>
|
|
166
|
-
);
|
|
164
|
+
return <ErrorBoundary fallback={fallback}>{element}</ErrorBoundary>;
|
|
167
165
|
};
|
|
168
166
|
|
|
169
167
|
export default memo(NestedView);
|
|
@@ -3,7 +3,7 @@ import type { CSSProperties } from "react";
|
|
|
3
3
|
/**
|
|
4
4
|
* Default 404 Not Found page component.
|
|
5
5
|
*/
|
|
6
|
-
|
|
6
|
+
const NotFound = (props: { style?: CSSProperties }) => (
|
|
7
7
|
<div
|
|
8
8
|
style={{
|
|
9
9
|
width: "100%",
|
|
@@ -25,6 +25,6 @@ import type { CSSProperties } from "react";
|
|
|
25
25
|
Page not found
|
|
26
26
|
</div>
|
|
27
27
|
</div>
|
|
28
|
-
)
|
|
28
|
+
);
|
|
29
29
|
|
|
30
30
|
export default NotFound;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { useStore } from "@alepha/react";
|
|
1
2
|
import { AlephaError } from "alepha";
|
|
2
3
|
import type { ReactRouterState } from "../providers/ReactPageProvider.ts";
|
|
3
|
-
import { useStore } from "@alepha/react";
|
|
4
4
|
|
|
5
5
|
export const useRouterState = (): ReactRouterState => {
|
|
6
6
|
const [state] = useStore("alepha.react.router.state");
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
+
import { AlephaReact } from "@alepha/react";
|
|
1
2
|
import { $module } from "alepha";
|
|
3
|
+
import { AlephaDateTime } from "alepha/datetime";
|
|
4
|
+
import { AlephaServer } from "alepha/server";
|
|
5
|
+
import { AlephaServerLinks } from "alepha/server/links";
|
|
2
6
|
import { $page } from "./primitives/$page.ts";
|
|
3
|
-
import {
|
|
7
|
+
import { ReactBrowserProvider } from "./providers/ReactBrowserProvider.ts";
|
|
4
8
|
import { ReactBrowserRendererProvider } from "./providers/ReactBrowserRendererProvider.ts";
|
|
5
9
|
import { ReactBrowserRouterProvider } from "./providers/ReactBrowserRouterProvider.ts";
|
|
6
|
-
import { ReactPageService } from "./services/ReactPageService.ts";
|
|
7
10
|
import { ReactPageProvider } from "./providers/ReactPageProvider.ts";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { AlephaServer } from "alepha/server";
|
|
11
|
-
import { AlephaServerLinks } from "alepha/server/links";
|
|
12
|
-
import { AlephaReact } from "@alepha/react";
|
|
11
|
+
import { ReactPageService } from "./services/ReactPageService.ts";
|
|
12
|
+
import { ReactRouter } from "./services/ReactRouter.ts";
|
|
13
13
|
|
|
14
14
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
15
15
|
|
|
16
16
|
export * from "./index.shared.ts";
|
|
17
|
-
export * from "./providers/ReactBrowserProvider.ts"
|
|
18
|
-
export * from "./providers/
|
|
19
|
-
export * from "./providers/
|
|
17
|
+
export * from "./providers/ReactBrowserProvider.ts";
|
|
18
|
+
export * from "./providers/ReactBrowserRendererProvider.ts";
|
|
19
|
+
export * from "./providers/ReactBrowserRouterProvider.ts";
|
|
20
20
|
|
|
21
21
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
22
22
|
|
|
@@ -43,4 +43,3 @@ export const AlephaReactRouter = $module({
|
|
|
43
43
|
.with(ReactBrowserRendererProvider)
|
|
44
44
|
.with(ReactRouter),
|
|
45
45
|
});
|
|
46
|
-
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
export { default as ErrorViewer } from "./components/ErrorViewer.tsx";
|
|
2
1
|
export type * from "./components/ErrorViewer.tsx";
|
|
2
|
+
export { default as ErrorViewer } from "./components/ErrorViewer.tsx";
|
|
3
|
+
export type * from "./components/Link.tsx";
|
|
3
4
|
export { default as Link, type LinkProps } from "./components/Link.tsx";
|
|
4
|
-
export type *
|
|
5
|
+
export type * from "./components/NestedView.tsx";
|
|
5
6
|
export { default as NestedView } from "./components/NestedView.tsx";
|
|
6
|
-
export type * from "./components/NestedView.tsx";
|
|
7
|
-
export { default as NotFound } from "./components/NotFound.tsx";
|
|
8
7
|
export type * from "./components/NotFound.tsx";
|
|
8
|
+
export { default as NotFound } from "./components/NotFound.tsx";
|
|
9
9
|
export * from "./constants/PAGE_PRELOAD_KEY.ts";
|
|
10
10
|
export * from "./contexts/RouterLayerContext.ts";
|
|
11
|
-
export * from "./primitives/$page.ts";
|
|
12
11
|
export * from "./errors/Redirection.ts";
|
|
13
12
|
export * from "./hooks/useActive.ts";
|
|
14
13
|
export * from "./hooks/useQueryParams.ts";
|
|
15
14
|
export * from "./hooks/useRouter.ts";
|
|
16
15
|
export * from "./hooks/useRouterState.ts";
|
|
17
|
-
export * from "./
|
|
18
|
-
export * from "./services/ReactPageService.ts"
|
|
16
|
+
export * from "./primitives/$page.ts";
|
|
19
17
|
export * from "./providers/ReactPageProvider.ts";
|
|
18
|
+
export * from "./services/ReactPageService.ts";
|
|
19
|
+
export * from "./services/ReactRouter.ts";
|
package/src/router/index.ts
CHANGED
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
import { AlephaReact } from "@alepha/react";
|
|
2
2
|
import { $module } from "alepha";
|
|
3
|
-
import {
|
|
4
|
-
import { ReactRouter } from "./services/ReactRouter.ts";
|
|
5
|
-
import { ReactPageProvider, type ReactRouterState } from "./providers/ReactPageProvider.ts";
|
|
3
|
+
import { AlephaDateTime } from "alepha/datetime";
|
|
6
4
|
import { AlephaServer, type ServerRequest } from "alepha/server";
|
|
5
|
+
import { AlephaServerCache } from "alepha/server/cache";
|
|
6
|
+
import { AlephaServerLinks } from "alepha/server/links";
|
|
7
7
|
import type { ReactNode } from "react";
|
|
8
|
+
import { $page, type PageAnimation } from "./primitives/$page.ts";
|
|
8
9
|
import type { ReactHydrationState } from "./providers/ReactBrowserProvider.ts";
|
|
10
|
+
import {
|
|
11
|
+
ReactPageProvider,
|
|
12
|
+
type ReactRouterState,
|
|
13
|
+
} from "./providers/ReactPageProvider.ts";
|
|
9
14
|
import { ReactServerProvider } from "./providers/ReactServerProvider.ts";
|
|
10
15
|
import { ReactServerTemplateProvider } from "./providers/ReactServerTemplateProvider.ts";
|
|
11
16
|
import { SSRManifestProvider } from "./providers/SSRManifestProvider.ts";
|
|
12
17
|
import { ReactPageServerService } from "./services/ReactPageServerService.ts";
|
|
13
|
-
import { AlephaServerCache } from "alepha/server/cache";
|
|
14
|
-
import { AlephaServerLinks } from "alepha/server/links";
|
|
15
18
|
import { ReactPageService } from "./services/ReactPageService.ts";
|
|
16
|
-
import {
|
|
19
|
+
import { ReactRouter } from "./services/ReactRouter.ts";
|
|
17
20
|
|
|
18
21
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
19
22
|
|
|
20
23
|
export * from "./index.shared.ts";
|
|
21
|
-
export * from "./providers/ReactPageProvider.ts";
|
|
22
24
|
export * from "./providers/ReactBrowserProvider.ts";
|
|
25
|
+
export * from "./providers/ReactPageProvider.ts";
|
|
23
26
|
export * from "./providers/ReactServerProvider.ts";
|
|
24
27
|
export * from "./providers/ReactServerTemplateProvider.ts";
|
|
25
28
|
export * from "./providers/SSRManifestProvider.ts";
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { AlephaReact } from "@alepha/react";
|
|
2
|
-
import { $page, NestedView, Redirection, ReactRouter } from "../index.browser.ts";
|
|
3
2
|
import { waitFor } from "@testing-library/dom";
|
|
4
3
|
import { Alepha, t } from "alepha";
|
|
5
4
|
import { act } from "react";
|
|
6
5
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
6
|
+
import {
|
|
7
|
+
$page,
|
|
8
|
+
NestedView,
|
|
9
|
+
ReactRouter,
|
|
10
|
+
Redirection,
|
|
11
|
+
} from "../index.browser.ts";
|
|
7
12
|
|
|
8
13
|
describe("$page browser tests", () => {
|
|
9
14
|
let alepha: Alepha;
|
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
import { $page, PagePrimitive, Redirection, NestedView, type ReactRouterState } from "../index.ts";
|
|
2
1
|
import { Alepha, t } from "alepha";
|
|
3
2
|
import type { FC } from "react";
|
|
4
3
|
import { beforeEach, describe, test, vi } from "vitest";
|
|
4
|
+
import {
|
|
5
|
+
$page,
|
|
6
|
+
NestedView,
|
|
7
|
+
PagePrimitive,
|
|
8
|
+
type ReactRouterState,
|
|
9
|
+
Redirection,
|
|
10
|
+
} from "../index.ts";
|
|
5
11
|
|
|
6
12
|
describe("$page primitive tests", () => {
|
|
7
13
|
let alepha: Alepha;
|
|
@@ -1,22 +1,21 @@
|
|
|
1
|
+
import type { ClientOnlyProps } from "@alepha/react";
|
|
2
|
+
import type { Head } from "@alepha/react/head";
|
|
1
3
|
import {
|
|
2
4
|
$inject,
|
|
3
5
|
type Async,
|
|
4
6
|
createPrimitive,
|
|
5
|
-
Primitive,
|
|
6
7
|
KIND,
|
|
8
|
+
Primitive,
|
|
7
9
|
type Static,
|
|
8
10
|
type TSchema,
|
|
9
11
|
} from "alepha";
|
|
10
12
|
import type { ServerRequest } from "alepha/server";
|
|
11
13
|
import type { ServerRouteCache } from "alepha/server/cache";
|
|
12
14
|
import type { FC, ReactNode } from "react";
|
|
15
|
+
import { PAGE_PRELOAD_KEY } from "../constants/PAGE_PRELOAD_KEY.ts";
|
|
13
16
|
import type { Redirection } from "../errors/Redirection.ts";
|
|
14
17
|
import type { ReactRouterState } from "../providers/ReactPageProvider.ts";
|
|
15
18
|
import { ReactPageService } from "../services/ReactPageService.ts";
|
|
16
|
-
import type { ClientOnlyProps } from "@alepha/react";
|
|
17
|
-
import type { Head } from "@alepha/react/head";
|
|
18
|
-
import { PAGE_PRELOAD_KEY } from "../constants/PAGE_PRELOAD_KEY.ts";
|
|
19
|
-
|
|
20
19
|
|
|
21
20
|
/**
|
|
22
21
|
* Main primitive for defining a React route in the application.
|
|
@@ -113,10 +112,7 @@ export const $page = <
|
|
|
113
112
|
>(
|
|
114
113
|
options: PagePrimitiveOptions<TConfig, TProps, TPropsParent>,
|
|
115
114
|
): PagePrimitive<TConfig, TProps, TPropsParent> => {
|
|
116
|
-
return createPrimitive(
|
|
117
|
-
PagePrimitive<TConfig, TProps, TPropsParent>,
|
|
118
|
-
options,
|
|
119
|
-
);
|
|
115
|
+
return createPrimitive(PagePrimitive<TConfig, TProps, TPropsParent>, options);
|
|
120
116
|
};
|
|
121
117
|
|
|
122
118
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
@@ -1,15 +1,26 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BrowserHeadProvider } from "@alepha/react/head";
|
|
2
|
+
import {
|
|
3
|
+
$atom,
|
|
4
|
+
$hook,
|
|
5
|
+
$inject,
|
|
6
|
+
$use,
|
|
7
|
+
Alepha,
|
|
8
|
+
type State,
|
|
9
|
+
type Static,
|
|
10
|
+
t,
|
|
11
|
+
} from "alepha";
|
|
2
12
|
import { DateTimeProvider } from "alepha/datetime";
|
|
3
13
|
import { $logger } from "alepha/logger";
|
|
4
14
|
import { LinkProvider } from "alepha/server/links";
|
|
5
|
-
import { BrowserHeadProvider } from "@alepha/react/head";
|
|
6
|
-
import { ReactBrowserRouterProvider } from "./ReactBrowserRouterProvider.ts";
|
|
7
|
-
import type { PreviousLayerData, ReactRouterState, } from "./ReactPageProvider.ts";
|
|
8
15
|
import type { RouterGoOptions } from "../services/ReactRouter.ts";
|
|
16
|
+
import { ReactBrowserRouterProvider } from "./ReactBrowserRouterProvider.ts";
|
|
17
|
+
import type {
|
|
18
|
+
PreviousLayerData,
|
|
19
|
+
ReactRouterState,
|
|
20
|
+
} from "./ReactPageProvider.ts";
|
|
9
21
|
|
|
10
22
|
export type { RouterGoOptions } from "../services/ReactRouter.ts";
|
|
11
23
|
|
|
12
|
-
|
|
13
24
|
/**
|
|
14
25
|
* React browser renderer configuration atom
|
|
15
26
|
*/
|
|
@@ -247,7 +258,7 @@ export class ReactBrowserProvider {
|
|
|
247
258
|
// low budget, but works for now
|
|
248
259
|
for (const [key, value] of Object.entries(hydration)) {
|
|
249
260
|
if (key !== "layers") {
|
|
250
|
-
this.alepha.
|
|
261
|
+
this.alepha.set(key as keyof State, value);
|
|
251
262
|
}
|
|
252
263
|
}
|
|
253
264
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { BrowserHeadProvider } from "@alepha/react/head";
|
|
1
2
|
import { $hook, $inject, Alepha } from "alepha";
|
|
2
3
|
import { $logger } from "alepha/logger";
|
|
3
4
|
import { type Route, RouterProvider } from "alepha/router";
|
|
4
5
|
import { createElement, type ReactNode } from "react";
|
|
5
|
-
import { BrowserHeadProvider } from "@alepha/react/head";
|
|
6
6
|
import NotFoundPage from "../components/NotFound.tsx";
|
|
7
7
|
import {
|
|
8
8
|
isPageRoute,
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { AlephaContext, ClientOnly } from "@alepha/react";
|
|
2
|
+
import type { Head } from "@alepha/react/head";
|
|
1
3
|
import {
|
|
2
4
|
$env,
|
|
3
5
|
$hook,
|
|
@@ -10,7 +12,6 @@ import {
|
|
|
10
12
|
} from "alepha";
|
|
11
13
|
import { $logger } from "alepha/logger";
|
|
12
14
|
import { createElement, type ReactNode, StrictMode } from "react";
|
|
13
|
-
import { AlephaContext, ClientOnly } from "@alepha/react";
|
|
14
15
|
import ErrorViewer from "../components/ErrorViewer.tsx";
|
|
15
16
|
import NestedView from "../components/NestedView.tsx";
|
|
16
17
|
import NotFoundPage from "../components/NotFound.tsx";
|
|
@@ -22,7 +23,6 @@ import {
|
|
|
22
23
|
type PagePrimitive,
|
|
23
24
|
type PagePrimitiveOptions,
|
|
24
25
|
} from "../primitives/$page.ts";
|
|
25
|
-
import type { Head } from "@alepha/react/head";
|
|
26
26
|
|
|
27
27
|
const envSchema = t.object({
|
|
28
28
|
REACT_STRICT_MODE: t.boolean({ default: true }),
|
|
@@ -476,7 +476,8 @@ export class ReactPageProvider {
|
|
|
476
476
|
value: {
|
|
477
477
|
index,
|
|
478
478
|
path,
|
|
479
|
-
onError:
|
|
479
|
+
onError:
|
|
480
|
+
this.getErrorHandler(page) ?? ((error) => this.renderError(error)),
|
|
480
481
|
},
|
|
481
482
|
},
|
|
482
483
|
element,
|
|
@@ -1,15 +1,33 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
|
-
import {
|
|
2
|
+
import { ServerHeadProvider } from "@alepha/react/head";
|
|
3
|
+
import {
|
|
4
|
+
$atom,
|
|
5
|
+
$env,
|
|
6
|
+
$hook,
|
|
7
|
+
$inject,
|
|
8
|
+
$use,
|
|
9
|
+
Alepha,
|
|
10
|
+
AlephaError,
|
|
11
|
+
type Static,
|
|
12
|
+
t,
|
|
13
|
+
} from "alepha";
|
|
3
14
|
import { FileSystemProvider } from "alepha/file";
|
|
4
15
|
import { $logger } from "alepha/logger";
|
|
5
|
-
import { type ServerHandler, ServerRouterProvider
|
|
16
|
+
import { type ServerHandler, ServerRouterProvider } from "alepha/server";
|
|
6
17
|
import { ServerLinksProvider } from "alepha/server/links";
|
|
7
18
|
import { ServerStaticProvider } from "alepha/server/static";
|
|
8
19
|
import { renderToReadableStream } from "react-dom/server";
|
|
9
|
-
import { ServerHeadProvider } from "@alepha/react/head";
|
|
10
20
|
import { Redirection } from "../errors/Redirection.ts";
|
|
11
|
-
import {
|
|
12
|
-
|
|
21
|
+
import {
|
|
22
|
+
$page,
|
|
23
|
+
type PagePrimitiveRenderOptions,
|
|
24
|
+
type PagePrimitiveRenderResult,
|
|
25
|
+
} from "../primitives/$page.ts";
|
|
26
|
+
import {
|
|
27
|
+
type PageRoute,
|
|
28
|
+
ReactPageProvider,
|
|
29
|
+
type ReactRouterState,
|
|
30
|
+
} from "./ReactPageProvider.ts";
|
|
13
31
|
import { ReactServerTemplateProvider } from "./ReactServerTemplateProvider.ts";
|
|
14
32
|
import { SSRManifestProvider } from "./SSRManifestProvider.ts";
|
|
15
33
|
|
|
@@ -44,7 +62,6 @@ export class ReactServerProvider {
|
|
|
44
62
|
protected readonly serverHeadProvider = $inject(ServerHeadProvider);
|
|
45
63
|
protected readonly serverStaticProvider = $inject(ServerStaticProvider);
|
|
46
64
|
protected readonly serverRouterProvider = $inject(ServerRouterProvider);
|
|
47
|
-
protected readonly serverTimingProvider = $inject(ServerTimingProvider);
|
|
48
65
|
protected readonly ssrManifestProvider = $inject(SSRManifestProvider);
|
|
49
66
|
|
|
50
67
|
/**
|
|
@@ -67,17 +84,11 @@ export class ReactServerProvider {
|
|
|
67
84
|
|
|
68
85
|
this.alepha.store.set("alepha.react.server.ssr", ssrEnabled);
|
|
69
86
|
|
|
70
|
-
// development mode
|
|
71
|
-
if (this.alepha.isViteDev()) {
|
|
72
|
-
await this.configureVite(ssrEnabled);
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
87
|
// production mode
|
|
77
88
|
let root = "";
|
|
78
89
|
|
|
79
90
|
// non-serverless mode only -> serve static files
|
|
80
|
-
if (!this.alepha.isServerless()) {
|
|
91
|
+
if (!this.alepha.isServerless() && !this.alepha.isViteDev()) {
|
|
81
92
|
root = await this.getPublicDirectory();
|
|
82
93
|
if (!root) {
|
|
83
94
|
this.log.warn(
|
|
@@ -194,7 +205,7 @@ export class ReactServerProvider {
|
|
|
194
205
|
if (parts.length > 0) {
|
|
195
206
|
// Pass assets so they get stripped from original head content
|
|
196
207
|
this.templateProvider.setEarlyHeadContent(
|
|
197
|
-
parts.join("\n")
|
|
208
|
+
`${parts.join("\n")}\n`,
|
|
198
209
|
assets,
|
|
199
210
|
);
|
|
200
211
|
this.log.debug("Early head content set", {
|
|
@@ -236,26 +247,6 @@ export class ReactServerProvider {
|
|
|
236
247
|
});
|
|
237
248
|
}
|
|
238
249
|
|
|
239
|
-
/**
|
|
240
|
-
* Configure Vite for SSR in development mode.
|
|
241
|
-
*/
|
|
242
|
-
protected async configureVite(ssrEnabled: boolean) {
|
|
243
|
-
if (!ssrEnabled) {
|
|
244
|
-
// do nothing, vite will handle everything for us
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
const url = `http://localhost:${this.alepha.env.SERVER_PORT ?? "5173"}`;
|
|
249
|
-
|
|
250
|
-
this.log.info("SSR (dev) OK", { url });
|
|
251
|
-
|
|
252
|
-
await this.registerPages(() =>
|
|
253
|
-
fetch(`${url}/index.html`)
|
|
254
|
-
.then((it) => it.text())
|
|
255
|
-
.catch(() => undefined),
|
|
256
|
-
);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
250
|
/**
|
|
260
251
|
* Create the request handler for a page route.
|
|
261
252
|
*/
|
|
@@ -350,7 +341,8 @@ export class ReactServerProvider {
|
|
|
350
341
|
});
|
|
351
342
|
// Can't do redirect after streaming started - already handled above
|
|
352
343
|
} else {
|
|
353
|
-
|
|
344
|
+
// disable logging here, it's noisy and duplicate
|
|
345
|
+
// this.log.error("HTML stream error", error);
|
|
354
346
|
}
|
|
355
347
|
},
|
|
356
348
|
},
|
|
@@ -413,7 +405,8 @@ export class ReactServerProvider {
|
|
|
413
405
|
redirect: error.redirect,
|
|
414
406
|
});
|
|
415
407
|
} else {
|
|
416
|
-
|
|
408
|
+
// disable logging here, it's noisy and duplicate
|
|
409
|
+
// this.log.error("Streaming render error", error);
|
|
417
410
|
}
|
|
418
411
|
},
|
|
419
412
|
});
|
|
@@ -516,7 +509,6 @@ export class ReactServerProvider {
|
|
|
516
509
|
|
|
517
510
|
type TemplateLoader = () => Promise<string | undefined>;
|
|
518
511
|
|
|
519
|
-
|
|
520
512
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
521
513
|
|
|
522
514
|
const envSchema = t.object({
|