@alepha/react 0.9.3 → 0.9.5

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.
Files changed (39) hide show
  1. package/README.md +64 -6
  2. package/dist/index.browser.js +442 -328
  3. package/dist/index.browser.js.map +1 -1
  4. package/dist/index.cjs +644 -482
  5. package/dist/index.cjs.map +1 -1
  6. package/dist/index.d.cts +402 -339
  7. package/dist/index.d.cts.map +1 -1
  8. package/dist/index.d.ts +412 -349
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +641 -484
  11. package/dist/index.js.map +1 -1
  12. package/package.json +16 -11
  13. package/src/components/Link.tsx +2 -5
  14. package/src/components/NestedView.tsx +164 -19
  15. package/src/components/NotFound.tsx +1 -1
  16. package/src/descriptors/$page.ts +100 -5
  17. package/src/errors/Redirection.ts +8 -5
  18. package/src/hooks/useActive.ts +25 -35
  19. package/src/hooks/useAlepha.ts +16 -2
  20. package/src/hooks/useClient.ts +7 -4
  21. package/src/hooks/useInject.ts +4 -1
  22. package/src/hooks/useQueryParams.ts +9 -6
  23. package/src/hooks/useRouter.ts +18 -31
  24. package/src/hooks/useRouterEvents.ts +30 -22
  25. package/src/hooks/useRouterState.ts +8 -20
  26. package/src/hooks/useSchema.ts +10 -15
  27. package/src/hooks/useStore.ts +0 -7
  28. package/src/index.browser.ts +14 -11
  29. package/src/index.shared.ts +2 -3
  30. package/src/index.ts +27 -31
  31. package/src/providers/ReactBrowserProvider.ts +151 -62
  32. package/src/providers/ReactBrowserRendererProvider.ts +22 -0
  33. package/src/providers/ReactBrowserRouterProvider.ts +137 -0
  34. package/src/providers/{PageDescriptorProvider.ts → ReactPageProvider.ts} +121 -104
  35. package/src/providers/ReactServerProvider.ts +90 -76
  36. package/src/{hooks/RouterHookApi.ts → services/ReactRouter.ts} +49 -62
  37. package/src/contexts/RouterContext.ts +0 -14
  38. package/src/providers/BrowserRouterProvider.ts +0 -155
  39. package/src/providers/ReactBrowserRenderer.ts +0 -93
package/dist/index.d.ts CHANGED
@@ -1,22 +1,15 @@
1
- import * as _alepha_core17 from "@alepha/core";
2
- import * as _alepha_core11 from "@alepha/core";
3
- import * as _alepha_core13 from "@alepha/core";
4
- import * as _alepha_core1 from "@alepha/core";
5
- import * as _alepha_core0 from "@alepha/core";
6
- import { Alepha, Async, Descriptor, KIND, Service, State, Static, TObject, TSchema } from "@alepha/core";
7
- import { ApiLinksResponse, RequestConfigSchema, ServerHandler, ServerRequest, ServerRouterProvider, ServerTimingProvider } from "@alepha/server";
1
+ import * as _alepha_core14 from "@alepha/core";
2
+ import { Alepha, Async, Descriptor, Hooks, KIND, Service, State, Static, TObject, TSchema } from "@alepha/core";
3
+ import { RequestConfigSchema, ServerHandler, ServerProvider, ServerRequest, ServerRouterProvider, ServerTimingProvider } from "@alepha/server";
8
4
  import { ServerRouteCache } from "@alepha/server-cache";
9
5
  import { ClientScope, HttpVirtualClient, LinkProvider, VirtualAction } from "@alepha/server-links";
10
- import * as react0$1 from "react";
6
+ import * as _alepha_logger1 from "@alepha/logger";
11
7
  import * as react0 from "react";
12
- import * as react1 from "react";
13
8
  import React, { AnchorHTMLAttributes, CSSProperties, ErrorInfo, FC, PropsWithChildren, ReactNode } from "react";
14
- import * as react_jsx_runtime0$1 from "react/jsx-runtime";
15
9
  import * as react_jsx_runtime0 from "react/jsx-runtime";
16
- import * as react_jsx_runtime2 from "react/jsx-runtime";
17
- import { Route, RouterProvider } from "@alepha/router";
18
10
  import { ServerStaticProvider } from "@alepha/server-static";
19
- import { Root } from "react-dom/client";
11
+ import { DateTimeProvider } from "@alepha/datetime";
12
+ import { Route, RouterProvider } from "@alepha/router";
20
13
 
21
14
  //#region src/components/ClientOnly.d.ts
