{"version":3,"sources":["../../src/client.ts","../../src/lib/mount-app.ts","../../src/lib/internal/WrapAppElement/WrapRouter.tsx","../../src/lib/internal/UnirendContext/UnirendProvider.tsx","../../src/lib/internal/UnirendContext/hooks.ts","../../src/lib/internal/utils.ts","../../src/lib/internal/WrapAppElement/Wrappers.tsx","../../src/lib/internal/UnirendHead/UnirendHeadProvider.tsx","../../src/lib/internal/UnirendHead/UnirendHead.tsx","../../src/lib/internal/WrapAppElement/CreateAppWrapper.tsx","../../src/lib/internal/WrapAppElement/WrapStaticRouter.tsx","../../src/lib/router-utils/query-params.ts"],"sourcesContent":["/**\n * Client-only exports for unirend\n *\n * This entry point only includes functions and types that are safe to use\n * in client-side code. It excludes server-only functionality like SSR servers,\n * file system operations, and server-side rendering utilities.\n *\n * Import from 'unirend/client' in your client-side code:\n *\n * ```typescript\n * import { mountApp, useIsSSR, useIsSSG, useIsClient, useIsDevelopment } from 'unirend/client';\n * import { routes } from './Routes';\n *\n * mountApp('root', routes);\n * ```\n */\n\n// Client-safe types\nexport type { MountAppOptions, MountAppResult } from './lib/mount-app';\nexport type {\n  UnirendContextValue,\n  UnirendRenderMode,\n  RequestContextManager,\n  DomainInfo,\n} from './lib/internal/UnirendContext';\n\n// Client-safe functions\nexport { mountApp } from './lib/mount-app';\n\n// UnirendHead — framework-native document head manager\nexport { UnirendHead } from './lib/internal/UnirendHead';\n\n// Unirend context hooks\nexport {\n  useIsSSR,\n  useIsSSG,\n  useIsClient,\n  useRenderMode,\n  useIsDevelopment,\n  useIsServer,\n  usePublicAppConfig,\n  useCDNBaseURL,\n  useDomainInfo,\n  useRequestContext,\n  useRequestContextValue,\n  useRequestContextObjectRaw,\n} from './lib/internal/UnirendContext';\n\n// Query param utilities\nexport {\n  useQueryParams,\n  stringifyQueryParams,\n} from './lib/router-utils/query-params';\n","import type React from 'react';\nimport { createRoot, hydrateRoot } from 'react-dom/client';\nimport { createBrowserRouter } from 'react-router';\nimport type { RouteObject } from 'react-router';\nimport { wrapRouter } from './internal/WrapAppElement';\nimport type {\n  UnirendContextValue,\n  DomainInfo,\n} from './internal/UnirendContext';\nimport { getDevMode } from 'lifecycleion/dev-mode';\n\n/**\n * Result type indicating how the app was mounted\n * - \"hydrated\": App was hydrated over existing SSR/SSG content\n * - \"rendered\": App was rendered fresh (SPA mode)\n * - \"not_found\": Container element was not found in the DOM\n */\nexport type MountAppResult = 'hydrated' | 'rendered' | 'not_found';\n\n/**\n * Options for mounting the app\n */\nexport type MountAppOptions = {\n  /**\n   * Whether to wrap the app element with React.StrictMode\n   * @default true\n   */\n  strictMode?: boolean;\n  /**\n   * Optional custom wrapper component for additional providers\n   * Applied after UnirendHeadProvider but before StrictMode (StrictMode is always outermost)\n   * Must be a React component that accepts children\n   */\n  rootProviders?: React.ComponentType<{ children: React.ReactNode }>;\n};\n\n/**\n * Intelligently mounts a React Router-based app by detecting whether to hydrate or render.\n *\n * This is the primary function for client-side mounting in unirend. It provides a unified,\n * opinionated API that works seamlessly across different rendering contexts:\n * - SSR/SSG: Hydrates pre-rendered HTML content\n * - SPA: Creates a fresh root and renders the app\n *\n * The detection is based on whether the container already has child elements,\n * which indicates pre-rendered content that should be hydrated rather than replaced.\n *\n * @param containerID - The ID of the root DOM element (e.g., \"root\", \"app\")\n * @param routes - Your React Router routes configuration\n * @param options - Optional configuration for mounting behavior\n * @returns MountAppResult indicating the mounting strategy used or if it failed\n *\n * @example\n * ```typescript\n * import { mountApp } from 'unirend/client';\n * import { routes } from './Routes';\n *\n * const result = mountApp('root', routes);\n *\n * // With custom providers\n * const customWrapper = (node) => (\n *   <ThemeProvider>\n *     <StateProvider>\n *       {node}\n *     </StateProvider>\n *   </ThemeProvider>\n * );\n *\n * const result = mountApp('root', routes, { wrapApp: customWrapper });\n *\n * if (result === 'hydrated') {\n *   console.log('Hydrated SSR content');\n * } else if (result === 'rendered') {\n *   console.log('Rendered as SPA');\n * } else {\n *   console.error('Failed to mount app');\n * }\n * ```\n */\nexport function mountApp(\n  containerID: string,\n  routes: RouteObject[],\n  options: MountAppOptions = {},\n): MountAppResult {\n  // Attempt to find the container element in the DOM\n  const container = document.getElementById(containerID);\n\n  // Early return if container doesn't exist\n  if (!container) {\n    return 'not_found';\n  }\n\n  // Create browser router from routes\n  const router = createBrowserRouter(routes);\n\n  // Read public app config from injected global (if available)\n  // The server injects this via window.__PUBLIC_APP_CONFIG__ during SSR/SSG\n  // Clone it to prevent mutations from affecting the global or other consumers\n  const globalConfig =\n    typeof window !== 'undefined'\n      ? (\n          window as unknown as {\n            // eslint-disable-next-line @typescript-eslint/naming-convention\n            __PUBLIC_APP_CONFIG__?: Record<string, unknown>;\n          }\n        ).__PUBLIC_APP_CONFIG__\n      : undefined;\n\n  const publicAppConfig = globalConfig\n    ? structuredClone(globalConfig)\n    : undefined;\n\n  const cdnBaseURL =\n    typeof window !== 'undefined'\n      ? ((\n          window as unknown as {\n            // eslint-disable-next-line @typescript-eslint/naming-convention\n            __CDN_BASE_URL__?: string;\n          }\n        ).__CDN_BASE_URL__ ?? '')\n      : '';\n\n  const domainInfo =\n    typeof window !== 'undefined'\n      ? ((\n          window as unknown as {\n            // eslint-disable-next-line @typescript-eslint/naming-convention\n            __DOMAIN_INFO__?: DomainInfo | null;\n          }\n        ).__DOMAIN_INFO__ ?? null)\n      : null;\n\n  // Provide default Unirend context for client-side\n  // Note: When hydrating SSR/SSG content, the server provides the correct context values\n  // This default is only used for pure client-side SPA scenarios (no SSR/SSG)\n  const unirendContext: UnirendContextValue = {\n    renderMode: 'client', // Pure client-side (server overrides to \"ssr\" or \"ssg\" during server rendering)\n    isDevelopment: getDevMode(), // false if global not set (safe production default)\n    fetchRequest: undefined, // No server request on client\n    publicAppConfig, // Config injected by server (SSR/SSG) or undefined (pure SPA)\n    cdnBaseURL, // CDN base URL injected by server (SSR/SSG) or empty string if not configured\n    domainInfo, // Domain info injected by server (SSR, or SSG when hostname is configured) or null\n    requestContextRevision: '0-0', // Initial revision for client-side\n  };\n\n  // Wrap the router with configured options\n  const wrappedAppElement = wrapRouter(router, {\n    ...options,\n    unirendContext,\n  });\n\n  // Check if container has existing content (indicates SSR/SSG)\n  // firstElementChild is more reliable than innerHTML for detecting pre-rendered content\n  if (container.firstElementChild) {\n    // Container has existing elements - this is likely SSR/SSG content\n    // Use hydrateRoot to preserve the existing DOM and attach React event handlers\n    hydrateRoot(container, wrappedAppElement);\n\n    return 'hydrated';\n  } else {\n    // Container is empty - this is SPA mode or development\n    // Use createRoot to render the app from scratch\n    const root = createRoot(container);\n    root.render(wrappedAppElement);\n\n    return 'rendered';\n  }\n}\n","import type { ReactElement } from 'react';\nimport { RouterProvider } from 'react-router';\nimport type { DataRouter } from 'react-router';\nimport { createAppWrapper } from './CreateAppWrapper';\nimport type { WrapAppElementOptions } from './types';\n\n/**\n * CLIENT-SIDE: Wraps a Browser Router with the standard app wrappers\n * Uses RouterProvider with UnirendHeadProvider (null collector — React 19 hoists natively)\n *\n * @param router - The Browser Router instance\n * @param options - Configuration options for wrapping\n * @returns The wrapped RouterProvider element\n */\n\nexport function wrapRouter(\n  router: DataRouter,\n  options: WrapAppElementOptions,\n): ReactElement {\n  const routerElement = <RouterProvider router={router} />;\n  return createAppWrapper(routerElement, options);\n}\n","import { UnirendContext } from './context';\nimport type { UnirendProviderProps } from './context';\n\n/**\n * UnirendProvider component that provides context to the app\n *\n * @example\n * ```tsx\n * <UnirendProvider value={{ renderMode: 'ssr', isDevelopment: true }}>\n *   <App />\n * </UnirendProvider>\n * ```\n */\nexport function UnirendProvider({ children, value }: UnirendProviderProps) {\n  return (\n    <UnirendContext.Provider value={value}>{children}</UnirendContext.Provider>\n  );\n}\n","import { useContext, useState, useEffect } from 'react';\nimport { deepFreeze } from '../utils';\nimport {\n  UnirendContext,\n  getRequestContextValue,\n  setRequestContextValue,\n  getRequestContextObject,\n  hasSSRRequestContext,\n  hasSSGRequestContext,\n  hasWindowRequestContext,\n  incrementContextRevision,\n} from './context';\nimport type {\n  UnirendRenderMode,\n  RequestContextManager,\n  DomainInfo,\n} from './context';\n\n/**\n * Hook to check if the app is rendering in SSR mode\n *\n * @returns true if rendering mode is 'ssr', false if 'ssg'\n *\n * @example\n * ```tsx\n * function MyComponent() {\n *   const isSSR = useIsSSR();\n *\n *   return <div>{isSSR ? 'Server-Side Rendered' : 'Static Generated'}</div>;\n * }\n * ```\n */\nexport function useIsSSR(): boolean {\n  const { renderMode } = useContext(UnirendContext);\n  return renderMode === 'ssr';\n}\n\n/**\n * Hook to check if the app is rendering in SSG mode\n *\n * @returns true if rendering mode is 'ssg', false otherwise\n *\n * @example\n * ```tsx\n * function MyComponent() {\n *   const isSSG = useIsSSG();\n *\n *   return <div>{isSSG ? 'Static Generated' : 'Not SSG'}</div>;\n * }\n * ```\n */\nexport function useIsSSG(): boolean {\n  const { renderMode } = useContext(UnirendContext);\n  return renderMode === 'ssg';\n}\n\n/**\n * Hook to check if the app is in client mode\n * Returns true for SPAs or after SSG build/SSR page hydration occurs\n *\n * @returns true if rendering mode is 'client', false otherwise\n *\n * @example\n * ```tsx\n * function MyComponent() {\n *   const isClient = useIsClient();\n *\n *   return <div>{isClient ? 'Client Mode' : 'Server Rendering'}</div>;\n * }\n * ```\n */\nexport function useIsClient(): boolean {\n  const { renderMode } = useContext(UnirendContext);\n  return renderMode === 'client';\n}\n\n/**\n * Hook to get the render mode\n *\n * @returns The current render mode ('ssr', 'ssg', or 'client')\n *\n * @example\n * ```tsx\n * function MyComponent() {\n *   const renderMode = useRenderMode();\n *\n *   return <div>Render Mode: {renderMode}</div>;\n * }\n * ```\n */\nexport function useRenderMode(): UnirendRenderMode {\n  const { renderMode } = useContext(UnirendContext);\n  return renderMode;\n}\n\n/**\n * Hook to check if the app is running in development mode\n *\n * @returns true if in development mode, false if in production\n *\n * @example\n * ```tsx\n * function MyComponent() {\n *   const isDev = useIsDevelopment();\n *\n *   return (\n *     <div>\n *       {isDev && <div>Development Mode - Debug Info</div>}\n *     </div>\n *   );\n * }\n * ```\n */\nexport function useIsDevelopment(): boolean {\n  const { isDevelopment } = useContext(UnirendContext);\n  return isDevelopment;\n}\n\n/**\n * Hook to check if the code is running on the server (SSR)\n * This checks if fetchRequest has the SSRHelper property attached\n *\n * @returns true if on SSR server (has SSRHelper), false if on client or SSG\n *\n * @example\n * ```tsx\n * function MyComponent() {\n *   const isServer = useIsServer();\n *\n *   return (\n *     <div>\n *       {isServer ? 'Running on SSR server' : 'Running on client or SSG'}\n *     </div>\n *   );\n * }\n * ```\n */\nexport function useIsServer(): boolean {\n  const { fetchRequest } = useContext(UnirendContext);\n  return fetchRequest !== undefined && 'SSRHelper' in fetchRequest;\n}\n\n/**\n * Hook to access public application configuration\n * This is a frozen (immutable) copy of the config passed to the server\n * Available on both server and client\n *\n * @returns The public app config object, or undefined if not provided\n *\n * @example\n * ```tsx\n * function MyComponent() {\n *   const config = usePublicAppConfig();\n *\n *   if (!config) {\n *     return <div>No config available</div>;\n *   }\n *\n *   return (\n *     <div>\n *       <p>API URL: {config.api_endpoint}</p>\n *       <p>App Name: {config.appName}</p>\n *     </div>\n *   );\n * }\n * ```\n */\nexport function usePublicAppConfig(): Record<string, unknown> | undefined {\n  const { publicAppConfig } = useContext(UnirendContext);\n  return publicAppConfig;\n}\n\n/**\n * Hook to get the CDN base URL configured for asset serving.\n *\n * Returns the effective CDN base URL for the current request — either a per-request\n * override (set in middleware via `request.CDNBaseURL`) or the app-level default\n * (`CDNBaseURL` in `serveSSRProd`/`registerProdApp` options). Returns an empty string\n * when no CDN is configured or when running Vite directly without the unirend server.\n *\n * Available on both server (during SSR rendering) and client (read from\n * `window.__CDN_BASE_URL__` injected into the page).\n *\n * @example\n * ```tsx\n * function AssetImage({ path }: { path: string }) {\n *   const cdnBase = useCDNBaseURL();\n *\n *   return <img src={`${cdnBase}${path}`} />;\n * }\n * ```\n */\nexport function useCDNBaseURL(): string {\n  const { cdnBaseURL } = useContext(UnirendContext);\n  return cdnBaseURL ?? '';\n}\n\n/**\n * Returns domain information computed server-side from the request hostname.\n *\n * - `hostname`: the bare requested hostname (port stripped), e.g. `'app.example.com'`\n * - `rootDomain`: the apex domain without a leading dot, e.g. `'example.com'`.\n *   Empty string for localhost / IP addresses.\n *   Prepend `.` when using as a cookie `domain` attribute to span subdomains:\n *   ```ts\n *   document.cookie = [\n *     'theme=dark',\n *     'path=/',\n *     'max-age=31536000',\n *     domainInfo?.rootDomain ? `domain=.${domainInfo.rootDomain}` : null,\n *   ].filter(Boolean).join('; ');\n *   ```\n *\n * Returns `null` when hostname is not known — SSG without a `hostname` option\n * configured, or pure SPA (no server to compute it via the public suffix list).\n *\n * @example\n * ```tsx\n * function ThemeProvider({ children }) {\n *   const domainInfo = useDomainInfo();\n *   // domainInfo?.hostname  → 'app.example.com'\n *   // domainInfo?.rootDomain → 'example.com'\n * }\n * ```\n */\nexport function useDomainInfo(): DomainInfo | null {\n  const { domainInfo } = useContext(UnirendContext);\n  return domainInfo ?? null;\n}\n\n/**\n * Hook to get the raw request context object for debugging purposes.\n * Returns a cloned, immutable copy of the entire request context.\n *\n * **Note:** This is primarily for debugging. Use `useRequestContextValue()`\n * or `useRequestContext()` for production code.\n *\n * @returns A cloned copy of the request context object, or undefined if not populated\n *\n * @example\n * ```tsx\n * function DebugPanel() {\n *   const rawContext = useRequestContextObjectRaw();\n *\n *   if (!rawContext) {\n *     return <div>Request context not populated</div>;\n *   }\n *\n *   return (\n *     <pre>{JSON.stringify(rawContext, null, 2)}</pre>\n *   );\n * }\n * ```\n */\nexport function useRequestContextObjectRaw():\n  | Record<string, unknown>\n  | undefined {\n  const context = useContext(UnirendContext);\n  const [rawContext, setRawContext] = useState<\n    Record<string, unknown> | undefined\n  >(() => {\n    // Get initial value on server\n    const contextObj = getRequestContextObject(context);\n    return contextObj ? deepFreeze(structuredClone(contextObj)) : undefined;\n  });\n\n  useEffect(() => {\n    // Update when context changes (reactive to modifications)\n    const contextObj = getRequestContextObject(context);\n\n    if (contextObj) {\n      // Create a cloned, immutable copy\n      const cloned = structuredClone(contextObj);\n\n      // Synchronizing with external state (request context) tracked by revision counter\n      setRawContext(deepFreeze(cloned));\n    } else {\n      setRawContext(undefined);\n    }\n  }, [context.requestContextRevision, context]);\n\n  return rawContext;\n}\n\n/**\n * Hook to access and manage the request context\n *\n * Returns an object with methods to get, set, check, delete, and inspect\n * the request context. The returned methods can be safely called in callbacks,\n * effects, or event handlers.\n *\n * @returns RequestContextManager object with context management methods\n *\n * @example\n * ```tsx\n * function MyComponent() {\n *   const requestContext = useRequestContext();\n *\n *   const handleThemeChange = (theme: string) => {\n *     requestContext.set('theme', theme);\n *   };\n *\n *   const userID = requestContext.get('userID');\n *   const hasTheme = requestContext.has('theme');\n *   const allKeys = requestContext.keys();\n *\n *   return (\n *     <div>\n *       <p>User ID: {userID}</p>\n *       <p>Has theme: {hasTheme ? 'Yes' : 'No'}</p>\n *       <p>Total entries: {requestContext.size()}</p>\n *       <button onClick={() => handleThemeChange('dark')}>Dark Theme</button>\n *       <button onClick={() => requestContext.clear()}>Clear All</button>\n *     </div>\n *   );\n * }\n * ```\n */\nexport function useRequestContext(): RequestContextManager {\n  const context = useContext(UnirendContext);\n\n  return {\n    get: (key: string): unknown => {\n      return getRequestContextValue(context, key);\n    },\n    set: (key: string, value: unknown): void => {\n      setRequestContextValue(context, key, value);\n    },\n    has: (key: string): boolean => {\n      // Try SSR first - check if we have SSR helpers with request context\n      if (context.fetchRequest && hasSSRRequestContext(context.fetchRequest)) {\n        // SSR: Check if key exists in fastify request context\n        return (\n          key in context.fetchRequest.SSRHelpers.fastifyRequest.requestContext\n        );\n      } else if (\n        // Try SSG - check if we have SSG helpers with request context\n        context.fetchRequest &&\n        hasSSGRequestContext(context.fetchRequest)\n      ) {\n        // SSG: Check if key exists in SSG request context\n        return key in context.fetchRequest.SSGHelpers.requestContext;\n      } else if (hasWindowRequestContext()) {\n        // Client: Check if key exists in window global\n        return (\n          key in\n          (\n            window as unknown as {\n              // eslint-disable-next-line @typescript-eslint/naming-convention\n              __FRONTEND_REQUEST_CONTEXT__: Record<string, unknown>;\n            }\n          ).__FRONTEND_REQUEST_CONTEXT__\n        );\n      } else {\n        // No context available\n        return false;\n      }\n    },\n    delete: (key: string): boolean => {\n      let didExist = false;\n\n      // Try SSR first - check if we have SSR helpers with request context\n      if (context.fetchRequest && hasSSRRequestContext(context.fetchRequest)) {\n        // SSR: Delete from fastify request context\n        didExist =\n          key in context.fetchRequest.SSRHelpers.fastifyRequest.requestContext;\n\n        // requestContext is intentionally mutable (context itself is not modified)\n        delete context.fetchRequest.SSRHelpers.fastifyRequest.requestContext[\n          key\n        ];\n      } else if (\n        // Try SSG - check if we have SSG helpers with request context\n        context.fetchRequest &&\n        hasSSGRequestContext(context.fetchRequest)\n      ) {\n        // SSG: Delete from SSG request context\n        didExist = key in context.fetchRequest.SSGHelpers.requestContext;\n        delete context.fetchRequest.SSGHelpers.requestContext[key];\n      } else if (hasWindowRequestContext()) {\n        // Client: Delete from window global\n        const ctx = (\n          window as unknown as {\n            // eslint-disable-next-line @typescript-eslint/naming-convention\n            __FRONTEND_REQUEST_CONTEXT__: Record<string, unknown>;\n          }\n        ).__FRONTEND_REQUEST_CONTEXT__;\n\n        didExist = key in ctx;\n        delete ctx[key];\n      }\n\n      // Increment revision to trigger re-renders if key existed\n      if (didExist) {\n        incrementContextRevision(context);\n      }\n\n      return didExist;\n    },\n    clear: (): number => {\n      let count = 0;\n\n      // Try SSR first - check if we have SSR helpers with request context\n      if (context.fetchRequest && hasSSRRequestContext(context.fetchRequest)) {\n        // SSR: Clear all keys from fastify request context\n        const ctx =\n          context.fetchRequest.SSRHelpers.fastifyRequest.requestContext;\n        const keys = Object.keys(ctx);\n        count = keys.length;\n\n        // Delete each key individually to preserve object reference\n        for (const key of keys) {\n          // requestContext is intentionally mutable (context itself is not modified)\n          delete ctx[key];\n        }\n      } else if (\n        // Try SSG - check if we have SSG helpers with request context\n        context.fetchRequest &&\n        hasSSGRequestContext(context.fetchRequest)\n      ) {\n        // SSG: Clear all keys from SSG request context\n        const ctx = context.fetchRequest.SSGHelpers.requestContext;\n        const keys = Object.keys(ctx);\n        count = keys.length;\n\n        // Delete each key individually to preserve object reference\n        for (const key of keys) {\n          delete ctx[key];\n        }\n      } else if (hasWindowRequestContext()) {\n        // Client: Clear all keys from window global\n        const ctx = (\n          window as unknown as {\n            // eslint-disable-next-line @typescript-eslint/naming-convention\n            __FRONTEND_REQUEST_CONTEXT__: Record<string, unknown>;\n          }\n        ).__FRONTEND_REQUEST_CONTEXT__;\n\n        const keys = Object.keys(ctx);\n        count = keys.length;\n\n        // Delete each key individually to preserve object reference\n        for (const key of keys) {\n          delete ctx[key];\n        }\n      }\n\n      // Increment revision to trigger re-renders if any keys were cleared\n      if (count > 0) {\n        incrementContextRevision(context);\n      }\n\n      return count;\n    },\n    keys: (): string[] => {\n      // Try SSR first - check if we have SSR helpers with request context\n      if (context.fetchRequest && hasSSRRequestContext(context.fetchRequest)) {\n        // SSR: Return keys from fastify request context\n        return Object.keys(\n          context.fetchRequest.SSRHelpers.fastifyRequest.requestContext,\n        );\n      } else if (\n        // Try SSG - check if we have SSG helpers with request context\n        context.fetchRequest &&\n        hasSSGRequestContext(context.fetchRequest)\n      ) {\n        // SSG: Return keys from SSG request context\n        return Object.keys(context.fetchRequest.SSGHelpers.requestContext);\n      } else if (hasWindowRequestContext()) {\n        // Client: Return keys from window global\n        return Object.keys(\n          (\n            window as unknown as {\n              // eslint-disable-next-line @typescript-eslint/naming-convention\n              __FRONTEND_REQUEST_CONTEXT__: Record<string, unknown>;\n            }\n          ).__FRONTEND_REQUEST_CONTEXT__,\n        );\n      } else {\n        // No context available - return empty array\n        return [];\n      }\n    },\n    size: (): number => {\n      // Try SSR first - check if we have SSR helpers with request context\n      if (context.fetchRequest && hasSSRRequestContext(context.fetchRequest)) {\n        // SSR: Return count of keys from fastify request context\n        return Object.keys(\n          context.fetchRequest.SSRHelpers.fastifyRequest.requestContext,\n        ).length;\n      } else if (\n        // Try SSG - check if we have SSG helpers with request context\n        context.fetchRequest &&\n        hasSSGRequestContext(context.fetchRequest)\n      ) {\n        // SSG: Return count of keys from SSG request context\n        return Object.keys(context.fetchRequest.SSGHelpers.requestContext)\n          .length;\n      } else if (hasWindowRequestContext()) {\n        // Client: Return count of keys from window global\n        return Object.keys(\n          (\n            window as unknown as {\n              // eslint-disable-next-line @typescript-eslint/naming-convention\n              __FRONTEND_REQUEST_CONTEXT__: Record<string, unknown>;\n            }\n          ).__FRONTEND_REQUEST_CONTEXT__,\n        ).length;\n      } else {\n        // No context available - return 0\n        return 0;\n      }\n    },\n  };\n}\n\n/**\n * Hook to access and reactively update a single request context value\n *\n * Similar to useState, this hook returns a tuple of [value, setValue] and will\n * cause the component to re-render when the value changes.\n *\n * @param key - The key to track in the request context\n * @returns A tuple of [value, setValue] similar to useState\n *\n * @example\n * ```tsx\n * function ThemeToggle() {\n *   const [theme, setTheme] = useRequestContextValue<string>('theme');\n *\n *   return (\n *     <div>\n *       <p>Current theme: {theme || 'default'}</p>\n *       <button onClick={() => setTheme('dark')}>Dark</button>\n *       <button onClick={() => setTheme('light')}>Light</button>\n *     </div>\n *   );\n * }\n * ```\n */\nexport function useRequestContextValue<T = unknown>(\n  key: string,\n): [T | undefined, (value: T) => void] {\n  const context = useContext(UnirendContext);\n\n  // State to track the current value\n  const [value, setValue] = useState<T | undefined>(\n    () => getRequestContextValue(context, key) as T | undefined,\n  );\n\n  // Effect to sync value when requestContextRevision changes (from other components)\n  // We intentionally only depend on requestContextRevision, not key\n  useEffect(() => {\n    // Synchronizing with external state (request context) tracked by revision counter\n    setValue(getRequestContextValue(context, key) as T | undefined);\n  }, [context.requestContextRevision, context, key]);\n\n  // Setter function that updates storage and increments revision\n  const setContextValue = (newValue: T): void => {\n    setRequestContextValue(context, key, newValue);\n    // Update local state immediately for this component\n    setValue(newValue);\n  };\n\n  return [value, setContextValue];\n}\n","/**\n * Recursively freezes an object and all nested objects, making the entire\n * structure immutable (deep freeze, vs Object.freeze which is shallow).\n *\n * Pure utility with no dependencies — safe to import in both server and\n * client code.\n *\n * Used to freeze public app config clones (so they cannot be mutated\n * within a request, even on nested sub-objects) and debug context snapshots\n * returned by useRequestContextObjectRaw(). The source object is never affected.\n */\nexport function deepFreeze<T>(obj: T): T {\n  if (obj === null || typeof obj !== 'object') {\n    return obj;\n  }\n\n  Object.freeze(obj);\n\n  for (const value of Object.values(obj as object)) {\n    if (value && typeof value === 'object' && !Object.isFrozen(value)) {\n      deepFreeze(value);\n    }\n  }\n\n  return obj;\n}\n\nexport const MINIMUM_SUPPORTED_NODE_MAJOR = 25;\n\nexport type RuntimeName = 'bun' | 'node' | 'unknown';\n\nexport interface RuntimeSupportInfo {\n  runtime: RuntimeName;\n  isSupported: boolean;\n  minimumNodeMajor: number;\n  nodeVersion?: string;\n  bunVersion?: string;\n}\n\ninterface RuntimeEnvironmentLike {\n  Bun?: unknown;\n  process?: {\n    versions?: Partial<Record<'node' | 'bun', string>>;\n  };\n}\n\nfunction parseMajorVersion(version?: string): number | undefined {\n  if (!version) {\n    return undefined;\n  }\n\n  const [majorPart] = version.split('.');\n  const major = Number.parseInt(majorPart, 10);\n\n  return Number.isFinite(major) ? major : undefined;\n}\n\n/**\n * Detect the current JavaScript runtime and whether it satisfies Unirend's\n * runtime requirement. Bun is treated as supported even if it reports an older\n * Node compatibility version via `process.versions.node`.\n */\nexport function getRuntimeSupportInfo(\n  minimumNodeMajor = MINIMUM_SUPPORTED_NODE_MAJOR,\n  environment: RuntimeEnvironmentLike = globalThis as RuntimeEnvironmentLike,\n): RuntimeSupportInfo {\n  const versions = environment.process?.versions;\n  const nodeVersion =\n    typeof versions?.node === 'string' ? versions.node : undefined;\n  const bunVersion =\n    typeof versions?.bun === 'string' ? versions.bun : undefined;\n  const isBun =\n    typeof environment.Bun !== 'undefined' || typeof bunVersion === 'string';\n\n  if (isBun) {\n    return {\n      runtime: 'bun',\n      isSupported: true,\n      minimumNodeMajor,\n      nodeVersion,\n      bunVersion,\n    };\n  }\n\n  if (!nodeVersion) {\n    return {\n      runtime: 'unknown',\n      isSupported: false,\n      minimumNodeMajor,\n    };\n  }\n\n  const nodeMajor = parseMajorVersion(nodeVersion);\n\n  return {\n    runtime: 'node',\n    isSupported: typeof nodeMajor === 'number' && nodeMajor >= minimumNodeMajor,\n    minimumNodeMajor,\n    nodeVersion,\n  };\n}\n\n/**\n * Convenience boolean check for Unirend's runtime requirement.\n */\nexport function isSupportedRuntime(\n  minimumNodeMajor = MINIMUM_SUPPORTED_NODE_MAJOR,\n  environment?: RuntimeEnvironmentLike,\n): boolean {\n  return getRuntimeSupportInfo(minimumNodeMajor, environment).isSupported;\n}\n\n/**\n * Throw a descriptive error when the current runtime does not satisfy\n * Unirend's runtime requirement.\n */\nexport function assertSupportedRuntime(\n  minimumNodeMajor = MINIMUM_SUPPORTED_NODE_MAJOR,\n  environment?: RuntimeEnvironmentLike,\n): void {\n  const runtimeInfo = getRuntimeSupportInfo(minimumNodeMajor, environment);\n\n  if (runtimeInfo.isSupported) {\n    return;\n  }\n\n  const detectedVersion = runtimeInfo.nodeVersion ?? 'unknown';\n\n  throw new Error(\n    `Unirend requires Node >= ${minimumNodeMajor} or Bun. Detected ${runtimeInfo.runtime} runtime with Node version ${detectedVersion}.`,\n  );\n}\n","import React, { type ComponentType, type ReactNode } from 'react';\nimport { UnirendHeadProvider } from '../UnirendHead';\nimport type { HeadCollector } from '../UnirendHead';\n\n/**\n * Conditional StrictMode wrapper component\n */\nexport function ConditionalStrictMode({\n  isEnabled,\n  children,\n}: {\n  isEnabled: boolean;\n  children: ReactNode;\n}) {\n  if (isEnabled) {\n    return <React.StrictMode>{children}</React.StrictMode>;\n  }\n\n  return <>{children}</>;\n}\n\n/**\n * UnirendHead wrapper — on server passes the collector, on client passes null\n */\nexport function UnirendHeadWrapper({\n  collector,\n  children,\n}: {\n  collector?: HeadCollector;\n  children: ReactNode;\n}) {\n  return (\n    <UnirendHeadProvider collector={collector ?? null}>\n      {children}\n    </UnirendHeadProvider>\n  );\n}\n\n/**\n * Custom wrapper component handler\n */\nexport function CustomWrapper({\n  WrapComponent,\n  children,\n}: {\n  WrapComponent?: ComponentType<{ children: ReactNode }>;\n  children: ReactNode;\n}) {\n  if (WrapComponent) {\n    return <WrapComponent>{children}</WrapComponent>;\n  }\n\n  return <>{children}</>;\n}\n","import type { ReactNode } from 'react';\nimport { UnirendHeadContext } from './context';\nimport type { HeadCollector } from './context';\n\n/**\n * Wraps the app tree to enable UnirendHead on both server and client.\n *\n * Server: pass a collector object — UnirendHead will push entries into it\n * during renderToString, then the caller reads the collected data.\n *\n * Client: pass null — UnirendHead renders the actual <title>/<meta>/<link>\n * tags and React 19 hoists them to <head> automatically.\n */\nexport function UnirendHeadProvider({\n  children,\n  collector,\n}: {\n  children: ReactNode;\n  collector: HeadCollector | null;\n}) {\n  return (\n    <UnirendHeadContext.Provider value={collector}>\n      {children}\n    </UnirendHeadContext.Provider>\n  );\n}\n","import React, { useContext } from 'react';\nimport type { ReactNode } from 'react';\nimport { UnirendHeadContext } from './context';\nimport type { HeadCollector } from './context';\n\n/**\n * Framework-native document head manager.\n *\n * Place <title>, <meta>, and <link> tags as direct children.\n * Works identically in SSR, SSG, and SPA modes.\n *\n * Server: collects tags via context for injection into the HTML template.\n * Client: renders tags directly; React 19 hoists them to <head>.\n *\n * @example\n * ```tsx\n * import { UnirendHead } from 'unirend/client';\n *\n * function HomePage() {\n *   return (\n *     <>\n *       <UnirendHead>\n *         <title>Home - My App</title>\n *         <meta name=\"description\" content=\"Welcome to my app\" />\n *         <link rel=\"canonical\" href=\"https://example.com/\" />\n *       </UnirendHead>\n *       <main>...</main>\n *     </>\n *   );\n * }\n * ```\n */\nexport function UnirendHead({ children }: { children?: ReactNode }) {\n  const collector = useContext(UnirendHeadContext);\n\n  if (collector !== null) {\n    // Server-side: walk children and collect into the ref.\n    // renderToString is synchronous so mutations here are safe.\n    collectServerHead(collector, children);\n\n    // Render nothing server-side — data is captured in the collector.\n    // The server injects it into <head> via the <!--ss-head--> marker.\n    return null;\n  }\n\n  // Client-side: render the children as real DOM elements.\n  // React 19 automatically hoists <title>, <meta>, <link> to <head>.\n  return <>{children}</>;\n}\n\nfunction collectServerHead(\n  collector: HeadCollector,\n  children: ReactNode,\n): void {\n  React.Children.forEach(children, (child) => {\n    if (!React.isValidElement(child)) {\n      return;\n    }\n\n    const type = child.type as string;\n    const props = child.props as Record<string, unknown>;\n\n    if (type === 'title') {\n      // Last write wins — child route titles override parent layout titles\n      collector.title = toTitleText(props.children as ReactNode);\n    } else if (type === 'meta') {\n      // Accumulate — parent layout and child page metas coexist\n      collector.metas.push(toHeadAttributes(props));\n    } else if (type === 'link') {\n      collector.links.push(toHeadAttributes(props));\n    }\n  });\n}\n\nfunction toTitleText(children: ReactNode): string {\n  return React.Children.toArray(children)\n    .map((node) => {\n      if (\n        typeof node === 'string' ||\n        typeof node === 'number' ||\n        typeof node === 'bigint'\n      ) {\n        return String(node);\n      }\n\n      return '';\n    })\n    .join('');\n}\n\nfunction toHeadAttributes(\n  props: Record<string, unknown>,\n): Record<string, string> {\n  const attrs: Record<string, string> = {};\n\n  for (const [key, value] of Object.entries(props)) {\n    if (key === 'children' || value === null || value === undefined) {\n      continue;\n    }\n\n    const attrValue = toHeadAttributeValue(value);\n    if (attrValue !== null) {\n      attrs[key] = attrValue;\n    }\n  }\n\n  return attrs;\n}\n\nfunction toHeadAttributeValue(value: unknown): string | null {\n  if (typeof value === 'string') {\n    return value;\n  }\n\n  if (typeof value === 'number' || typeof value === 'bigint') {\n    return String(value);\n  }\n\n  if (typeof value === 'boolean') {\n    return value ? 'true' : 'false';\n  }\n\n  return null;\n}\n","import type { ReactElement } from 'react';\nimport type { HeadCollector } from '../UnirendHead';\nimport { UnirendProvider } from '../UnirendContext';\nimport {\n  ConditionalStrictMode,\n  UnirendHeadWrapper,\n  CustomWrapper,\n} from './Wrappers';\nimport type { WrapAppElementOptions } from './types';\n\n/**\n * Core unified wrapper function that applies the standard app wrapper chain\n * This ensures EXACTLY the same wrapping order between client and server:\n * StrictMode (outermost) > UnirendProvider > UnirendHeadProvider > rootProviders > RouterElement (innermost)\n *\n * The key insight is that client and server should render identically:\n * - Router type (RouterProvider vs StaticRouterProvider) - different\n * - UnirendHeadProvider - SAME on both, but server gets a collector, client gets null\n * - UnirendProvider - SAME on both, provides render mode and server context\n *\n * @param routerElement - The router element (RouterProvider or StaticRouterProvider)\n * @param options - Configuration options for wrapping\n * @param headCollector - Head data collector for server-side rendering (null on client)\n * @returns The wrapped React element\n */\n\nexport function createAppWrapper(\n  routerElement: ReactElement,\n  options: WrapAppElementOptions,\n  headCollector?: HeadCollector,\n): ReactElement {\n  const {\n    strictMode: isStrictMode = true,\n    rootProviders,\n    unirendContext,\n  } = options;\n\n  return (\n    <ConditionalStrictMode isEnabled={isStrictMode}>\n      <UnirendProvider value={unirendContext}>\n        <UnirendHeadWrapper collector={headCollector}>\n          <CustomWrapper WrapComponent={rootProviders}>\n            {routerElement}\n          </CustomWrapper>\n        </UnirendHeadWrapper>\n      </UnirendProvider>\n    </ConditionalStrictMode>\n  );\n}\n","import type { ReactElement } from 'react';\nimport { StaticRouterProvider } from 'react-router';\nimport type { StaticHandlerContext } from 'react-router';\nimport type { HeadCollector } from '../UnirendHead';\nimport { createAppWrapper } from './CreateAppWrapper';\nimport type { WrapAppElementOptions } from './types';\n\n/**\n * SERVER-SIDE: Wraps a Static Router with the standard app wrappers\n * Uses StaticRouterProvider with UnirendHeadProvider (collector captures head data)\n *\n * @param router - The Static Router instance\n * @param context - The static router context\n * @param options - Configuration options for wrapping\n * @param headCollector - Head data collector for server-side rendering\n * @returns The wrapped StaticRouterProvider element\n */\n\nexport function wrapStaticRouter(\n  router: Parameters<typeof StaticRouterProvider>[0]['router'],\n  context: StaticHandlerContext,\n  options: WrapAppElementOptions,\n  headCollector?: HeadCollector,\n): ReactElement {\n  const routerElement = (\n    <StaticRouterProvider router={router} context={context} />\n  );\n\n  return createAppWrapper(routerElement, options, headCollector);\n}\n","import { useMemo } from 'react';\nimport { useLocation } from 'react-router';\nimport qs from 'qs';\n\n/**\n * Returns the current URL's query parameters parsed with qs, supporting nested\n * objects and arrays (e.g. `?filters[status]=active&ids[]=1&ids[]=2`).\n *\n * The returned object matches the shape of `params.queryParams` in page data\n * loader handlers — so what you read in a component is consistent with what\n * the server handler receives.\n *\n * Re-parses only when the search string changes.\n *\n * @example\n * ```tsx\n * import { useQueryParams } from 'unirend/client';\n *\n * interface ProductsQueryParams {\n *   filters?: { status?: string; tags?: string[] };\n * }\n *\n * function ProductsPage() {\n *   const { filters } = useQueryParams<ProductsQueryParams>();\n *   return <div>Status: {filters?.status}</div>;\n * }\n * ```\n */\nexport function useQueryParams<T = Record<string, unknown>>(): T {\n  const { search } = useLocation();\n\n  return useMemo(\n    () => qs.parse(search, { ignoreQueryPrefix: true }),\n    [search],\n  ) as unknown as T;\n}\n\n/**\n * Serializes a params object into a query string using qs, supporting nested\n * objects and arrays. Returns the string without a leading `?` — prepend one\n * yourself when passing to `navigate()` or building a `<Link to>`.\n *\n * @example\n * ```ts\n * import { stringifyQueryParams } from 'unirend/router-utils';\n * import { useNavigate } from 'react-router';\n *\n * const navigate = useNavigate();\n * navigate(`?${stringifyQueryParams({ filters: { status: 'active' }, ids: [1, 2] })}`);\n * // → ?filters%5Bstatus%5D=active&ids%5B0%5D=1&ids%5B1%5D=2\n * ```\n */\nexport function stringifyQueryParams(params: Record<string, unknown>): string {\n  return qs.stringify(params);\n}\n"],"mappings":"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","names":["import_react_router","import_context","import_react","import_context","import_jsx_runtime","import_react","import_context","import_jsx_runtime","React","import_jsx_runtime","React","import_jsx_runtime","import_jsx_runtime","import_react_router","import_jsx_runtime","import_react","import_react_router","qs"]}