import { type Vite } from '@adonisjs/vite';
import type { HttpContext } from '@adonisjs/core/http';
import { type ServerRenderer } from './server_renderer.js';
import type { PageProps, PageObject, AsPageProps, RequestInfo, InertiaConfig, ComponentProps, SharedProps } from './types.js';
import { defer, merge, always, optional, deepMerge } from './props.ts';
import { type AsyncOrSync } from '@poppinss/utils/types';
/**
 * Main class used to interact with Inertia
 *
 * Provides a complete interface for handling Inertia.js requests, rendering pages,
 * managing props, and controlling page navigation behavior.
 *
 * @example
 * ```js
 * const inertia = new Inertia(ctx, config, vite, serverRenderer)
 *
 * // Render a page
 * const result = await inertia.render('Home', { user: { name: 'John' } })
 *
 * // Clear browser history
 * inertia.clearHistory()
 *
 * // Redirect to a different location
 * inertia.location('/dashboard')
 * ```
 */
export declare class Inertia<Pages> {
    #private;
    protected ctx: HttpContext;
    protected config: InertiaConfig;
    /**
     * Defer prop evaluation until client-side rendering
     *
     * @example
     * ```js
     * {
     *   expensiveData: inertia.defer(() => computeExpensiveData())
     * }
     * ```
     */
    defer: typeof defer;
    /**
     * Always include prop in both server and client renders
     *
     * @example
     * ```js
     * {
     *   currentUser: inertia.always(() => getCurrentUser())
     * }
     * ```
     */
    always: typeof always;
    /**
     * Merge prop with existing client-side data
     *
     * @example
     * ```js
     * {
     *   posts: inertia.merge(() => getPosts())
     * }
     * ```
     */
    merge: typeof merge;
    /**
     * Include prop only when specifically requested
     *
     * @example
     * ```js
     * {
     *   optionalData: inertia.optional(() => getOptionalData())
     * }
     * ```
     */
    optional: typeof optional;
    /**
     * Deep merge prop with existing client-side data
     *
     * @example
     * ```js
     * {
     *   settings: inertia.deepMerge(() => getSettings())
     * }
     * ```
     */
    deepMerge: typeof deepMerge;
    /**
     * Creates a new Inertia instance
     *
     * @param ctx - HTTP context for the current request
     * @param config - Inertia configuration object
     * @param vite - Vite instance for asset management
     * @param serverRenderer - Optional server renderer for SSR
     *
     * @example
     * ```js
     * const inertia = new Inertia(ctx, {
     *   rootView: 'app',
     *   ssr: { enabled: true }
     * }, vite, serverRenderer)
     * ```
     */
    constructor(ctx: HttpContext, config: InertiaConfig, vite?: Vite, serverRenderer?: ServerRenderer);
    /**
     * Extract Inertia-specific information from request headers
     *
     * Parses various Inertia headers to determine request type and props filtering.
     *
     * @param reCompute - Whether to recompute the request info instead of using cached version
     * @returns The request information object containing Inertia-specific data
     *
     * @example
     * ```js
     * const info = inertia.requestInfo()
     * if (info.isInertiaRequest) {
     *   // Handle as Inertia request
     * }
     * ```
     */
    requestInfo(reCompute?: boolean): RequestInfo;
    /**
     * Compute and cache the assets version
     *
     * Uses Vite manifest hash when available, otherwise defaults to '1'.
     *
     * @returns The computed version string for asset versioning
     */
    getVersion(): string;
    /**
     * Determine if server-side rendering is enabled for a specific component
     *
     * Checks global SSR settings and component-specific configuration.
     *
     * @param component - The component name to check
     * @returns Promise resolving to true if SSR is enabled for the component
     *
     * @example
     * ```js
     * const shouldSSR = await inertia.ssrEnabled('UserProfile')
     * if (shouldSSR) {
     *   // Render on server
     * }
     * ```
     */
    ssrEnabled<Page extends keyof Pages & string>(component: Page): Promise<boolean>;
    /**
     * Share props across all pages
     *
     * Merges the provided props with existing shared state, making them available
     * to all pages rendered by this Inertia instance. Shared props are included
     * in every page render alongside page-specific props.
     *
     * @param sharedState - Props to share across all pages
     * @returns The Inertia instance for method chaining
     *
     * @example
     * ```js
     * // Share user data across all pages
     * inertia.share({
     *   user: getCurrentUser(),
     *   flash: getFlashMessages()
     * })
     *
     * // Chain multiple shares
     * inertia
     *   .share({ currentUser: user })
     *   .share({ permissions: userPermissions })
     * ```
     */
    share(sharedState: PageProps | (() => AsyncOrSync<PageProps>)): this;
    /**
     * Build a page object with processed props and metadata
     *
     * Creates the complete page object that will be sent to the client or used for SSR.
     *
     * @param page - The page component name
     * @param pageProps - Props to pass to the page component
     * @returns Promise resolving to the complete page object
     *
     * @example
     * ```js
     * const pageObject = await inertia.page('Dashboard', {
     *   user: { name: 'John' },
     *   posts: defer(() => getPosts())
     * })
     * ```
     */
    page<Page extends keyof Pages & string>(page: Page, pageProps: Pages[Page] extends ComponentProps ? AsPageProps<Omit<Pages[Page], keyof SharedProps>> : never): Promise<PageObject<Pages[Page]>>;
    /**
     * Render a page using Inertia
     *
     * This method handles three distinct rendering scenarios:
     * 1. Inertia requests - Returns JSON page object for client-side navigation
     * 2. Initial page loads with SSR - Returns HTML with server-rendered content
     * 3. Initial page loads without SSR - Returns HTML for client-side hydration
     *
     * @param page - The page component name to render
     * @param pageProps - Props to pass to the page component
     * @param viewProps - Additional props to pass to the root view template
     * @returns Promise resolving to PageObject for Inertia requests, HTML string for initial page loads
     *
     * @example
     * ```js
     * // For Inertia requests, returns PageObject
     * const result = await inertia.render('Profile', {
     *   user: getCurrentUser(),
     *   posts: defer(() => getUserPosts())
     * })
     *
     * // For initial page loads, returns HTML string
     * const html = await inertia.render('Home', { welcome: 'Hello World' })
     * ```
     */
    render<Page extends keyof Pages & string>(page: Page, pageProps: Pages[Page] extends ComponentProps ? AsPageProps<Omit<Pages[Page], keyof SharedProps>> : never, viewProps?: Record<string, any>): Promise<string | PageObject<Pages[Page]>>;
    /**
     * Clear the browser history on the next navigation
     *
     * Instructs the client to clear the browser history stack when navigating.
     *
     * @example
     * ```js
     * inertia.clearHistory()
     * return inertia.render('Dashboard', props)
     * ```
     */
    clearHistory(): void;
    /**
     * Control whether browser history should be encrypted
     *
     * Enables or disables encryption of sensitive data in browser history.
     *
     * @param encrypt - Whether to encrypt history (defaults to true)
     *
     * @example
     * ```js
     * // Enable encryption for sensitive pages
     * inertia.encryptHistory(true)
     *
     * // Disable encryption for public pages
     * inertia.encryptHistory(false)
     * ```
     */
    encryptHistory(encrypt?: boolean): void;
    /**
     * Redirect to a different location
     *
     * Sets the appropriate headers to redirect the client to a new URL.
     * Uses a 409 status code which Inertia.js interprets as a redirect instruction.
     *
     * @param url - The URL to redirect to
     *
     * @example
     * ```js
     * // Redirect after login
     * inertia.location('/dashboard')
     *
     * // Redirect with full URL
     * inertia.location('https://example.com/external')
     * ```
     */
    location(url: string): void;
}