22
15
  interface ClientOnlyProps {
@@ -35,132 +28,139 @@ interface ClientOnlyProps {
35
28
  */
36
29
  declare const ClientOnly: (props: PropsWithChildren<ClientOnlyProps>) => ReactNode;
37
30
  //#endregion
38
- //#region src/providers/BrowserRouterProvider.d.ts
39
- interface BrowserRoute extends Route {
40
- page: PageRoute;
41
- }
42
- declare class BrowserRouterProvider extends RouterProvider<BrowserRoute> {
43
- protected readonly log: _alepha_core17.Logger;
44
- protected readonly alepha: Alepha;
45
- protected readonly pageDescriptorProvider: PageDescriptorProvider;
46
- add(entry: PageRouteEntry): void;
47
- protected readonly configure: _alepha_core17.HookDescriptor<"configure">;
48
- transition(url: URL, options?: TransitionOptions): Promise<RouterRenderResult>;
49
- root(state: RouterState, context: PageReactContext): ReactNode;
31
+ //#region src/errors/Redirection.d.ts
32
+ /**
33
+ * Used for Redirection during the page loading.
34
+ *
35
+ * Depends on the context, it can be thrown or just returned.
36
+ */
37
+ declare class Redirection extends Error {
38
+ readonly redirect: string;
39
+ constructor(redirect: string);
50
40
  }
51
- //# sourceMappingURL=BrowserRouterProvider.d.ts.map
52
41
  //#endregion
53
- //#region src/providers/ReactBrowserProvider.d.ts
54
- declare class ReactBrowserProvider {
55
- protected readonly log: _alepha_core11.Logger;
56
- protected readonly client: LinkProvider;
57
- protected readonly alepha: Alepha;
58
- protected readonly router: BrowserRouterProvider;
59
- protected root: Root;
60
- transitioning?: {
61
- to: string;
42
+ //#region src/providers/ReactPageProvider.d.ts
43
+ declare const envSchema$2: _alepha_core14.TObject<{
44
+ REACT_STRICT_MODE: _alepha_core14.TBoolean;
45
+ }>;
46
+ declare module "@alepha/core" {
47
+ interface Env extends Partial<Static<typeof envSchema$2>> {}
48
+ }
49
+ declare class ReactPageProvider {
50
+ protected readonly log: _alepha_logger1.Logger;
51
+ protected readonly env: {
52
+ REACT_STRICT_MODE: boolean;
62
53
  };
63
- state: RouterState;
64
- get document(): Document;
65
- get history(): History;
66
- get location(): Location;
67
- get url(): string;
68
- pushState(url: string, replace?: boolean): void;
69
- invalidate(props?: Record<string, any>): Promise<void>;
70
- go(url: string, options?: RouterGoOptions): Promise<void>;
71
- protected render(options?: {
72
- url?: string;
73
- previous?: PreviousLayerData[];
74
- }): Promise<RouterRenderResult>;
54
+ protected readonly alepha: Alepha;
55
+ protected readonly pages: PageRoute[];
56
+ getPages(): PageRoute[];
57
+ page(name: string): PageRoute;
58
+ pathname(name: string, options?: {
59
+ params?: Record<string, string>;
60
+ query?: Record<string, string>;
61
+ }): string;
62
+ url(name: string, options?: {
63
+ params?: Record<string, string>;
64
+ host?: string;
65
+ }): URL;
66
+ root(state: ReactRouterState): ReactNode;
67
+ protected convertStringObjectToObject: (schema?: TSchema, value?: any) => any;
75
68
  /**
76
- * Get embedded layers from the server.
69
+ * Create a new RouterState based on a given route and request.
70
+ * This method resolves the layers for the route, applying any query and params schemas defined in the route.
71
+ * It also handles errors and redirects.
77
72
  */
78
- protected getHydrationState(): ReactHydrationState | undefined;
79
- readonly ready: _alepha_core11.HookDescriptor<"ready">;
73
+ createLayers(route: PageRoute, state: ReactRouterState, previous?: PreviousLayerData[]): Promise<CreateLayersResult>;
74
+ protected createRedirectionLayer(redirect: string): CreateLayersResult;
75
+ protected getErrorHandler(route: PageRoute): ErrorHandler | undefined;
76
+ protected createElement(page: PageRoute, props: Record<string, any>): Promise<ReactNode>;
77
+ renderError(error: Error): ReactNode;
78
+ renderEmptyView(): ReactNode;
79
+ href(page: {
80
+ options: {
81
+ name?: string;
82
+ };
83
+ }, params?: Record<string, any>): string;
84
+ compile(path: string, params?: Record<string, string>): string;
85
+ protected renderView(index: number, path: string, view: ReactNode | undefined, page: PageRoute): ReactNode;
86
+ protected readonly configure: _alepha_core14.HookDescriptor<"configure">;
87
+ protected map(pages: Array<PageDescriptor>, target: PageDescriptor): PageRouteEntry;
88
+ add(entry: PageRouteEntry): void;
89
+ protected createMatch(page: PageRoute): string;
90
+ protected _next: number;
91
+ protected nextId(): string;
80
92
  }
81
- interface RouterGoOptions {
82
- replace?: boolean;
83
- match?: TransitionOptions;
84
- params?: Record<string, string>;
85
- query?: Record<string, string>;
93
+ declare const isPageRoute: (it: any) => it is PageRoute;
94
+ interface PageRouteEntry extends Omit<PageDescriptorOptions, "children" | "parent"> {
95
+ children?: PageRouteEntry[];
86
96
  }
87
- interface ReactHydrationState {
88
- layers?: Array<PreviousLayerData>;
89
- links?: ApiLinksResponse;
97
+ interface PageRoute extends PageRouteEntry {
98
+ type: "page";
99
+ name: string;
100
+ parent?: PageRoute;
101
+ match: string;
90
102
  }
91
- //# sourceMappingURL=ReactBrowserProvider.d.ts.map
92
- //#endregion
93
- //#region src/hooks/RouterHookApi.d.ts
94
- declare class RouterHookApi<T extends object> {
95
- private readonly pages;
96
- private readonly context;
97
- private readonly state;
98
- private readonly layer;
99
- private readonly pageApi;
100
- private readonly browser?;
101
- constructor(pages: PageRoute[], context: PageReactContext, state: RouterState, layer: {
102
- path: string;
103
- }, pageApi: PageDescriptorProvider, browser?: ReactBrowserProvider | undefined);
104
- path(name: keyof VirtualRouter<T>, config?: {
105
- params?: Record<string, string>;
106
- query?: Record<string, string>;
107
- }): string;
108
- getURL(): URL;
109
- get location(): Location;
110
- get current(): RouterState;
111
- get pathname(): string;
112
- get query(): Record<string, string>;
113
- back(): Promise<void>;
114
- forward(): Promise<void>;
115
- invalidate(props?: Record<string, any>): Promise<void>;
103
+ interface Layer {
104
+ config?: {
105
+ query?: Record<string, any>;
106
+ params?: Record<string, any>;
107
+ context?: Record<string, any>;
108
+ };
109
+ name: string;
110
+ props?: Record<string, any>;
111
+ error?: Error;
112
+ part?: string;
113
+ element: ReactNode;
114
+ index: number;
115
+ path: string;
116
+ route?: PageRoute;
117
+ cache?: boolean;
118
+ }
119
+ type PreviousLayerData = Omit<Layer, "element" | "index" | "path">;
120
+ interface AnchorProps {
121
+ href: string;
122
+ onClick: (ev?: any) => any;
123
+ }
124
+ interface ReactRouterState {
116
125
  /**
117
- * Create a valid href for the given pathname.
118
- *
119
- * @param pathname
120
- * @param layer
126
+ * Stack of layers for the current page.
121
127
  */
122
- createHref(pathname: HrefLike, layer?: {
123
- path: string;
124
- }, options?: {
125
- params?: Record<string, any>;
126
- }): string;
127
- go(path: string, options?: RouterGoOptions): Promise<void>;
128
- go(path: keyof VirtualRouter<T>, options?: RouterGoOptions): Promise<void>;
129
- anchor(path: string, options?: {
130
- params?: Record<string, any>;
131
- }): AnchorProps;
132
- anchor(path: keyof VirtualRouter<T>, options?: {
133
- params?: Record<string, any>;
134
- }): AnchorProps;
128
+ layers: Array<Layer>;
135
129
  /**
136
- * Set query params.
137
- *
138
- * @param record
139
- * @param options
130
+ * URL of the current page.
140
131
  */
141
- setQueryParams(record: Record<string, any> | ((queryParams: Record<string, any>) => Record<string, any>), options?: {
142
- /**
143
- * If true, this will add a new entry to the history stack.
144
- */
145
- push?: boolean;
146
- }): void;
132
+ url: URL;
133
+ /**
134
+ * Error handler for the current page.
135
+ */
136
+ onError: ErrorHandler;
137
+ /**
138
+ * Params extracted from the URL for the current page.
139
+ */
140
+ params: Record<string, any>;
141
+ /**
142
+ * Query parameters extracted from the URL for the current page.
143
+ */
144
+ query: Record<string, string>;
145
+ /**
146
+ * Optional meta information associated with the current page.
147
+ */
148
+ meta: Record<string, any>;
147
149
  }
148
- type HrefLike = string | {
149
- options: {
150
- path?: string;
151
- name?: string;
152
- };
153
- };
154
- type VirtualRouter<T> = { [K in keyof T as T[K] extends PageDescriptor ? K : never]: T[K] };
155
- //# sourceMappingURL=RouterHookApi.d.ts.map
156
- //#endregion
157
- //#region src/errors/Redirection.d.ts
158
- declare class Redirection extends Error {
159
- readonly page: HrefLike;
160
- constructor(page: HrefLike);
150
+ interface RouterStackItem {
151
+ route: PageRoute;
152
+ config?: Record<string, any>;
153
+ props?: Record<string, any>;
154
+ error?: Error;
155
+ cache?: boolean;
156
+ }
157
+ interface TransitionOptions {
158
+ previous?: PreviousLayerData[];
159
+ }
160
+ interface CreateLayersResult {
161
+ redirect?: string;
162
+ state?: ReactRouterState;
161
163
  }
162
- //# sourceMappingURL=Redirection.d.ts.map
163
-
164
164
  //#endregion
165
165
  //#region src/descriptors/$page.d.ts
166
166
  /**
@@ -299,8 +299,51 @@ interface PageDescriptorOptions<TConfig extends PageConfigSchema = PageConfigSch
299
299
  * Called when user leaves the page. (browser only)
300
300
  */
301
301
  onLeave?: () => void;
302
+ /**
303
+ * @experimental
304
+ *
305
+ * Add a css animation when the page is loaded or unloaded.
306
+ * It uses CSS animations, so you need to define the keyframes in your CSS.
307
+ *
308
+ * @example Simple animation name
309
+ * ```ts
310
+ * animation: "fadeIn"
311
+ * ```
312
+ *
313
+ * CSS example:
314
+ * ```css
315
+ * @keyframes fadeIn {
316
+ * from { opacity: 0; }
317
+ * to { opacity: 1; }
318
+ * }
319
+ * ```
320
+ *
321
+ * @example Detailed animation
322
+ * ```ts
323
+ * animation: {
324
+ * enter: { name: "fadeIn", duration: 300 },
325
+ * exit: { name: "fadeOut", duration: 200, timing: "ease-in-out" },
326
+ * }
327
+ * ```
328
+ *
329
+ * @example Only exit animation
330
+ * ```ts
331
+ * animation: {
332
+ * exit: "fadeOut"
333
+ * }
334
+ * ```
335
+ *
336
+ * @example With custom timing function
337
+ * ```ts
338
+ * animation: {
339
+ * enter: { name: "fadeIn", duration: 300, timing: "cubic-bezier(0.4, 0, 0.2, 1)" },
340
+ * exit: { name: "fadeOut", duration: 200, timing: "ease-in-out" },
341
+ * }
342
+ * ```
343
+ */
344
+ animation?: PageAnimation;
302
345
  }
303
- type ErrorHandler = (error: Error, context: PageReactContext) => ReactNode | Redirection | undefined;
346
+ type ErrorHandler = (error: Error, state: ReactRouterState) => ReactNode | Redirection | undefined;
304
347
  declare class PageDescriptor<TConfig extends PageConfigSchema = PageConfigSchema, TProps extends object = TPropsDefault, TPropsParent extends object = TPropsParentDefault> extends Descriptor<PageDescriptorOptions<TConfig, TProps, TPropsParent>> {
305
348
  protected onInit(): void;
306
349
  get name(): string;
@@ -309,6 +352,12 @@ declare class PageDescriptor<TConfig extends PageConfigSchema = PageConfigSchema
309
352
  * Only valid for server-side rendering, it will throw an error if called on the client-side.
310
353
  */
311
354
  render(options?: PageDescriptorRenderOptions): Promise<PageDescriptorRenderResult>;
355
+ fetch(options?: PageDescriptorRenderOptions): Promise<{
356
+ html: string;
357
+ response: Response;
358
+ }>;
359
+ match(url: string): boolean;
360
+ pathname(config: any): string;
312
361
  }
313
362
  interface PageConfigSchema {
314
363
  query?: TSchema;
@@ -319,144 +368,122 @@ type TPropsParentDefault = {};
319
368
  interface PageDescriptorRenderOptions {
320
369
  params?: Record<string, string>;
321
370
  query?: Record<string, string>;
371
+ /**
372
+ * If true, the HTML layout will be included in the response.
373
+ * If false, only the page content will be returned.
374
+ *
375
+ * @default true
376
+ */
322
377
  html?: boolean;
323
378
  hydration?: boolean;
324
379
  }
325
380
  interface PageDescriptorRenderResult {
326
381
  html: string;
327
- context: PageReactContext;
382
+ state: ReactRouterState;
383
+ redirect?: string;
328
384
  }
329
385
  interface PageRequestConfig<TConfig extends PageConfigSchema = PageConfigSchema> {
330
386
  params: TConfig["params"] extends TSchema ? Static<TConfig["params"]> : Record<string, string>;
331
387
  query: TConfig["query"] extends TSchema ? Static<TConfig["query"]> : Record<string, string>;
332
388
  }
333
- type PageResolve<TConfig extends PageConfigSchema = PageConfigSchema, TPropsParent extends object = TPropsParentDefault> = PageRequestConfig<TConfig> & TPropsParent & PageReactContext;
334
- //# sourceMappingURL=$page.d.ts.map
389
+ type PageResolve<TConfig extends PageConfigSchema = PageConfigSchema, TPropsParent extends object = TPropsParentDefault> = PageRequestConfig<TConfig> & TPropsParent & Omit<ReactRouterState, "layers" | "onError">;
390
+ type PageAnimation = PageAnimationObject | ((state: ReactRouterState) => PageAnimationObject | undefined);
391
+ type PageAnimationObject = CssAnimationName | {
392
+ enter?: CssAnimation | CssAnimationName;
393
+ exit?: CssAnimation | CssAnimationName;
394
+ };
395
+ type CssAnimationName = string;
396
+ type CssAnimation = {
397
+ name: string;
398
+ duration?: number;
399
+ timing?: string;
400
+ };
335
401
  //#endregion
336
- //#region src/providers/PageDescriptorProvider.d.ts
337
- declare const envSchema$1: _alepha_core13.TObject<{
338
- REACT_STRICT_MODE: _alepha_core13.TBoolean;
402
+ //#region src/providers/ReactBrowserRouterProvider.d.ts
403
+ interface BrowserRoute extends Route {
404
+ page: PageRoute;
405
+ }
406
+ declare class ReactBrowserRouterProvider extends RouterProvider<BrowserRoute> {
407
+ protected readonly log: _alepha_logger1.Logger;
408
+ protected readonly alepha: Alepha;
409
+ protected readonly pageApi: ReactPageProvider;
410
+ add(entry: PageRouteEntry): void;
411
+ protected readonly configure: _alepha_core14.HookDescriptor<"configure">;
412
+ transition(url: URL, previous?: PreviousLayerData[], meta?: {}): Promise<string | void>;
413
+ root(state: ReactRouterState): ReactNode;
414
+ }
415
+ //#endregion
416
+ //#region src/providers/ReactBrowserProvider.d.ts
417
+ declare const envSchema$1: _alepha_core14.TObject<{
418
+ REACT_ROOT_ID: _alepha_core14.TString;
339
419
  }>;
340
420
  declare module "@alepha/core" {
341
421
  interface Env extends Partial<Static<typeof envSchema$1>> {}
342
422
  }
343
- declare class PageDescriptorProvider {
344
- protected readonly log: _alepha_core13.Logger;
423
+ interface ReactBrowserRendererOptions {
424
+ scrollRestoration?: "top" | "manual";
425
+ }
426
+ declare class ReactBrowserProvider {
345
427
  protected readonly env: {
346
- REACT_STRICT_MODE: boolean;
428
+ REACT_ROOT_ID: string;
347
429
  };
430
+ protected readonly log: _alepha_logger1.Logger;
431
+ protected readonly client: LinkProvider;
348
432
  protected readonly alepha: Alepha;
349
- protected readonly pages: PageRoute[];
350
- getPages(): PageRoute[];
351
- page(name: string): PageRoute;
352
- pathname(name: string, options?: {
353
- params?: Record<string, string>;
354
- query?: Record<string, string>;
355
- }): string;
356
- url(name: string, options?: {
357
- params?: Record<string, string>;
358
- base?: string;
359
- }): URL;
360
- root(state: RouterState, context: PageReactContext): ReactNode;
361
- createLayers(route: PageRoute, request: PageRequest): Promise<CreateLayersResult>;
362
- protected createRedirectionLayer(href: HrefLike, context: {
363
- pathname: string;
364
- search: string;
365
- }): {
366
- layers: never[];
367
- redirect: string;
368
- pathname: string;
369
- search: string;
370
- };
371
- protected getErrorHandler(route: PageRoute): ErrorHandler | undefined;
372
- protected createElement(page: PageRoute, props: Record<string, any>): Promise<ReactNode>;
373
- renderError(error: Error): ReactNode;
374
- renderEmptyView(): ReactNode;
375
- href(page: {
376
- options: {
377
- name?: string;
378
- };
379
- }, params?: Record<string, any>): string;
380
- compile(path: string, params?: Record<string, string>): string;
381
- protected renderView(index: number, path: string, view: ReactNode | undefined, page: PageRoute): ReactNode;
382
- protected readonly configure: _alepha_core13.HookDescriptor<"configure">;
383
- protected map(pages: Array<PageDescriptor>, target: PageDescriptor): PageRouteEntry;
384
- add(entry: PageRouteEntry): void;
385
- protected createMatch(page: PageRoute): string;
386
- protected _next: number;
387
- protected nextId(): string;
388
- }
389
- declare const isPageRoute: (it: any) => it is PageRoute;
390
- interface PageRouteEntry extends Omit<PageDescriptorOptions, "children" | "parent"> {
391
- children?: PageRouteEntry[];
392
- }
393
- interface PageRoute extends PageRouteEntry {
394
- type: "page";
395
- name: string;
396
- parent?: PageRoute;
397
- match: string;
398
- }
399
- interface Layer {
400
- config?: {
401
- query?: Record<string, any>;
402
- params?: Record<string, any>;
403
- context?: Record<string, any>;
433
+ protected readonly router: ReactBrowserRouterProvider;
434
+ protected readonly dateTimeProvider: DateTimeProvider;
435
+ options: ReactBrowserRendererOptions;
436
+ protected getRootElement(): HTMLElement;
437
+ transitioning?: {
438
+ to: string;
439
+ from?: string;
404
440
  };
405
- name: string;
406
- props?: Record<string, any>;
407
- error?: Error;
408
- part?: string;
409
- element: ReactNode;
410
- index: number;
411
- path: string;
412
- route?: PageRoute;
413
- cache?: boolean;
414
- }
415
- type PreviousLayerData = Omit<Layer, "element" | "index" | "path">;
416
- interface AnchorProps {
417
- href: string;
418
- onClick: (ev?: any) => any;
419
- }
420
- interface RouterState {
421
- pathname: string;
422
- search: string;
423
- layers: Array<Layer>;
424
- }
425
- interface TransitionOptions {
426
- state?: RouterState;
427
- previous?: PreviousLayerData[];
428
- context?: PageReactContext;
429
- }
430
- interface RouterStackItem {
431
- route: PageRoute;
432
- config?: Record<string, any>;
433
- props?: Record<string, any>;
434
- error?: Error;
435
- cache?: boolean;
441
+ get state(): ReactRouterState;
442
+ /**
443
+ * Accessor for Document DOM API.
444
+ */
445
+ get document(): Document;
446
+ /**
447
+ * Accessor for History DOM API.
448
+ */
449
+ get history(): History;
450
+ /**
451
+ * Accessor for Location DOM API.
452
+ */
453
+ get location(): Location;
454
+ get base(): string;
455
+ get url(): string;
456
+ pushState(path: string, replace?: boolean): void;
457
+ invalidate(props?: Record<string, any>): Promise<void>;
458
+ go(url: string, options?: RouterGoOptions): Promise<void>;
459
+ protected render(options?: RouterRenderOptions): Promise<void>;
460
+ /**
461
+ * Get embedded layers from the server.
462
+ */
463
+ protected getHydrationState(): ReactHydrationState | undefined;
464
+ protected readonly onTransitionEnd: _alepha_core14.HookDescriptor<"react:transition:end">;
465
+ readonly ready: _alepha_core14.HookDescriptor<"ready">;
436
466
  }
437
- interface RouterRenderResult {
438
- state: RouterState;
439
- context: PageReactContext;
440
- redirect?: string;
467
+ interface RouterGoOptions {
468
+ replace?: boolean;
469
+ match?: TransitionOptions;
470
+ params?: Record<string, string>;
471
+ query?: Record<string, string>;
472
+ meta?: Record<string, any>;
473
+ /**
474
+ * Recreate the whole page, ignoring the current state.
475
+ */
476
+ force?: boolean;
441
477
  }
442
- interface PageRequest extends PageReactContext {
443
- params: Record<string, any>;
444
- query: Record<string, string>;
478
+ type ReactHydrationState = {
479
+ layers?: Array<PreviousLayerData>;
480
+ } & {
481
+ [key: string]: any;
482
+ };
483
+ interface RouterRenderOptions {
484
+ url?: string;
445
485
  previous?: PreviousLayerData[];
446
- }
447
- interface CreateLayersResult extends RouterState {
448
- redirect?: string;
449
- }
450
- /**
451
- * It's like RouterState, but publicly available in React context.
452
- * This is where we store all plugin data!
453
- */
454
- interface PageReactContext {
455
- url: URL;
456
- onError: ErrorHandler;
457
- links?: ApiLinksResponse;
458
- params: Record<string, any>;
459
- query: Record<string, string>;
486
+ meta?: Record<string, any>;
460
487
  }
461
488
  //#endregion
462
489
  //#region src/components/ErrorBoundary.d.ts
@@ -499,120 +526,170 @@ declare class ErrorBoundary extends React.Component<PropsWithChildren<ErrorBound
499
526
  render(): ReactNode;
500
527
  }
501
528
  //#endregion
529
+ //#region src/components/ErrorViewer.d.ts
530
+ interface ErrorViewerProps {
531
+ error: Error;
532
+ alepha: Alepha;
533
+ }
534
+ declare const ErrorViewer: ({
535
+ error,
536
+ alepha
537
+ }: ErrorViewerProps) => react_jsx_runtime0.JSX.Element;
538
+ //#endregion
502
539
  //#region src/components/Link.d.ts
503
540
  interface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
504
- to: string;
505
- children?: React.ReactNode;
541
+ href: string;
506
542
  }
507
- declare const Link: (props: LinkProps) => react_jsx_runtime0$1.JSX.Element;
543
+ declare const Link: (props: LinkProps) => react_jsx_runtime0.JSX.Element;
508
544
  //#endregion
509
545
  //#region src/components/NestedView.d.ts
510
546
  interface NestedViewProps {
511
547
  children?: ReactNode;
548
+ errorBoundary?: false | ((error: Error) => ReactNode);
512
549
  }
513
- /**
514
- * A component that renders the current view of the nested router layer.
515
- *
516
- * To be simple, it renders the `element` of the current child page of a parent page.
517
- *
518
- * @example
519
- * ```tsx
520
- * import { NestedView } from "@alepha/react";
521
- *
522
- * class App {
523
- * parent = $page({
524
- * component: () => <NestedView />,
525
- * });
526
- *
527
- * child = $page({
528
- * parent: this.root,
529
- * component: () => <div>Child Page</div>,
530
- * });
531
- * }
532
- * ```
533
- */
534
- declare const NestedView: (props: NestedViewProps) => react_jsx_runtime0.JSX.Element;
550
+ declare const _default: react0.MemoExoticComponent<(props: NestedViewProps) => react_jsx_runtime0.JSX.Element>;
535
551
  //#endregion
536
552
  //#region src/components/NotFound.d.ts
537
553
  declare function NotFoundPage(props: {
538
554
  style?: CSSProperties;
539
- }): react_jsx_runtime2.JSX.Element;
540
- //# sourceMappingURL=NotFound.d.ts.map
555
+ }): react_jsx_runtime0.JSX.Element;
541
556
  //#endregion
542
557
  //#region src/contexts/AlephaContext.d.ts
543
- declare const AlephaContext: react0$1.Context<Alepha | undefined>;
544
- //# sourceMappingURL=AlephaContext.d.ts.map
545
- //#endregion
546
- //#region src/contexts/RouterContext.d.ts
547
- interface RouterContextValue {
548
- state: RouterState;
549
- context: PageReactContext;
550
- }
551
- declare const RouterContext: react0.Context<RouterContextValue | undefined>;
552
- //# sourceMappingURL=RouterContext.d.ts.map
558
+ declare const AlephaContext: react0.Context<Alepha | undefined>;
553
559
  //#endregion
554
560
  //#region src/contexts/RouterLayerContext.d.ts
555
561
  interface RouterLayerContextValue {
556
562
  index: number;
557
563
  path: string;
558
564
  }
559
- declare const RouterLayerContext: react1.Context<RouterLayerContextValue | undefined>;
560
- //# sourceMappingURL=RouterLayerContext.d.ts.map
565
+ declare const RouterLayerContext: react0.Context<RouterLayerContextValue | undefined>;
561
566
  //#endregion
562
567
  //#region src/hooks/useActive.d.ts
563
- declare const useActive: (path?: HrefLike) => UseActiveHook;
568
+ interface UseActiveOptions {
569
+ href: string;
570
+ startWith?: boolean;
571
+ }
572
+ declare const useActive: (args: string | UseActiveOptions) => UseActiveHook;
564
573
  interface UseActiveHook {
565
574
  isActive: boolean;
566
575
  anchorProps: AnchorProps;
567
576
  isPending: boolean;
568
- name?: string;
569
577
  }
570
- //# sourceMappingURL=useActive.d.ts.map
571
578
  //#endregion
572
579
  //#region src/hooks/useAlepha.d.ts
580
+ /**
581
+ * Main Alepha hook.
582
+ *
583
+ * It provides access to the Alepha instance within a React component.
584
+ *
585
+ * With Alepha, you can access the core functionalities of the framework:
586
+ *
587
+ * - alepha.state() for state management
588
+ * - alepha.inject() for dependency injection
589
+ * - alepha.emit() for event handling
590
+ * etc...
591
+ */
573
592
  declare const useAlepha: () => Alepha;
574
- //# sourceMappingURL=useAlepha.d.ts.map
575
593
  //#endregion
576
594
  //#region src/hooks/useClient.d.ts
577
- declare const useClient: <T extends object>(_scope?: ClientScope) => HttpVirtualClient<T>;
578
- //# sourceMappingURL=useClient.d.ts.map
595
+ /**
596
+ * Hook to get a virtual client for the specified scope.
597
+ *
598
+ * It's the React-hook version of `$client()`, from `AlephaServerLinks` module.
599
+ */
600
+ declare const useClient: <T extends object>(scope?: ClientScope) => HttpVirtualClient<T>;
579
601
  //#endregion
580
602
  //#region src/hooks/useInject.d.ts
603
+ /**
604
+ * Hook to inject a service instance.
605
+ * It's a wrapper of `useAlepha().inject(service)` with a memoization.
606
+ */
581
607
  declare const useInject: <T extends object>(service: Service<T>) => T;
582
- //# sourceMappingURL=useInject.d.ts.map
583
608
  //#endregion
584
609
  //#region src/hooks/useQueryParams.d.ts
610
+ /**
611
+ * Not well tested. Use with caution.
612
+ */
613
+ declare const useQueryParams: <T extends TObject>(schema: T, options?: UseQueryParamsHookOptions) => [Static<T>, (data: Static<T>) => void];
585
614
  interface UseQueryParamsHookOptions {
586
615
  format?: "base64" | "querystring";
587
616
  key?: string;
588
617
  push?: boolean;
589
618
  }
590
- declare const useQueryParams: <T extends TObject>(schema: T, options?: UseQueryParamsHookOptions) => [Static<T>, (data: Static<T>) => void];
591
- //# sourceMappingURL=useQueryParams.d.ts.map
619
+ //#endregion
620
+ //#region src/services/ReactRouter.d.ts
621
+ declare class ReactRouter<T extends object> {
622
+ protected readonly alepha: Alepha;
623
+ protected readonly pageApi: ReactPageProvider;
624
+ get state(): ReactRouterState;
625
+ get pages(): PageRoute[];
626
+ get browser(): ReactBrowserProvider | undefined;
627
+ path(name: keyof VirtualRouter<T>, config?: {
628
+ params?: Record<string, any>;
629
+ query?: Record<string, any>;
630
+ }): string;
631
+ getURL(): URL;
632
+ get location(): Location;
633
+ get current(): ReactRouterState;
634
+ get pathname(): string;
635
+ get query(): Record<string, string>;
636
+ back(): Promise<void>;
637
+ forward(): Promise<void>;
638
+ invalidate(props?: Record<string, any>): Promise<void>;
639
+ go(path: string, options?: RouterGoOptions): Promise<void>;
640
+ go(path: keyof VirtualRouter<T>, options?: RouterGoOptions): Promise<void>;
641
+ anchor(path: string, options?: RouterGoOptions): AnchorProps;
642
+ anchor(path: keyof VirtualRouter<T>, options?: RouterGoOptions): AnchorProps;
643
+ base(path: string): string;
644
+ /**
645
+ * Set query params.
646
+ *
647
+ * @param record
648
+ * @param options
649
+ */
650
+ setQueryParams(record: Record<string, any> | ((queryParams: Record<string, any>) => Record<string, any>), options?: {
651
+ /**
652
+ * If true, this will add a new entry to the history stack.
653
+ */
654
+ push?: boolean;
655
+ }): void;
656
+ }
657
+ type VirtualRouter<T> = { [K in keyof T as T[K] extends PageDescriptor ? K : never]: T[K] };
592
658
  //#endregion
593
659
  //#region src/hooks/useRouter.d.ts
594
- declare const useRouter: <T extends object>() => RouterHookApi<T>;
595
- //# sourceMappingURL=useRouter.d.ts.map
660
+ /**
661
+ * Use this hook to access the React Router instance.
662
+ *
663
+ * You can add a type parameter to specify the type of your application.
664
+ * This will allow you to use the router in a typesafe way.
665
+ *
666
+ * @example
667
+ * class App {
668
+ * home = $page();
669
+ * }
670
+ *
671
+ * const router = useRouter<App>();
672
+ * router.go("home"); // typesafe
673
+ */
674
+ declare const useRouter: <T extends object = any>() => ReactRouter<T>;
596
675
  //#endregion
597
676
  //#region src/hooks/useRouterEvents.d.ts
677
+ type Hook<T extends keyof Hooks> = ((ev: Hooks[T]) => void) | {
678
+ priority?: "first" | "last";
679
+ callback: (ev: Hooks[T]) => void;
680
+ };
681
+ /**
682
+ * Subscribe to various router events.
683
+ */
598
684
  declare const useRouterEvents: (opts?: {
599
- onBegin?: (ev: {
600
- state: RouterState;
601
- }) => void;
602
- onEnd?: (ev: {
603
- state: RouterState;
604
- context: PageReactContext;
605
- }) => void;
606
- onError?: (ev: {
607
- state: RouterState;
608
- error: Error;
609
- }) => void;
685
+ onBegin?: Hook<"react:transition:begin">;
686
+ onError?: Hook<"react:transition:error">;
687
+ onEnd?: Hook<"react:transition:end">;
688
+ onSuccess?: Hook<"react:transition:success">;
610
689
  }, deps?: any[]) => void;
611
- //# sourceMappingURL=useRouterEvents.d.ts.map
612
690
  //#endregion
613
691
  //#region src/hooks/useRouterState.d.ts
614
- declare const useRouterState: () => RouterState;
615
- //# sourceMappingURL=useRouterState.d.ts.map
692
+ declare const useRouterState: () => ReactRouterState;
616
693
  //#endregion
617
694
  //#region src/hooks/useSchema.d.ts
618
695
  declare const useSchema: <TConfig extends RequestConfigSchema>(action: VirtualAction<TConfig>) => UseSchemaReturn<TConfig>;
@@ -625,22 +702,20 @@ type UseSchemaReturn<TConfig extends RequestConfigSchema> = TConfig & {
625
702
  declare const ssrSchemaLoading: (alepha: Alepha, name: string) => RequestConfigSchema | {
626
703
  loading: boolean;
627
704
  };
628
- //# sourceMappingURL=useSchema.d.ts.map
629
705
  //#endregion
630
706
  //#region src/hooks/useStore.d.ts
631
707
  /**
632
708
  * Hook to access and mutate the Alepha state.
633
709
  */
634
710
  declare const useStore: <Key extends keyof State>(key: Key, defaultValue?: State[Key]) => [State[Key], (value: State[Key]) => void];
635
- //# sourceMappingURL=useStore.d.ts.map
636
711
  //#endregion
637
712
  //#region src/providers/ReactServerProvider.d.ts
638
- declare const envSchema: _alepha_core1.TObject<{
639
- REACT_SERVER_DIST: _alepha_core1.TString;
640
- REACT_SERVER_PREFIX: _alepha_core1.TString;
641
- REACT_SSR_ENABLED: _alepha_core1.TOptional<_alepha_core1.TBoolean>;
642
- REACT_ROOT_ID: _alepha_core1.TString;
643
- REACT_SERVER_TEMPLATE: _alepha_core1.TOptional<_alepha_core1.TString>;
713
+ declare const envSchema: _alepha_core14.TObject<{
714
+ REACT_SERVER_DIST: _alepha_core14.TString;
715
+ REACT_SERVER_PREFIX: _alepha_core14.TString;
716
+ REACT_SSR_ENABLED: _alepha_core14.TOptional<_alepha_core14.TBoolean>;
717
+ REACT_ROOT_ID: _alepha_core14.TString;
718
+ REACT_SERVER_TEMPLATE: _alepha_core14.TOptional<_alepha_core14.TString>;
644
719
  }>;
645
720
  declare module "@alepha/core" {
646
721
  interface Env extends Partial<Static<typeof envSchema>> {}
@@ -649,9 +724,10 @@ declare module "@alepha/core" {
649
724
  }
650
725
  }
651
726
  declare class ReactServerProvider {
652
- protected readonly log: _alepha_core1.Logger;
727
+ protected readonly log: _alepha_logger1.Logger;
653
728
  protected readonly alepha: Alepha;
654
- protected readonly pageDescriptorProvider: PageDescriptorProvider;
729
+ protected readonly pageApi: ReactPageProvider;
730
+ protected readonly serverProvider: ServerProvider;
655
731
  protected readonly serverStaticProvider: ServerStaticProvider;
656
732
  protected readonly serverRouterProvider: ServerRouterProvider;
657
733
  protected readonly serverTimingProvider: ServerTimingProvider;
@@ -663,7 +739,7 @@ declare class ReactServerProvider {
663
739
  REACT_ROOT_ID: string;
664
740
  };
665
741
  protected readonly ROOT_DIV_REGEX: RegExp;
666
- readonly onConfigure: _alepha_core1.HookDescriptor<"configure">;
742
+ readonly onConfigure: _alepha_core14.HookDescriptor<"configure">;
667
743
  get template(): string;
668
744
  protected registerPages(templateLoader: TemplateLoader): Promise<void>;
669
745
  protected getPublicDirectory(): string;
@@ -672,16 +748,9 @@ declare class ReactServerProvider {
672
748
  /**
673
749
  * For testing purposes, creates a render function that can be used.
674
750
  */
675
- protected createRenderFunction(name: string, withIndex?: boolean): (options?: PageDescriptorRenderOptions) => Promise<{
676
- context: PageRequest;
677
- state: CreateLayersResult;
678
- html: string;
679
- } | {
680
- context: PageRequest;
681
- html: string;
682
- }>;
683
- protected createHandler(page: PageRoute, templateLoader: TemplateLoader): ServerHandler;
684
- renderToHtml(template: string, state: RouterState, context: PageReactContext, hydration?: boolean): string | Redirection;
751
+ protected createRenderFunction(name: string, withIndex?: boolean): (options?: PageDescriptorRenderOptions) => Promise<PageDescriptorRenderResult>;
752
+ protected createHandler(route: PageRoute, templateLoader: TemplateLoader): ServerHandler;
753
+ renderToHtml(template: string, state: ReactRouterState, hydration?: boolean): string | Redirection;
685
754
  protected fillTemplate(response: {
686
755
  html: string;
687
756
  }, app: string, script: string): void;
@@ -690,43 +759,39 @@ type TemplateLoader = () => Promise<string | undefined>;
690
759
  //#endregion
691
760
  //#region src/index.d.ts
692
761
  declare module "@alepha/core" {
762
+ interface State {
763
+ "react.router.state"?: ReactRouterState;
764
+ }
693
765
  interface Hooks {
694
- "react:router:createLayers": {
695
- request: ServerRequest;
696
- context: PageRequest;
697
- layers: PageRequest[];
698
- };
699
766
  "react:server:render:begin": {
700
767
  request?: ServerRequest;
701
- context: PageRequest;
768
+ state: ReactRouterState;
702
769
  };
703
770
  "react:server:render:end": {
704
771
  request?: ServerRequest;
705
- context: PageRequest;
706
- state: RouterState;
772
+ state: ReactRouterState;
707
773
  html: string;
708
774
  };
709
775
  "react:browser:render": {
710
- state: RouterState;
711
- context: PageReactContext;
776
+ root: HTMLDivElement;
777
+ element: ReactNode;
778
+ state: ReactRouterState;
712
779
  hydration?: ReactHydrationState;
713
780
  };
714
781
  "react:transition:begin": {
715
- state: RouterState;
716
- context: PageReactContext;
782
+ previous: ReactRouterState;
783
+ state: ReactRouterState;
784
+ animation?: PageAnimation;
717
785
  };
718
786
  "react:transition:success": {
719
- state: RouterState;
720
- context: PageReactContext;
787
+ state: ReactRouterState;
721
788
  };
722
789
  "react:transition:error": {
790
+ state: ReactRouterState;
723
791
  error: Error;
724
- state: RouterState;
725
- context: PageReactContext;
726
792
  };
727
793
  "react:transition:end": {
728
- state: RouterState;
729
- context: PageReactContext;
794
+ state: ReactRouterState;
730
795
  };
731
796
  }
732
797
  }
@@ -740,9 +805,7 @@ declare module "@alepha/core" {
740
805
  * @see {@link $page}
741
806
  * @module alepha.react
742
807
  */
743
- declare const AlephaReact: _alepha_core0.Service<_alepha_core0.Module>;
744
- //# sourceMappingURL=index.d.ts.map
745
-
808
+ declare const AlephaReact: _alepha_core14.Service<_alepha_core14.Module>;
746
809
  //#endregion
747
- export { $page, AlephaContext, AlephaReact, AnchorProps, ClientOnly, CreateLayersResult, ErrorBoundary, ErrorHandler, HrefLike, Layer, Link, LinkProps, NestedView, NotFoundPage as NotFound, PageConfigSchema, PageDescriptor, PageDescriptorOptions, PageDescriptorProvider, PageDescriptorRenderOptions, PageDescriptorRenderResult, PageReactContext, PageRequest, PageRequestConfig, PageResolve, PageRoute, PageRouteEntry, PreviousLayerData, ReactBrowserProvider, ReactHydrationState, ReactServerProvider, Redirection, RouterContext, RouterContextValue, RouterGoOptions, RouterHookApi, RouterLayerContext, RouterLayerContextValue, RouterRenderResult, RouterStackItem, RouterState, TPropsDefault, TPropsParentDefault, TransitionOptions, UseActiveHook, UseQueryParamsHookOptions, UseSchemaReturn, VirtualRouter, isPageRoute, ssrSchemaLoading, useActive, useAlepha, useClient, useInject, useQueryParams, useRouter, useRouterEvents, useRouterState, useSchema, useStore };
810
+ export { $page, AlephaContext, AlephaReact, AnchorProps, ClientOnly, CreateLayersResult, ErrorBoundary, ErrorHandler, ErrorViewer, Layer, Link, LinkProps, _default as NestedView, NotFoundPage as NotFound, PageAnimation, PageConfigSchema, PageDescriptor, PageDescriptorOptions, PageDescriptorRenderOptions, PageDescriptorRenderResult, PageRequestConfig, PageResolve, PageRoute, PageRouteEntry, PreviousLayerData, ReactBrowserProvider, ReactBrowserRendererOptions, ReactHydrationState, ReactPageProvider, ReactRouter, ReactRouterState, ReactServerProvider, Redirection, RouterGoOptions, RouterLayerContext, RouterLayerContextValue, RouterRenderOptions, RouterStackItem, TPropsDefault, TPropsParentDefault, TransitionOptions, UseActiveHook, UseActiveOptions, UseQueryParamsHookOptions, UseSchemaReturn, VirtualRouter, isPageRoute, ssrSchemaLoading, useActive, useAlepha, useClient, useInject, useQueryParams, useRouter, useRouterEvents, useRouterState, useSchema, useStore };
748
811
  //# sourceMappingURL=index.d.ts.map