UNPKG

rakkasjs

Version:

Bleeding-edge React framework powered by Vite

771 lines (753 loc) 31.5 kB
import * as React from 'react'; import React__default, { ComponentType, ReactNode, ReactElement, AnchorHTMLAttributes, CSSProperties, FormEvent, FC, PropsWithChildren } from 'react'; import { ResolvedConfig } from 'vite'; import { RequestContext, RequestHandlerStack } from '@hattip/compose'; export { RequestContext, Locals as ServerSideLocals } from '@hattip/compose'; import * as _hattip_core from '@hattip/core'; /** An object for storing stuff local to your app */ interface PageLocals { } /** A page component default exported from a page module */ type Page<P = Record<string, string>, M = Record<string, unknown>> = ComponentType<PageProps<P, M>> & { /** Function to be called before rendering the page */ preload?: PreloadFunction<P, M>; }; /** A layout component default exported from a layout module. */ type Layout<P = Record<string, string>, M = Record<string, unknown>> = ComponentType<LayoutProps<P, M>> & { /** Function to be called before rendering the layout */ preload?: PreloadFunction<P, M>; }; /** Props passed to a page component */ interface PageProps<P = Record<string, string>, M = Record<string, unknown>> { /** Current URL */ url: URL; /** Route parameters */ params: P; /** Action data */ actionData?: any; /** Page meta data coming from the preload functions */ meta: M; } /** Props passed to a layout component */ interface LayoutProps<P = Record<string, string>, M = Record<string, unknown>> extends PageProps<P, M> { children: ReactNode; } /** Function to be called before each time loading a page or layout. * * Usage: * ``` * MyPageOrLayoutComponent.preload = (context: PreloadContext) => { * return { * meta: { * someKey: "Some metadata to be passed to the pages and layouts", * }, * head: <Head title="My Page Title" />, * }; * }; * ``` * You can also handle redirections by returning a * {@link PreloadResult.redirect redirect} prop. */ type PreloadFunction<P = Record<string, string>, M = Record<string, unknown>> = (context: PreloadContext<P>) => PreloadResult<M> | void | Promise<PreloadResult<M> | void>; /** Arguments passed to the action function */ interface ActionContext<P = Record<string, string>> extends PageContext { /** Route parameters */ params: P; /** Request context */ requestContext: RequestContext; } /** Arguments passed to the preload function */ interface PreloadContext<P = Record<string, string>> extends PageContext { /** Route parameters */ params: P; /** Action data */ actionData?: any; } /** * Arguments passed to server-side page functions like `headers`, * `prerender`, and `action` */ type ServerSidePageContext<P = Record<string, string>> = PreloadContext<P> & { requestContext: RequestContext; }; /** Return type of a preload function */ interface PreloadResult<M = Record<string, unknown>> { /** Metadata passed to page and layout components. */ meta?: Partial<M>; /** Head tags rendered for the page. Use the <Head /> component. */ head?: ReactNode; /** Redirection */ redirect?: RedirectProps; } interface PageRouteGuardContext<P = Record<string, string>> extends PageContext { /** Dynamic path parameters */ params: P; } /** Type for the default export of page guards */ type PageRouteGuard<P = Record<string, string>> = (ctx: PageRouteGuardContext<P>) => LookupHookResult; type ActionHandler = (pageContext: ActionContext) => ActionResult<any> | Promise<ActionResult<any>>; /** Function to set response headers */ type HeadersFunction<M = Record<string, unknown>> = (context: ServerSidePageContext, meta: M) => ResponseHeadersProps | Promise<ResponseHeadersProps>; /** Function to control static prerendering behavior */ type PrerenderFunction<M = Record<string, unknown>> = (context: ServerSidePageContext, meta: M) => PrerenderResult | Promise<PrerenderResult>; /** Return type of the prerender function */ interface PrerenderResult { /** Should this page be prerendered? Defaults to true */ shouldPrerender?: boolean; /** Should the prerenderer crawl this page? Defaults to the value of prerender */ shouldCrawl?: boolean; /** More links to prerender */ links?: (URL | string)[]; } /** * Return type of the beforeXxxLookup hooks. * * - `true` continues with the lookup * - `false` skips the lookup * - `{ redirect: string | URL }` redirects to the given URL * - `{ rewrite: string | URL }` rewrites the URL to the given URL */ type LookupHookResult = boolean | Redirection | { /** Render this URL instead of the requested one */ rewrite: string | URL; }; /** Redirection */ interface Redirection { /** Location to redirect to */ redirect: string | URL; /** Whether the redirect is permanent @default false */ permanent?: boolean; /** The status code to use (hes precedence over `permanent`) */ status?: number; /** Set response headers */ headers?: Record<string, string | string[]> | ((headers: Headers) => void); } type ActionResult<T> = Redirection | { data: T; /** The status code */ status?: number; /** Response headers */ headers?: Record<string, string | string[]> | ((headers: Headers) => void); }; type RouteConfigExport = RouteConfig | ((config: ResolvedConfig) => RouteConfig | Promise<RouteConfig>); interface RouteConfig extends BaseRouteConfig { defaults?: BaseRouteConfig; } interface BaseRouteConfig { disabled?: boolean; renderingMode?: "hydrate" | "server" | "client"; } /** Page hooks common to the server and client */ interface CommonHooks { /** Called before the page is rendered. It can be used to add custom * properties to the page context. This is always called *after* the * server-side or client-side `extendPageContext` hooks. */ extendPageContext?(ctx: PageContext): void; /** * Called before attempting to match the URL to a page. It's used for * rewriting or redirecting the URL. */ beforePageLookup?(ctx: PageContext, url: URL): LookupHookResult; /** * This hook is intended for wrapping the React app with provider * components. This is always called *after* the server-side or client-side * `wrapApp` hooks. */ wrapApp?(app: ReactElement): ReactElement; } interface HeadProps { async?: boolean; base?: any; bodyAttributes?: JSX.IntrinsicElements["body"] & { [key: string]: string | number | boolean | null | undefined; }; children?: ReactNode; defaultTitle?: string; defer?: boolean; encodeSpecialCharacters?: boolean; htmlAttributes?: JSX.IntrinsicElements["html"] & { [key: string]: string | number | boolean | null | undefined; }; onChangeClientState?: (newState: any, addedTags: HeadTags, removedTags: HeadTags) => void; link?: JSX.IntrinsicElements["link"][]; meta?: JSX.IntrinsicElements["meta"][]; noscript?: Array<any>; script?: Array<any>; style?: Array<any>; title?: string; titleAttributes?: Object; titleTemplate?: string; prioritizeSeoTags?: boolean; } interface HeadTags { baseTag: Array<any>; linkTags: Array<HTMLLinkElement>; metaTags: Array<HTMLMetaElement>; noscriptTags: Array<any>; scriptTags: Array<HTMLScriptElement>; styleTags: Array<HTMLStyleElement>; } declare function Head(props: HeadProps): JSX.Element; /** useQuery options */ interface UseQueryOptions { /** * Time in milliseconds after which the value will be evicted from the * cache when there are no subscribers. Use 0 for immediate eviction and * `Infinity` to disable. * * @default 300_000 (5 minutes) */ cacheTime?: number; /** * Time in milliseconds after which a cached value will be considered * stale. * * @default 100 */ staleTime?: number; /** * Refetch the query when the component is mounted. If set to `true`, a stale * query will be refetched when the component is mounted. If set to `"always"`, * the query will be refetched when the component is mounted regardless of * staleness. `false` disables this behavior. * * @default true */ refetchOnMount?: boolean | "always"; /** * Refetch the query when the window gains focus. If set to `true`, the * query will be refetched on window focus if it is stale. If set to * `"always"`, the query will be refetched on window focus regardless of * staleness. `false` disables this behavior. * * @default false */ refetchOnWindowFocus?: boolean | "always"; /** * Continuously refetch every `refetchInterval` milliseconds. Set to false * to disable. * * @default false */ refetchInterval?: number | false; /** * Perform continuous refetching even when the window is in the background. * * @default false */ refetchIntervalInBackground?: boolean; /** * Refetch the query when the internet connection is restored. If set to * `true`, a stale query will be refetched when the internet connection is * restored. If set to `"always"`, the query will be refetched when the * internet connection is restored regardless of staleness. `false` disables * this behavior. * * @default false */ refetchOnReconnect?: boolean | "always"; } /** Context within which the page is being rendered */ interface PageContext { /** URL */ url: URL; /** Isomorphic fetch function */ fetch: typeof fetch; /** Query client used by useQuery */ queryClient: QueryClient; /** Request context, only defined on the server */ requestContext?: RequestContext; /** Application-specific stuff */ locals: PageLocals; /** Page action data */ actionData?: any; } declare function usePageContext(): PageContext; /** Function passed to useQuery */ type QueryFn<T> = (ctx: PageContext) => T | Promise<T>; /** * Fetches data * * @template T Type of data * @param key Query key. Queries with the same key are considered identical. Pass undefined to disable the query. * @param fn Query function that does the actual data fetching * @param [options] Query options * @returns query Query result */ declare function useQuery<T>(key: undefined, fn: QueryFn<T>, options?: UseQueryOptions): undefined; declare function useQuery<T>(key: string, fn: QueryFn<T>, options?: UseQueryOptions): QueryResult<T>; declare function useQuery<T>(key: string | undefined, fn: QueryFn<T>, options?: UseQueryOptions): QueryResult<T> | undefined; /** Return value of useQuery */ interface QueryResult<T> { /** Fetched data */ data: T; /** Refetch the data */ refetch(): void; /** Is the data being refetched? */ isRefetching: boolean; /** Update date of the last returned data */ dataUpdatedAt?: number; } interface EventSourceResult<T> { /** Last data */ data?: T; /** Update date of the last returned data */ dataUpdatedAt?: number; } /** Query client that manages the cache used by useQuery */ interface QueryClient { /** Get the data cached for the given key */ getQueryData(key: string): any; /** * Set the data associated for the given key. * You can also pass a promise here. */ setQueryData(key: string, data: any): void; /** * Start fetching the data for the given key. */ prefetchQuery(key: string, data: Promise<any>): void; /** * Invalidate one or more queries. */ invalidateQueries(keys?: string | string[] | ((key: string) => boolean)): void; } /** Access the query client that manages the cache used by useQuery */ declare function useQueryClient(): QueryClient; /** Function passed to useMutation */ type MutationFunction<T, V> = (vars: V) => T | Promise<T>; /** Optinos for useMutation */ interface UseMutationOptions<T, V> { /** Called just before the mutation starts */ onMutate?(vars: V): void | Promise<void>; /** Called when the mutation fails */ onError?(error: unknown): void; /** Called when the mutation ends (either error or success) */ onSettled?(data?: T, error?: unknown): void; /** Called when the mutation completes successfully */ onSuccess?(data: T): void; } /** Initial mutation state */ interface UseMutationIdleResult { /** Mutation status */ status: "idle"; /** Data returned from the mutation */ data?: undefined; /** Error thrown by the mutation */ error?: undefined; /** Was there an error? */ isError: false; /** Is the mutation in its initial state? */ isIdle: true; /** Is the mutation currently underway? */ isLoading: false; /** Did the last mutation complete successfully? */ isSuccess: false; } /** Loading mutation state */ interface UseMutationLoadingResult { /** Mutation status */ status: "loading"; /** Data returned from the mutation */ data?: undefined; /** Error thrown by from the mutation */ error?: undefined; /** Was there an error? */ isError: false; /** Is the mutation in its initial state? */ isIdle: false; /** Is the mutation currently underway? */ isLoading: true; /** Did the last mutation complete successfully? */ isSuccess: false; } /** Failed mutation state */ interface UseMutationErrorResult { /** Mutation status */ status: "error"; /** Data returned from the mutation */ data?: undefined; /** Error thrown by from the mutation */ error: unknown; /** Was there an error? */ isError: true; /** Is the mutation in its initial state? */ isIdle: false; /** Is the mutation currently underway? */ isLoading: false; /** Did the last mutation complete successfully? */ isSuccess: false; } /** Successful mutation state */ interface UseMutationSuccessResult<T> { /** Mutation status */ status: "success"; /** Data returned from the mutation */ data: T; /** Error thrown by from the mutation */ error?: undefined; /** Was there an error? */ isError: false; /** Is the mutation in its initial state? */ isIdle: false; /** Is the mutation currently underway? */ isLoading: false; /** Did the last mutation complete successfully? */ isSuccess: true; } interface UseMutationMethods<T, V> { /** Fire the mutation */ mutate(vars: V): void; /** Fire the mutation and await its result */ mutateAsync(vars: V): Promise<T>; /** Reset the mutation to its initial state */ reset(): void; } /** Return value of useMutation */ type UseMutationResult<T, V> = UseMutationMethods<T, V> & (UseMutationIdleResult | UseMutationLoadingResult | UseMutationErrorResult | UseMutationSuccessResult<T>); /** * Performs a mutation * @template T Type of mutation result data * @template V Type of mutation variables * @param mutationFn Function that performs the mutation * @param [options] Mutation options * @returns mutation Mutation result */ declare function useMutation<T, V = void>(mutationFn: MutationFunction<T, V>, options?: UseMutationOptions<T, V>): UseMutationResult<T, V>; /** Optinos for useMutation */ interface UseMutationsOptions<T, V> { /** Called just before the mutation starts */ onMutate?(id: number, vars: V): void | Promise<void>; /** Called when the mutation fails */ onError?(id: number, error: unknown): void; /** Called when the mutation ends (either error or success) */ onSettled?(id: number, data?: T, error?: unknown): void; /** Called when the mutation completes successfully */ onSuccess?(id: number, data: T): void; } interface UseMutationsResult<T, V> { /** Fire the mutation */ mutate(vars: V): void; /** Fire the mutation and await its result */ mutateAsync(vars: V): Promise<T>; /** Mutations that are currently underway */ pending: { id: number; vars: V; }[]; } /** * Performs a mutation that can be fired multiple times at once. Each triggered * mutation will have a unique ID that can be used to track it in the `pending` * array in the return value. You can use `onSuccess`, `onError`, and * `onSettled` to track the status of each mutation to provide loading states * or optimistic updates. * * @template T Type of mutation result data * @template V Type of mutation variables * @param mutationFn Function that performs the mutation * @param [options] Mutation options * @returns Mutation result */ declare function useMutations<T, V = void>(mutationFn: MutationFunction<T, V>, options?: UseMutationsOptions<T, V>): UseMutationsResult<T, V>; /** Return value of useLocation */ interface UseLocationResult { current: Readonly<URL>; pending: Readonly<URL> | undefined; } /** Hook to get the navigation state */ declare function useLocation(): UseLocationResult; /** Cancel the last navigation. Returns a function that "redoes" the cancelled navigation. */ declare function cancelLastNavigation(): () => void; /** Navigation options */ interface NavigationOptions { /** Replace the current history entry */ replace?: boolean; /** Restore scroll position (or scroll to top) */ scroll?: boolean; /** Custom user data to be stored in the history entry */ data?: any; /** Action data */ actionData?: any; } /** * Navigate, using client-side navigation if possible. * @param to URL to navigate to * @param options Navigation options * @returns Whether the navigation was completed or cancelled */ declare function navigate(to: string | Readonly<URL>, options?: NavigationOptions): Promise<boolean>; /** {@link Link} props */ interface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> { /** Data to be passed to the history entry */ historyState?: any; /** Whether to replace the current history entry */ replaceState?: boolean; /** Whether to disable scroll position restoration (or scroll to top) */ noScroll?: boolean; /** Called when navigation starts */ onNavigationStart?: () => void; } /** Link component for client-side navigation */ declare const Link: React__default.ForwardRefExoticComponent<LinkProps & React__default.RefAttributes<HTMLAnchorElement>>; /** {@link StyledLink} props */ interface StyledLinkProps extends LinkProps { /** Class to be added if `href` matches the current URL */ activeClass?: string; /** Style to be added if `href` matches the current URL */ activeStyle?: CSSProperties; /** Class to be added if navigation is underway because the user clicked on this link */ pendingClass?: string; /** Style to be added if navigation is underway because the user clicked on this link */ pendingStyle?: CSSProperties; /** * Custom comparison function for checking if the current URL matches this link * @param url URL to be compared to `href` * @param href Value of `href` property, passed for convenience * * @returns true if the URL matches `href` */ onCompareUrls?(url: URL, href: URL): boolean; } /** * Like {@link Link} but allows adding classes and/or styles based on whether this is the active URL. */ declare const StyledLink: React__default.ForwardRefExoticComponent<StyledLinkProps & React__default.RefAttributes<HTMLAnchorElement>>; type UseSubmitResult = { submitHandler(event: FormEvent<HTMLFormElement>): void; } & (UseMutationIdleResult | UseMutationLoadingResult | UseMutationErrorResult | UseMutationSuccessResult<any>); declare function useSubmit(options?: UseMutationOptions<any, HTMLFormElement>): UseSubmitResult; /** {@link ClientOnly} props */ interface ClientOnlyProps { /** Fallback to be rendered during SSR */ fallback: ReactNode; /** Content to be rendered on client-side */ children: ReactNode; } /** Opt out of server-side rendering */ declare function ClientOnly(props: ClientOnlyProps): ReactElement; /** Suspense boundary that only runs on the client */ declare function ClientSuspense(props: ClientOnlyProps): ReactElement; /** {@link Redirect} props */ interface RedirectProps { /** The URL to redirect to */ href: string; /** Whether the redirect is permanent @default false */ permanent?: boolean; /** The status code to use (hes precedence over `permanent`) */ status?: number; } /** * Component for redirecting the user to a different URL. Handling redirections * in {@link CommonHooks["beforePageLookup"] beforePageLookup hook} or in the * {@link PreloadFunction preload function} function results in better SEO so * it's recommended over using this component. */ declare const Redirect: (props: RedirectProps) => ReactElement; /** {@link ResponseHeaders} props */ interface ResponseHeadersProps { /** Status code */ status?: number | ((currentStatus: number) => number); /** The headers to set */ headers?: Record<string, string | string[]> | ((headers: Headers) => void); /** * Time to hold the render stream before returning the response. Set to * true to hold until the page is fully rendered, effectively disabling * streaming. */ throttleRenderStream?: number | true; } /** * Component for setting response status, respnse headers, and throttling the * SSR stream. Exporting a {@link HeadersFunction headers()} function from your * pages or layouts usually works better for SEO and is recommended over this * component. */ declare const ResponseHeaders: (props: ResponseHeadersProps) => ReactElement; interface FallbackProps { error: Error; resetErrorBoundary: (...args: Array<unknown>) => void; } interface ErrorBoundaryPropsWithComponent { onResetKeysChange?: (prevResetKeys: Array<unknown> | undefined, resetKeys: Array<unknown> | undefined) => void; onReset?: (...args: Array<unknown>) => void; onError?: (error: Error, info: { componentStack: string; }) => void; resetKeys?: Array<unknown>; fallback?: never; FallbackComponent: React.ComponentType<FallbackProps>; fallbackRender?: never; } declare function FallbackRender(props: FallbackProps): React.ReactElement<unknown, string | React.FunctionComponent | typeof React.Component> | null; interface ErrorBoundaryPropsWithRender { onResetKeysChange?: (prevResetKeys: Array<unknown> | undefined, resetKeys: Array<unknown> | undefined) => void; onReset?: (...args: Array<unknown>) => void; onError?: (error: Error, info: { componentStack: string; }) => void; resetKeys?: Array<unknown>; fallback?: never; FallbackComponent?: never; fallbackRender: typeof FallbackRender; } interface ErrorBoundaryPropsWithFallback { onResetKeysChange?: (prevResetKeys: Array<unknown> | undefined, resetKeys: Array<unknown> | undefined) => void; onReset?: (...args: Array<unknown>) => void; onError?: (error: Error, info: { componentStack: string; }) => void; resetKeys?: Array<unknown>; fallback: React.ReactElement<unknown, string | React.FunctionComponent | typeof React.Component> | null; FallbackComponent?: never; fallbackRender?: never; } declare type ErrorBoundaryProps = ErrorBoundaryPropsWithFallback | ErrorBoundaryPropsWithComponent | ErrorBoundaryPropsWithRender; declare function useErrorHandler(givenError?: unknown): (error: unknown) => void; /** @see https://github.com/bvaughn/react-error-boundary */ declare const ErrorBoundary: FC<PropsWithChildren<ErrorBoundaryProps>>; /** * Hook for getting the request context. Returns undefined on the client. */ declare function useRequestContext(): RequestContext | undefined; /** Callback passed to useServerSide/runServerside family of functions */ type ServerSideFunction<T> = (context: RequestContext) => T | Promise<T>; /** Options for {@link useServerSideQuery} */ interface UseServerSideQueryOptions extends UseQueryOptions { /** Query key. Rakkas will generate a unique key if not provided. */ key?: string; /** * If true, a POST request will be sent instead of GET. It may be useful * when the query requires a large amount of data to be sent from the * client. The down side is that it cannot be prerendered so it shouldn't * be used when rendering static pages. */ usePostMethod?: boolean; } type UseFormMutationResult<T> = { action: string; submitHandler(event: FormEvent<HTMLFormElement>): void; } & (UseMutationIdleResult | UseMutationLoadingResult | UseMutationErrorResult | UseMutationSuccessResult<T>); type UseFormMutationFn<T> = (context: RequestContext) => ActionResult<T> | Promise<ActionResult<T>>; declare function useFormAction(desc: [moduleId: string, counter: number, closure: any[]]): URL; /** * Hook for running a piece of code on the server to fetch data. The callback * will always run on the server. When the hook is rendered on the client, * Rakkas will send a request to the server. You can think of this hook as a * convenience wrapper around {@link useQuery} and {@link runServerSideQuery}. * * @param fn The function to run on the server * @param options Options for the query */ declare const useServerSideQuery: <T>(fn: ServerSideFunction<T>, options?: UseServerSideQueryOptions) => QueryResult<T>; /** * Runs a piece of code on the server. The callback will always run the server. * When the hook is rendered on the client, Rakkas will send a request to the * server. * * @param context The request context * @param fn The function to run on the server * @param options Options for the query */ declare const runServerSideQuery: <T>(context: RequestContext | undefined, fn: ServerSideFunction<T>) => Promise<T>; /** * Runs a piece of code on the server. The callback will always run the server. * When the hook is rendered on the client, Rakkas will send a request to the * server. The difference between this and {@link runServerSideQuery} is that * `runServerSideMutation` can only run on the client and, as such, it doesn't * need a request context argument. * * @param fn The function to run on the server */ declare const runServerSideMutation: <T>(fn: ServerSideFunction<T>) => Promise<T>; /** * Hook for running a piece of code on the server to modify some data. When the * hook is rendered, Rakkas will send a request to the server and the callback * will always run on the server. You can think of this hook as a convenience * wrapper around {@link useMutation} and {@link runServerSideMutation}. * * @param fn The function to run on the server * @param options Options for the mutation */ declare const useServerSideMutation: <T, V = void>(fn: (context: RequestContext, vars: V) => T | Promise<T>, options?: UseMutationOptions<T, V>) => UseMutationResult<T, V>; declare const useFormMutation: <T>(fn: UseFormMutationFn<T>, options?: UseMutationOptions<T, void>) => UseFormMutationResult<T>; declare const useServerSentEvents: <T>(fn: ServerSideFunction<ReadableStream<T>>) => EventSourceResult<T>; /** Client-side customization hooks */ interface ClientHooks { /** Called before the client starts */ beforeStart?(): void | Promise<void>; /** * This is called before the page is rendered. It's used for adding custom * data to the page context. */ extendPageContext?(ctx: PageContext): void; /** * This hook is intended for wrapping the React app with provider * components on the client only. */ wrapApp?(app: ReactElement): ReactElement; } /** Options passed to {@link startClient} */ interface StartClientOptions { /** Default options for {@link useQuery} hooks */ defaultQueryOptions?: UseQueryOptions; /** Client hooks */ hooks?: ClientHooks; } /** Starts the client. */ declare function startClient(options?: StartClientOptions): Promise<void>; declare module "@hattip/compose" { interface RequestContextExtensions { /** Dynamic path parameters */ params: Record<string, string>; /** Isomorphic fetch function */ fetch: typeof fetch; /** Server-side customiization hooks */ hooks: ServerHooks[]; /** Set to true when searching for a not found page */ notFound?: boolean; } } /** Server-side customization hooks */ interface ServerHooks { /** * Hattip middleware handlers to insert at various stages of the request * processing chain */ middleware?: { /** Middlewares to be run before mathcing pages */ beforePages?: RequestHandlerStack; /** Middlewares to be run before matching API routes */ beforeApiRoutes?: RequestHandlerStack; /** Middlewares to be run before not-found handling */ beforeNotFound?: RequestHandlerStack; }; /** Create server-side page rendering hooks */ createPageHooks?(ctx: RequestContext): PageRequestHooks; } /** Hooks for customizing the page rendering on the server */ interface PageRequestHooks { /** * This is called before the page is rendered. It's used for adding custom * data to the page context. */ extendPageContext?(ctx: PageContext): void | Promise<void>; /** * This hook is intended for wrapping the React app with provider * components on the server only. */ wrapApp?(app: ReactElement): ReactElement; /** Write to the document's head section */ emitToDocumentHead?(): string; /** Emit a chunk of HTML before each time React emits a chunk */ emitBeforeSsrChunk?(): string | undefined; /** Wrap React's SSR stream */ wrapSsrStream?(stream: ReadableStream): ReadableStream; } /** * Creates a HatTip request handler. Call this to create a HatTip request * handler and fefault export it from your HatTip entry. */ declare function createRequestHandler(userHooks?: ServerHooks): _hattip_core.HattipHandler; export { ActionContext, ActionHandler, ActionResult, BaseRouteConfig, ClientHooks, ClientOnly, ClientOnlyProps, ClientSuspense, CommonHooks, ErrorBoundary, ErrorBoundaryProps, ErrorBoundaryPropsWithComponent, ErrorBoundaryPropsWithFallback, ErrorBoundaryPropsWithRender, FallbackProps, Head, HeadProps, HeadTags, HeadersFunction, Layout, LayoutProps, Link, LinkProps, LookupHookResult, MutationFunction, NavigationOptions, Page, PageContext, PageRequestHooks as PageHooks, PageLocals, PageProps, PageRouteGuard, PageRouteGuardContext, PreloadContext, PreloadFunction, PreloadResult, PrerenderFunction, PrerenderResult, QueryClient, QueryFn, QueryResult, Redirect, RedirectProps, ResponseHeaders, ResponseHeadersProps, RouteConfig, RouteConfigExport, ServerHooks, ServerSideFunction, ServerSidePageContext, StartClientOptions, StyledLink, StyledLinkProps, UseFormMutationFn, UseFormMutationResult, UseLocationResult, UseMutationErrorResult, UseMutationIdleResult, UseMutationLoadingResult, UseMutationMethods, UseMutationOptions, UseMutationResult, UseMutationSuccessResult, UseMutationsOptions, UseMutationsResult, UseQueryOptions, UseServerSideQueryOptions, cancelLastNavigation, createRequestHandler, navigate, runServerSideMutation as runSSM, runServerSideQuery as runSSQ, runServerSideMutation, runServerSideQuery, startClient, useErrorHandler, useFormAction, useFormMutation, useLocation, useMutation, useMutations, usePageContext, useQuery, useQueryClient, useRequestContext, useServerSentEvents as useSSE, useServerSideMutation as useSSM, useServerSideQuery as useSSQ, useServerSentEvents, useServerSideMutation, useServerSideQuery, useSubmit };