@kasperrt/smolter 0.4.2 → 0.4.3
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/.generated/core/environment.ts +1 -0
- package/.generated/core/navigation.ts +1 -0
- package/.generated/core/resource-types.ts +4 -0
- package/.generated/core/resources.ts +2 -0
- package/.generated/core/responses.ts +12 -0
- package/.generated/core/utils.ts +5 -2
- package/.generated/preact/await.tsx +1 -0
- package/.generated/preact/client.tsx +7 -1
- package/.generated/preact/document.tsx +10 -0
- package/.generated/preact/index.ts +6 -2
- package/.generated/preact/lazy-route.ts +7 -0
- package/.generated/preact/navigation.tsx +6 -0
- package/.generated/preact/route-hooks.tsx +12 -2
- package/.generated/preact/route-types.ts +14 -0
- package/.generated/preact/router.tsx +3 -0
- package/.generated/react/data.ts +5 -1
- package/.generated/react/index.ts +11 -1
- package/.generated/react/outlet.ts +48 -0
- package/.generated/react/resources/components.tsx +12 -0
- package/.generated/server/application.tsx +3 -0
- package/.generated/server/assets.ts +7 -0
- package/.generated/server/handler.ts +3 -0
- package/.generated/server/http.ts +2 -0
- package/.generated/server/node.ts +5 -2
- package/.generated/server/preact.ts +5 -2
- package/CHANGELOG.md +10 -0
- package/README.md +16 -16
- package/dist/core/environment.d.ts +1 -0
- package/dist/core/navigation.d.ts +1 -0
- package/dist/core/resource-types.d.ts +4 -0
- package/dist/core/resources.d.ts +2 -0
- package/dist/core/resources.js +2 -0
- package/dist/core/responses.d.ts +12 -0
- package/dist/core/responses.js +5 -0
- package/dist/core/utils.d.ts +5 -2
- package/dist/core/utils.js +1 -2
- package/dist/preact/await.d.ts +1 -0
- package/dist/preact/await.js +1 -0
- package/dist/preact/client.d.ts +7 -1
- package/dist/preact/client.js +6 -1
- package/dist/preact/document.d.ts +10 -0
- package/dist/preact/document.js +9 -0
- package/dist/preact/index.d.ts +6 -2
- package/dist/preact/lazy-route.d.ts +2 -0
- package/dist/preact/lazy-route.js +6 -0
- package/dist/preact/navigation.d.ts +6 -0
- package/dist/preact/navigation.js +2 -0
- package/dist/preact/route-hooks.d.ts +10 -0
- package/dist/preact/route-hooks.js +12 -2
- package/dist/preact/route-types.d.ts +14 -0
- package/dist/preact/router.d.ts +3 -0
- package/dist/preact/router.js +2 -0
- package/dist/react/data.d.ts +5 -1
- package/dist/react/index.d.ts +6 -1
- package/dist/react/index.js +2 -1
- package/dist/react/outlet.d.ts +16 -0
- package/dist/react/outlet.js +26 -0
- package/dist/react/resources/components.d.ts +12 -0
- package/dist/react/resources/components.js +11 -0
- package/dist/server/application.d.ts +3 -0
- package/dist/server/application.js +2 -0
- package/dist/server/assets.d.ts +2 -0
- package/dist/server/assets.js +6 -0
- package/dist/server/handler.d.ts +3 -0
- package/dist/server/http.d.ts +2 -0
- package/dist/server/http.js +2 -0
- package/dist/server/node.d.ts +5 -1
- package/dist/server/preact.d.ts +5 -1
- package/jsr.json +1 -1
- package/package.json +6 -5
|
@@ -6,6 +6,7 @@ import { pendingLocation } from "../core/presentation.js";
|
|
|
6
6
|
import { useNavigationSnapshot } from "./navigation-state.js";
|
|
7
7
|
import { useCallback } from "preact/hooks";
|
|
8
8
|
//#region .generated/preact/route-hooks.tsx
|
|
9
|
+
/** Read root loader data from the application context. */
|
|
9
10
|
function useRootData() {
|
|
10
11
|
return useApplication().root;
|
|
11
12
|
}
|
|
@@ -18,9 +19,11 @@ function useRouteLoaderData(id) {
|
|
|
18
19
|
if (!route || route.path !== snapshot.path) return void 0;
|
|
19
20
|
return snapshot.data;
|
|
20
21
|
}
|
|
22
|
+
/** Read the current route error for an error boundary. */
|
|
21
23
|
function useRouteError() {
|
|
22
24
|
return useSnapshot("error");
|
|
23
25
|
}
|
|
26
|
+
/** Read the current page navigation or submission state. */
|
|
24
27
|
function useNavigation() {
|
|
25
28
|
const router = useRouter();
|
|
26
29
|
const snapshot = useSnapshot();
|
|
@@ -30,18 +33,21 @@ function useNavigation() {
|
|
|
30
33
|
location
|
|
31
34
|
}), [snapshot.state, location?.href]);
|
|
32
35
|
}
|
|
36
|
+
/** Read the active flat route match and loader data; this is not a nested layout match chain. */
|
|
33
37
|
function useMatches() {
|
|
34
|
-
const
|
|
38
|
+
const router = useRouter();
|
|
35
39
|
const snapshot = useSnapshot();
|
|
36
40
|
return [{
|
|
37
|
-
id: routes.find((item) => item.path === snapshot.path)?.id ?? "",
|
|
41
|
+
id: router.routes.find((item) => item.path === snapshot.path)?.id ?? "",
|
|
38
42
|
data: snapshot.data,
|
|
39
43
|
params: snapshot.params
|
|
40
44
|
}];
|
|
41
45
|
}
|
|
46
|
+
/** Read context supplied by the nearest Outlet. */
|
|
42
47
|
function useOutletContext() {
|
|
43
48
|
return useContext(OutletContext);
|
|
44
49
|
}
|
|
50
|
+
/** Return a function that submits form data through the current router. */
|
|
45
51
|
function useSubmit() {
|
|
46
52
|
const router = useRouter();
|
|
47
53
|
return useCallback((value, options = {}) => {
|
|
@@ -56,6 +62,7 @@ function useSubmit() {
|
|
|
56
62
|
return router.submit(target, body, { method });
|
|
57
63
|
}, [router]);
|
|
58
64
|
}
|
|
65
|
+
/** Read the current router location as a URL. */
|
|
59
66
|
function useURLLocation() {
|
|
60
67
|
const href = useSnapshot("url");
|
|
61
68
|
const snapshot = useNavigationSnapshot(useRouter());
|
|
@@ -68,6 +75,7 @@ function useURLLocation() {
|
|
|
68
75
|
snapshot.key
|
|
69
76
|
]);
|
|
70
77
|
}
|
|
78
|
+
/** Return the application navigation function, including history offsets and relative destinations. */
|
|
71
79
|
function useNavigate() {
|
|
72
80
|
const router = useRouter();
|
|
73
81
|
return useCallback((to, options) => {
|
|
@@ -80,6 +88,7 @@ function useNavigate() {
|
|
|
80
88
|
router.navigate(target, options);
|
|
81
89
|
}, [router]);
|
|
82
90
|
}
|
|
91
|
+
/** Read URL search parameters and update them through router navigation. */
|
|
83
92
|
function useSearchParams() {
|
|
84
93
|
const location = useURLLocation();
|
|
85
94
|
const navigate = useNavigate();
|
|
@@ -87,6 +96,7 @@ function useSearchParams() {
|
|
|
87
96
|
navigate(`${location.pathname}?${new URLSearchParams(value)}`, options);
|
|
88
97
|
}, [location.pathname, navigate])];
|
|
89
98
|
}
|
|
99
|
+
/** Read the last browser history operation. */
|
|
90
100
|
function useNavigationType() {
|
|
91
101
|
return useNavigationSnapshot(useRouter()).type;
|
|
92
102
|
}
|
|
@@ -1,20 +1,28 @@
|
|
|
1
1
|
import type { DataArgs, RevalidationArgs, Route, Snapshot } from "../core/index.ts";
|
|
2
2
|
import type { DataResponse } from "../core/responses.ts";
|
|
3
3
|
import type { ComponentType, ReactNode } from "preact/compat";
|
|
4
|
+
/** Request, route parameters and cancellation signal supplied to a loader. */
|
|
4
5
|
export interface LoaderFunctionArgs extends DataArgs {
|
|
5
6
|
context?: unknown;
|
|
6
7
|
}
|
|
8
|
+
/** Request, route parameters and cancellation signal supplied to an action. */
|
|
7
9
|
export type ActionFunctionArgs = LoaderFunctionArgs;
|
|
10
|
+
/** Loader arguments with a serverLoader callback for the server transport. */
|
|
8
11
|
export interface ClientLoaderFunctionArgs extends LoaderFunctionArgs {
|
|
9
12
|
serverLoader: <T = unknown>() => Promise<T>;
|
|
10
13
|
}
|
|
14
|
+
/** Action arguments with a serverAction callback for the server transport. */
|
|
11
15
|
export interface ClientActionFunctionArgs extends LoaderFunctionArgs {
|
|
12
16
|
serverAction: <T = unknown>() => Promise<T>;
|
|
13
17
|
}
|
|
18
|
+
/** Navigation or mutation context used to decide whether loader data should refresh. */
|
|
14
19
|
export type ShouldRevalidateFunctionArgs = RevalidationArgs;
|
|
15
20
|
type UnwrapData<T> = T extends DataResponse<infer V> ? V : T;
|
|
21
|
+
/** Infer successful loader data, unwrapping promises and data responses. */
|
|
16
22
|
export type RouteData<T> = T extends (...args: never[]) => infer R ? UnwrapData<Exclude<Awaited<R>, Response | Error>> : T;
|
|
23
|
+
/** A document metadata descriptor, such as a title, meta tag or structured-data record. */
|
|
17
24
|
export type MetaDescriptor = Record<string, unknown>;
|
|
25
|
+
/** Loader data, error, parameters and location supplied to a route metadata function. */
|
|
18
26
|
export interface MetaArgs<T> {
|
|
19
27
|
data: RouteData<T> | undefined;
|
|
20
28
|
loaderData: RouteData<T> | undefined;
|
|
@@ -22,8 +30,11 @@ export interface MetaArgs<T> {
|
|
|
22
30
|
params: Record<string, string>;
|
|
23
31
|
location: URL;
|
|
24
32
|
}
|
|
33
|
+
/** Derive document metadata descriptors from the current route data and location. */
|
|
25
34
|
export type MetaFunction<T = unknown> = (args: MetaArgs<T>) => MetaDescriptor[];
|
|
35
|
+
/** Return link descriptors rendered in the document head. */
|
|
26
36
|
export type LinksFunction = () => Record<string, string>[];
|
|
37
|
+
/** Data route with optional lazy component, preload and document metadata integration. */
|
|
27
38
|
export interface AppRoute extends Route {
|
|
28
39
|
resolveComponent?: () => ComponentType | undefined;
|
|
29
40
|
preload?: () => Promise<void>;
|
|
@@ -31,6 +42,7 @@ export interface AppRoute extends Route {
|
|
|
31
42
|
routePath?: string;
|
|
32
43
|
meta?: MetaFunction;
|
|
33
44
|
}
|
|
45
|
+
/** Root document components, loader, metadata and revalidation policy for a Preact application. */
|
|
34
46
|
export interface RootModule {
|
|
35
47
|
/** Route identity used by targeted revalidation. Defaults to root. */
|
|
36
48
|
id?: string;
|
|
@@ -46,10 +58,12 @@ export interface RootModule {
|
|
|
46
58
|
meta?: MetaFunction;
|
|
47
59
|
shouldRevalidate?: (args: RevalidationArgs) => boolean;
|
|
48
60
|
}
|
|
61
|
+
/** Serialized root data and route snapshot used to hydrate without repeating initial loaders. */
|
|
49
62
|
export interface Hydration {
|
|
50
63
|
rootError?: boolean;
|
|
51
64
|
root: unknown;
|
|
52
65
|
snapshot: Snapshot;
|
|
53
66
|
}
|
|
67
|
+
/** Transform a data transport response using the current request context. */
|
|
54
68
|
export type HandleDataRequestFunction = (response: Response, args: LoaderFunctionArgs) => Response | Promise<Response>;
|
|
55
69
|
export {};
|
package/dist/preact/router.d.ts
CHANGED
|
@@ -3,14 +3,17 @@ import type { ReactNode } from "preact/compat";
|
|
|
3
3
|
import { type ApplicationContext } from "./root-context.ts";
|
|
4
4
|
import { createRootStore } from "./root-data.ts";
|
|
5
5
|
import type { AppRoute } from "./route-types.ts";
|
|
6
|
+
/** Optional children and context shared with descendants through useOutletContext. */
|
|
6
7
|
export interface OutletProps {
|
|
7
8
|
context?: unknown;
|
|
8
9
|
children?: ReactNode;
|
|
9
10
|
}
|
|
11
|
+
/** Render supplied children or the active route, and provide outlet context to descendants. */
|
|
10
12
|
export declare function Outlet({ context, children, }: OutletProps): import("preact").JSX.Element;
|
|
11
13
|
export interface ApplicationProps extends ApplicationContext {
|
|
12
14
|
document?: boolean;
|
|
13
15
|
rootStore?: ReturnType<typeof createRootStore>;
|
|
14
16
|
}
|
|
17
|
+
/** Render a Preact root document and active route with shared root data and application context. */
|
|
15
18
|
export declare function RouterApplication(props: ApplicationProps): import("preact").JSX.Element;
|
|
16
19
|
export declare function prepareRoutes(routes: AppRoute[], preserveDeferred?: boolean): AppRoute[];
|
package/dist/preact/router.js
CHANGED
|
@@ -6,6 +6,7 @@ import { createStore } from "../core/store.js";
|
|
|
6
6
|
import { Routes } from "./routes.js";
|
|
7
7
|
import { jsx } from "preact/jsx-runtime";
|
|
8
8
|
//#region .generated/preact/router.tsx
|
|
9
|
+
/** Render supplied children or the active route, and provide outlet context to descendants. */
|
|
9
10
|
function Outlet({ context, children }) {
|
|
10
11
|
const current = useContext(OutletContext);
|
|
11
12
|
return /* @__PURE__ */ jsx(OutletContext, {
|
|
@@ -16,6 +17,7 @@ function Outlet({ context, children }) {
|
|
|
16
17
|
}) })
|
|
17
18
|
});
|
|
18
19
|
}
|
|
20
|
+
/** Render a Preact root document and active route with shared root data and application context. */
|
|
19
21
|
function RouterApplication(props) {
|
|
20
22
|
const rootStore = useMemo(() => props.rootStore ?? createStore(props.root), [props.rootStore, props.root]);
|
|
21
23
|
const root = useSyncExternalStore(rootStore.subscribe, rootStore.getSnapshot);
|
package/dist/react/data.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* Independent React resource data, forms and subscriptions.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
2
6
|
export type { ActionFunctionArgs as ResourceActionArgs, DataResult as ResourceResult, LoaderFunctionArgs as ResourceLoaderArgs, ShouldRevalidateFunctionArgs as ResourceRevalidationArgs, } from "../core/resource-types.ts";
|
|
3
7
|
export { createResourceRouter, ResourceRouter, } from "../core/resources.ts";
|
|
4
8
|
export type { ResourceRouteModule } from "./resources/components.tsx";
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* React routing components, typed data hooks and forms.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
2
6
|
export type * from "../core/index.ts";
|
|
3
7
|
export { createDataRouter, createRouter, defineRoute, } from "../core/index.ts";
|
|
4
8
|
export { RouterProvider, type RouterProviderProps, useRouter, } from "./context.ts";
|
|
@@ -6,4 +10,5 @@ export * from "./fetcher.ts";
|
|
|
6
10
|
export * from "./form.ts";
|
|
7
11
|
export * from "./hooks.ts";
|
|
8
12
|
export * from "./link.ts";
|
|
13
|
+
export { Outlet, type OutletProps, useMatches, useOutletContext, } from "./outlet.ts";
|
|
9
14
|
export * from "./routes.ts";
|
package/dist/react/index.js
CHANGED
|
@@ -7,4 +7,5 @@ import { useFetcher } from "./fetcher.js";
|
|
|
7
7
|
import { useActionData, useLoaderData, useLocation, useParams, useRevalidator } from "./hooks.js";
|
|
8
8
|
import { Link } from "./link.js";
|
|
9
9
|
import { Routes } from "./routes.js";
|
|
10
|
-
|
|
10
|
+
import { Outlet, useMatches, useOutletContext } from "./outlet.js";
|
|
11
|
+
export { Form, Link, Outlet, RouterProvider, Routes, createDataRouter, createRouter, defineRoute, useActionData, useFetcher, useLoaderData, useLocation, useMatches, useOutletContext, useParams, useRevalidator, useRouter };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type ReactNode } from "./runtime.ts";
|
|
2
|
+
/** Optional children and context shared with descendants through useOutletContext. */
|
|
3
|
+
export interface OutletProps {
|
|
4
|
+
context?: unknown;
|
|
5
|
+
children?: ReactNode;
|
|
6
|
+
}
|
|
7
|
+
/** Render the active route under a layout's shared context. */
|
|
8
|
+
export declare function Outlet({ context, children }: OutletProps): ReactNode;
|
|
9
|
+
/** Read the nearest Outlet's context. */
|
|
10
|
+
export declare function useOutletContext<T>(): T;
|
|
11
|
+
/** Read the active flat route match; this is not a nested layout match chain. */
|
|
12
|
+
export declare function useMatches(): {
|
|
13
|
+
id: string;
|
|
14
|
+
data: unknown;
|
|
15
|
+
params: import("../core/index.ts").Params;
|
|
16
|
+
}[];
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { createContext, createElement, useContext } from "./runtime.js";
|
|
2
|
+
import { useRouter, useSnapshot } from "./context.js";
|
|
3
|
+
import { Routes } from "./routes.js";
|
|
4
|
+
//#region .generated/react/outlet.ts
|
|
5
|
+
var OutletContext = createContext(void 0);
|
|
6
|
+
/** Render the active route under a layout's shared context. */
|
|
7
|
+
function Outlet({ context, children }) {
|
|
8
|
+
const inherited = useContext(OutletContext);
|
|
9
|
+
return createElement(OutletContext.Provider, { value: context ?? inherited }, children ?? createElement(Routes, { fallback: createElement("p", { role: "status" }, "Loading…") }));
|
|
10
|
+
}
|
|
11
|
+
/** Read the nearest Outlet's context. */
|
|
12
|
+
function useOutletContext() {
|
|
13
|
+
return useContext(OutletContext);
|
|
14
|
+
}
|
|
15
|
+
/** Read the active flat route match; this is not a nested layout match chain. */
|
|
16
|
+
function useMatches() {
|
|
17
|
+
const router = useRouter();
|
|
18
|
+
const snapshot = useSnapshot();
|
|
19
|
+
return [{
|
|
20
|
+
id: router.routes.find((item) => item.path === snapshot.path)?.id ?? "",
|
|
21
|
+
data: snapshot.data,
|
|
22
|
+
params: snapshot.params
|
|
23
|
+
}];
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
export { Outlet, useMatches, useOutletContext };
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import type { DataResult, NavigationState, Params, ResourceModule, RouteState } from "../../core/resource-types.ts";
|
|
3
3
|
import type { ResourceRouter } from "../../core/resources.ts";
|
|
4
4
|
import { type ComponentType, type PropsWithChildren } from "react";
|
|
5
|
+
/** Resource handlers with optional React content, pending UI and retry boundary. */
|
|
5
6
|
export interface ResourceRouteModule extends ResourceModule {
|
|
6
7
|
default?: ComponentType;
|
|
7
8
|
ErrorBoundary?: ComponentType<{
|
|
@@ -16,19 +17,26 @@ interface RouterProviderProps extends PropsWithChildren {
|
|
|
16
17
|
}[];
|
|
17
18
|
router: ResourceRouter;
|
|
18
19
|
}
|
|
20
|
+
/** Provide a resource router and load initial matches; dispose it when unmounted. */
|
|
19
21
|
export declare function RouterProvider({ children, initialMatches, router, }: RouterProviderProps): import("react").JSX.Element;
|
|
20
22
|
interface RouteProps extends PropsWithChildren {
|
|
21
23
|
params?: Params;
|
|
22
24
|
persistent?: boolean;
|
|
23
25
|
routeId: string;
|
|
24
26
|
}
|
|
27
|
+
/** Provide a resource route and render its content, loading state or retry boundary. */
|
|
25
28
|
export declare function Route({ children, params, persistent, routeId, }: RouteProps): import("react").JSX.Element;
|
|
29
|
+
/** Read the current resource route loader result. */
|
|
26
30
|
export declare function useLoaderData<Data>(): Data | null;
|
|
31
|
+
/** Read loader data for a registered resource route. */
|
|
27
32
|
export declare function useRouteLoaderData<Data>(routeId: string, params?: Params): Data | null;
|
|
33
|
+
/** Read the current resource route action result. */
|
|
28
34
|
export declare function useActionData<Data>(): Data | null;
|
|
35
|
+
/** Read the current page navigation or submission state. */
|
|
29
36
|
export declare function useNavigation(): {
|
|
30
37
|
state: NavigationState;
|
|
31
38
|
};
|
|
39
|
+
/** Return the resource route revalidation function. */
|
|
32
40
|
export declare function useRevalidator(): {
|
|
33
41
|
revalidate: () => Promise<DataResult<unknown>>;
|
|
34
42
|
state: string;
|
|
@@ -46,8 +54,11 @@ interface FormProps extends PropsWithChildren {
|
|
|
46
54
|
input?: unknown;
|
|
47
55
|
params?: Params;
|
|
48
56
|
}
|
|
57
|
+
/** Submit a resource action from a form without document navigation. */
|
|
49
58
|
export declare function Form({ action, children, input, params, }: FormProps): import("react").JSX.Element;
|
|
59
|
+
/** Return a function that submits form data through the current router. */
|
|
50
60
|
export declare function useSubmit(): (input?: unknown) => Promise<DataResult<unknown>>;
|
|
61
|
+
/** Read or mutate a resource independently of the rendered route. */
|
|
51
62
|
export declare function useFetcher<Data = unknown>(options?: FetcherOptions): readonly [
|
|
52
63
|
{
|
|
53
64
|
data: Data | null;
|
|
@@ -60,5 +71,6 @@ export declare function useFetcher<Data = unknown>(options?: FetcherOptions): re
|
|
|
60
71
|
submit: (input: unknown, target?: FetcherTarget) => Promise<DataResult<Data>>;
|
|
61
72
|
}
|
|
62
73
|
];
|
|
74
|
+
/** Read the resource router supplied by its provider. */
|
|
63
75
|
export declare function useRouter(): ResourceRouter;
|
|
64
76
|
export type { NavigationState, RouteState };
|
|
@@ -4,6 +4,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
4
4
|
var RouterContext = createContext(null);
|
|
5
5
|
var RouteContext = createContext(null);
|
|
6
6
|
var FormContext = createContext(null);
|
|
7
|
+
/** Provide a resource router and load initial matches; dispose it when unmounted. */
|
|
7
8
|
function RouterProvider({ children, initialMatches = EMPTY_MATCHES, router }) {
|
|
8
9
|
useEffect(() => {
|
|
9
10
|
for (const match of initialMatches) router.load(match.routeId, match.params ?? {});
|
|
@@ -14,6 +15,7 @@ function RouterProvider({ children, initialMatches = EMPTY_MATCHES, router }) {
|
|
|
14
15
|
children
|
|
15
16
|
});
|
|
16
17
|
}
|
|
18
|
+
/** Provide a resource route and render its content, loading state or retry boundary. */
|
|
17
19
|
function Route({ children, params = {}, persistent = false, routeId }) {
|
|
18
20
|
const router = useRouter();
|
|
19
21
|
const stableParams = useStableParams(params);
|
|
@@ -59,21 +61,26 @@ function Route({ children, params = {}, persistent = false, routeId }) {
|
|
|
59
61
|
})
|
|
60
62
|
});
|
|
61
63
|
}
|
|
64
|
+
/** Read the current resource route loader result. */
|
|
62
65
|
function useLoaderData() {
|
|
63
66
|
const route = useCurrentRoute();
|
|
64
67
|
return useRouteLoaderData(route.routeId, route.params);
|
|
65
68
|
}
|
|
69
|
+
/** Read loader data for a registered resource route. */
|
|
66
70
|
function useRouteLoaderData(routeId, params = {}) {
|
|
67
71
|
return useRouteState(routeId, useStableParams(params), true).loaderData;
|
|
68
72
|
}
|
|
73
|
+
/** Read the current resource route action result. */
|
|
69
74
|
function useActionData() {
|
|
70
75
|
const route = useCurrentRoute();
|
|
71
76
|
return useRouteState(route.routeId, route.params, false).actionData;
|
|
72
77
|
}
|
|
78
|
+
/** Read the current page navigation or submission state. */
|
|
73
79
|
function useNavigation() {
|
|
74
80
|
const route = useCurrentRoute();
|
|
75
81
|
return { state: useRouteState(route.routeId, route.params, false).navigationState };
|
|
76
82
|
}
|
|
83
|
+
/** Return the resource route revalidation function. */
|
|
77
84
|
function useRevalidator() {
|
|
78
85
|
const route = useCurrentRoute();
|
|
79
86
|
const router = useRouter();
|
|
@@ -87,6 +94,7 @@ function useRevalidator() {
|
|
|
87
94
|
state.navigationState
|
|
88
95
|
]);
|
|
89
96
|
}
|
|
97
|
+
/** Submit a resource action from a form without document navigation. */
|
|
90
98
|
function Form({ action, children, input, params }) {
|
|
91
99
|
const currentRoute = useContext(RouteContext);
|
|
92
100
|
const router = useRouter();
|
|
@@ -104,11 +112,13 @@ function Form({ action, children, input, params }) {
|
|
|
104
112
|
children
|
|
105
113
|
});
|
|
106
114
|
}
|
|
115
|
+
/** Return a function that submits form data through the current router. */
|
|
107
116
|
function useSubmit() {
|
|
108
117
|
const submit = useContext(FormContext);
|
|
109
118
|
if (!submit) throw new Error("useSubmit must be used inside Form.");
|
|
110
119
|
return submit;
|
|
111
120
|
}
|
|
121
|
+
/** Read or mutate a resource independently of the rendered route. */
|
|
112
122
|
function useFetcher(options = {}) {
|
|
113
123
|
const currentRoute = useContext(RouteContext);
|
|
114
124
|
const router = useRouter();
|
|
@@ -169,6 +179,7 @@ function useFetcher(options = {}) {
|
|
|
169
179
|
submit
|
|
170
180
|
])];
|
|
171
181
|
}
|
|
182
|
+
/** Read the resource router supplied by its provider. */
|
|
172
183
|
function useRouter() {
|
|
173
184
|
const router = useContext(RouterContext);
|
|
174
185
|
if (!router) throw new Error("RouterProvider is missing.");
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
/** @jsxImportSource preact */
|
|
2
2
|
import type { AppRoute, RootModule } from "../preact/route-types.ts";
|
|
3
|
+
/** SSR settings for CSP nonce and early deferred-data hydration. */
|
|
3
4
|
export interface RenderApplicationOptions {
|
|
4
5
|
nonce?: string;
|
|
5
6
|
earlyHydration?: boolean;
|
|
6
7
|
}
|
|
8
|
+
/** Render a Preact application response with root and route data, streaming deferred content when enabled. */
|
|
7
9
|
export declare function renderApplication(request: Request, routes: AppRoute[], rootModule: RootModule, entry: string, options?: RenderApplicationOptions): Promise<Response>;
|
|
10
|
+
/** Dispatch a normalized application URL to its route loader or action and return an HTTP response. */
|
|
8
11
|
export declare function dispatchRoute(request: Request, routes: AppRoute[], document?: boolean): Promise<Response>;
|
|
@@ -13,6 +13,7 @@ import { jsx } from "preact/jsx-runtime";
|
|
|
13
13
|
import { renderToReadableStream } from "preact-render-to-string/stream";
|
|
14
14
|
//#region .generated/server/application.tsx
|
|
15
15
|
/** @jsxImportSource preact */
|
|
16
|
+
/** Render a Preact application response with root and route data, streaming deferred content when enabled. */
|
|
16
17
|
async function renderApplication(request, routes, rootModule, entry, options = {}) {
|
|
17
18
|
routes = routes.map((route) => ({
|
|
18
19
|
...route,
|
|
@@ -160,6 +161,7 @@ async function dispatch(request, routes, document = false) {
|
|
|
160
161
|
}
|
|
161
162
|
return Response.json(await normalizeResult(value) ?? null);
|
|
162
163
|
}
|
|
164
|
+
/** Dispatch a normalized application URL to its route loader or action and return an HTTP response. */
|
|
163
165
|
async function dispatchRoute(request, routes, document = false) {
|
|
164
166
|
const response = await dispatch(request, routes, document);
|
|
165
167
|
return document ? response : privateResponse(response);
|
package/dist/server/assets.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
/** Emitted JavaScript and stylesheet URLs associated with a route. */
|
|
1
2
|
export interface RouteAssets {
|
|
2
3
|
path: string;
|
|
3
4
|
files: string[];
|
|
4
5
|
styles?: string[];
|
|
5
6
|
}
|
|
7
|
+
/** Collect matched-route JavaScript and stylesheet assets from the production route manifest. */
|
|
6
8
|
export declare function routePreloads(routes: RouteAssets[], pathname: string, base: string): string;
|
package/dist/server/assets.js
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { matchRoutes } from "../core/match.js";
|
|
2
2
|
//#region .generated/server/assets.ts
|
|
3
|
+
/**
|
|
4
|
+
* Production route asset discovery for SSR preload hints.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
/** Collect matched-route JavaScript and stylesheet assets from the production route manifest. */
|
|
3
9
|
function routePreloads(routes, pathname, base) {
|
|
4
10
|
const route = matchRoutes(routes, pathname)?.route;
|
|
5
11
|
const prefix = base.replace(/\/$/, "");
|
package/dist/server/handler.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export interface ServerBuild {
|
|
|
4
4
|
default: (request: Request, entry: string) => Response | Promise<Response>;
|
|
5
5
|
handleDataRequest: (request: Request) => Response | Promise<Response>;
|
|
6
6
|
}
|
|
7
|
+
/** SSR build, browser entry URL and application-scoped data endpoint for Node or Express. */
|
|
7
8
|
export interface RequestHandlerOptions {
|
|
8
9
|
build: ServerBuild;
|
|
9
10
|
/** Browser entry URL resolved from Vite's production manifest. */
|
|
@@ -11,11 +12,13 @@ export interface RequestHandlerOptions {
|
|
|
11
12
|
/** Must match the browser and Vite transport endpoint. */
|
|
12
13
|
dataEndpoint?: string;
|
|
13
14
|
}
|
|
15
|
+
/** Node request with optional Express protocol and original URL information. */
|
|
14
16
|
export interface ServerIncomingMessage extends IncomingMessage {
|
|
15
17
|
/** Express supplies this using the application's trust proxy policy. */
|
|
16
18
|
protocol?: string;
|
|
17
19
|
originalUrl?: string;
|
|
18
20
|
}
|
|
21
|
+
/** Express-compatible callback for forwarding middleware errors. */
|
|
19
22
|
export type NextHandler = (error?: unknown) => void;
|
|
20
23
|
/** Node/Express middleware; mount after metrics, tracing and static assets. */
|
|
21
24
|
export declare function createRequestHandler({ build, entry, dataEndpoint, }: RequestHandlerOptions): (incoming: ServerIncomingMessage, outgoing: ServerResponse, next: NextHandler) => Promise<void>;
|
package/dist/server/http.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { ServerResponse } from "node:http";
|
|
2
2
|
import type { ServerIncomingMessage } from "./handler.ts";
|
|
3
|
+
/** Convert a Node request to a Web Request with cancellation and an optional normalized route target. */
|
|
3
4
|
export declare function webRequest(incoming: ServerIncomingMessage, outgoing: ServerResponse, target?: string): Promise<Request>;
|
|
4
5
|
interface StreamingResponse extends ServerResponse {
|
|
5
6
|
flush?: () => void;
|
|
6
7
|
}
|
|
8
|
+
/** Write a Web Response to Node with streaming backpressure and disconnect cancellation. */
|
|
7
9
|
export declare function send(response: Response, outgoing: StreamingResponse): Promise<void>;
|
|
8
10
|
export {};
|
package/dist/server/http.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Readable, Transform } from "node:stream";
|
|
2
2
|
import { pipeline } from "node:stream/promises";
|
|
3
3
|
//#region .generated/server/http.ts
|
|
4
|
+
/** Convert a Node request to a Web Request with cancellation and an optional normalized route target. */
|
|
4
5
|
async function webRequest(incoming, outgoing, target) {
|
|
5
6
|
const origin = `${incoming.protocol ?? "http"}://${incoming.headers.host}`;
|
|
6
7
|
const headers = new Headers();
|
|
@@ -16,6 +17,7 @@ async function webRequest(incoming, outgoing, target) {
|
|
|
16
17
|
...incoming.method !== "GET" && incoming.method !== "HEAD" && { body: new Uint8Array(Buffer.concat(chunks)) }
|
|
17
18
|
});
|
|
18
19
|
}
|
|
20
|
+
/** Write a Web Response to Node with streaming backpressure and disconnect cancellation. */
|
|
19
21
|
async function send(response, outgoing) {
|
|
20
22
|
outgoing.statusCode = response.status;
|
|
21
23
|
response.headers.forEach((value, name) => {
|
package/dist/server/node.d.ts
CHANGED
package/dist/server/preact.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* Preact SSR rendering and route data dispatch.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
2
6
|
export { dispatchRoute, type RenderApplicationOptions, renderApplication, } from "./application.tsx";
|
|
3
7
|
export * from "./index.ts";
|
package/jsr.json
CHANGED
package/package.json
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"build:examples": "pnpm --filter \"@smolter/example-*\" build",
|
|
21
21
|
"smoke:production": "node scripts/production-smoke.mjs",
|
|
22
22
|
"jsr:check": "node scripts/jsr.mjs",
|
|
23
|
-
"build:site": "
|
|
23
|
+
"build:site": "pnpm --filter @smolter/example-preact build --mode hosted",
|
|
24
24
|
"smoke:site": "node scripts/site-smoke.mjs",
|
|
25
25
|
"docs:badges": "node scripts/readme-badges.mjs",
|
|
26
26
|
"docs:reference": "pnpm build && node scripts/docs-reference.mjs",
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"@smolter/preact": "workspace:*",
|
|
36
36
|
"@smolter/react": "workspace:*",
|
|
37
37
|
"@smolter/server": "workspace:*",
|
|
38
|
+
"@smolter/ui": "workspace:*",
|
|
38
39
|
"@smolter/vite": "workspace:*",
|
|
39
40
|
"@types/node": "24.10.1",
|
|
40
41
|
"@types/react": "19.3.0",
|
|
@@ -56,7 +57,7 @@
|
|
|
56
57
|
"wouter": "3.13.0",
|
|
57
58
|
"wouter-preact": "3.13.0"
|
|
58
59
|
},
|
|
59
|
-
"version": "0.4.
|
|
60
|
+
"version": "0.4.3",
|
|
60
61
|
"description": "A tiny typed data router for React and Preact.",
|
|
61
62
|
"sideEffects": false,
|
|
62
63
|
"license": "MIT",
|
|
@@ -135,10 +136,10 @@
|
|
|
135
136
|
"CHANGELOG.md"
|
|
136
137
|
],
|
|
137
138
|
"peerDependencies": {
|
|
138
|
-
"react": ">=18",
|
|
139
139
|
"preact": ">=11.0.1",
|
|
140
|
-
"
|
|
141
|
-
"
|
|
140
|
+
"preact-render-to-string": ">=6.8.1",
|
|
141
|
+
"react": ">=18",
|
|
142
|
+
"vite": ">=8"
|
|
142
143
|
},
|
|
143
144
|
"peerDependenciesMeta": {
|
|
144
145
|
"react": {
|