@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
package/dist/router/index.d.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { ClientOnlyProps } from "@alepha/react";
|
|
2
|
-
import * as
|
|
2
|
+
import * as alepha1 from "alepha";
|
|
3
3
|
import { Alepha, AlephaError, Async, KIND, Primitive, Static, TObject, TSchema } from "alepha";
|
|
4
4
|
import { DateTimeProvider } from "alepha/datetime";
|
|
5
5
|
import * as alepha_logger0 from "alepha/logger";
|
|
6
6
|
import { LinkProvider } from "alepha/server/links";
|
|
7
|
+
import { BrowserHeadProvider, Head, ServerHeadProvider, SimpleHead } from "@alepha/react/head";
|
|
7
8
|
import { Route, RouterProvider } from "alepha/router";
|
|
8
9
|
import * as react0 from "react";
|
|
9
10
|
import { AnchorHTMLAttributes, CSSProperties, FC, ReactNode } from "react";
|
|
10
11
|
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
11
|
-
import * as alepha_server0 from "alepha/server";
|
|
12
12
|
import { ServerHandler, ServerRequest, ServerRouterProvider, ServerTimingProvider } from "alepha/server";
|
|
13
|
+
import { FileSystemProvider } from "alepha/file";
|
|
13
14
|
import { ServerStaticProvider } from "alepha/server/static";
|
|
14
|
-
import * as alepha_server_cache0 from "alepha/server/cache";
|
|
15
15
|
import { ServerRouteCache } from "alepha/server/cache";
|
|
16
16
|
|
|
17
17
|
//#region ../../src/router/errors/Redirection.d.ts
|
|
@@ -26,7 +26,7 @@ import { ServerRouteCache } from "alepha/server/cache";
|
|
|
26
26
|
* import { Redirection } from "@alepha/react";
|
|
27
27
|
*
|
|
28
28
|
* const MyPage = $page({
|
|
29
|
-
*
|
|
29
|
+
* loader: async () => {
|
|
30
30
|
* if (needRedirect) {
|
|
31
31
|
* throw new Redirection("/new-path");
|
|
32
32
|
* }
|
|
@@ -40,11 +40,11 @@ declare class Redirection extends AlephaError {
|
|
|
40
40
|
}
|
|
41
41
|
//#endregion
|
|
42
42
|
//#region ../../src/router/providers/ReactPageProvider.d.ts
|
|
43
|
-
declare const envSchema$
|
|
44
|
-
REACT_STRICT_MODE:
|
|
43
|
+
declare const envSchema$1: alepha1.TObject<{
|
|
44
|
+
REACT_STRICT_MODE: alepha1.TBoolean;
|
|
45
45
|
}>;
|
|
46
46
|
declare module "alepha" {
|
|
47
|
-
interface Env extends Partial<Static<typeof envSchema$
|
|
47
|
+
interface Env extends Partial<Static<typeof envSchema$1>> {}
|
|
48
48
|
}
|
|
49
49
|
/**
|
|
50
50
|
* Handle page routes for React applications. (Browser and Server)
|
|
@@ -86,7 +86,7 @@ declare class ReactPageProvider {
|
|
|
86
86
|
}, params?: Record<string, any>): string;
|
|
87
87
|
compile(path: string, params?: Record<string, string>): string;
|
|
88
88
|
protected renderView(index: number, path: string, view: ReactNode | undefined, page: PageRoute): ReactNode;
|
|
89
|
-
protected readonly configure:
|
|
89
|
+
protected readonly configure: alepha1.HookPrimitive<"configure">;
|
|
90
90
|
protected map(pages: Array<PagePrimitive>, target: PagePrimitive): PageRouteEntry;
|
|
91
91
|
add(entry: PageRouteEntry): void;
|
|
92
92
|
protected createMatch(page: PageRoute): string;
|
|
@@ -157,6 +157,11 @@ interface ReactRouterState {
|
|
|
157
157
|
* Optional meta information associated with the current page.
|
|
158
158
|
*/
|
|
159
159
|
meta: Record<string, any>;
|
|
160
|
+
/**
|
|
161
|
+
* Head configuration for the current page (title, meta tags, etc.).
|
|
162
|
+
* Populated by HeadProvider during SSR.
|
|
163
|
+
*/
|
|
164
|
+
head: Head;
|
|
160
165
|
name?: string;
|
|
161
166
|
}
|
|
162
167
|
interface RouterStackItem {
|
|
@@ -186,6 +191,14 @@ declare abstract class ReactPageService {
|
|
|
186
191
|
render(name: string, options?: PagePrimitiveRenderOptions): Promise<PagePrimitiveRenderResult>;
|
|
187
192
|
}
|
|
188
193
|
//#endregion
|
|
194
|
+
//#region ../../src/router/constants/PAGE_PRELOAD_KEY.d.ts
|
|
195
|
+
/**
|
|
196
|
+
* Symbol key for SSR module preloading path.
|
|
197
|
+
* Using Symbol.for() allows the Vite plugin to inject this at build time.
|
|
198
|
+
* @internal
|
|
199
|
+
*/
|
|
200
|
+
declare const PAGE_PRELOAD_KEY: unique symbol;
|
|
201
|
+
//#endregion
|
|
189
202
|
//#region ../../src/router/primitives/$page.d.ts
|
|
190
203
|
/**
|
|
191
204
|
* Main primitive for defining a React route in the application.
|
|
@@ -199,7 +212,7 @@ declare abstract class ReactPageService {
|
|
|
199
212
|
* - Type-safe URL parameter and query string validation
|
|
200
213
|
*
|
|
201
214
|
* **Data Loading**
|
|
202
|
-
* - Server-side data fetching with the `
|
|
215
|
+
* - Server-side data fetching with the `loader` function
|
|
203
216
|
* - Automatic serialization and hydration for SSR
|
|
204
217
|
* - Access to request context, URL params, and parent data
|
|
205
218
|
*
|
|
@@ -236,7 +249,7 @@ declare abstract class ReactPageService {
|
|
|
236
249
|
* params: t.object({ id: t.integer() }),
|
|
237
250
|
* query: t.object({ tab: t.optional(t.text()) })
|
|
238
251
|
* },
|
|
239
|
-
*
|
|
252
|
+
* loader: async ({ params }) => {
|
|
240
253
|
* const user = await userApi.getUser(params.id);
|
|
241
254
|
* return { user };
|
|
242
255
|
* },
|
|
@@ -249,7 +262,7 @@ declare abstract class ReactPageService {
|
|
|
249
262
|
* const projectSection = $page({
|
|
250
263
|
* path: "/projects/:id",
|
|
251
264
|
* children: () => [projectBoard, projectSettings],
|
|
252
|
-
*
|
|
265
|
+
* loader: async ({ params }) => {
|
|
253
266
|
* const project = await projectApi.get(params.id);
|
|
254
267
|
* return { project };
|
|
255
268
|
* },
|
|
@@ -268,7 +281,7 @@ declare abstract class ReactPageService {
|
|
|
268
281
|
* static: {
|
|
269
282
|
* entries: posts.map(p => ({ params: { slug: p.slug } }))
|
|
270
283
|
* },
|
|
271
|
-
*
|
|
284
|
+
* loader: async ({ params }) => {
|
|
272
285
|
* const post = await loadPost(params.slug);
|
|
273
286
|
* return { post };
|
|
274
287
|
* }
|
|
@@ -309,12 +322,12 @@ interface PagePrimitiveOptions<TConfig extends PageConfigSchema = PageConfigSche
|
|
|
309
322
|
*
|
|
310
323
|
* > In SSR, the returned data will be serialized and sent to the client, then reused during the client-side hydration.
|
|
311
324
|
*
|
|
312
|
-
*
|
|
325
|
+
* Loader can be stopped by throwing an error, which will be handled by the `errorHandler` function.
|
|
313
326
|
* It's common to throw a `NotFoundError` to display a 404 page.
|
|
314
327
|
*
|
|
315
328
|
* RedirectError can be thrown to redirect the user to another page.
|
|
316
329
|
*/
|
|
317
|
-
|
|
330
|
+
loader?: (context: PageLoader<TConfig, TPropsParent>) => Async<TProps>;
|
|
318
331
|
/**
|
|
319
332
|
* Default props to pass to the component when rendering the page.
|
|
320
333
|
*
|
|
@@ -354,7 +367,7 @@ interface PagePrimitiveOptions<TConfig extends PageConfigSchema = PageConfigSche
|
|
|
354
367
|
*/
|
|
355
368
|
can?: () => boolean;
|
|
356
369
|
/**
|
|
357
|
-
* Catch any error from the `
|
|
370
|
+
* Catch any error from the `loader` function or during `rendering`.
|
|
358
371
|
*
|
|
359
372
|
* Expected to return one of the following:
|
|
360
373
|
* - a ReactNode to render an error page
|
|
@@ -366,7 +379,7 @@ interface PagePrimitiveOptions<TConfig extends PageConfigSchema = PageConfigSche
|
|
|
366
379
|
*
|
|
367
380
|
* @example Catch a 404 from API and render a custom not found component:
|
|
368
381
|
* ```ts
|
|
369
|
-
*
|
|
382
|
+
* loader: async ({ params, query }) => {
|
|
370
383
|
* api.fetch("/api/resource", { params, query });
|
|
371
384
|
* },
|
|
372
385
|
* errorHandler: (error, context) => {
|
|
@@ -378,7 +391,7 @@ interface PagePrimitiveOptions<TConfig extends PageConfigSchema = PageConfigSche
|
|
|
378
391
|
*
|
|
379
392
|
* @example Catch an 401 error and redirect the user to the login page:
|
|
380
393
|
* ```ts
|
|
381
|
-
*
|
|
394
|
+
* loader: async ({ params, query }) => {
|
|
382
395
|
* // but the user is not authenticated
|
|
383
396
|
* api.fetch("/api/resource", { params, query });
|
|
384
397
|
* },
|
|
@@ -459,6 +472,37 @@ interface PagePrimitiveOptions<TConfig extends PageConfigSchema = PageConfigSche
|
|
|
459
472
|
* ```
|
|
460
473
|
*/
|
|
461
474
|
animation?: PageAnimation;
|
|
475
|
+
/**
|
|
476
|
+
* Head configuration for the page (title, meta tags, etc.).
|
|
477
|
+
*
|
|
478
|
+
* Can be a static object or a function that receives resolved props.
|
|
479
|
+
*
|
|
480
|
+
* @example Static head
|
|
481
|
+
* ```ts
|
|
482
|
+
* head: {
|
|
483
|
+
* title: "My Page",
|
|
484
|
+
* description: "Page description",
|
|
485
|
+
* }
|
|
486
|
+
* ```
|
|
487
|
+
*
|
|
488
|
+
* @example Dynamic head based on props
|
|
489
|
+
* ```ts
|
|
490
|
+
* head: (props) => ({
|
|
491
|
+
* title: props.user.name,
|
|
492
|
+
* description: `Profile of ${props.user.name}`,
|
|
493
|
+
* })
|
|
494
|
+
* ```
|
|
495
|
+
*/
|
|
496
|
+
head?: Head | ((props: TProps, previous?: Head) => Head);
|
|
497
|
+
/**
|
|
498
|
+
* Source path for SSR module preloading.
|
|
499
|
+
*
|
|
500
|
+
* This is automatically injected by the viteAlephaPreload plugin.
|
|
501
|
+
* It maps to the source file path used in Vite's SSR manifest.
|
|
502
|
+
*
|
|
503
|
+
* @internal
|
|
504
|
+
*/
|
|
505
|
+
[PAGE_PRELOAD_KEY]?: string;
|
|
462
506
|
}
|
|
463
507
|
type ErrorHandler = (error: Error, state: ReactRouterState) => ReactNode | Redirection | undefined;
|
|
464
508
|
declare class PagePrimitive<TConfig extends PageConfigSchema = PageConfigSchema, TProps extends object = TPropsDefault, TPropsParent extends object = TPropsParentDefault> extends Primitive<PagePrimitiveOptions<TConfig, TProps, TPropsParent>> {
|
|
@@ -506,7 +550,7 @@ interface PageRequestConfig<TConfig extends PageConfigSchema = PageConfigSchema>
|
|
|
506
550
|
params: TConfig["params"] extends TSchema ? Static<TConfig["params"]> : Record<string, string>;
|
|
507
551
|
query: TConfig["query"] extends TSchema ? Static<TConfig["query"]> : Record<string, string>;
|
|
508
552
|
}
|
|
509
|
-
type
|
|
553
|
+
type PageLoader<TConfig extends PageConfigSchema = PageConfigSchema, TPropsParent extends object = TPropsParentDefault> = PageRequestConfig<TConfig> & TPropsParent & Omit<ReactRouterState, "layers" | "onError">;
|
|
510
554
|
type PageAnimation = PageAnimationObject | ((state: ReactRouterState) => PageAnimationObject | undefined);
|
|
511
555
|
type PageAnimationObject = CssAnimationName | {
|
|
512
556
|
enter?: CssAnimation | CssAnimationName;
|
|
@@ -530,67 +574,13 @@ declare class ReactBrowserRouterProvider extends RouterProvider<BrowserRoute> {
|
|
|
530
574
|
protected readonly log: alepha_logger0.Logger;
|
|
531
575
|
protected readonly alepha: Alepha;
|
|
532
576
|
protected readonly pageApi: ReactPageProvider;
|
|
577
|
+
protected readonly browserHeadProvider: BrowserHeadProvider;
|
|
533
578
|
add(entry: PageRouteEntry): void;
|
|
534
|
-
protected readonly configure:
|
|
579
|
+
protected readonly configure: alepha1.HookPrimitive<"configure">;
|
|
535
580
|
transition(url: URL, previous?: PreviousLayerData[], meta?: {}): Promise<string | void>;
|
|
536
581
|
root(state: ReactRouterState): ReactNode;
|
|
537
582
|
}
|
|
538
583
|
//#endregion
|
|
539
|
-
//#region ../../src/core/components/ClientOnly.d.ts
|
|
540
|
-
interface ClientOnlyProps$1 {
|
|
541
|
-
fallback?: ReactNode;
|
|
542
|
-
disabled?: boolean;
|
|
543
|
-
}
|
|
544
|
-
//#endregion
|
|
545
|
-
//#region ../../src/core/index.d.ts
|
|
546
|
-
declare module "alepha" {
|
|
547
|
-
interface Hooks {
|
|
548
|
-
/**
|
|
549
|
-
* Fires when a user action is starting.
|
|
550
|
-
* Action can be a form submission, a route transition, or a custom action.
|
|
551
|
-
*/
|
|
552
|
-
"react:action:begin": {
|
|
553
|
-
type: string;
|
|
554
|
-
id?: string;
|
|
555
|
-
};
|
|
556
|
-
/**
|
|
557
|
-
* Fires when a user action has succeeded.
|
|
558
|
-
* Action can be a form submission, a route transition, or a custom action.
|
|
559
|
-
*/
|
|
560
|
-
"react:action:success": {
|
|
561
|
-
type: string;
|
|
562
|
-
id?: string;
|
|
563
|
-
};
|
|
564
|
-
/**
|
|
565
|
-
* Fires when a user action has failed.
|
|
566
|
-
* Action can be a form submission, a route transition, or a custom action.
|
|
567
|
-
*/
|
|
568
|
-
"react:action:error": {
|
|
569
|
-
type: string;
|
|
570
|
-
id?: string;
|
|
571
|
-
error: Error;
|
|
572
|
-
};
|
|
573
|
-
/**
|
|
574
|
-
* Fires when a user action has completed, regardless of success or failure.
|
|
575
|
-
* Action can be a form submission, a route transition, or a custom action.
|
|
576
|
-
*/
|
|
577
|
-
"react:action:end": {
|
|
578
|
-
type: string;
|
|
579
|
-
id?: string;
|
|
580
|
-
};
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
/**
|
|
584
|
-
* Provides full-stack React development with declarative routing, server-side rendering, and client-side hydration.
|
|
585
|
-
*
|
|
586
|
-
* The React module enables building modern React applications using the `$page` primitive on class properties.
|
|
587
|
-
* It delivers seamless server-side rendering, automatic code splitting, and client-side navigation with full
|
|
588
|
-
* type safety and schema validation for route parameters and data.
|
|
589
|
-
*
|
|
590
|
-
* @see {@link $page}
|
|
591
|
-
* @module alepha.react
|
|
592
|
-
*/
|
|
593
|
-
//#endregion
|
|
594
584
|
//#region ../../src/router/services/ReactRouter.d.ts
|
|
595
585
|
interface RouterGoOptions {
|
|
596
586
|
replace?: boolean;
|
|
@@ -607,7 +597,7 @@ interface RouterGoOptions {
|
|
|
607
597
|
*
|
|
608
598
|
* Can be safely used server-side, but most methods will be no-op.
|
|
609
599
|
*/
|
|
610
|
-
declare class ReactRouter<T
|
|
600
|
+
declare class ReactRouter<T extends object> {
|
|
611
601
|
protected readonly alepha: Alepha;
|
|
612
602
|
protected readonly pageApi: ReactPageProvider;
|
|
613
603
|
get state(): ReactRouterState;
|
|
@@ -617,62 +607,11 @@ declare class ReactRouter<T$1 extends object> {
|
|
|
617
607
|
isActive(href: string, options?: {
|
|
618
608
|
startWith?: boolean;
|
|
619
609
|
}): boolean;
|
|
620
|
-
node(name: keyof VirtualRouter<T
|
|
610
|
+
node(name: keyof VirtualRouter<T> | string, config?: {
|
|
621
611
|
params?: Record<string, any>;
|
|
622
612
|
query?: Record<string, any>;
|
|
623
|
-
}):
|
|
624
|
-
|
|
625
|
-
children: undefined;
|
|
626
|
-
type: "page";
|
|
627
|
-
name: string;
|
|
628
|
-
parent?: PageRoute;
|
|
629
|
-
match: string;
|
|
630
|
-
path?: string | undefined;
|
|
631
|
-
schema?: PageConfigSchema | undefined;
|
|
632
|
-
resolve?: ((context: PageResolve<PageConfigSchema, TPropsParentDefault>) => any) | undefined;
|
|
633
|
-
props?: (() => Partial<any>) | undefined;
|
|
634
|
-
component?: react0.FC<any> | undefined;
|
|
635
|
-
lazy?: (() => Promise<{
|
|
636
|
-
default: react0.FC<any>;
|
|
637
|
-
}>) | undefined;
|
|
638
|
-
can?: (() => boolean) | undefined;
|
|
639
|
-
errorHandler?: ErrorHandler | undefined;
|
|
640
|
-
static?: boolean | {
|
|
641
|
-
entries?: Partial<PageRequestConfig<PageConfigSchema>>[] | undefined;
|
|
642
|
-
} | undefined;
|
|
643
|
-
cache?: alepha_server_cache0.ServerRouteCache | undefined;
|
|
644
|
-
client?: (boolean | ClientOnlyProps$1) | undefined;
|
|
645
|
-
onServerResponse?: ((request: alepha_server0.ServerRequest) => unknown) | undefined;
|
|
646
|
-
onLeave?: (() => void) | undefined;
|
|
647
|
-
animation?: PageAnimation | undefined;
|
|
648
|
-
} | {
|
|
649
|
-
label: any;
|
|
650
|
-
href: string;
|
|
651
|
-
children: undefined;
|
|
652
|
-
type: "page";
|
|
653
|
-
name: string;
|
|
654
|
-
parent?: PageRoute;
|
|
655
|
-
match: string;
|
|
656
|
-
path?: string | undefined;
|
|
657
|
-
schema?: PageConfigSchema | undefined;
|
|
658
|
-
resolve?: ((context: PageResolve<PageConfigSchema, TPropsParentDefault>) => any) | undefined;
|
|
659
|
-
props?: (() => Partial<any>) | undefined;
|
|
660
|
-
component?: react0.FC<any> | undefined;
|
|
661
|
-
lazy?: (() => Promise<{
|
|
662
|
-
default: react0.FC<any>;
|
|
663
|
-
}>) | undefined;
|
|
664
|
-
can?: (() => boolean) | undefined;
|
|
665
|
-
errorHandler?: ErrorHandler | undefined;
|
|
666
|
-
static?: boolean | {
|
|
667
|
-
entries?: Partial<PageRequestConfig<PageConfigSchema>>[] | undefined;
|
|
668
|
-
} | undefined;
|
|
669
|
-
cache?: alepha_server_cache0.ServerRouteCache | undefined;
|
|
670
|
-
client?: (boolean | ClientOnlyProps$1) | undefined;
|
|
671
|
-
onServerResponse?: ((request: alepha_server0.ServerRequest) => unknown) | undefined;
|
|
672
|
-
onLeave?: (() => void) | undefined;
|
|
673
|
-
animation?: PageAnimation | undefined;
|
|
674
|
-
};
|
|
675
|
-
path(name: keyof VirtualRouter<T$1> | string, config?: {
|
|
613
|
+
}): any;
|
|
614
|
+
path(name: keyof VirtualRouter<T> | string, config?: {
|
|
676
615
|
params?: Record<string, any>;
|
|
677
616
|
query?: Record<string, any>;
|
|
678
617
|
}): string;
|
|
@@ -690,9 +629,9 @@ declare class ReactRouter<T$1 extends object> {
|
|
|
690
629
|
forward(): Promise<void>;
|
|
691
630
|
invalidate(props?: Record<string, any>): Promise<void>;
|
|
692
631
|
go(path: string, options?: RouterGoOptions): Promise<void>;
|
|
693
|
-
go(path: keyof VirtualRouter<T
|
|
632
|
+
go(path: keyof VirtualRouter<T>, options?: RouterGoOptions): Promise<void>;
|
|
694
633
|
anchor(path: string, options?: RouterGoOptions): AnchorProps;
|
|
695
|
-
anchor(path: keyof VirtualRouter<T
|
|
634
|
+
anchor(path: keyof VirtualRouter<T>, options?: RouterGoOptions): AnchorProps;
|
|
696
635
|
base(path: string): string;
|
|
697
636
|
/**
|
|
698
637
|
* Set query params.
|
|
@@ -707,20 +646,14 @@ declare class ReactRouter<T$1 extends object> {
|
|
|
707
646
|
push?: boolean;
|
|
708
647
|
}): void;
|
|
709
648
|
}
|
|
710
|
-
type VirtualRouter<T
|
|
649
|
+
type VirtualRouter<T> = { [K in keyof T as T[K] extends PagePrimitive ? K : never]: T[K] };
|
|
711
650
|
//#endregion
|
|
712
651
|
//#region ../../src/router/providers/ReactBrowserProvider.d.ts
|
|
713
|
-
declare const envSchema$1: alepha12.TObject<{
|
|
714
|
-
REACT_ROOT_ID: alepha12.TString;
|
|
715
|
-
}>;
|
|
716
|
-
declare module "alepha" {
|
|
717
|
-
interface Env extends Partial<Static<typeof envSchema$1>> {}
|
|
718
|
-
}
|
|
719
652
|
/**
|
|
720
653
|
* React browser renderer configuration atom
|
|
721
654
|
*/
|
|
722
|
-
declare const reactBrowserOptions:
|
|
723
|
-
scrollRestoration:
|
|
655
|
+
declare const reactBrowserOptions: alepha1.Atom<alepha1.TObject<{
|
|
656
|
+
scrollRestoration: alepha1.TUnsafe<"top" | "manual">;
|
|
724
657
|
}>, "alepha.react.browser.options">;
|
|
725
658
|
type ReactBrowserRendererOptions = Static<typeof reactBrowserOptions.schema>;
|
|
726
659
|
declare module "alepha" {
|
|
@@ -729,17 +662,16 @@ declare module "alepha" {
|
|
|
729
662
|
}
|
|
730
663
|
}
|
|
731
664
|
declare class ReactBrowserProvider {
|
|
732
|
-
protected readonly env: {
|
|
733
|
-
REACT_ROOT_ID: string;
|
|
734
|
-
};
|
|
735
665
|
protected readonly log: alepha_logger0.Logger;
|
|
736
666
|
protected readonly client: LinkProvider;
|
|
737
667
|
protected readonly alepha: Alepha;
|
|
738
668
|
protected readonly router: ReactBrowserRouterProvider;
|
|
739
669
|
protected readonly dateTimeProvider: DateTimeProvider;
|
|
670
|
+
protected readonly browserHeadProvider: BrowserHeadProvider;
|
|
740
671
|
protected readonly options: Readonly<{
|
|
741
672
|
scrollRestoration: "top" | "manual";
|
|
742
673
|
}>;
|
|
674
|
+
get rootId(): string;
|
|
743
675
|
protected getRootElement(): HTMLElement;
|
|
744
676
|
transitioning?: {
|
|
745
677
|
to: string;
|
|
@@ -768,8 +700,8 @@ declare class ReactBrowserProvider {
|
|
|
768
700
|
* Get embedded layers from the server.
|
|
769
701
|
*/
|
|
770
702
|
protected getHydrationState(): ReactHydrationState | undefined;
|
|
771
|
-
protected readonly onTransitionEnd:
|
|
772
|
-
readonly ready:
|
|
703
|
+
protected readonly onTransitionEnd: alepha1.HookPrimitive<"react:transition:end">;
|
|
704
|
+
readonly ready: alepha1.HookPrimitive<"ready">;
|
|
773
705
|
}
|
|
774
706
|
type ReactHydrationState = {
|
|
775
707
|
layers?: Array<PreviousLayerData>;
|
|
@@ -1138,7 +1070,7 @@ interface UseActiveHook {
|
|
|
1138
1070
|
/**
|
|
1139
1071
|
* Hook to manage query parameters in the URL using a defined schema.
|
|
1140
1072
|
*/
|
|
1141
|
-
declare const useQueryParams: <T
|
|
1073
|
+
declare const useQueryParams: <T extends TObject>(schema: T, options?: UseQueryParamsHookOptions) => [Partial<Static<T>>, (data: Static<T>) => void];
|
|
1142
1074
|
interface UseQueryParamsHookOptions {
|
|
1143
1075
|
format?: "base64" | "querystring";
|
|
1144
1076
|
key?: string;
|
|
@@ -1160,57 +1092,483 @@ interface UseQueryParamsHookOptions {
|
|
|
1160
1092
|
* const router = useRouter<App>();
|
|
1161
1093
|
* router.go("home"); // typesafe
|
|
1162
1094
|
*/
|
|
1163
|
-
declare const useRouter: <T
|
|
1095
|
+
declare const useRouter: <T extends object = any>() => ReactRouter<T>;
|
|
1164
1096
|
//#endregion
|
|
1165
1097
|
//#region ../../src/router/hooks/useRouterState.d.ts
|
|
1166
1098
|
declare const useRouterState: () => ReactRouterState;
|
|
1167
1099
|
//#endregion
|
|
1168
|
-
//#region ../../src/router/providers/
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1100
|
+
//#region ../../src/router/providers/ReactServerTemplateProvider.d.ts
|
|
1101
|
+
/**
|
|
1102
|
+
* Handles HTML template parsing, preprocessing, and streaming for SSR.
|
|
1103
|
+
*
|
|
1104
|
+
* Responsibilities:
|
|
1105
|
+
* - Parse template once at startup into logical slots
|
|
1106
|
+
* - Pre-encode static parts as Uint8Array for zero-copy streaming
|
|
1107
|
+
* - Render dynamic parts (attributes, head content) efficiently
|
|
1108
|
+
* - Build hydration data for client-side rehydration
|
|
1109
|
+
*
|
|
1110
|
+
* This provider is injected into ReactServerProvider to handle all
|
|
1111
|
+
* template-related operations, keeping ReactServerProvider focused
|
|
1112
|
+
* on request handling and React rendering coordination.
|
|
1113
|
+
*/
|
|
1114
|
+
declare class ReactServerTemplateProvider {
|
|
1115
|
+
protected readonly log: alepha_logger0.Logger;
|
|
1116
|
+
protected readonly alepha: Alepha;
|
|
1117
|
+
/**
|
|
1118
|
+
* Shared TextEncoder instance - reused across all requests.
|
|
1119
|
+
*/
|
|
1120
|
+
protected readonly encoder: TextEncoder;
|
|
1121
|
+
/**
|
|
1122
|
+
* Pre-encoded common strings for streaming.
|
|
1123
|
+
*/
|
|
1124
|
+
protected readonly ENCODED: {
|
|
1125
|
+
readonly HYDRATION_PREFIX: Uint8Array<ArrayBuffer>;
|
|
1126
|
+
readonly HYDRATION_SUFFIX: Uint8Array<ArrayBuffer>;
|
|
1127
|
+
readonly EMPTY: Uint8Array<ArrayBuffer>;
|
|
1128
|
+
};
|
|
1129
|
+
/**
|
|
1130
|
+
* Cached template slots - parsed once, reused for all requests.
|
|
1131
|
+
*/
|
|
1132
|
+
protected slots: TemplateSlots | null;
|
|
1133
|
+
/**
|
|
1134
|
+
* Root element ID for React mounting.
|
|
1135
|
+
*/
|
|
1136
|
+
get rootId(): string;
|
|
1137
|
+
/**
|
|
1138
|
+
* Regex pattern for matching the root div and extracting its content.
|
|
1139
|
+
*/
|
|
1140
|
+
get rootDivRegex(): RegExp;
|
|
1141
|
+
/**
|
|
1142
|
+
* Extract the content inside the root div from HTML.
|
|
1143
|
+
*
|
|
1144
|
+
* @param html - Full HTML string
|
|
1145
|
+
* @returns The content inside the root div, or undefined if not found
|
|
1146
|
+
*/
|
|
1147
|
+
extractRootContent(html: string): string | undefined;
|
|
1148
|
+
/**
|
|
1149
|
+
* Check if template has been parsed and slots are available.
|
|
1150
|
+
*/
|
|
1151
|
+
isReady(): boolean;
|
|
1152
|
+
/**
|
|
1153
|
+
* Get the parsed template slots.
|
|
1154
|
+
* Throws if template hasn't been parsed yet.
|
|
1155
|
+
*/
|
|
1156
|
+
getSlots(): TemplateSlots;
|
|
1157
|
+
/**
|
|
1158
|
+
* Parse an HTML template into logical slots for efficient streaming.
|
|
1159
|
+
*
|
|
1160
|
+
* This should be called once during server startup/configuration.
|
|
1161
|
+
* The parsed slots are cached and reused for all requests.
|
|
1162
|
+
*
|
|
1163
|
+
* @param template - The HTML template string (typically index.html)
|
|
1164
|
+
*/
|
|
1165
|
+
parseTemplate(template: string): TemplateSlots;
|
|
1166
|
+
/**
|
|
1167
|
+
* Parse HTML attributes string into a record.
|
|
1168
|
+
*
|
|
1169
|
+
* Handles: key="value", key='value', key=value, and boolean key
|
|
1170
|
+
*/
|
|
1171
|
+
protected parseAttributes(attrStr: string): Record<string, string>;
|
|
1172
|
+
/**
|
|
1173
|
+
* Render attributes record to HTML string.
|
|
1174
|
+
*
|
|
1175
|
+
* @param attrs - Attributes to render
|
|
1176
|
+
* @returns HTML attribute string like ` lang="en" class="dark"`
|
|
1177
|
+
*/
|
|
1178
|
+
renderAttributes(attrs: Record<string, string>): string;
|
|
1179
|
+
/**
|
|
1180
|
+
* Render merged HTML attributes (original + dynamic).
|
|
1181
|
+
*/
|
|
1182
|
+
renderMergedHtmlAttrs(dynamicAttrs?: Record<string, string>): string;
|
|
1183
|
+
/**
|
|
1184
|
+
* Render merged body attributes (original + dynamic).
|
|
1185
|
+
*/
|
|
1186
|
+
renderMergedBodyAttrs(dynamicAttrs?: Record<string, string>): string;
|
|
1187
|
+
/**
|
|
1188
|
+
* Render head content (title, meta, link, script tags).
|
|
1189
|
+
*
|
|
1190
|
+
* @param head - Head data to render
|
|
1191
|
+
* @param includeOriginal - Whether to include original head content
|
|
1192
|
+
* @returns HTML string with head content
|
|
1193
|
+
*/
|
|
1194
|
+
renderHeadContent(head?: SimpleHead, includeOriginal?: boolean): string;
|
|
1195
|
+
/**
|
|
1196
|
+
* Render a meta tag.
|
|
1197
|
+
*/
|
|
1198
|
+
protected renderMetaTag(meta: {
|
|
1199
|
+
name?: string;
|
|
1200
|
+
property?: string;
|
|
1201
|
+
content: string;
|
|
1202
|
+
}): string;
|
|
1203
|
+
/**
|
|
1204
|
+
* Render a link tag.
|
|
1205
|
+
*/
|
|
1206
|
+
protected renderLinkTag(link: {
|
|
1207
|
+
rel: string;
|
|
1208
|
+
href: string;
|
|
1209
|
+
as?: string;
|
|
1210
|
+
crossorigin?: string;
|
|
1211
|
+
}): string;
|
|
1212
|
+
/**
|
|
1213
|
+
* Render a script tag.
|
|
1214
|
+
*/
|
|
1215
|
+
protected renderScriptTag(script: Record<string, string | boolean>): string;
|
|
1216
|
+
/**
|
|
1217
|
+
* Escape HTML special characters.
|
|
1218
|
+
*/
|
|
1219
|
+
escapeHtml(str: string): string;
|
|
1220
|
+
/**
|
|
1221
|
+
* Safely serialize data to JSON for embedding in HTML.
|
|
1222
|
+
* Escapes characters that could break out of script tags.
|
|
1223
|
+
*/
|
|
1224
|
+
safeJsonSerialize(data: unknown): string;
|
|
1225
|
+
/**
|
|
1226
|
+
* Build hydration data from router state.
|
|
1227
|
+
*
|
|
1228
|
+
* This creates the data structure that will be serialized to window.__ssr
|
|
1229
|
+
* for client-side rehydration.
|
|
1230
|
+
*/
|
|
1231
|
+
buildHydrationData(state: ReactRouterState): HydrationData;
|
|
1232
|
+
/**
|
|
1233
|
+
* Encode a string to Uint8Array using the shared encoder.
|
|
1234
|
+
*/
|
|
1235
|
+
encode(str: string): Uint8Array;
|
|
1236
|
+
/**
|
|
1237
|
+
* Get the pre-encoded hydration script prefix.
|
|
1238
|
+
*/
|
|
1239
|
+
get hydrationPrefix(): Uint8Array;
|
|
1240
|
+
/**
|
|
1241
|
+
* Get the pre-encoded hydration script suffix.
|
|
1242
|
+
*/
|
|
1243
|
+
get hydrationSuffix(): Uint8Array;
|
|
1244
|
+
/**
|
|
1245
|
+
* Create a ReadableStream that streams the HTML template with React content.
|
|
1246
|
+
*
|
|
1247
|
+
* This is the main entry point for SSR streaming. It:
|
|
1248
|
+
* 1. Sends <head> immediately (browser starts downloading assets)
|
|
1249
|
+
* 2. Streams React content as it renders
|
|
1250
|
+
* 3. Appends hydration script and closing tags
|
|
1251
|
+
*
|
|
1252
|
+
* @param reactStream - ReadableStream from renderToReadableStream
|
|
1253
|
+
* @param state - Router state with head data
|
|
1254
|
+
* @param options - Streaming options
|
|
1255
|
+
*/
|
|
1256
|
+
createHtmlStream(reactStream: ReadableStream<Uint8Array>, state: ReactRouterState, options?: {
|
|
1257
|
+
hydration?: boolean;
|
|
1258
|
+
onError?: (error: unknown) => void;
|
|
1259
|
+
}): ReadableStream<Uint8Array>;
|
|
1260
|
+
/**
|
|
1261
|
+
* Early head content for preloading.
|
|
1262
|
+
*
|
|
1263
|
+
* Contains entry assets (JS + CSS) that are always required and can be
|
|
1264
|
+
* sent before page loaders run.
|
|
1265
|
+
*/
|
|
1266
|
+
protected earlyHeadContent: string;
|
|
1267
|
+
/**
|
|
1268
|
+
* Set the early head content (entry script + CSS).
|
|
1269
|
+
*
|
|
1270
|
+
* Also strips these assets from the original head content to avoid duplicates,
|
|
1271
|
+
* since we're moving them to the early phase.
|
|
1272
|
+
*
|
|
1273
|
+
* @param content - HTML string with entry assets
|
|
1274
|
+
* @param entryAssets - Entry asset paths to strip from original head
|
|
1275
|
+
*/
|
|
1276
|
+
setEarlyHeadContent(content: string, entryAssets?: {
|
|
1277
|
+
js?: string;
|
|
1278
|
+
css: string[];
|
|
1279
|
+
}): void;
|
|
1280
|
+
/**
|
|
1281
|
+
* Escape special regex characters in a string.
|
|
1282
|
+
*/
|
|
1283
|
+
protected escapeRegExp(str: string): string;
|
|
1284
|
+
/**
|
|
1285
|
+
* Create an optimized HTML stream with early head streaming.
|
|
1286
|
+
*
|
|
1287
|
+
* This version sends critical assets (entry.js, CSS) BEFORE page loaders run,
|
|
1288
|
+
* allowing the browser to start downloading them immediately.
|
|
1289
|
+
*
|
|
1290
|
+
* Flow:
|
|
1291
|
+
* 1. Send DOCTYPE, <html>, <head> open, entry preloads (IMMEDIATE)
|
|
1292
|
+
* 2. Run async work (createLayers, etc.)
|
|
1293
|
+
* 3. Send rest of head, body, React content, hydration
|
|
1294
|
+
*
|
|
1295
|
+
* @param globalHead - Global head with htmlAttributes (from $head primitives)
|
|
1296
|
+
* @param asyncWork - Async function to run between early head and rest of stream
|
|
1297
|
+
* @param options - Streaming options
|
|
1298
|
+
*/
|
|
1299
|
+
createEarlyHtmlStream(globalHead: SimpleHead, asyncWork: () => Promise<{
|
|
1300
|
+
state: ReactRouterState;
|
|
1301
|
+
reactStream: ReadableStream<Uint8Array>;
|
|
1302
|
+
} | null>, options?: {
|
|
1303
|
+
hydration?: boolean;
|
|
1304
|
+
onError?: (error: unknown) => void;
|
|
1305
|
+
onRedirect?: (url: string) => void;
|
|
1306
|
+
}): ReadableStream<Uint8Array>;
|
|
1179
1307
|
}
|
|
1180
1308
|
/**
|
|
1181
|
-
*
|
|
1309
|
+
* Template slots - the template split into logical parts for efficient streaming.
|
|
1310
|
+
*
|
|
1311
|
+
* Static parts are pre-encoded as Uint8Array for zero-copy streaming.
|
|
1312
|
+
* Dynamic parts (attributes, head content) are kept as strings/objects for merging.
|
|
1313
|
+
*/
|
|
1314
|
+
interface TemplateSlots {
|
|
1315
|
+
doctype: Uint8Array;
|
|
1316
|
+
htmlOpen: Uint8Array;
|
|
1317
|
+
htmlClose: Uint8Array;
|
|
1318
|
+
headOpen: Uint8Array;
|
|
1319
|
+
headClose: Uint8Array;
|
|
1320
|
+
bodyOpen: Uint8Array;
|
|
1321
|
+
bodyClose: Uint8Array;
|
|
1322
|
+
rootOpen: Uint8Array;
|
|
1323
|
+
rootClose: Uint8Array;
|
|
1324
|
+
scriptClose: Uint8Array;
|
|
1325
|
+
htmlOriginalAttrs: Record<string, string>;
|
|
1326
|
+
bodyOriginalAttrs: Record<string, string>;
|
|
1327
|
+
headOriginalContent: string;
|
|
1328
|
+
beforeRoot: string;
|
|
1329
|
+
afterRoot: string;
|
|
1330
|
+
}
|
|
1331
|
+
/**
|
|
1332
|
+
* Hydration state that gets serialized to window.__ssr
|
|
1182
1333
|
*/
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1334
|
+
interface HydrationData {
|
|
1335
|
+
layers: Array<{
|
|
1336
|
+
data?: unknown;
|
|
1337
|
+
error?: {
|
|
1338
|
+
name: string;
|
|
1339
|
+
message: string;
|
|
1340
|
+
stack?: string;
|
|
1341
|
+
};
|
|
1342
|
+
}>;
|
|
1343
|
+
[key: string]: unknown;
|
|
1344
|
+
}
|
|
1345
|
+
//#endregion
|
|
1346
|
+
//#region ../../src/router/atoms/ssrManifestAtom.d.ts
|
|
1347
|
+
/**
|
|
1348
|
+
* Schema for the SSR manifest atom.
|
|
1349
|
+
*/
|
|
1350
|
+
declare const ssrManifestAtomSchema: alepha1.TObject<{
|
|
1351
|
+
/**
|
|
1352
|
+
* Preload manifest mapping short keys to source paths.
|
|
1353
|
+
* Generated by viteAlephaSsrPreload plugin at build time.
|
|
1354
|
+
*/
|
|
1355
|
+
preload: alepha1.TOptional<alepha1.TRecord<"^.*$", alepha1.TString>>;
|
|
1356
|
+
/**
|
|
1357
|
+
* SSR manifest mapping source files to their required chunks.
|
|
1358
|
+
*/
|
|
1359
|
+
ssr: alepha1.TOptional<alepha1.TRecord<"^.*$", alepha1.TArray<alepha1.TString>>>;
|
|
1360
|
+
/**
|
|
1361
|
+
* Client manifest mapping source files to their output information.
|
|
1362
|
+
*/
|
|
1363
|
+
client: alepha1.TOptional<alepha1.TRecord<"^.*$", alepha1.TObject<{
|
|
1364
|
+
file: alepha1.TString;
|
|
1365
|
+
src: alepha1.TOptional<alepha1.TString>;
|
|
1366
|
+
isEntry: alepha1.TOptional<alepha1.TBoolean>;
|
|
1367
|
+
isDynamicEntry: alepha1.TOptional<alepha1.TBoolean>;
|
|
1368
|
+
imports: alepha1.TOptional<alepha1.TArray<alepha1.TString>>;
|
|
1369
|
+
dynamicImports: alepha1.TOptional<alepha1.TArray<alepha1.TString>>;
|
|
1370
|
+
css: alepha1.TOptional<alepha1.TArray<alepha1.TString>>;
|
|
1371
|
+
assets: alepha1.TOptional<alepha1.TArray<alepha1.TString>>;
|
|
1372
|
+
}>>>;
|
|
1373
|
+
}>;
|
|
1374
|
+
/**
|
|
1375
|
+
* Type for the SSR manifest schema.
|
|
1376
|
+
*/
|
|
1377
|
+
type SsrManifestAtomSchema = typeof ssrManifestAtomSchema;
|
|
1378
|
+
//#endregion
|
|
1379
|
+
//#region ../../src/router/providers/SSRManifestProvider.d.ts
|
|
1380
|
+
/**
|
|
1381
|
+
* Provider for SSR manifest data used for module preloading.
|
|
1382
|
+
*
|
|
1383
|
+
* The manifest is populated at build time by embedding data into the
|
|
1384
|
+
* generated index.js via the ssrManifestAtom. This eliminates filesystem
|
|
1385
|
+
* reads at runtime, making it optimal for serverless deployments.
|
|
1386
|
+
*
|
|
1387
|
+
* Manifest files are generated during `vite build`:
|
|
1388
|
+
* - manifest.json (client manifest)
|
|
1389
|
+
* - ssr-manifest.json (SSR manifest)
|
|
1390
|
+
* - preload-manifest.json (from viteAlephaSsrPreload plugin)
|
|
1391
|
+
*/
|
|
1392
|
+
declare class SSRManifestProvider {
|
|
1393
|
+
protected readonly alepha: Alepha;
|
|
1394
|
+
/**
|
|
1395
|
+
* Get the manifest from the store at runtime.
|
|
1396
|
+
* This ensures the manifest is available even when set after module load.
|
|
1397
|
+
*/
|
|
1398
|
+
protected get manifest(): Static<SsrManifestAtomSchema>;
|
|
1399
|
+
/**
|
|
1400
|
+
* Get the preload manifest.
|
|
1401
|
+
*/
|
|
1402
|
+
protected get preloadManifest(): PreloadManifest | undefined;
|
|
1403
|
+
/**
|
|
1404
|
+
* Get the SSR manifest.
|
|
1405
|
+
*/
|
|
1406
|
+
protected get ssrManifest(): SSRManifest | undefined;
|
|
1407
|
+
/**
|
|
1408
|
+
* Get the client manifest.
|
|
1409
|
+
*/
|
|
1410
|
+
protected get clientManifest(): ClientManifest | undefined;
|
|
1411
|
+
/**
|
|
1412
|
+
* Resolve a preload key to its source path.
|
|
1413
|
+
*
|
|
1414
|
+
* The key is a short hash injected by viteAlephaSsrPreload plugin,
|
|
1415
|
+
* which maps to the full source path in the preload manifest.
|
|
1416
|
+
*
|
|
1417
|
+
* @param key - Short hash key (e.g., "a1b2c3d4")
|
|
1418
|
+
* @returns Source path (e.g., "src/pages/UserDetail.tsx") or undefined
|
|
1419
|
+
*/
|
|
1420
|
+
resolvePreloadKey(key: string): string | undefined;
|
|
1421
|
+
/**
|
|
1422
|
+
* Get all chunks required for a source file, including transitive dependencies.
|
|
1423
|
+
*
|
|
1424
|
+
* Uses the client manifest to recursively resolve all imported chunks,
|
|
1425
|
+
* not just the direct chunks from the SSR manifest.
|
|
1426
|
+
*
|
|
1427
|
+
* @param sourcePath - Source file path (e.g., "src/pages/Home.tsx")
|
|
1428
|
+
* @returns Array of chunk URLs to preload, or empty array if not found
|
|
1429
|
+
*/
|
|
1430
|
+
getChunks(sourcePath: string): string[];
|
|
1431
|
+
/**
|
|
1432
|
+
* Find manifest entry for a source path, trying different extensions.
|
|
1433
|
+
*/
|
|
1434
|
+
protected findManifestEntry(sourcePath: string): {
|
|
1435
|
+
file: string;
|
|
1436
|
+
src?: string;
|
|
1437
|
+
isEntry?: boolean;
|
|
1438
|
+
isDynamicEntry?: boolean;
|
|
1439
|
+
imports?: string[];
|
|
1440
|
+
dynamicImports?: string[];
|
|
1441
|
+
css?: string[];
|
|
1442
|
+
assets?: string[];
|
|
1443
|
+
} | undefined;
|
|
1444
|
+
/**
|
|
1445
|
+
* Recursively collect all chunk URLs for a manifest entry.
|
|
1446
|
+
*/
|
|
1447
|
+
protected collectChunksRecursive(key: string, chunks: Set<string>, visited: Set<string>): void;
|
|
1448
|
+
/**
|
|
1449
|
+
* Fallback to SSR manifest for chunk lookup.
|
|
1450
|
+
*/
|
|
1451
|
+
protected getChunksFromSSRManifest(sourcePath: string): string[];
|
|
1452
|
+
/**
|
|
1453
|
+
* Collect modulepreload links for a route and its parent chain.
|
|
1454
|
+
*/
|
|
1455
|
+
collectPreloadLinks(route: PageRoute): Array<{
|
|
1456
|
+
rel: string;
|
|
1457
|
+
href: string;
|
|
1458
|
+
as?: string;
|
|
1459
|
+
crossorigin?: string;
|
|
1460
|
+
}>;
|
|
1461
|
+
/**
|
|
1462
|
+
* Get all chunks for multiple source files.
|
|
1463
|
+
*
|
|
1464
|
+
* @param sourcePaths - Array of source file paths
|
|
1465
|
+
* @returns Deduplicated array of chunk URLs
|
|
1466
|
+
*/
|
|
1467
|
+
getChunksForMultiple(sourcePaths: string[]): string[];
|
|
1468
|
+
/**
|
|
1469
|
+
* Check if manifests are loaded and available.
|
|
1470
|
+
*/
|
|
1471
|
+
isAvailable(): boolean;
|
|
1472
|
+
/**
|
|
1473
|
+
* Cached entry assets - computed once at first access.
|
|
1474
|
+
*/
|
|
1475
|
+
protected cachedEntryAssets: EntryAssets | null;
|
|
1476
|
+
/**
|
|
1477
|
+
* Get the entry point assets (main entry.js and associated CSS files).
|
|
1478
|
+
*
|
|
1479
|
+
* These assets are always required for all pages and can be preloaded
|
|
1480
|
+
* before page-specific loaders run.
|
|
1481
|
+
*
|
|
1482
|
+
* @returns Entry assets with js and css paths, or null if manifest unavailable
|
|
1483
|
+
*/
|
|
1484
|
+
getEntryAssets(): EntryAssets | null;
|
|
1485
|
+
/**
|
|
1486
|
+
* Build preload link tags for entry assets.
|
|
1487
|
+
*
|
|
1488
|
+
* @returns Array of link objects ready to be rendered
|
|
1489
|
+
*/
|
|
1490
|
+
getEntryPreloadLinks(): Array<{
|
|
1491
|
+
rel: string;
|
|
1492
|
+
href: string;
|
|
1493
|
+
as?: string;
|
|
1494
|
+
crossorigin?: string;
|
|
1188
1495
|
}>;
|
|
1189
|
-
}>, "alepha.react.server.options">;
|
|
1190
|
-
type ReactServerProviderOptions = Static<typeof reactServerOptions.schema>;
|
|
1191
|
-
declare module "alepha" {
|
|
1192
|
-
interface State {
|
|
1193
|
-
[reactServerOptions.key]: ReactServerProviderOptions;
|
|
1194
|
-
}
|
|
1195
1496
|
}
|
|
1497
|
+
/**
|
|
1498
|
+
* Entry assets structure containing the main entry JS and associated CSS files.
|
|
1499
|
+
*/
|
|
1500
|
+
interface EntryAssets {
|
|
1501
|
+
/** Main entry JavaScript file (e.g., "/assets/entry.abc123.js") */
|
|
1502
|
+
js?: string;
|
|
1503
|
+
/** Associated CSS files (e.g., ["/assets/style.abc123.css"]) */
|
|
1504
|
+
css: string[];
|
|
1505
|
+
}
|
|
1506
|
+
/**
|
|
1507
|
+
* SSR Manifest structure from Vite.
|
|
1508
|
+
* Maps source file paths to their required chunks/assets.
|
|
1509
|
+
*/
|
|
1510
|
+
type SSRManifest = Record<string, string[]>;
|
|
1511
|
+
/**
|
|
1512
|
+
* Client manifest structure from Vite.
|
|
1513
|
+
* Maps source files to their output information.
|
|
1514
|
+
*/
|
|
1515
|
+
interface ClientManifest {
|
|
1516
|
+
[key: string]: {
|
|
1517
|
+
file: string;
|
|
1518
|
+
src?: string;
|
|
1519
|
+
isEntry?: boolean;
|
|
1520
|
+
isDynamicEntry?: boolean;
|
|
1521
|
+
imports?: string[];
|
|
1522
|
+
dynamicImports?: string[];
|
|
1523
|
+
css?: string[];
|
|
1524
|
+
assets?: string[];
|
|
1525
|
+
};
|
|
1526
|
+
}
|
|
1527
|
+
/**
|
|
1528
|
+
* Preload manifest mapping short keys to source paths.
|
|
1529
|
+
* Generated by viteAlephaSsrPreload plugin at build time.
|
|
1530
|
+
*/
|
|
1531
|
+
type PreloadManifest = Record<string, string>;
|
|
1532
|
+
//#endregion
|
|
1533
|
+
//#region ../../src/router/providers/ReactServerProvider.d.ts
|
|
1196
1534
|
/**
|
|
1197
1535
|
* React server provider responsible for SSR and static file serving.
|
|
1198
1536
|
*
|
|
1199
|
-
*
|
|
1537
|
+
* Coordinates between:
|
|
1538
|
+
* - ReactPageProvider: Page routing and layer resolution
|
|
1539
|
+
* - ReactServerTemplateProvider: HTML template parsing and streaming
|
|
1540
|
+
* - ServerHeadProvider: Head content management
|
|
1541
|
+
* - SSRManifestProvider: Module preload link collection
|
|
1542
|
+
*
|
|
1543
|
+
* Uses `react-dom/server` under the hood.
|
|
1200
1544
|
*/
|
|
1201
1545
|
declare class ReactServerProvider {
|
|
1546
|
+
/**
|
|
1547
|
+
* SSR response headers - pre-allocated to avoid object creation per request.
|
|
1548
|
+
*/
|
|
1549
|
+
protected readonly SSR_HEADERS: {
|
|
1550
|
+
readonly "content-type": "text/html";
|
|
1551
|
+
readonly "cache-control": "no-store, no-cache, must-revalidate, proxy-revalidate";
|
|
1552
|
+
readonly pragma: "no-cache";
|
|
1553
|
+
readonly expires: "0";
|
|
1554
|
+
};
|
|
1555
|
+
protected readonly fs: FileSystemProvider;
|
|
1202
1556
|
protected readonly log: alepha_logger0.Logger;
|
|
1203
1557
|
protected readonly alepha: Alepha;
|
|
1204
1558
|
protected readonly env: {
|
|
1205
1559
|
REACT_SSR_ENABLED?: boolean | undefined;
|
|
1206
|
-
REACT_ROOT_ID: string;
|
|
1207
1560
|
};
|
|
1208
1561
|
protected readonly pageApi: ReactPageProvider;
|
|
1562
|
+
protected readonly templateProvider: ReactServerTemplateProvider;
|
|
1563
|
+
protected readonly serverHeadProvider: ServerHeadProvider;
|
|
1209
1564
|
protected readonly serverStaticProvider: ServerStaticProvider;
|
|
1210
1565
|
protected readonly serverRouterProvider: ServerRouterProvider;
|
|
1211
1566
|
protected readonly serverTimingProvider: ServerTimingProvider;
|
|
1212
|
-
readonly
|
|
1213
|
-
|
|
1567
|
+
protected readonly ssrManifestProvider: SSRManifestProvider;
|
|
1568
|
+
/**
|
|
1569
|
+
* Cached check for ServerLinksProvider - avoids has() lookup per request.
|
|
1570
|
+
*/
|
|
1571
|
+
protected hasServerLinksProvider: boolean;
|
|
1214
1572
|
protected readonly options: Readonly<{
|
|
1215
1573
|
publicDir: string;
|
|
1216
1574
|
staticServer: {
|
|
@@ -1221,38 +1579,101 @@ declare class ReactServerProvider {
|
|
|
1221
1579
|
/**
|
|
1222
1580
|
* Configure the React server provider.
|
|
1223
1581
|
*/
|
|
1224
|
-
readonly onConfigure:
|
|
1582
|
+
readonly onConfigure: alepha1.HookPrimitive<"configure">;
|
|
1583
|
+
/**
|
|
1584
|
+
* Get the current HTML template.
|
|
1585
|
+
*/
|
|
1225
1586
|
get template(): string;
|
|
1587
|
+
/**
|
|
1588
|
+
* Register all pages as server routes.
|
|
1589
|
+
*/
|
|
1226
1590
|
protected registerPages(templateLoader: TemplateLoader): Promise<void>;
|
|
1591
|
+
/**
|
|
1592
|
+
* Set up early head content with entry assets.
|
|
1593
|
+
*
|
|
1594
|
+
* This content is sent immediately when streaming starts, before page loaders run,
|
|
1595
|
+
* allowing the browser to start downloading entry.js and CSS files early.
|
|
1596
|
+
*
|
|
1597
|
+
* Uses <script type="module"> instead of <link rel="modulepreload"> for JS
|
|
1598
|
+
* because the script needs to execute anyway - this way the browser starts
|
|
1599
|
+
* downloading, parsing, AND will execute as soon as ready.
|
|
1600
|
+
*
|
|
1601
|
+
* Also strips these assets from the original template head to avoid duplicates.
|
|
1602
|
+
*/
|
|
1603
|
+
protected setupEarlyHeadContent(): void;
|
|
1227
1604
|
/**
|
|
1228
1605
|
* Get the public directory path where static files are located.
|
|
1229
1606
|
*/
|
|
1230
|
-
protected getPublicDirectory(): string
|
|
1607
|
+
protected getPublicDirectory(): Promise<string>;
|
|
1231
1608
|
/**
|
|
1232
1609
|
* Configure the static file server to serve files from the given root directory.
|
|
1233
1610
|
*/
|
|
1234
1611
|
protected configureStaticServer(root: string): Promise<void>;
|
|
1235
1612
|
/**
|
|
1236
|
-
* Configure Vite for SSR.
|
|
1613
|
+
* Configure Vite for SSR in development mode.
|
|
1237
1614
|
*/
|
|
1238
1615
|
protected configureVite(ssrEnabled: boolean): Promise<void>;
|
|
1239
1616
|
/**
|
|
1240
|
-
*
|
|
1617
|
+
* Create the request handler for a page route.
|
|
1241
1618
|
*/
|
|
1242
|
-
render(name: string, options?: PagePrimitiveRenderOptions): Promise<PagePrimitiveRenderResult>;
|
|
1243
1619
|
protected createHandler(route: PageRoute, templateLoader: TemplateLoader): ServerHandler;
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1620
|
+
/**
|
|
1621
|
+
* Core page rendering logic shared between SSR handler and static prerendering.
|
|
1622
|
+
*
|
|
1623
|
+
* Handles:
|
|
1624
|
+
* - Layer resolution (loaders)
|
|
1625
|
+
* - Redirect detection
|
|
1626
|
+
* - Head content filling
|
|
1627
|
+
* - Preload link collection
|
|
1628
|
+
* - React stream rendering
|
|
1629
|
+
*
|
|
1630
|
+
* @param route - The page route to render
|
|
1631
|
+
* @param state - The router state
|
|
1632
|
+
* @returns Render result with redirect or React stream
|
|
1633
|
+
*/
|
|
1634
|
+
protected renderPage(route: PageRoute, state: ReactRouterState): Promise<{
|
|
1635
|
+
redirect?: string;
|
|
1636
|
+
reactStream?: ReadableStream<Uint8Array>;
|
|
1637
|
+
}>;
|
|
1638
|
+
/**
|
|
1639
|
+
* For testing purposes, renders a page to HTML string.
|
|
1640
|
+
* Uses the same streaming code path as production, then collects to string.
|
|
1641
|
+
*
|
|
1642
|
+
* @param name - Page name to render
|
|
1643
|
+
* @param options - Render options (params, query, html, hydration)
|
|
1644
|
+
*/
|
|
1645
|
+
render(name: string, options?: PagePrimitiveRenderOptions): Promise<PagePrimitiveRenderResult>;
|
|
1646
|
+
/**
|
|
1647
|
+
* Collect a ReadableStream into a string.
|
|
1648
|
+
*/
|
|
1649
|
+
protected streamToString(stream: ReadableStream<Uint8Array>): Promise<string>;
|
|
1249
1650
|
}
|
|
1250
1651
|
type TemplateLoader = () => Promise<string | undefined>;
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1652
|
+
declare const envSchema: alepha1.TObject<{
|
|
1653
|
+
REACT_SSR_ENABLED: alepha1.TOptional<alepha1.TBoolean>;
|
|
1654
|
+
}>;
|
|
1655
|
+
declare module "alepha" {
|
|
1656
|
+
interface Env extends Partial<Static<typeof envSchema>> {}
|
|
1657
|
+
interface State {
|
|
1658
|
+
"alepha.react.server.ssr"?: boolean;
|
|
1659
|
+
"alepha.react.server.template"?: string;
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
/**
|
|
1663
|
+
* React server provider configuration atom
|
|
1664
|
+
*/
|
|
1665
|
+
declare const reactServerOptions: alepha1.Atom<alepha1.TObject<{
|
|
1666
|
+
publicDir: alepha1.TString;
|
|
1667
|
+
staticServer: alepha1.TObject<{
|
|
1668
|
+
disabled: alepha1.TBoolean;
|
|
1669
|
+
path: alepha1.TString;
|
|
1670
|
+
}>;
|
|
1671
|
+
}>, "alepha.react.server.options">;
|
|
1672
|
+
type ReactServerProviderOptions = Static<typeof reactServerOptions.schema>;
|
|
1673
|
+
declare module "alepha" {
|
|
1674
|
+
interface State {
|
|
1675
|
+
[reactServerOptions.key]: ReactServerProviderOptions;
|
|
1676
|
+
}
|
|
1256
1677
|
}
|
|
1257
1678
|
//#endregion
|
|
1258
1679
|
//#region ../../src/router/index.d.ts
|
|
@@ -1278,6 +1699,9 @@ declare module "alepha" {
|
|
|
1278
1699
|
};
|
|
1279
1700
|
/**
|
|
1280
1701
|
* Fires when the React application is being rendered on the browser.
|
|
1702
|
+
*
|
|
1703
|
+
* Note: this one is not really necessary, it's a hack because we need to isolate renderer from server code in order
|
|
1704
|
+
* to avoid including react-dom/client in server bundles.
|
|
1281
1705
|
*/
|
|
1282
1706
|
"react:browser:render": {
|
|
1283
1707
|
root: HTMLElement;
|
|
@@ -1321,14 +1745,14 @@ declare module "alepha" {
|
|
|
1321
1745
|
* - URL pattern matching with parameters (e.g., `/users/:id`)
|
|
1322
1746
|
* - Nested routing with parent-child relationships
|
|
1323
1747
|
* - Type-safe URL parameter and query string validation
|
|
1324
|
-
* - Server-side data fetching with the `
|
|
1748
|
+
* - Server-side data fetching with the `loader` function
|
|
1325
1749
|
* - Lazy loading and code splitting
|
|
1326
1750
|
* - Page animations and error handling
|
|
1327
1751
|
*
|
|
1328
1752
|
* @see {@link $page}
|
|
1329
1753
|
* @module alepha.react.router
|
|
1330
1754
|
*/
|
|
1331
|
-
declare const AlephaReactRouter:
|
|
1755
|
+
declare const AlephaReactRouter: alepha1.Service<alepha1.Module>;
|
|
1332
1756
|
//#endregion
|
|
1333
|
-
export { $page, AlephaReactRouter, AnchorProps, ConcretePageRoute, CreateLayersResult, ErrorHandler, ErrorViewer, Layer, Link, type LinkProps, _default as NestedView, NestedViewProps, NotFound, PageAnimation, PageConfigSchema, PagePrimitive, PagePrimitiveOptions, PagePrimitiveRenderOptions, PagePrimitiveRenderResult, PageRequestConfig,
|
|
1757
|
+
export { $page, AlephaReactRouter, AnchorProps, ClientManifest, ConcretePageRoute, CreateLayersResult, EntryAssets, ErrorHandler, ErrorViewer, HydrationData, Layer, Link, type LinkProps, _default as NestedView, NestedViewProps, NotFound, PAGE_PRELOAD_KEY, PageAnimation, PageConfigSchema, PageLoader, PagePrimitive, PagePrimitiveOptions, PagePrimitiveRenderOptions, PagePrimitiveRenderResult, PageRequestConfig, PageRoute, PageRouteEntry, PreloadManifest, PreviousLayerData, ReactBrowserProvider, ReactBrowserRendererOptions, ReactHydrationState, ReactPageProvider, ReactPageService, ReactRouter, ReactRouterState, ReactServerProvider, ReactServerProviderOptions, ReactServerTemplateProvider, Redirection, type RouterGoOptions, RouterLayerContext, RouterLayerContextValue, RouterRenderOptions, RouterStackItem, SSRManifest, SSRManifestProvider, TPropsDefault, TPropsParentDefault, TemplateSlots, TransitionOptions, UseActiveHook, UseActiveOptions, UseQueryParamsHookOptions, VirtualRouter, isPageRoute, reactBrowserOptions, reactServerOptions, useActive, useQueryParams, useRouter, useRouterState };
|
|
1334
1758
|
//# sourceMappingURL=index.d.ts.map
|