@alepha/react 0.7.0 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.browser.cjs +59 -22
- package/dist/index.browser.js +42 -6
- package/dist/index.cjs +152 -85
- package/dist/index.d.ts +317 -206
- package/dist/index.js +130 -64
- package/dist/{useActive-DjpZBEuB.cjs → useRouterState-C2uo0jXu.cjs} +319 -140
- package/dist/{useActive-BX41CqY8.js → useRouterState-D5__ZcUV.js} +321 -143
- package/package.json +11 -10
- package/src/components/ClientOnly.tsx +35 -0
- package/src/components/ErrorBoundary.tsx +1 -1
- package/src/components/ErrorViewer.tsx +161 -0
- package/src/components/Link.tsx +9 -3
- package/src/components/NestedView.tsx +18 -3
- package/src/components/NotFound.tsx +30 -0
- package/src/descriptors/$page.ts +141 -30
- package/src/errors/RedirectionError.ts +4 -1
- package/src/hooks/RouterHookApi.ts +42 -24
- package/src/hooks/useAlepha.ts +12 -0
- package/src/hooks/useClient.ts +8 -6
- package/src/hooks/useInject.ts +2 -2
- package/src/hooks/useQueryParams.ts +1 -1
- package/src/hooks/useRouter.ts +6 -0
- package/src/index.browser.ts +4 -2
- package/src/index.shared.ts +11 -5
- package/src/index.ts +3 -4
- package/src/providers/BrowserRouterProvider.ts +4 -3
- package/src/providers/PageDescriptorProvider.ts +91 -20
- package/src/providers/ReactBrowserProvider.ts +6 -59
- package/src/providers/ReactBrowserRenderer.ts +72 -0
- package/src/providers/ReactServerProvider.ts +200 -81
- package/dist/index.browser.cjs.map +0 -1
- package/dist/index.browser.js.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/useActive-BX41CqY8.js.map +0 -1
- package/dist/useActive-DjpZBEuB.cjs.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import * as _alepha_core from '@alepha/core';
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import { HttpClientLink, HttpClient, ApiLinksResponse, ServerRouterProvider, ServerHandler, ServerRequest } from '@alepha/server';
|
|
2
|
+
import { TSchema as TSchema$1, KIND, OPTIONS, Static as Static$1, Async, Alepha, Service, TObject as TObject$1 } from '@alepha/core';
|
|
3
|
+
import { ServerRoute, ServerRequest, ApiLinksResponse, HttpClient, ClientScope, HttpVirtualClient, ServerRouterProvider, ServerTimingProvider, ServerHandler } from '@alepha/server';
|
|
5
4
|
import * as React from 'react';
|
|
6
|
-
import React__default, { ReactNode, FC,
|
|
5
|
+
import React__default, { PropsWithChildren, ReactNode, FC, ErrorInfo, AnchorHTMLAttributes } from 'react';
|
|
7
6
|
import { Root } from 'react-dom/client';
|
|
8
7
|
import { RouterProvider, Route } from '@alepha/router';
|
|
9
8
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
@@ -126,215 +125,138 @@ interface TSchema extends TKind, SchemaOptions {
|
|
|
126
125
|
static: unknown;
|
|
127
126
|
}
|
|
128
127
|
|
|
129
|
-
interface
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
bodyAttributes?: Record<string, string>;
|
|
133
|
-
meta?: Array<{
|
|
134
|
-
name: string;
|
|
135
|
-
content: string;
|
|
136
|
-
}>;
|
|
137
|
-
}
|
|
138
|
-
declare class ServerHeadProvider {
|
|
139
|
-
renderHead(template: string, head: Head$1): string;
|
|
140
|
-
mergeAttributes(existing: string, attrs: Record<string, string>): string;
|
|
141
|
-
parseAttributes(attrStr: string): Record<string, string>;
|
|
142
|
-
escapeHtml(str: string): string;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
declare class BrowserHeadProvider {
|
|
146
|
-
renderHead(document: Document, head: Head$1): void;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
interface BrowserRoute extends Route {
|
|
150
|
-
page: PageRoute;
|
|
151
|
-
}
|
|
152
|
-
declare class BrowserRouterProvider extends RouterProvider<BrowserRoute> {
|
|
153
|
-
protected readonly log: _alepha_core.Logger;
|
|
154
|
-
protected readonly alepha: Alepha;
|
|
155
|
-
protected readonly pageDescriptorProvider: PageDescriptorProvider;
|
|
156
|
-
add(entry: PageRouteEntry): void;
|
|
157
|
-
protected readonly configure: _alepha_core.HookDescriptor<"configure">;
|
|
158
|
-
transition(url: URL, options?: TransitionOptions): Promise<RouterRenderResult>;
|
|
159
|
-
root(state: RouterState, context: PageReactContext): ReactNode;
|
|
128
|
+
interface ClientOnlyProps {
|
|
129
|
+
fallback?: ReactNode;
|
|
130
|
+
disabled?: boolean;
|
|
160
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* A small utility component that renders its children only on the client side.
|
|
134
|
+
*
|
|
135
|
+
* Optionally, you can provide a fallback React node that will be rendered.
|
|
136
|
+
*
|
|
137
|
+
* You should use this component when
|
|
138
|
+
* - you have code that relies on browser-specific APIs
|
|
139
|
+
* - you want to avoid server-side rendering for a specific part of your application
|
|
140
|
+
* - you want to prevent pre-rendering of a component
|
|
141
|
+
*/
|
|
142
|
+
declare const ClientOnly: (props: PropsWithChildren<ClientOnlyProps>) => ReactNode;
|
|
161
143
|
|
|
162
|
-
declare const
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
interface Env extends Partial<Static$1<typeof envSchema$1>> {
|
|
167
|
-
}
|
|
144
|
+
declare const KEY = "PAGE";
|
|
145
|
+
interface PageConfigSchema {
|
|
146
|
+
query?: TSchema$1;
|
|
147
|
+
params?: TSchema$1;
|
|
168
148
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
protected readonly alepha: Alepha;
|
|
173
|
-
protected readonly router: BrowserRouterProvider;
|
|
174
|
-
protected readonly headProvider: BrowserHeadProvider;
|
|
175
|
-
protected readonly env: {
|
|
176
|
-
REACT_ROOT_ID: string;
|
|
177
|
-
};
|
|
178
|
-
protected root: Root;
|
|
179
|
-
transitioning?: {
|
|
180
|
-
to: string;
|
|
181
|
-
};
|
|
182
|
-
state: RouterState;
|
|
183
|
-
get document(): Document;
|
|
184
|
-
get history(): History;
|
|
185
|
-
get url(): string;
|
|
186
|
-
invalidate(props?: Record<string, any>): Promise<void>;
|
|
149
|
+
type TPropsDefault = any;
|
|
150
|
+
type TPropsParentDefault = {};
|
|
151
|
+
interface PageDescriptorOptions<TConfig extends PageConfigSchema = PageConfigSchema, TProps extends object = TPropsDefault, TPropsParent extends object = TPropsParentDefault> extends Pick<ServerRoute, "cache"> {
|
|
187
152
|
/**
|
|
153
|
+
* Name your page.
|
|
188
154
|
*
|
|
189
|
-
* @
|
|
190
|
-
* @param options
|
|
155
|
+
* @default Descriptor key
|
|
191
156
|
*/
|
|
192
|
-
|
|
193
|
-
protected render(options?: {
|
|
194
|
-
url?: string;
|
|
195
|
-
previous?: PreviousLayerData[];
|
|
196
|
-
}): Promise<RouterRenderResult>;
|
|
157
|
+
name?: string;
|
|
197
158
|
/**
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
* @protected
|
|
159
|
+
* Optional description of the page.
|
|
201
160
|
*/
|
|
202
|
-
|
|
161
|
+
description?: string;
|
|
203
162
|
/**
|
|
163
|
+
* Add a pathname to the page.
|
|
204
164
|
*
|
|
205
|
-
*
|
|
206
|
-
*/
|
|
207
|
-
protected getRootElement(): HTMLElement;
|
|
208
|
-
/**
|
|
165
|
+
* Pathname can contain parameters, like `/post/:slug`.
|
|
209
166
|
*
|
|
210
|
-
* @
|
|
167
|
+
* @default ""
|
|
211
168
|
*/
|
|
212
|
-
|
|
213
|
-
readonly onTransitionEnd: _alepha_core.HookDescriptor<"react:transition:end">;
|
|
214
|
-
}
|
|
215
|
-
interface RouterGoOptions {
|
|
216
|
-
replace?: boolean;
|
|
217
|
-
match?: TransitionOptions;
|
|
218
|
-
params?: Record<string, string>;
|
|
219
|
-
}
|
|
220
|
-
interface ReactHydrationState {
|
|
221
|
-
layers?: PreviousLayerData[];
|
|
222
|
-
links?: HttpClientLink[];
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
declare class RouterHookApi {
|
|
226
|
-
private readonly state;
|
|
227
|
-
private readonly layer;
|
|
228
|
-
private readonly browser?;
|
|
229
|
-
constructor(state: RouterState, layer: {
|
|
230
|
-
path: string;
|
|
231
|
-
}, browser?: ReactBrowserProvider | undefined);
|
|
169
|
+
path?: string;
|
|
232
170
|
/**
|
|
233
|
-
*
|
|
171
|
+
* Add an input schema to define:
|
|
172
|
+
* - `params`: parameters from the pathname.
|
|
173
|
+
* - `query`: query parameters from the URL.
|
|
234
174
|
*/
|
|
235
|
-
|
|
175
|
+
schema?: TConfig;
|
|
236
176
|
/**
|
|
177
|
+
* Load data before rendering the page.
|
|
237
178
|
*
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
179
|
+
* This function receives
|
|
180
|
+
* - the request context and
|
|
181
|
+
* - the parent props (if page has a parent)
|
|
241
182
|
*
|
|
242
|
-
|
|
243
|
-
get query(): Record<string, string>;
|
|
244
|
-
/**
|
|
183
|
+
* In SSR, the returned data will be serialized and sent to the client, then reused during the client-side hydration.
|
|
245
184
|
*
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
/**
|
|
185
|
+
* Resolve can be stopped by throwing an error, which will be handled by the `errorHandler` function.
|
|
186
|
+
* It's common to throw a `NotFoundError` to display a 404 page.
|
|
249
187
|
*
|
|
188
|
+
* RedirectError can be thrown to redirect the user to another page.
|
|
250
189
|
*/
|
|
251
|
-
|
|
190
|
+
resolve?: (context: PageResolve<TConfig, TPropsParent>) => Async<TProps>;
|
|
252
191
|
/**
|
|
192
|
+
* The component to render when the page is loaded.
|
|
253
193
|
*
|
|
254
|
-
*
|
|
194
|
+
* If `lazy` is defined, this will be ignored.
|
|
195
|
+
* Prefer using `lazy` to improve the initial loading time.
|
|
255
196
|
*/
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* Create a valid href for the given pathname.
|
|
259
|
-
*
|
|
260
|
-
* @param pathname
|
|
261
|
-
* @param layer
|
|
262
|
-
*/
|
|
263
|
-
createHref(pathname: HrefLike, layer?: {
|
|
264
|
-
path: string;
|
|
265
|
-
}): string;
|
|
266
|
-
go(path: string, options?: RouterGoOptions): Promise<void>;
|
|
267
|
-
go<T extends object>(path: keyof VirtualRouter<T>, options?: RouterGoOptions): Promise<void>;
|
|
268
|
-
anchor(path: string): AnchorProps;
|
|
197
|
+
component?: FC<TProps & TPropsParent>;
|
|
269
198
|
/**
|
|
270
|
-
*
|
|
199
|
+
* Lazy load the component when the page is loaded.
|
|
271
200
|
*
|
|
272
|
-
*
|
|
273
|
-
*
|
|
201
|
+
* It's recommended to use this for components to improve the initial loading time
|
|
202
|
+
* and enable code-splitting.
|
|
274
203
|
*/
|
|
275
|
-
setQueryParams(record: Record<string, any> | ((queryParams: Record<string, any>) => Record<string, any>), options?: {
|
|
276
|
-
/**
|
|
277
|
-
* If true, this will add a new entry to the history stack.
|
|
278
|
-
*/
|
|
279
|
-
push?: boolean;
|
|
280
|
-
}): void;
|
|
281
|
-
}
|
|
282
|
-
type HrefLike = string | {
|
|
283
|
-
options: {
|
|
284
|
-
path?: string;
|
|
285
|
-
name?: string;
|
|
286
|
-
};
|
|
287
|
-
};
|
|
288
|
-
type VirtualRouter<T> = {
|
|
289
|
-
[K in keyof T as T[K] extends PageDescriptor ? K : never]: T[K];
|
|
290
|
-
};
|
|
291
|
-
|
|
292
|
-
declare const KEY = "PAGE";
|
|
293
|
-
interface PageConfigSchema {
|
|
294
|
-
query?: TSchema$1;
|
|
295
|
-
params?: TSchema$1;
|
|
296
|
-
}
|
|
297
|
-
type TPropsDefault = any;
|
|
298
|
-
type TPropsParentDefault = object;
|
|
299
|
-
interface PageDescriptorOptions<TConfig extends PageConfigSchema = PageConfigSchema, TProps extends object = TPropsDefault, TPropsParent extends object = TPropsParentDefault> {
|
|
300
|
-
name?: string;
|
|
301
|
-
path?: string;
|
|
302
|
-
schema?: TConfig;
|
|
303
|
-
resolve?: (config: PageResolve<TConfig, TPropsParent>) => Async<TProps>;
|
|
304
|
-
component?: FC<TProps & TPropsParent>;
|
|
305
204
|
lazy?: () => Promise<{
|
|
306
205
|
default: FC<TProps & TPropsParent>;
|
|
307
206
|
}>;
|
|
207
|
+
/**
|
|
208
|
+
* Set some children pages and make the page a parent page.
|
|
209
|
+
*
|
|
210
|
+
* /!\ Parent page can't be rendered directly. /!\
|
|
211
|
+
*
|
|
212
|
+
* If you still want to render at this pathname, add a child page with an empty path.
|
|
213
|
+
*/
|
|
308
214
|
children?: Array<{
|
|
309
215
|
[OPTIONS]: PageDescriptorOptions;
|
|
310
216
|
}>;
|
|
311
217
|
parent?: {
|
|
312
|
-
[OPTIONS]: PageDescriptorOptions<
|
|
218
|
+
[OPTIONS]: PageDescriptorOptions<PageConfigSchema, TPropsParent>;
|
|
313
219
|
};
|
|
314
220
|
can?: () => boolean;
|
|
315
|
-
head?: Head | ((props: TProps, previous?: Head) => Head);
|
|
221
|
+
head?: Head$1 | ((props: TProps, previous?: Head$1) => Head$1);
|
|
316
222
|
errorHandler?: (error: Error) => ReactNode;
|
|
223
|
+
prerender?: boolean | {
|
|
224
|
+
entries?: Array<Partial<PageRequestConfig<TConfig>>>;
|
|
225
|
+
};
|
|
226
|
+
/**
|
|
227
|
+
* If true, the page will be rendered on the client-side.
|
|
228
|
+
*/
|
|
229
|
+
client?: boolean | ClientOnlyProps;
|
|
230
|
+
afterHandler?: (request: ServerRequest) => any;
|
|
317
231
|
}
|
|
318
232
|
interface PageDescriptor<TConfig extends PageConfigSchema = PageConfigSchema, TProps extends object = TPropsDefault, TPropsParent extends object = TPropsParentDefault> {
|
|
319
233
|
[KIND]: typeof KEY;
|
|
320
234
|
[OPTIONS]: PageDescriptorOptions<TConfig, TProps, TPropsParent>;
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
createAnchorProps: (routerHook: RouterHookApi) => {
|
|
327
|
-
href: string;
|
|
328
|
-
onClick: () => void;
|
|
329
|
-
};
|
|
330
|
-
can: () => boolean;
|
|
235
|
+
/**
|
|
236
|
+
* For testing or build purposes, this will render the page (with or without the HTML layout) and return the HTML and context.
|
|
237
|
+
* Only valid for server-side rendering, it will throw an error if called on the client-side.
|
|
238
|
+
*/
|
|
239
|
+
render: (options?: PageDescriptorRenderOptions) => Promise<PageDescriptorRenderResult>;
|
|
331
240
|
}
|
|
241
|
+
/**
|
|
242
|
+
* Main descriptor for defining a React route in the application.
|
|
243
|
+
*/
|
|
332
244
|
declare const $page: {
|
|
333
|
-
<TConfig extends PageConfigSchema = PageConfigSchema, TProps extends object = any, TPropsParent extends object =
|
|
245
|
+
<TConfig extends PageConfigSchema = PageConfigSchema, TProps extends object = any, TPropsParent extends object = TPropsParentDefault>(options: PageDescriptorOptions<TConfig, TProps, TPropsParent>): PageDescriptor<TConfig, TProps, TPropsParent>;
|
|
334
246
|
[KIND]: string;
|
|
335
247
|
};
|
|
336
|
-
interface
|
|
248
|
+
interface PageDescriptorRenderOptions {
|
|
249
|
+
params?: Record<string, string>;
|
|
250
|
+
query?: Record<string, string>;
|
|
251
|
+
withLayout?: boolean;
|
|
252
|
+
}
|
|
253
|
+
interface PageDescriptorRenderResult {
|
|
254
|
+
html: string;
|
|
255
|
+
context: PageReactContext;
|
|
256
|
+
}
|
|
257
|
+
interface Head$1 {
|
|
337
258
|
title?: string;
|
|
259
|
+
description?: string;
|
|
338
260
|
titleSeparator?: string;
|
|
339
261
|
htmlAttributes?: Record<string, string>;
|
|
340
262
|
bodyAttributes?: Record<string, string>;
|
|
@@ -342,6 +264,32 @@ interface Head {
|
|
|
342
264
|
name: string;
|
|
343
265
|
content: string;
|
|
344
266
|
}>;
|
|
267
|
+
keywords?: string[];
|
|
268
|
+
author?: string;
|
|
269
|
+
robots?: string;
|
|
270
|
+
themeColor?: string;
|
|
271
|
+
viewport?: string | {
|
|
272
|
+
width?: string;
|
|
273
|
+
height?: string;
|
|
274
|
+
initialScale?: string;
|
|
275
|
+
maximumScale?: string;
|
|
276
|
+
userScalable?: "no" | "yes" | "0" | "1";
|
|
277
|
+
interactiveWidget?: "resizes-visual" | "resizes-content" | "overlays-content";
|
|
278
|
+
};
|
|
279
|
+
og?: {
|
|
280
|
+
title?: string;
|
|
281
|
+
description?: string;
|
|
282
|
+
image?: string;
|
|
283
|
+
url?: string;
|
|
284
|
+
type?: string;
|
|
285
|
+
};
|
|
286
|
+
twitter?: {
|
|
287
|
+
card?: string;
|
|
288
|
+
title?: string;
|
|
289
|
+
description?: string;
|
|
290
|
+
image?: string;
|
|
291
|
+
site?: string;
|
|
292
|
+
};
|
|
345
293
|
}
|
|
346
294
|
interface PageRequestConfig<TConfig extends PageConfigSchema = PageConfigSchema> {
|
|
347
295
|
params: TConfig["params"] extends TSchema$1 ? Static$1<TConfig["params"]> : Record<string, string>;
|
|
@@ -349,18 +297,32 @@ interface PageRequestConfig<TConfig extends PageConfigSchema = PageConfigSchema>
|
|
|
349
297
|
}
|
|
350
298
|
type PageResolve<TConfig extends PageConfigSchema = PageConfigSchema, TPropsParent extends object = TPropsParentDefault> = PageRequestConfig<TConfig> & TPropsParent & PageReactContext;
|
|
351
299
|
|
|
300
|
+
declare const envSchema$1: _alepha_core.TObject<{
|
|
301
|
+
REACT_STRICT_MODE: TBoolean;
|
|
302
|
+
}>;
|
|
303
|
+
declare module "@alepha/core" {
|
|
304
|
+
interface Env extends Partial<Static$1<typeof envSchema$1>> {
|
|
305
|
+
}
|
|
306
|
+
}
|
|
352
307
|
declare class PageDescriptorProvider {
|
|
353
308
|
protected readonly log: _alepha_core.Logger;
|
|
309
|
+
protected readonly env: {
|
|
310
|
+
REACT_STRICT_MODE: boolean;
|
|
311
|
+
};
|
|
354
312
|
protected readonly alepha: Alepha;
|
|
355
313
|
protected readonly pages: PageRoute[];
|
|
356
314
|
getPages(): PageRoute[];
|
|
357
315
|
page(name: string): PageRoute;
|
|
316
|
+
url(name: string, options?: {
|
|
317
|
+
params?: Record<string, string>;
|
|
318
|
+
base?: string;
|
|
319
|
+
}): URL;
|
|
358
320
|
root(state: RouterState, context: PageReactContext): ReactNode;
|
|
359
321
|
createLayers(route: PageRoute, request: PageRequest): Promise<CreateLayersResult>;
|
|
360
322
|
protected getErrorHandler(route: PageRoute): ((error: Error) => ReactNode) | undefined;
|
|
361
323
|
protected createElement(page: PageRoute, props: Record<string, any>): Promise<ReactNode>;
|
|
362
324
|
protected fillHead(page: PageRoute, ctx: PageRequest, props: Record<string, any>): void;
|
|
363
|
-
renderError(
|
|
325
|
+
renderError(error: Error): ReactNode;
|
|
364
326
|
renderEmptyView(): ReactNode;
|
|
365
327
|
href(page: {
|
|
366
328
|
options: {
|
|
@@ -368,7 +330,7 @@ declare class PageDescriptorProvider {
|
|
|
368
330
|
};
|
|
369
331
|
}, params?: Record<string, any>): string;
|
|
370
332
|
compile(path: string, params?: Record<string, string>): string;
|
|
371
|
-
protected renderView(index: number, path: string, view
|
|
333
|
+
protected renderView(index: number, path: string, view: ReactNode | undefined, page: PageRoute): ReactNode;
|
|
372
334
|
protected readonly configure: _alepha_core.HookDescriptor<"configure">;
|
|
373
335
|
protected map(pages: Array<{
|
|
374
336
|
value: {
|
|
@@ -406,7 +368,7 @@ interface Layer {
|
|
|
406
368
|
index: number;
|
|
407
369
|
path: string;
|
|
408
370
|
}
|
|
409
|
-
type PreviousLayerData = Omit<Layer, "element">;
|
|
371
|
+
type PreviousLayerData = Omit<Layer, "element" | "index" | "path">;
|
|
410
372
|
interface AnchorProps {
|
|
411
373
|
href: string;
|
|
412
374
|
onClick: (ev: any) => any;
|
|
@@ -446,27 +408,167 @@ interface CreateLayersResult extends RouterState {
|
|
|
446
408
|
*/
|
|
447
409
|
interface PageReactContext {
|
|
448
410
|
url: URL;
|
|
449
|
-
head: Head;
|
|
411
|
+
head: Head$1;
|
|
450
412
|
onError: (error: Error) => ReactNode;
|
|
451
413
|
links?: ApiLinksResponse;
|
|
452
414
|
}
|
|
453
415
|
|
|
416
|
+
interface Head {
|
|
417
|
+
title?: string;
|
|
418
|
+
htmlAttributes?: Record<string, string>;
|
|
419
|
+
bodyAttributes?: Record<string, string>;
|
|
420
|
+
meta?: Array<{
|
|
421
|
+
name: string;
|
|
422
|
+
content: string;
|
|
423
|
+
}>;
|
|
424
|
+
}
|
|
425
|
+
declare class ServerHeadProvider {
|
|
426
|
+
renderHead(template: string, head: Head): string;
|
|
427
|
+
mergeAttributes(existing: string, attrs: Record<string, string>): string;
|
|
428
|
+
parseAttributes(attrStr: string): Record<string, string>;
|
|
429
|
+
escapeHtml(str: string): string;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
declare class BrowserHeadProvider {
|
|
433
|
+
renderHead(document: Document, head: Head): void;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
interface BrowserRoute extends Route {
|
|
437
|
+
page: PageRoute;
|
|
438
|
+
}
|
|
439
|
+
declare class BrowserRouterProvider extends RouterProvider<BrowserRoute> {
|
|
440
|
+
protected readonly log: _alepha_core.Logger;
|
|
441
|
+
protected readonly alepha: Alepha;
|
|
442
|
+
protected readonly pageDescriptorProvider: PageDescriptorProvider;
|
|
443
|
+
add(entry: PageRouteEntry): void;
|
|
444
|
+
protected readonly configure: _alepha_core.HookDescriptor<"configure">;
|
|
445
|
+
transition(url: URL, options?: TransitionOptions): Promise<RouterRenderResult>;
|
|
446
|
+
root(state: RouterState, context: PageReactContext): ReactNode;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
declare class ReactBrowserProvider {
|
|
450
|
+
protected readonly log: _alepha_core.Logger;
|
|
451
|
+
protected readonly client: HttpClient;
|
|
452
|
+
protected readonly alepha: Alepha;
|
|
453
|
+
protected readonly router: BrowserRouterProvider;
|
|
454
|
+
protected readonly headProvider: BrowserHeadProvider;
|
|
455
|
+
protected root: Root;
|
|
456
|
+
transitioning?: {
|
|
457
|
+
to: string;
|
|
458
|
+
};
|
|
459
|
+
state: RouterState;
|
|
460
|
+
get document(): Document;
|
|
461
|
+
get history(): History;
|
|
462
|
+
get url(): string;
|
|
463
|
+
invalidate(props?: Record<string, any>): Promise<void>;
|
|
464
|
+
go(url: string, options?: RouterGoOptions): Promise<void>;
|
|
465
|
+
protected render(options?: {
|
|
466
|
+
url?: string;
|
|
467
|
+
previous?: PreviousLayerData[];
|
|
468
|
+
}): Promise<RouterRenderResult>;
|
|
469
|
+
/**
|
|
470
|
+
* Get embedded layers from the server.
|
|
471
|
+
*/
|
|
472
|
+
protected getHydrationState(): ReactHydrationState | undefined;
|
|
473
|
+
readonly ready: _alepha_core.HookDescriptor<"ready">;
|
|
474
|
+
readonly onTransitionEnd: _alepha_core.HookDescriptor<"react:transition:end">;
|
|
475
|
+
}
|
|
476
|
+
interface RouterGoOptions {
|
|
477
|
+
replace?: boolean;
|
|
478
|
+
match?: TransitionOptions;
|
|
479
|
+
params?: Record<string, string>;
|
|
480
|
+
}
|
|
481
|
+
interface ReactHydrationState {
|
|
482
|
+
layers?: Array<PreviousLayerData>;
|
|
483
|
+
links?: ApiLinksResponse;
|
|
484
|
+
}
|
|
485
|
+
|
|
454
486
|
interface NestedViewProps {
|
|
455
487
|
children?: ReactNode;
|
|
456
488
|
}
|
|
457
489
|
/**
|
|
458
|
-
*
|
|
490
|
+
* A component that renders the current view of the nested router layer.
|
|
491
|
+
*
|
|
492
|
+
* To be simple, it renders the `element` of the current child page of a parent page.
|
|
493
|
+
*
|
|
494
|
+
* @example
|
|
495
|
+
* ```tsx
|
|
496
|
+
* import { NestedView } from "@alepha/react";
|
|
459
497
|
*
|
|
460
|
-
*
|
|
461
|
-
*
|
|
498
|
+
* class App {
|
|
499
|
+
* parent = $page({
|
|
500
|
+
* component: () => <NestedView />,
|
|
501
|
+
* });
|
|
502
|
+
*
|
|
503
|
+
* child = $page({
|
|
504
|
+
* parent: this.root,
|
|
505
|
+
* component: () => <div>Child Page</div>,
|
|
506
|
+
* });
|
|
507
|
+
* }
|
|
508
|
+
* ```
|
|
462
509
|
*/
|
|
463
510
|
declare const NestedView: (props: NestedViewProps) => react_jsx_runtime.JSX.Element;
|
|
464
511
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
512
|
+
declare class RouterHookApi {
|
|
513
|
+
private readonly pages;
|
|
514
|
+
private readonly state;
|
|
515
|
+
private readonly layer;
|
|
516
|
+
private readonly browser?;
|
|
517
|
+
constructor(pages: PageRoute[], state: RouterState, layer: {
|
|
518
|
+
path: string;
|
|
519
|
+
}, browser?: ReactBrowserProvider | undefined);
|
|
520
|
+
get current(): RouterState;
|
|
521
|
+
get pathname(): string;
|
|
522
|
+
get query(): Record<string, string>;
|
|
523
|
+
back(): Promise<void>;
|
|
524
|
+
forward(): Promise<void>;
|
|
525
|
+
invalidate(props?: Record<string, any>): Promise<void>;
|
|
526
|
+
/**
|
|
527
|
+
* Create a valid href for the given pathname.
|
|
528
|
+
*
|
|
529
|
+
* @param pathname
|
|
530
|
+
* @param layer
|
|
531
|
+
*/
|
|
532
|
+
createHref(pathname: HrefLike, layer?: {
|
|
533
|
+
path: string;
|
|
534
|
+
}, options?: {
|
|
535
|
+
params?: Record<string, any>;
|
|
536
|
+
}): string;
|
|
537
|
+
go(path: string, options?: RouterGoOptions): Promise<void>;
|
|
538
|
+
go<T extends object>(path: keyof VirtualRouter<T>, options?: RouterGoOptions): Promise<void>;
|
|
539
|
+
anchor(path: string, options?: {
|
|
540
|
+
params?: Record<string, any>;
|
|
541
|
+
}): AnchorProps;
|
|
542
|
+
anchor<T extends object>(path: keyof VirtualRouter<T>, options?: {
|
|
543
|
+
params?: Record<string, any>;
|
|
544
|
+
}): AnchorProps;
|
|
545
|
+
/**
|
|
546
|
+
* Set query params.
|
|
547
|
+
*
|
|
548
|
+
* @param record
|
|
549
|
+
* @param options
|
|
550
|
+
*/
|
|
551
|
+
setQueryParams(record: Record<string, any> | ((queryParams: Record<string, any>) => Record<string, any>), options?: {
|
|
552
|
+
/**
|
|
553
|
+
* If true, this will add a new entry to the history stack.
|
|
554
|
+
*/
|
|
555
|
+
push?: boolean;
|
|
556
|
+
}): void;
|
|
557
|
+
}
|
|
558
|
+
type HrefLike = string | {
|
|
559
|
+
options: {
|
|
560
|
+
path?: string;
|
|
561
|
+
name?: string;
|
|
562
|
+
};
|
|
563
|
+
};
|
|
564
|
+
type VirtualRouter<T> = {
|
|
565
|
+
[K in keyof T as T[K] extends PageDescriptor ? K : never]: T[K];
|
|
566
|
+
};
|
|
567
|
+
|
|
568
|
+
declare class RedirectionError extends Error {
|
|
569
|
+
readonly page: HrefLike;
|
|
570
|
+
constructor(page: HrefLike);
|
|
468
571
|
}
|
|
469
|
-
declare const Link: (props: LinkProps) => react_jsx_runtime.JSX.Element | null;
|
|
470
572
|
|
|
471
573
|
/**
|
|
472
574
|
* Props for the ErrorBoundary component.
|
|
@@ -507,6 +609,12 @@ declare class ErrorBoundary extends React__default.Component<PropsWithChildren<E
|
|
|
507
609
|
render(): ReactNode;
|
|
508
610
|
}
|
|
509
611
|
|
|
612
|
+
interface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
613
|
+
to: string | PageDescriptor;
|
|
614
|
+
children?: React__default.ReactNode;
|
|
615
|
+
}
|
|
616
|
+
declare const Link: (props: LinkProps) => react_jsx_runtime.JSX.Element | null;
|
|
617
|
+
|
|
510
618
|
interface RouterContextValue {
|
|
511
619
|
alepha: Alepha;
|
|
512
620
|
state: RouterState;
|
|
@@ -520,10 +628,19 @@ interface RouterLayerContextValue {
|
|
|
520
628
|
}
|
|
521
629
|
declare const RouterLayerContext: React.Context<RouterLayerContextValue | undefined>;
|
|
522
630
|
|
|
523
|
-
declare const
|
|
631
|
+
declare const useActive: (path: HrefLike) => UseActiveHook;
|
|
632
|
+
interface UseActiveHook {
|
|
633
|
+
isActive: boolean;
|
|
634
|
+
anchorProps: AnchorProps;
|
|
635
|
+
isPending: boolean;
|
|
636
|
+
name?: string;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
declare const useAlepha: () => Alepha;
|
|
640
|
+
|
|
641
|
+
declare const useClient: <T extends object>(_scope?: ClientScope) => HttpVirtualClient<T>;
|
|
524
642
|
|
|
525
|
-
declare const
|
|
526
|
-
declare const useApi: <T extends object>() => _alepha_server.HttpVirtualClient<T>;
|
|
643
|
+
declare const useInject: <T extends object>(clazz: Service<T>) => T;
|
|
527
644
|
|
|
528
645
|
interface UseQueryParamsHookOptions {
|
|
529
646
|
format?: "base64" | "querystring";
|
|
@@ -549,23 +666,10 @@ declare const useRouterEvents: (opts?: {
|
|
|
549
666
|
|
|
550
667
|
declare const useRouterState: () => RouterState;
|
|
551
668
|
|
|
552
|
-
declare const useActive: (path: HrefLike) => UseActiveHook;
|
|
553
|
-
interface UseActiveHook {
|
|
554
|
-
isActive: boolean;
|
|
555
|
-
anchorProps: AnchorProps;
|
|
556
|
-
isPending: boolean;
|
|
557
|
-
name?: string;
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
declare class RedirectionError extends Error {
|
|
561
|
-
readonly page: HrefLike;
|
|
562
|
-
constructor(page: HrefLike);
|
|
563
|
-
}
|
|
564
|
-
|
|
565
669
|
declare const envSchema: TObject<{
|
|
566
670
|
REACT_SERVER_DIST: TString;
|
|
567
671
|
REACT_SERVER_PREFIX: TString;
|
|
568
|
-
REACT_SSR_ENABLED: TBoolean
|
|
672
|
+
REACT_SSR_ENABLED: TOptional<TBoolean>;
|
|
569
673
|
REACT_ROOT_ID: TString;
|
|
570
674
|
}>;
|
|
571
675
|
declare module "@alepha/core" {
|
|
@@ -583,30 +687,37 @@ declare class ReactServerProvider {
|
|
|
583
687
|
protected readonly serverStaticProvider: ServerStaticProvider;
|
|
584
688
|
protected readonly serverRouterProvider: ServerRouterProvider;
|
|
585
689
|
protected readonly headProvider: ServerHeadProvider;
|
|
690
|
+
protected readonly serverTimingProvider: ServerTimingProvider;
|
|
586
691
|
protected readonly env: {
|
|
587
|
-
|
|
692
|
+
REACT_SSR_ENABLED?: boolean | undefined;
|
|
588
693
|
REACT_SERVER_DIST: string;
|
|
589
694
|
REACT_SERVER_PREFIX: string;
|
|
590
|
-
|
|
695
|
+
REACT_ROOT_ID: string;
|
|
591
696
|
};
|
|
592
697
|
protected readonly ROOT_DIV_REGEX: RegExp;
|
|
593
|
-
|
|
594
|
-
|
|
698
|
+
readonly onConfigure: _alepha_core.HookDescriptor<"configure">;
|
|
699
|
+
get template(): string | undefined;
|
|
700
|
+
protected registerPages(templateLoader: TemplateLoader): Promise<void>;
|
|
595
701
|
protected getPublicDirectory(): string;
|
|
596
702
|
protected configureStaticServer(root: string): Promise<void>;
|
|
597
|
-
protected configureVite(): Promise<void>;
|
|
703
|
+
protected configureVite(ssrEnabled: boolean): Promise<void>;
|
|
598
704
|
/**
|
|
599
705
|
* For testing purposes, creates a render function that can be used.
|
|
600
706
|
*/
|
|
601
|
-
protected createRenderFunction(name: string): (options?: {
|
|
707
|
+
protected createRenderFunction(name: string, withIndex?: boolean): (options?: {
|
|
602
708
|
params?: Record<string, string>;
|
|
603
709
|
query?: Record<string, string>;
|
|
604
|
-
}) => Promise<
|
|
605
|
-
|
|
606
|
-
|
|
710
|
+
}) => Promise<{
|
|
711
|
+
context: PageRequest;
|
|
712
|
+
html: string;
|
|
713
|
+
}>;
|
|
714
|
+
protected createHandler(page: PageRoute, templateLoader: TemplateLoader): ServerHandler;
|
|
715
|
+
renderToHtml(template: string, state: RouterState, context: PageReactContext): string;
|
|
716
|
+
protected fillTemplate(response: {
|
|
607
717
|
html: string;
|
|
608
718
|
}, app: string, script: string): void;
|
|
609
719
|
}
|
|
720
|
+
type TemplateLoader = () => Promise<string | undefined>;
|
|
610
721
|
|
|
611
722
|
declare module "@alepha/core" {
|
|
612
723
|
interface Hooks {
|
|
@@ -642,4 +753,4 @@ declare class ReactModule {
|
|
|
642
753
|
constructor();
|
|
643
754
|
}
|
|
644
755
|
|
|
645
|
-
export { $page, type AnchorProps, type CreateLayersResult, ErrorBoundary, type Head, type HrefLike, type Layer, Link, NestedView, type PageConfigSchema, type PageDescriptor, type PageDescriptorOptions, PageDescriptorProvider, type PageReactContext, type PageRequest, type PageRequestConfig, type PageResolve, type PageRoute, type PageRouteEntry, type PreviousLayerData, ReactBrowserProvider, type ReactHydrationState, ReactModule, ReactServerProvider, RedirectionError, RouterContext, type RouterContextValue, type RouterGoOptions, RouterHookApi, RouterLayerContext, type RouterLayerContextValue, type RouterRenderResult, type RouterStackItem, type RouterState, type TPropsDefault, type TPropsParentDefault, type TransitionOptions, type UseActiveHook, type UseQueryParamsHookOptions, type VirtualRouter, envSchema, isPageRoute, useActive,
|
|
756
|
+
export { $page, type AnchorProps, ClientOnly, type CreateLayersResult, ErrorBoundary, type Head$1 as Head, type HrefLike, type Layer, Link, NestedView, type PageConfigSchema, type PageDescriptor, type PageDescriptorOptions, PageDescriptorProvider, type PageDescriptorRenderOptions, type PageDescriptorRenderResult, type PageReactContext, type PageRequest, type PageRequestConfig, type PageResolve, type PageRoute, type PageRouteEntry, type PreviousLayerData, ReactBrowserProvider, type ReactHydrationState, ReactModule, ReactServerProvider, RedirectionError, RouterContext, type RouterContextValue, type RouterGoOptions, RouterHookApi, RouterLayerContext, type RouterLayerContextValue, type RouterRenderResult, type RouterStackItem, type RouterState, type TPropsDefault, type TPropsParentDefault, type TransitionOptions, type UseActiveHook, type UseQueryParamsHookOptions, type VirtualRouter, envSchema, isPageRoute, useActive, useAlepha, useClient, useInject, useQueryParams, useRouter, useRouterEvents, useRouterState };
|