{"version":3,"sources":["../modules/runtime/client/index.tsx","../modules/runtime/client/bootstrap.tsx","../modules/runtime/client/constants.ts","../modules/runtime/client/window-data.ts","../modules/runtime/client/route-matcher.ts","../modules/runtime/client/metadata.ts","../modules/runtime/client/AppShell.tsx","../modules/runtime/client/RouterView.tsx","../modules/react/cache/client-data-cache/index.ts","../modules/runtime/client/navigation.ts","../modules/runtime/client/RouterContext.tsx","../modules/runtime/client/hot-reload.ts"],"sourcesContent":["// Re-export all public types and functions\r\nexport type {\r\n  ClientLoadedComponents,\r\n  ClientRouteLoaded,\r\n  ClientRouteMatch,\r\n  RouteViewState,\r\n  InitialData,\r\n} from \"./types\";\r\n\r\nexport { bootstrapClient } from \"./bootstrap\";\r\nexport type { AppShellProps } from \"./AppShell\";\r\n","import { hydrateRoot } from \"react-dom/client\";\r\nimport { APP_CONTAINER_ID } from \"./constants\";\r\nimport { getWindowData, getRouterData, setRouterData, setPreservedLayoutProps } from \"./window-data\";\r\nimport { matchRouteClient } from \"./route-matcher\";\r\nimport { applyMetadata } from \"./metadata\";\r\nimport { AppShell } from \"./AppShell\";\r\nimport { setupHotReload } from \"./hot-reload\";\r\nimport type {\r\n  InitialData,\r\n  ClientRouteLoaded,\r\n  RouteViewState,\r\n} from \"./types\";\r\n\r\nexport async function loadInitialRoute(\r\n  initialUrl: string,\r\n  initialData: InitialData | null,\r\n  routes: ClientRouteLoaded[],\r\n  notFoundRoute: ClientRouteLoaded | null,\r\n  errorRoute: ClientRouteLoaded | null\r\n): Promise<RouteViewState> {\r\n  const isInitialNotFound = initialData?.notFound === true;\r\n  const isInitialError = initialData?.error === true;\r\n\r\n  let initialRoute: ClientRouteLoaded | null = null;\r\n  let initialParams: Record<string, string> = {};\r\n  let initialComponents = null;\r\n\r\n  if (isInitialError && errorRoute) {\r\n    initialRoute = errorRoute;\r\n    initialParams = initialData?.params ?? {};\r\n    initialComponents = await errorRoute.load();\r\n  } else if (isInitialNotFound && notFoundRoute) {\r\n    initialRoute = notFoundRoute;\r\n    initialParams = {};\r\n    initialComponents = await notFoundRoute.load();\r\n  } else {\r\n    const match = matchRouteClient(initialUrl, routes);\r\n    if (match) {\r\n      initialRoute = match.route;\r\n      initialParams = match.params;\r\n      initialComponents = await match.route.load();\r\n    } else if (notFoundRoute) {\r\n      initialRoute = notFoundRoute;\r\n      initialParams = {};\r\n      initialComponents = await notFoundRoute.load();\r\n    } else {\r\n      console.warn(\r\n        `[client] No route match found for ${initialUrl}. Available routes:`,\r\n        routes.map((r) => r.pattern)\r\n      );\r\n    }\r\n  }\r\n\r\n  return {\r\n    url: initialUrl,\r\n    route: initialRoute,\r\n    params: initialParams,\r\n    components: initialComponents,\r\n    props: initialData?.props ?? {},\r\n  };\r\n}\r\n\r\n/**\r\n * Initializes router data from server or builds it from the current URL.\r\n */\r\nfunction initializeRouterData(\r\n  initialUrl: string,\r\n  initialData: InitialData | null\r\n): void {\r\n  let routerData = getRouterData();\r\n  if (!routerData) {\r\n    const url = new URL(initialUrl, window.location.origin);\r\n    // Use initialData.pathname if available (rewritten path from server)\r\n    // This ensures rewrites work correctly on the client\r\n    const pathname = initialData?.pathname || url.pathname;\r\n    routerData = {\r\n      pathname,\r\n      params: initialData?.params || {},\r\n      searchParams: Object.fromEntries(url.searchParams.entries()),\r\n    };\r\n    setRouterData(routerData);\r\n  }\r\n}\r\n\r\n/**\r\n * Loads and hydrates the initial route.\r\n */\r\nasync function hydrateInitialRoute(\r\n  container: HTMLElement,\r\n  initialUrl: string,\r\n  initialData: InitialData | null,\r\n  routes: ClientRouteLoaded[],\r\n  notFoundRoute: ClientRouteLoaded | null,\r\n  errorRoute: ClientRouteLoaded | null\r\n): Promise<void> {\r\n  try {\r\n    // Load initial route\r\n    const initialState = await loadInitialRoute(\r\n      initialUrl,\r\n      initialData,\r\n      routes,\r\n      notFoundRoute,\r\n      errorRoute\r\n    );\r\n\r\n    // Apply metadata if available\r\n    if (initialData?.metadata) {\r\n      try {\r\n        applyMetadata(initialData.metadata);\r\n      } catch (metadataError) {\r\n        console.warn(\"[client] Error applying metadata:\", metadataError);\r\n        // Continue even if metadata fails\r\n      }\r\n    }\r\n\r\n    // Hydrate React root\r\n    hydrateRoot(\r\n      container,\r\n      <AppShell\r\n        initialState={initialState}\r\n        routes={routes}\r\n        notFoundRoute={notFoundRoute}\r\n        errorRoute={errorRoute}\r\n      />\r\n    );\r\n  } catch (error) {\r\n    console.error(\r\n      \"[client] Error loading initial route components for\",\r\n      initialUrl,\r\n      error\r\n    );\r\n    throw error; // Re-throw to handle in bootstrapClient\r\n  }\r\n}\r\n\r\n/**\r\n * Bootstraps the client-side application.\r\n * \r\n * Simplified flow:\r\n * 1. Setup hot reload (development only)\r\n * 2. Get container and initial data\r\n * 3. Initialize router data\r\n * 4. Load and hydrate initial route\r\n *\r\n * @param routes - Array of client routes\r\n * @param notFoundRoute - Not-found route definition\r\n * @param errorRoute - Error route definition\r\n */\r\nexport function bootstrapClient(\r\n  routes: ClientRouteLoaded[],\r\n  notFoundRoute: ClientRouteLoaded | null,\r\n  errorRoute: ClientRouteLoaded | null = null\r\n): void {\r\n  // 1. Setup hot reload (development only)\r\n  setupHotReload();\r\n\r\n  // Start bootstrap process\r\n  (async () => {\r\n    try {\r\n      // 2. Get container and initial data\r\n      const container = document.getElementById(APP_CONTAINER_ID);\r\n      if (!container) {\r\n        console.error(`\\n❌ [client] Hydration failed: Container #${APP_CONTAINER_ID} not found`);\r\n        console.error(\"💡 This usually means:\");\r\n        console.error(\"  • The HTML structure doesn't match what React expects\");\r\n        console.error(\"  • The container was removed before hydration\");\r\n        console.error(\"  • There's a mismatch between SSR and client HTML\\n\");\r\n        return;\r\n      }\r\n\r\n      const initialData = getWindowData();\r\n      \r\n      // Use initialData.pathname if available (contains rewritten path from server)\r\n      // Otherwise fall back to window.location.pathname (original URL)\r\n      // This ensures rewrites work correctly: server rewrites the path, client uses rewritten path for matching\r\n      const initialUrl = (initialData?.pathname || window.location.pathname) + window.location.search;\r\n\r\n      // Preserve layout props from initial load (they come combined in initialData.props)\r\n      // In SSR, layout hooks are always executed, so we need to extract layout props\r\n      // For now, we'll preserve all props as layout props since they're combined\r\n      // This ensures navigation items are available even in SPA navigation\r\n      if (initialData?.props) {\r\n        // In SSR, props are combined (layout + page), so we preserve them all as layout props\r\n        // This is not perfect but ensures layout props are available in SPA navigation\r\n        setPreservedLayoutProps(initialData.props);\r\n      }\r\n\r\n      // 3. Initialize router data\r\n      // Use initialData.pathname if available (rewritten path) for router data\r\n      const routerPathname = initialData?.pathname || window.location.pathname;\r\n      initializeRouterData(routerPathname + window.location.search, initialData);\r\n\r\n      // 4. Load and hydrate initial route\r\n      await hydrateInitialRoute(\r\n        container,\r\n        initialUrl,\r\n        initialData,\r\n        routes,\r\n        notFoundRoute,\r\n        errorRoute\r\n      );\r\n    } catch (error) {\r\n      // Fatal error during bootstrap - reload the page\r\n      console.error(\"\\n❌ [client] Fatal error during bootstrap:\");\r\n      console.error(error);\r\n      if (error instanceof Error) {\r\n        console.error(\"\\nError details:\");\r\n        console.error(`  Message: ${error.message}`);\r\n        if (error.stack) {\r\n          console.error(`  Stack: ${error.stack}`);\r\n        }\r\n      }\r\n      console.error(\"\\n💡 Attempting page reload to recover...\\n\");\r\n      window.location.reload();\r\n    }\r\n  })();\r\n}\r\n\r\n","// Client-side constants (hardcoded to avoid alias resolution issues in Rspack)\r\nexport const WINDOW_DATA_KEY = \"__FW_DATA__\";\r\nexport const ROUTER_DATA_KEY = \"__LOLY_ROUTER_DATA__\";\r\nexport const APP_CONTAINER_ID = \"__app\";\r\n// Global key for navigate function fallback (exposed by AppShell for hydration timing issues)\r\nexport const ROUTER_NAVIGATE_KEY = \"__LOLY_ROUTER_NAVIGATE__\";\r\n\r\n","import { WINDOW_DATA_KEY, ROUTER_DATA_KEY } from \"./constants\";\nimport type { InitialData, RouterData } from \"./types\";\n\nconst LAYOUT_PROPS_KEY = \"__FW_LAYOUT_PROPS__\";\n\nexport function getWindowData(): InitialData | null {\n  if (typeof window === \"undefined\") {\n    return null;\n  }\n  return (window[WINDOW_DATA_KEY] as InitialData | undefined) ?? null;\n}\n\n/**\n * Gets preserved layout props from window storage.\n * Layout props are preserved across SPA navigations when layout hooks are skipped.\n */\nexport function getPreservedLayoutProps(): Record<string, any> | null {\n  if (typeof window === \"undefined\") {\n    return null;\n  }\n  return ((window as any)[LAYOUT_PROPS_KEY] as Record<string, any> | undefined) ?? null;\n}\n\n/**\n * Sets preserved layout props in window storage.\n * These props are used when layout hooks are skipped in SPA navigation.\n */\nexport function setPreservedLayoutProps(props: Record<string, any> | null): void {\n  if (typeof window === \"undefined\") {\n    return;\n  }\n  if (props === null) {\n    delete (window as any)[LAYOUT_PROPS_KEY];\n  } else {\n    (window as any)[LAYOUT_PROPS_KEY] = props;\n  }\n}\n\nexport function getRouterData(): RouterData | null {\n  if (typeof window === \"undefined\") {\n    return null;\n  }\n  return (window[ROUTER_DATA_KEY] as RouterData | undefined) ?? null;\n}\n\nexport function setWindowData(data: InitialData): void {\n  window[WINDOW_DATA_KEY] = data;\n  \n  // Dispatch event for components to listen to (e.g. ThemeProvider)\n  // This ensures components update when navigating in SPA mode\n  if (typeof window !== \"undefined\") {\n    window.dispatchEvent(\n      new CustomEvent(\"fw-data-refresh\", {\n        detail: { data },\n      })\n    );\n  }\n}\n\nexport function setRouterData(data: RouterData): void {\n  window[ROUTER_DATA_KEY] = data;\n  \n  // Dispatch event for router data updates\n  if (typeof window !== \"undefined\") {\n    window.dispatchEvent(\n      new CustomEvent(\"fw-router-data-refresh\", {\n        detail: { data },\n      })\n    );\n  }\n}\n\nexport function getCurrentTheme(): string | null {\n  return getWindowData()?.theme ?? null;\n}\n\n","import type { ClientRouteLoaded, ClientRouteMatch } from \"./types\";\r\n\r\nexport function buildClientRegexFromPattern(pattern: string): RegExp {\r\n  const segments = pattern.split(\"/\").filter(Boolean);\r\n  const regexParts: string[] = [];\r\n\r\n  for (let i = 0; i < segments.length; i++) {\r\n    const seg = segments[i];\r\n\r\n    // catch-all [...slug]\r\n    if (seg.startsWith(\"[...\") && seg.endsWith(\"]\")) {\r\n      if (i !== segments.length - 1) {\r\n        throw new Error(\r\n          `Catch-all segment \"${seg}\" in \"${pattern}\" must be the last segment.`\r\n        );\r\n      }\r\n      regexParts.push(\"(.+)\");\r\n      continue;\r\n    }\r\n\r\n    // dynamic [id]\r\n    if (seg.startsWith(\"[\") && seg.endsWith(\"]\")) {\r\n      regexParts.push(\"([^/]+)\");\r\n      continue;\r\n    }\r\n\r\n    // static segment\r\n    const escaped = seg.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\r\n    regexParts.push(escaped);\r\n  }\r\n\r\n  const regexSource = \"^/\" + regexParts.join(\"/\") + \"/?$\";\r\n  return new RegExp(regexSource);\r\n}\r\n\r\nexport function matchRouteClient(\r\n  pathWithSearch: string,\r\n  routes: ClientRouteLoaded[]\r\n): ClientRouteMatch | null {\r\n  const [pathname] = pathWithSearch.split(\"?\");\r\n  for (const r of routes) {\r\n    const regex = buildClientRegexFromPattern(r.pattern);\r\n    const match = regex.exec(pathname);\r\n    if (!match) continue;\r\n\r\n    const params: Record<string, string> = {};\r\n    r.paramNames.forEach((name, idx) => {\r\n      params[name] = decodeURIComponent(match[idx + 1] || \"\");\r\n    });\r\n\r\n    return { route: r, params };\r\n  }\r\n  return null;\r\n}\r\n\r\n","import type { PageMetadata } from \"@router/index\";\r\n\r\n/**\r\n * Helper to get or create a meta tag element\r\n */\r\nfunction getOrCreateMeta(\r\n  selector: string,\r\n  attributes: { name?: string; property?: string; httpEquiv?: string }\r\n): HTMLMetaElement {\r\n  let meta = document.querySelector(selector) as HTMLMetaElement | null;\r\n  if (!meta) {\r\n    meta = document.createElement(\"meta\");\r\n    if (attributes.name) meta.name = attributes.name;\r\n    if (attributes.property) meta.setAttribute(\"property\", attributes.property);\r\n    if (attributes.httpEquiv) meta.httpEquiv = attributes.httpEquiv;\r\n    document.head.appendChild(meta);\r\n  }\r\n  return meta;\r\n}\r\n\r\n/**\r\n * Helper to get or create a link tag element\r\n */\r\nfunction getOrCreateLink(rel: string, href: string): HTMLLinkElement {\r\n  const selector = `link[rel=\"${rel}\"]`;\r\n  let link = document.querySelector(selector) as HTMLLinkElement | null;\r\n  if (!link) {\r\n    link = document.createElement(\"link\");\r\n    link.rel = rel;\r\n    link.href = href;\r\n    document.head.appendChild(link);\r\n  } else {\r\n    link.href = href;\r\n  }\r\n  return link;\r\n}\r\n\r\n/**\r\n * Updates page metadata in the document head.\r\n * Supports all metadata fields including Open Graph, Twitter Cards, canonical URLs, etc.\r\n * \r\n * Uses requestAnimationFrame to batch DOM operations and avoid forced reflows.\r\n * \r\n * @param md - Page metadata object\r\n */\r\nexport function applyMetadata(md?: PageMetadata | null): void {\r\n  if (!md) return;\r\n\r\n  // Batch all DOM operations in a single frame to avoid forced reflows\r\n  requestAnimationFrame(() => {\r\n    // Title\r\n    if (md.title) {\r\n      document.title = md.title;\r\n    }\r\n\r\n    // Description\r\n    if (md.description) {\r\n      const meta = getOrCreateMeta('meta[name=\"description\"]', { name: \"description\" });\r\n      meta.content = md.description;\r\n    }\r\n\r\n    // Robots\r\n    if (md.robots) {\r\n      const meta = getOrCreateMeta('meta[name=\"robots\"]', { name: \"robots\" });\r\n      meta.content = md.robots;\r\n    }\r\n\r\n    // Theme color\r\n    if (md.themeColor) {\r\n      const meta = getOrCreateMeta('meta[name=\"theme-color\"]', { name: \"theme-color\" });\r\n      meta.content = md.themeColor;\r\n    }\r\n\r\n    // Viewport\r\n    if (md.viewport) {\r\n      const meta = getOrCreateMeta('meta[name=\"viewport\"]', { name: \"viewport\" });\r\n      meta.content = md.viewport;\r\n    }\r\n\r\n    // Canonical URL\r\n    if (md.canonical) {\r\n      getOrCreateLink(\"canonical\", md.canonical);\r\n    }\r\n\r\n    // Open Graph tags\r\n    if (md.openGraph) {\r\n      const og = md.openGraph;\r\n\r\n      if (og.title) {\r\n        const meta = getOrCreateMeta('meta[property=\"og:title\"]', { property: \"og:title\" });\r\n        meta.content = og.title;\r\n      }\r\n\r\n      if (og.description) {\r\n        const meta = getOrCreateMeta('meta[property=\"og:description\"]', { property: \"og:description\" });\r\n        meta.content = og.description;\r\n      }\r\n\r\n      if (og.type) {\r\n        const meta = getOrCreateMeta('meta[property=\"og:type\"]', { property: \"og:type\" });\r\n        meta.content = og.type;\r\n      }\r\n\r\n      if (og.url) {\r\n        const meta = getOrCreateMeta('meta[property=\"og:url\"]', { property: \"og:url\" });\r\n        meta.content = og.url;\r\n      }\r\n\r\n      if (og.image) {\r\n        if (typeof og.image === \"string\") {\r\n          const meta = getOrCreateMeta('meta[property=\"og:image\"]', { property: \"og:image\" });\r\n          meta.content = og.image;\r\n        } else {\r\n          const meta = getOrCreateMeta('meta[property=\"og:image\"]', { property: \"og:image\" });\r\n          meta.content = og.image.url;\r\n\r\n          if (og.image.width) {\r\n            const metaWidth = getOrCreateMeta('meta[property=\"og:image:width\"]', { property: \"og:image:width\" });\r\n            metaWidth.content = String(og.image.width);\r\n          }\r\n\r\n          if (og.image.height) {\r\n            const metaHeight = getOrCreateMeta('meta[property=\"og:image:height\"]', { property: \"og:image:height\" });\r\n            metaHeight.content = String(og.image.height);\r\n          }\r\n\r\n          if (og.image.alt) {\r\n            const metaAlt = getOrCreateMeta('meta[property=\"og:image:alt\"]', { property: \"og:image:alt\" });\r\n            metaAlt.content = og.image.alt;\r\n          }\r\n        }\r\n      }\r\n\r\n      if (og.siteName) {\r\n        const meta = getOrCreateMeta('meta[property=\"og:site_name\"]', { property: \"og:site_name\" });\r\n        meta.content = og.siteName;\r\n      }\r\n\r\n      if (og.locale) {\r\n        const meta = getOrCreateMeta('meta[property=\"og:locale\"]', { property: \"og:locale\" });\r\n        meta.content = og.locale;\r\n      }\r\n    }\r\n\r\n    // Twitter Card tags\r\n    if (md.twitter) {\r\n      const twitter = md.twitter;\r\n\r\n      if (twitter.card) {\r\n        const meta = getOrCreateMeta('meta[name=\"twitter:card\"]', { name: \"twitter:card\" });\r\n        meta.content = twitter.card;\r\n      }\r\n\r\n      if (twitter.title) {\r\n        const meta = getOrCreateMeta('meta[name=\"twitter:title\"]', { name: \"twitter:title\" });\r\n        meta.content = twitter.title;\r\n      }\r\n\r\n      if (twitter.description) {\r\n        const meta = getOrCreateMeta('meta[name=\"twitter:description\"]', { name: \"twitter:description\" });\r\n        meta.content = twitter.description;\r\n      }\r\n\r\n      if (twitter.image) {\r\n        const meta = getOrCreateMeta('meta[name=\"twitter:image\"]', { name: \"twitter:image\" });\r\n        meta.content = twitter.image;\r\n      }\r\n\r\n      if (twitter.imageAlt) {\r\n        const meta = getOrCreateMeta('meta[name=\"twitter:image:alt\"]', { name: \"twitter:image:alt\" });\r\n        meta.content = twitter.imageAlt;\r\n      }\r\n\r\n      if (twitter.site) {\r\n        const meta = getOrCreateMeta('meta[name=\"twitter:site\"]', { name: \"twitter:site\" });\r\n        meta.content = twitter.site;\r\n      }\r\n\r\n      if (twitter.creator) {\r\n        const meta = getOrCreateMeta('meta[name=\"twitter:creator\"]', { name: \"twitter:creator\" });\r\n        meta.content = twitter.creator;\r\n      }\r\n    }\r\n\r\n    // Custom meta tags\r\n    if (md.metaTags && Array.isArray(md.metaTags)) {\r\n      md.metaTags.forEach((tag) => {\r\n        let selector = \"\";\r\n        if (tag.name) {\r\n          selector = `meta[name=\"${tag.name}\"]`;\r\n        } else if (tag.property) {\r\n          selector = `meta[property=\"${tag.property}\"]`;\r\n        } else if (tag.httpEquiv) {\r\n          selector = `meta[http-equiv=\"${tag.httpEquiv}\"]`;\r\n        }\r\n\r\n        if (selector) {\r\n          const meta = getOrCreateMeta(selector, {\r\n            name: tag.name,\r\n            property: tag.property,\r\n            httpEquiv: tag.httpEquiv,\r\n          });\r\n          meta.content = tag.content;\r\n        }\r\n      });\r\n    }\r\n\r\n    // Custom link tags\r\n    if (md.links && Array.isArray(md.links)) {\r\n      md.links.forEach((link) => {\r\n        getOrCreateLink(link.rel, link.href);\r\n        // Note: Additional attributes like 'as', 'crossorigin', 'type' would need\r\n        // more complex logic to update existing links. For now, we just ensure\r\n        // the link exists with the correct href.\r\n      });\r\n    }\r\n  });\r\n}\r\n\r\n","import { useEffect, useState, useRef, useCallback } from \"react\";\r\nimport { RouterView } from \"./RouterView\";\r\nimport {\r\n  navigate,\r\n  createClickHandler,\r\n  createPopStateHandler,\r\n  createHoverHandler,\r\n  type NavigationHandlers,\r\n} from \"./navigation\";\r\nimport { RouterContext } from \"./RouterContext\";\r\nimport { ROUTER_NAVIGATE_KEY, WINDOW_DATA_KEY } from \"./constants\";\r\nimport { applyMetadata } from \"./metadata\";\r\nimport type {\r\n  RouteViewState,\r\n  ClientRouteLoaded,\r\n} from \"./types\";\r\n\r\nexport interface AppShellProps {\r\n  initialState: RouteViewState;\r\n  routes: ClientRouteLoaded[];\r\n  notFoundRoute: ClientRouteLoaded | null;\r\n  errorRoute: ClientRouteLoaded | null;\r\n}\r\n\r\nexport function AppShell({\r\n  initialState,\r\n  routes,\r\n  notFoundRoute,\r\n  errorRoute,\r\n}: AppShellProps) {\r\n  const [state, setState] = useState<RouteViewState>(initialState);\r\n  const handlersRef = useRef<NavigationHandlers>({\r\n    setState,\r\n    routes,\r\n    notFoundRoute,\r\n    errorRoute,\r\n  });\r\n\r\n  useEffect(() => {\r\n    handlersRef.current = {\r\n      setState,\r\n      routes,\r\n      notFoundRoute,\r\n      errorRoute,\r\n    };\r\n  }, [routes, notFoundRoute, errorRoute]);\r\n\r\n  // Create navigate function for router context\r\n  const handleNavigate = useCallback(\r\n    async (\r\n      nextUrl: string,\r\n      options?: { revalidate?: boolean; replace?: boolean }\r\n    ) => {\r\n      await navigate(nextUrl, handlersRef.current, {\r\n        revalidate: options?.revalidate,\r\n      });\r\n    },\r\n    []\r\n  );\r\n\r\n  /**\r\n   * SOLUTION: Expose navigate function globally as fallback\r\n   * \r\n   * During React hydration, components rendered in layouts may execute before\r\n   * RouterContext is fully available. By exposing navigate globally, useRouter\r\n   * can access it even when the context isn't ready yet, ensuring SPA navigation\r\n   * works correctly from the first render.\r\n   * \r\n   * This is similar to how window.__FW_DATA__ is used for initial data.\r\n   */\r\n  useEffect(() => {\r\n    if (typeof window !== \"undefined\") {\r\n      window[ROUTER_NAVIGATE_KEY] = handleNavigate;\r\n      return () => {\r\n        delete window[ROUTER_NAVIGATE_KEY];\r\n      };\r\n    }\r\n  }, [handleNavigate]);\r\n\r\n  useEffect(() => {\r\n    let isMounted = true;\r\n\r\n    async function handleNavigateInternal(\r\n      nextUrl: string,\r\n      options?: { revalidate?: boolean }\r\n    ) {\r\n      if (!isMounted) return;\r\n      await navigate(nextUrl, handlersRef.current, options);\r\n    }\r\n\r\n    const handleClick = createClickHandler(handleNavigateInternal);\r\n    const handlePopState = createPopStateHandler(handleNavigateInternal);\r\n    const handleHover = createHoverHandler(routes, notFoundRoute);\r\n\r\n    window.addEventListener(\"click\", handleClick, false);\r\n    window.addEventListener(\"popstate\", handlePopState, false);\r\n    window.addEventListener(\"mouseover\", handleHover, false);\r\n\r\n    return () => {\r\n      isMounted = false;\r\n      window.removeEventListener(\"click\", handleClick, false);\r\n      window.removeEventListener(\"popstate\", handlePopState, false);\r\n      window.removeEventListener(\"mouseover\", handleHover, false);\r\n    };\r\n  }, [routes, notFoundRoute]);\r\n\r\n  // Listen for data refresh events and update state when current route is revalidated\r\n  useEffect(() => {\r\n    const handleDataRefresh = () => {\r\n      const freshData = window[WINDOW_DATA_KEY];\r\n      \r\n      if (!freshData) return;\r\n      \r\n      const currentPathname = window.location.pathname;\r\n      const freshPathname = freshData.pathname;\r\n      \r\n      if (freshPathname === currentPathname) {\r\n        if (freshData.metadata !== undefined) {\r\n          applyMetadata(freshData.metadata);\r\n        }\r\n        \r\n        setState((prevState) => ({\r\n          ...prevState,\r\n          props: freshData.props ?? prevState.props,\r\n          params: freshData.params ?? prevState.params,\r\n        }));\r\n      }\r\n    };\r\n\r\n    window.addEventListener(\"fw-data-refresh\", handleDataRefresh);\r\n\r\n    return () => {\r\n      window.removeEventListener(\"fw-data-refresh\", handleDataRefresh);\r\n    };\r\n  }, []); // Empty deps - only register once, not when state.url changes\r\n\r\n  const isError = state.route === errorRoute;\r\n  const isNotFound = state.route === notFoundRoute;\r\n  const routeType = isError ? \"error\" : isNotFound ? \"notfound\" : \"normal\";\r\n  const routeKey = `${state.url}:${routeType}`;\r\n\r\n  return (\r\n    <RouterContext.Provider value={{ navigate: handleNavigate }}>\r\n      <RouterView key={routeKey} state={state} />\r\n    </RouterContext.Provider>\r\n  );\r\n}\r\n\r\n","import type { RouteViewState } from \"./types\";\r\n\r\nexport function RouterView({ state }: { state: RouteViewState }) {\r\n  if (!state.route) {\r\n    // Don't show 404 if we're waiting for components to load\r\n    if (state.components === null) {\r\n      return null;\r\n    }\r\n    return <h1>404 - Route not found</h1>;\r\n  }\r\n\r\n  if (!state.components) {\r\n    return null;\r\n  }\r\n\r\n  const { Page, layouts } = state.components;\r\n  const { params, props } = state;\r\n\r\n  let element = <Page params={params} {...props} />;\r\n\r\n  const layoutChain = layouts.slice().reverse();\r\n  for (const Layout of layoutChain) {\r\n    element = (\r\n      <Layout params={params} {...props}>\r\n        {element}\r\n      </Layout>\r\n    );\r\n  }\r\n\r\n  return element;\r\n}\r\n\r\n","import type { PageMetadata } from \"@router/index\";\n\n/**\n * Response data structure from server for route data requests\n */\nexport type RouteDataResponse = {\n  /** Combined props (layout + page) - kept for backward compatibility */\n  props?: Record<string, unknown>;\n  /** Layout props (from layout.server.hook.ts) - only present when layout hooks were executed */\n  layoutProps?: Record<string, unknown>;\n  /** Page props (from page.server.hook.ts) - always present in data requests */\n  pageProps?: Record<string, unknown>;\n  metadata?: PageMetadata | null;\n  theme?: string;\n  redirect?: { destination: string; permanent?: boolean };\n  notFound?: boolean;\n  error?: boolean;\n  message?: string;\n  params?: Record<string, string>;\n  /** Pathname after rewrite (for client-side route matching) */\n  pathname?: string;\n};\n\ntype RouteData = {\n  ok: boolean;\n  status: number;\n  json: RouteDataResponse;\n};\n\ntype CacheEntry =\n  | { status: \"pending\"; promise: Promise<RouteData> }\n  | { status: \"fulfilled\"; value: RouteData }\n  | { status: \"rejected\"; error: any };\n\n// Use window to guarantee a single shared cache instance\n// across all bundles/modules\nconst CACHE_KEY = \"__FW_DATA_CACHE__\";\n\n// Maximum number of entries in the cache (LRU)\nconst MAX_CACHE_SIZE = 100;\n\ntype CacheStore = {\n  data: Map<string, CacheEntry>;\n  index: Map<string, Set<string>>; // pathBase -> Set of keys\n  lru: string[]; // Ordered list: most recent at end, oldest at start\n};\n\nfunction getCacheStore(): CacheStore {\n  if (typeof window !== \"undefined\") {\n    if (!(window as any)[CACHE_KEY]) {\n      (window as any)[CACHE_KEY] = {\n        data: new Map<string, CacheEntry>(),\n        index: new Map<string, Set<string>>(),\n        lru: [],\n      };\n    }\n    return (window as any)[CACHE_KEY];\n  }\n  // Fallback for SSR (though this shouldn't be used on the client)\n  return {\n    data: new Map<string, CacheEntry>(),\n    index: new Map<string, Set<string>>(),\n    lru: [],\n  };\n}\n\nconst cacheStore = getCacheStore();\nconst dataCache = cacheStore.data;\nconst pathIndex = cacheStore.index;\nconst lru = cacheStore.lru;\n\n// Helper functions for cache management\n\n/**\n * Extract base path from a cache key (removes query params)\n */\nfunction extractPathBase(key: string): string {\n  return key.split(\"?\")[0];\n}\n\n/**\n * Add key to path index\n */\nfunction addToIndex(key: string): void {\n  const pathBase = extractPathBase(key);\n  if (!pathIndex.has(pathBase)) {\n    pathIndex.set(pathBase, new Set());\n  }\n  pathIndex.get(pathBase)!.add(key);\n}\n\n/**\n * Remove key from path index\n */\nfunction removeFromIndex(key: string): void {\n  const pathBase = extractPathBase(key);\n  const keys = pathIndex.get(pathBase);\n  if (keys) {\n    keys.delete(key);\n    if (keys.size === 0) {\n      pathIndex.delete(pathBase);\n    }\n  }\n}\n\n/**\n * Update LRU order - move key to end (most recent)\n */\nfunction updateLRU(key: string): void {\n  const index = lru.indexOf(key);\n  if (index !== -1) {\n    lru.splice(index, 1);\n  }\n  lru.push(key);\n}\n\n/**\n * Remove oldest entries if cache exceeds MAX_CACHE_SIZE\n */\nfunction evictOldest(): void {\n  while (lru.length >= MAX_CACHE_SIZE && lru.length > 0) {\n    const oldestKey = lru.shift()!;\n    dataCache.delete(oldestKey);\n    removeFromIndex(oldestKey);\n  }\n}\n\n/**\n * Set cache entry and maintain indexes\n */\nfunction setCacheEntry(key: string, entry: CacheEntry): void {\n  const existingEntry = dataCache.get(key);\n  const wasFulfilled = existingEntry?.status === \"fulfilled\";\n  \n  dataCache.set(key, entry);\n  \n  // Only track fulfilled entries in LRU and index (not pending/rejected)\n  if (entry.status === \"fulfilled\") {\n    // Add to index if it wasn't already fulfilled (new entry or transition from pending/rejected)\n    if (!wasFulfilled) {\n      addToIndex(key);\n    }\n    updateLRU(key);\n    evictOldest();\n  } else if (wasFulfilled) {\n    // If entry was fulfilled and now isn't (transitioning to pending/rejected), remove from index\n    removeFromIndex(key);\n  }\n}\n\n/**\n * Delete cache entry and clean up indexes\n */\nfunction deleteCacheEntry(key: string): void {\n  if (dataCache.has(key)) {\n    dataCache.delete(key);\n    removeFromIndex(key);\n    const lruIndex = lru.indexOf(key);\n    if (lruIndex !== -1) {\n      lru.splice(lruIndex, 1);\n    }\n  }\n}\n\nfunction buildDataUrl(url: string): string {\n  return url + (url.includes(\"?\") ? \"&\" : \"?\") + \"__fw_data=1\";\n}\n\nasync function fetchRouteDataOnce(\n  url: string,\n  skipLayoutHooks: boolean = true\n): Promise<RouteData> {\n  const dataUrl = buildDataUrl(url);\n\n  const headers: Record<string, string> = {\n    \"x-fw-data\": \"1\",\n    Accept: \"application/json\",\n  };\n\n  // Send header to skip layout hooks execution in SPA navigation\n  // Only skip if skipLayoutHooks is true (normal SPA navigation)\n  // If false (revalidate), don't send header to force execution of all hooks\n  if (skipLayoutHooks) {\n    headers[\"x-skip-layout-hooks\"] = \"true\";\n  }\n\n  const res = await fetch(dataUrl, { headers });\n\n  let json: any = {};\n\n  try {\n    const text = await res.text();\n    if (text) {\n      json = JSON.parse(text);\n    }\n  } catch (parseError) {\n    console.error(\n      \"[client][cache] Failed to parse response as JSON:\",\n      parseError\n    );\n  }\n\n  const result: RouteData = {\n    ok: res.ok,\n    status: res.status,\n    json,\n  };\n\n  return result;\n}\n\n/**\n * Revalidates route data by removing it from the cache.\n * The next time you navigate to this route, fresh data will be fetched from the server.\n * This is a client-side function and does not require a server-side revalidation.\n *\n * @param path - The route path to revalidate (e.g., '/posts/1' or '/posts/1?page=2')\n *               If query params are not included, revalidates all variants of that route.\n *\n * @example\n * ```ts\n * // After saving something to the DB, revalidate the route\n * await saveToDatabase(data);\n * revalidatePath('/posts');\n * \n * // Revalidate a specific route with query params\n * revalidatePath('/posts?page=2');\n * ```\n */\nexport function revalidatePath(path: string, skipAutoRevalidate: boolean = false): void {\n  // Normalize the base path (without query params)\n  const normalizedPath = path.split(\"?\")[0];\n  const hasQueryParams = path.includes(\"?\");\n  \n  // Get all keys for this path base from index (O(1) lookup)\n  const keysForPath = pathIndex.get(normalizedPath);\n  \n  if (!keysForPath || keysForPath.size === 0) {\n    return; // No entries to revalidate\n  }\n  \n  // If the path includes specific query params, extract them\n  let specificQueryParams: string | undefined;\n  if (hasQueryParams) {\n    const queryPart = path.split(\"?\")[1];\n    // Sort query params for consistent comparison\n    specificQueryParams = queryPart\n      .split(\"&\")\n      .filter((p) => !p.startsWith(\"__fw_data=\"))\n      .sort()\n      .join(\"&\");\n  }\n  \n  // Iterate only over keys for this path (much smaller set)\n  const keysToDelete: string[] = [];\n  for (const key of keysForPath) {\n    // If specific query params were specified, check if they match\n    if (hasQueryParams && specificQueryParams) {\n      const [, keyQuery = \"\"] = key.split(\"?\");\n      const keyQueryParams = keyQuery\n        .split(\"&\")\n        .filter((p) => !p.startsWith(\"__fw_data=\"))\n        .sort()\n        .join(\"&\");\n      \n      if (keyQueryParams === specificQueryParams) {\n        keysToDelete.push(key);\n      }\n    } else {\n      // If no specific query params, revalidate all variants\n      keysToDelete.push(key);\n    }\n  }\n  \n  // Delete matching entries\n  keysToDelete.forEach((key) => {\n    deleteCacheEntry(key);\n  });\n  \n  // If the revalidated path matches the current route, automatically refresh data\n  // UNLESS skipAutoRevalidate is true (to prevent recursive calls from revalidate())\n  if (!skipAutoRevalidate && typeof window !== \"undefined\") {\n    const currentPathname = window.location.pathname;\n    const currentSearch = window.location.search;\n    const matchesCurrentPath = normalizedPath === currentPathname;\n    \n    if (matchesCurrentPath) {\n      if (hasQueryParams && specificQueryParams) {\n        const currentQueryParams = currentSearch\n          .replace(\"?\", \"\")\n          .split(\"&\")\n          .filter((p) => !p.startsWith(\"__fw_data=\"))\n          .sort()\n          .join(\"&\");\n        \n        if (currentQueryParams === specificQueryParams) {\n          revalidate().catch((err) => {\n            console.error(\n              \"[client][cache] Error revalidating current route:\",\n              err\n            );\n          });\n        }\n      } else {\n        revalidate().catch((err) => {\n          console.error(\n            \"[client][cache] Error revalidating current route:\",\n            err\n          );\n        });\n      }\n    }\n  }\n}\n\n/**\n * Revalidates and refreshes the current page data.\n * Similar to Next.js's `router.refresh()`.\n * \n * This function:\n * 1. Removes the current route from cache\n * 2. Fetches fresh data from the server\n * 3. Updates window.__FW_DATA__ with the new data\n * 4. Dispatches a 'fw-data-refresh' event for components to listen to\n * \n * @returns Promise that resolves with the fresh route data\n * \n * @example\n * ```ts\n * // Refresh current page data after a mutation\n * await revalidate();\n * ```\n */\n// Flag to prevent recursive calls to revalidate()\nlet isRevalidating = false;\n\nexport async function revalidate(): Promise<RouteData> {\n  if (typeof window === \"undefined\") {\n    throw new Error(\"revalidate() can only be called on the client\");\n  }\n\n  // Prevent multiple simultaneous revalidations\n  if (isRevalidating) {\n    // Wait for the current revalidation to complete\n    const key = buildDataUrl(window.location.pathname + window.location.search);\n    const entry = dataCache.get(key);\n    if (entry && entry.status === \"pending\") {\n      return entry.promise;\n    }\n    // If no pending entry, something went wrong, allow the call\n  }\n\n  isRevalidating = true;\n  try {\n    const pathname = window.location.pathname + window.location.search;\n    \n    // Revalidate the path (remove from cache)\n    // Pass a flag to prevent revalidatePath from calling revalidate() again (recursive call)\n    revalidatePath(pathname, true); // true = skip auto-revalidate\n    \n    // Fetch fresh data\n    const freshData = await getRouteData(pathname, { revalidate: true });\n    \n    // Update window.__FW_DATA__ if it exists\n    if ((window as any).__FW_DATA__ && freshData.ok && freshData.json) {\n      const currentData = (window as any).__FW_DATA__;\n      \n      // Update preserved layout props if new ones were returned\n      if (freshData.json.layoutProps !== undefined && freshData.json.layoutProps !== null) {\n        (window as any).__FW_LAYOUT_PROPS__ = freshData.json.layoutProps;\n      }\n      \n      // Combine layout props (new or preserved) + page props\n      let combinedProps = currentData.props || {};\n      if (freshData.json.layoutProps !== undefined && freshData.json.layoutProps !== null) {\n        // Use new layout props\n        combinedProps = {\n          ...freshData.json.layoutProps,\n          ...(freshData.json.pageProps ?? freshData.json.props ?? {}),\n        };\n      } else if (freshData.json.pageProps !== undefined) {\n        // Use preserved layout props + new page props\n        const preservedLayoutProps = (window as any).__FW_LAYOUT_PROPS__ || {};\n        combinedProps = {\n          ...preservedLayoutProps,\n          ...freshData.json.pageProps,\n        };\n      } else if (freshData.json.props) {\n        // Fallback to combined props\n        combinedProps = freshData.json.props;\n      }\n      \n      (window as any).__FW_DATA__ = {\n        ...currentData,\n        pathname: pathname.split(\"?\")[0],\n        params: freshData.json.params || currentData.params || {},\n        props: combinedProps,\n        metadata: freshData.json.metadata ?? currentData.metadata ?? null,\n        notFound: freshData.json.notFound ?? false,\n        error: freshData.json.error ?? false,\n      };\n      \n      // Dispatch event for components to listen to\n      window.dispatchEvent(new CustomEvent(\"fw-data-refresh\", {\n        detail: { data: freshData },\n      }));\n    }\n    \n    return freshData;\n  } finally {\n    isRevalidating = false;\n  }\n}\n\n/**\n * @deprecated Use `revalidatePath()` instead. This function is kept for backwards compatibility.\n */\nexport function revalidateRouteData(url: string): void {\n  revalidatePath(url);\n}\n\nexport function prefetchRouteData(url: string): void {\n  const key = buildDataUrl(url);\n\n  const cached = dataCache.get(key);\n\n  if (cached && cached.status !== \"rejected\") {\n    // Update LRU if it exists and is fulfilled\n    if (cached.status === \"fulfilled\") {\n      updateLRU(key);\n    }\n    return;\n  }\n\n  // Prefetch uses skipLayoutHooks: true (normal navigation behavior)\n  const promise = fetchRouteDataOnce(url, true)\n    .then((value) => {\n      setCacheEntry(key, { status: \"fulfilled\", value });\n      return value;\n    })\n    .catch((error) => {\n      console.error(\"[client][cache] Error prefetching route data:\", error);\n      dataCache.set(key, { status: \"rejected\", error });\n      throw error;\n    });\n\n  dataCache.set(key, { status: \"pending\", promise });\n}\n\nexport type GetRouteDataOptions = {\n  /**\n   * If true, forces revalidation of route data,\n   * ignoring the cache and fetching fresh data from the server.\n   * Similar to Next.js's `router.refresh()` behavior.\n   */\n  revalidate?: boolean;\n};\n\nexport async function getRouteData(\n  url: string,\n  options?: GetRouteDataOptions\n): Promise<RouteData> {\n  const key = buildDataUrl(url);\n\n  // If revalidation is requested, remove the entry from cache\n  // This ensures we don't reuse pending or fulfilled entries\n  if (options?.revalidate) {\n    deleteCacheEntry(key);\n  }\n\n  const entry = dataCache.get(key);\n\n  if (entry && !options?.revalidate) {\n    // Only use cached entry if not revalidating\n    if (entry.status === \"fulfilled\") {\n      // Update LRU: mark as recently used\n      updateLRU(key);\n      return entry.value;\n    }\n    if (entry.status === \"pending\") {\n      // Return existing pending promise to avoid duplicate requests\n      return entry.promise;\n    }\n  }\n\n  // No entry in cache (or revalidating), fetch it\n  // skipLayoutHooks: true for normal SPA navigation, false when revalidating\n  const skipLayoutHooks = !options?.revalidate;\n  \n  // Check again if an entry was added while we were processing (race condition)\n  const currentEntry = dataCache.get(key);\n  if (currentEntry && !options?.revalidate) {\n    if (currentEntry.status === \"fulfilled\") {\n      updateLRU(key);\n      return currentEntry.value;\n    }\n    if (currentEntry.status === \"pending\") {\n      return currentEntry.promise;\n    }\n  }\n  \n  // Create a new promise for this fetch\n  const promise = fetchRouteDataOnce(url, skipLayoutHooks)\n    .then((value) => {\n      // Only set cache entry if this is still the current fetch for this key\n      // This prevents race conditions where multiple revalidations happen simultaneously\n      const entryAfterFetch = dataCache.get(key);\n      if (!entryAfterFetch || entryAfterFetch.status === \"pending\") {\n        setCacheEntry(key, { status: \"fulfilled\", value });\n      }\n      return value;\n    })\n    .catch((error) => {\n      console.error(\"[client][cache] Error fetching route data:\", error);\n      const entryAfterFetch = dataCache.get(key);\n      if (!entryAfterFetch || entryAfterFetch.status === \"pending\") {\n        dataCache.set(key, { status: \"rejected\", error });\n      }\n      throw error;\n    });\n\n  // Set pending entry - if revalidating, we already deleted it, so this is safe\n  dataCache.set(key, { status: \"pending\", promise });\n  \n  return promise;\n}\n","import { getRouteData } from \"../../react/cache/index\";\nimport type { RouteDataResponse } from \"../../react/cache/client-data-cache\";\nimport { matchRouteClient } from \"./route-matcher\";\nimport { applyMetadata } from \"./metadata\";\nimport { setWindowData, getCurrentTheme, setRouterData, getPreservedLayoutProps, setPreservedLayoutProps } from \"./window-data\";\nimport type {\n  ClientRouteLoaded,\n  RouteViewState,\n  InitialData,\n  RouterData,\n  ClientLoadedComponents,\n} from \"./types\";\n\nexport type NavigationHandlers = {\n  setState: (state: RouteViewState) => void;\n  routes: ClientRouteLoaded[];\n  notFoundRoute: ClientRouteLoaded | null;\n  errorRoute: ClientRouteLoaded | null;\n};\n\nasync function handleErrorRoute(\n  nextUrl: string,\n  json: RouteDataResponse,\n  errorRoute: ClientRouteLoaded,\n  setState: (state: RouteViewState) => void\n): Promise<boolean> {\n  try {\n    const components = await errorRoute.load();\n    \n    // Get theme: prioritize cookie, then server, then window data, then default\n    let theme: string = \"light\";\n    if (typeof document !== \"undefined\") {\n      const cookieMatch = document.cookie.match(/theme=([^;]+)/);\n      if (cookieMatch) {\n        theme = cookieMatch[1];\n      } else if (json.theme) {\n        theme = json.theme;\n      } else {\n        const currentTheme = getCurrentTheme();\n        if (currentTheme) theme = currentTheme;\n      }\n    } else if (json.theme) {\n      theme = json.theme;\n    }\n    \n    // Preserve layout props if not in response (SPA navigation)\n    let layoutProps: Record<string, any> = {};\n    if (json.layoutProps !== undefined && json.layoutProps !== null) {\n      layoutProps = json.layoutProps;\n      setPreservedLayoutProps(layoutProps);\n    } else {\n      const preserved = getPreservedLayoutProps();\n      if (preserved) {\n        layoutProps = preserved;\n      }\n    }\n\n    const pageProps = json.pageProps ?? json.props ?? {\n      error: json.message || \"An error occurred\",\n    };\n\n    const errorProps = {\n      ...layoutProps,\n      ...pageProps,\n      theme,\n    };\n\n    const windowData: InitialData = {\n      pathname: nextUrl,\n      params: json.params || {},\n      props: errorProps,\n      metadata: json.metadata ?? null,\n      theme,\n      notFound: false,\n      error: true,\n    };\n\n    setWindowData(windowData);\n\n    // Update routerData\n    const url = new URL(nextUrl, typeof window !== \"undefined\" ? window.location.origin : \"http://localhost\");\n    const routerData: RouterData = {\n      pathname: url.pathname,\n      params: json.params || {},\n      searchParams: Object.fromEntries(url.searchParams.entries()),\n    };\n    setRouterData(routerData);\n\n    setState({\n      url: nextUrl,\n      route: errorRoute,\n      params: json.params || {},\n      components,\n      props: errorProps,\n    });\n    return true;\n  } catch (loadError) {\n    console.error(\"\\n❌ [client] Error loading error route components:\");\n    console.error(loadError);\n    if (loadError instanceof Error) {\n      console.error(`   Message: ${loadError.message}`);\n      if (loadError.stack) {\n        console.error(`   Stack: ${loadError.stack.split('\\n').slice(0, 3).join('\\n   ')}`);\n      }\n    }\n    console.error(\"💡 Falling back to full page reload\\n\");\n    window.location.href = nextUrl;\n    return false;\n  }\n}\n\nasync function handleNotFoundRoute(\n  nextUrl: string,\n  json: RouteDataResponse,\n  notFoundRoute: ClientRouteLoaded | null,\n  setState: (state: RouteViewState) => void\n): Promise<void> {\n  // Get theme: prioritize cookie, then server, then window data, then default\n  let theme: string = \"light\";\n  if (typeof document !== \"undefined\") {\n    const cookieMatch = document.cookie.match(/theme=([^;]+)/);\n    if (cookieMatch) {\n      theme = cookieMatch[1];\n    } else if (json.theme) {\n      theme = json.theme;\n    } else {\n      const currentTheme = getCurrentTheme();\n      if (currentTheme) theme = currentTheme;\n    }\n  } else if (json.theme) {\n    theme = json.theme;\n  }\n  \n  // Preserve layout props if not in response (SPA navigation)\n  let layoutProps: Record<string, any> = {};\n  if (json.layoutProps !== undefined && json.layoutProps !== null) {\n    layoutProps = json.layoutProps;\n    setPreservedLayoutProps(layoutProps);\n  } else {\n    const preserved = getPreservedLayoutProps();\n    if (preserved) {\n      layoutProps = preserved;\n    }\n  }\n\n  const pageProps = json.pageProps ?? json.props ?? {};\n\n  const notFoundProps = {\n    ...layoutProps,\n    ...pageProps,\n    theme,\n  };\n\n  const windowData: InitialData = {\n    pathname: nextUrl,\n    params: {},\n    props: notFoundProps,\n    metadata: json.metadata ?? null,\n    theme,\n    notFound: true,\n    error: false,\n  };\n\n  setWindowData(windowData);\n\n  // Update routerData\n  const url = new URL(nextUrl, typeof window !== \"undefined\" ? window.location.origin : \"http://localhost\");\n  const routerData: RouterData = {\n    pathname: url.pathname,\n    params: {},\n    searchParams: Object.fromEntries(url.searchParams.entries()),\n  };\n  setRouterData(routerData);\n\n  if (notFoundRoute) {\n    const components = await notFoundRoute.load();\n    setState({\n      url: nextUrl,\n      route: notFoundRoute,\n      params: {},\n      components,\n      props: notFoundProps,\n    });\n  } else {\n    setState({\n      url: nextUrl,\n      route: null,\n      params: {},\n      components: null,\n      props: {},\n    });\n  }\n}\n\nasync function handleNormalRoute(\n  nextUrl: string,\n  json: RouteDataResponse,\n  routes: ClientRouteLoaded[],\n  setState: (state: RouteViewState) => void\n): Promise<boolean> {\n  applyMetadata(json.metadata ?? null);\n  \n  // Get theme: prioritize cookie (source of truth), then server response, then window data, then default\n  // Cookie is the source of truth because it persists across navigation\n  let theme: string = \"light\"; // Default\n  if (typeof document !== \"undefined\") {\n    const cookieMatch = document.cookie.match(/theme=([^;]+)/);\n    if (cookieMatch) {\n      theme = cookieMatch[1];\n    } else if (json.theme) {\n      theme = json.theme;\n    } else {\n      const currentTheme = getCurrentTheme();\n      if (currentTheme) {\n        theme = currentTheme;\n      }\n    }\n  } else if (json.theme) {\n    theme = json.theme;\n  }\n  \n  // Handle layout props preservation:\n  // - If layoutProps are in response, use them and preserve them\n  // - If layoutProps are NOT in response (layout hooks were skipped), use preserved ones\n  let layoutProps: Record<string, any> = {};\n  if (json.layoutProps !== undefined && json.layoutProps !== null) {\n    // Layout hooks were executed, use new layout props and preserve them\n    layoutProps = json.layoutProps;\n    setPreservedLayoutProps(layoutProps);\n  } else {\n    // Layout hooks were skipped, use preserved layout props\n    const preserved = getPreservedLayoutProps();\n    if (preserved) {\n      layoutProps = preserved;\n    }\n  }\n\n  // Get page props (always from response)\n  const pageProps = json.pageProps ?? json.props ?? {};\n\n  // Combine: layout props (preserved or new) + page props (always new)\n  // Page props override layout props if there's a conflict\n  const combinedProps = {\n    ...layoutProps,\n    ...pageProps,\n    theme, // Always include theme\n  };\n\n  // Use pathname from server response if available (for rewrites)\n  // Otherwise use the original nextUrl\n  // Try to match with rewritten pathname first, then fall back to original URL\n  const pathnameForMatch = json.pathname || nextUrl;\n  let matched = matchRouteClient(pathnameForMatch, routes);\n  \n  // If no match with rewritten pathname, try with original URL\n  // (some routes might not need rewrite, or rewrite might not apply)\n  if (!matched) {\n    matched = matchRouteClient(nextUrl, routes);\n  }\n\n  if (!matched) {\n    // Server returned data but no route match - this shouldn't happen normally\n    // But if it does, do full page reload to let server handle it\n    console.warn(\n      `[client] Server returned data for ${nextUrl} but no route match found. Available routes:`,\n      routes.map((r) => r.pattern)\n    );\n    window.location.href = nextUrl;\n    return false;\n  }\n\n  // Use pathname from server if available (rewritten), otherwise use nextUrl\n  const finalPathname = json.pathname || nextUrl;\n  const windowData: InitialData = {\n    pathname: finalPathname,\n    params: matched.params,\n    props: combinedProps,\n    metadata: json.metadata ?? null,\n    theme,\n    notFound: false,\n    error: false,\n  };\n\n  setWindowData(windowData);\n\n  // Update routerData\n  const url = new URL(nextUrl, typeof window !== \"undefined\" ? window.location.origin : \"http://localhost\");\n  const routerData: RouterData = {\n    pathname: url.pathname,\n    params: matched.params,\n    searchParams: Object.fromEntries(url.searchParams.entries()),\n  };\n  setRouterData(routerData);\n\n  // Use prefetched route if available, otherwise load it\n  const prefetched = prefetchedRoutes.get(matched.route);\n  const components = prefetched ? await prefetched : await matched.route.load();\n  \n  // Cache the loaded route for future use\n  if (!prefetched) {\n    prefetchedRoutes.set(matched.route, Promise.resolve(components));\n  }\n\n  window.scrollTo({\n    top: 0,\n    behavior: \"smooth\",\n  });\n\n  setState({\n    url: nextUrl,\n    route: matched.route,\n    params: matched.params,\n    components,\n    props: combinedProps,\n  });\n\n  return true;\n}\n\nexport type NavigateOptions = {\n  /**\n   * If true, forces revalidation of route data,\n   * ignoring the cache and fetching fresh data from the server.\n   * Similar to Next.js's `router.refresh()` behavior.\n   */\n  revalidate?: boolean;\n};\n\nexport async function navigate(\n  nextUrl: string,\n  handlers: NavigationHandlers,\n  options?: NavigateOptions\n): Promise<void> {\n  const { setState, routes, notFoundRoute, errorRoute } = handlers;\n\n  try {\n    const { ok, json } = await getRouteData(nextUrl, {\n      revalidate: options?.revalidate,\n    });\n\n    if (json && json.error) {\n      if (errorRoute) {\n        const handled = await handleErrorRoute(\n          nextUrl,\n          json,\n          errorRoute,\n          setState\n        );\n        if (handled) return;\n      } else {\n        console.warn(\n          \"[client] Error route not available, reloading page.\",\n          errorRoute\n        );\n        window.location.href = nextUrl;\n        return;\n      }\n    }\n\n    // 🔴 HTTP error (404/500/etc)\n    if (!ok) {\n      if (json?.redirect) {\n        window.location.href = json.redirect.destination;\n        return;\n      }\n      window.location.href = nextUrl;\n      return;\n    }\n\n    // Redirect via JSON\n    if (json.redirect) {\n      window.location.href = json.redirect.destination;\n      return;\n    }\n\n    // Handle notFound\n    if (json.notFound) {\n      await handleNotFoundRoute(nextUrl, json, notFoundRoute, setState);\n      return;\n    }\n\n    // Normal route\n    await handleNormalRoute(nextUrl, json, routes, setState);\n  } catch (err) {\n    console.error(\"[client] Error fetching FW data:\", err);\n    window.location.href = nextUrl;\n  }\n}\n\n// Cache for prefetched routes to avoid loading twice\nconst prefetchedRoutes = new WeakMap<ClientRouteLoaded, Promise<ClientLoadedComponents>>();\n\n/**\n * Prefetches a route's components when user hovers over a link.\n * This improves perceived performance by loading the route before the user clicks.\n */\nfunction prefetchRoute(\n  url: string,\n  routes: ClientRouteLoaded[],\n  notFoundRoute: ClientRouteLoaded | null\n): void {\n  const [pathname] = url.split(\"?\");\n  const matched = matchRouteClient(pathname, routes);\n  \n  if (!matched) {\n    // If no match, might be not-found route\n    if (notFoundRoute) {\n      const existing = prefetchedRoutes.get(notFoundRoute);\n      if (!existing) {\n        const promise = notFoundRoute.load();\n        prefetchedRoutes.set(notFoundRoute, promise);\n      }\n    }\n    return;\n  }\n\n  // Prefetch the matched route if not already prefetched\n  const existing = prefetchedRoutes.get(matched.route);\n  if (!existing) {\n    const promise = matched.route.load();\n    prefetchedRoutes.set(matched.route, promise);\n  }\n}\n\n/**\n * Creates a hover handler for prefetching routes on link hover.\n */\nexport function createHoverHandler(\n  routes: ClientRouteLoaded[],\n  notFoundRoute: ClientRouteLoaded | null\n): (ev: MouseEvent) => void {\n  return function handleHover(ev: MouseEvent) {\n    try {\n      const target = ev.target as HTMLElement | null;\n      if (!target) return;\n\n      const anchor = target.closest(\"a[href]\") as HTMLAnchorElement | null;\n      if (!anchor) return;\n\n      const href = anchor.getAttribute(\"href\");\n      if (!href) return;\n      if (href.startsWith(\"#\")) return;\n\n      const url = new URL(href, window.location.href);\n      if (url.origin !== window.location.origin) return;\n      if (anchor.target && anchor.target !== \"_self\") return;\n\n      const nextUrl = url.pathname + url.search;\n      const currentUrl = window.location.pathname + window.location.search;\n      if (nextUrl === currentUrl) return;\n\n      // Prefetch the route\n      prefetchRoute(nextUrl, routes, notFoundRoute);\n    } catch (error) {\n      // Silently fail - prefetch is an optimization, not critical\n    }\n  };\n}\n\nexport function createClickHandler(\n  navigate: (url: string, options?: NavigateOptions) => void\n): (ev: MouseEvent) => void {\n  return function handleClick(ev: MouseEvent) {\n    try {\n      // Exit early if event was already prevented\n      if (ev.defaultPrevented) return;\n      \n      // Verify it's a real mouse event (not synthetic or keyboard)\n      if (ev.type !== \"click\") return;\n      if (ev.button !== 0) return;\n      if (ev.metaKey || ev.ctrlKey || ev.shiftKey || ev.altKey) return;\n      \n      // Verify event has valid coordinates (real mouse events have them)\n      const target = ev.target as HTMLElement | null;\n      if (ev.clientX === 0 && ev.clientY === 0 && ev.detail === 0) {\n        // Could be a synthetic event, be more cautious\n        if (target) {\n          const tagName = target.tagName.toLowerCase();\n          if (tagName === \"input\" || tagName === \"textarea\" || tagName === \"button\" || tagName === \"select\") {\n            return; // It's an input, don't process synthetic events\n          }\n        }\n      }\n\n      if (!target) return;\n\n      // Check FIRST if target is an interactive element (faster)\n      const tagName = target.tagName.toLowerCase();\n      if (\n        tagName === \"input\" ||\n        tagName === \"textarea\" ||\n        tagName === \"button\" ||\n        tagName === \"select\" ||\n        target.isContentEditable ||\n        target.getAttribute(\"contenteditable\") === \"true\"\n      ) {\n        return; // It's an interactive element, don't process\n      }\n\n      // Check if it's inside an interactive element using closest (more efficient than composedPath)\n      const interactiveParent = target.closest(\"input, textarea, button, select, [contenteditable], label\");\n      if (interactiveParent) {\n        // If parent is a label, check if it has an associated control\n        if (interactiveParent.tagName.toLowerCase() === \"label\") {\n          const label = interactiveParent as HTMLLabelElement;\n          if (label.control) {\n            return; // Label has an associated control (input, etc)\n          }\n        } else {\n          return; // It's inside an interactive element\n        }\n      }\n\n      // Only search for anchor if it's not an interactive element\n      const anchor = target.closest(\"a[href]\") as HTMLAnchorElement | null;\n      if (!anchor) return;\n\n    const href = anchor.getAttribute(\"href\");\n    if (!href) return;\n    if (href.startsWith(\"#\")) return;\n\n    const url = new URL(href, window.location.href);\n    if (url.origin !== window.location.origin) return;\n    if (anchor.target && anchor.target !== \"_self\") return;\n\n    ev.preventDefault();\n\n    const nextUrl = url.pathname + url.search;\n    const currentUrl = window.location.pathname + window.location.search;\n    if (nextUrl === currentUrl) return;\n\n    // Detect if link has data-revalidate to force revalidation\n    const shouldRevalidate =\n      anchor.hasAttribute(\"data-revalidate\") &&\n      anchor.getAttribute(\"data-revalidate\") !== \"false\";\n\n    window.history.pushState({}, \"\", nextUrl);\n    navigate(nextUrl, shouldRevalidate ? { revalidate: true } : undefined);\n    } catch (error) {\n      // Silenciar errores para evitar bloquear el navegador\n      console.error(\"[navigation] Error in click handler:\", error);\n    }\n  };\n}\n\nexport function createPopStateHandler(\n  navigate: (url: string, options?: NavigateOptions) => void\n): () => void {\n  return function handlePopState() {\n    const nextUrl = window.location.pathname + window.location.search;\n    navigate(nextUrl);\n  };\n}\n\n","import { createContext, useContext } from \"react\";\r\n\r\nexport type NavigateFunction = (\r\n  url: string,\r\n  options?: { revalidate?: boolean; replace?: boolean }\r\n) => Promise<void>;\r\n\r\nexport interface RouterContextValue {\r\n  navigate: NavigateFunction;\r\n}\r\n\r\nexport const RouterContext = createContext<RouterContextValue | null>(null);\r\n\r\nexport function useRouterContext(): RouterContextValue {\r\n  const context = useContext(RouterContext);\r\n  if (!context) {\r\n    throw new Error(\r\n      \"useRouter must be used within a RouterProvider. Make sure you're using it inside a Loly app.\"\r\n    );\r\n  }\r\n  return context;\r\n}\r\n","/**\r\n * Sets up hot reload via Server-Sent Events (SSE) in development mode.\r\n * Listens for file changes and reloads the page when needed.\r\n * \r\n * This module is separate from bootstrap to keep concerns separated\r\n * and make the code more maintainable.\r\n */\r\nexport function setupHotReload(): void {\r\n  // process.env.NODE_ENV is replaced by DefinePlugin at build time\r\n  // DefinePlugin replaces this with a string literal: \"development\" or \"production\"\r\n  // @ts-expect-error - process.env.NODE_ENV is replaced at build time by DefinePlugin\r\n  const nodeEnv: string = process.env.NODE_ENV || \"production\";\r\n  const isDev = nodeEnv === \"development\";\r\n  \r\n  if (!isDev) {\r\n    // Silently skip in production - no logging\r\n    return;\r\n  }\r\n  \r\n  console.log(\"[hot-reload] Setting up hot reload client...\");\r\n\r\n  let eventSource: EventSource | null = null;\r\n  let reloadTimeout: ReturnType<typeof setTimeout> | null = null;\r\n  let reconnectTimeout: ReturnType<typeof setTimeout> | null = null;\r\n  let reconnectAttempts = 0;\r\n  const MAX_RECONNECT_ATTEMPTS = 10;\r\n  const RECONNECT_DELAY = 1000; // 1 second\r\n  const RELOAD_DELAY = 100; // Reduced from 500ms to 100ms for faster reload\r\n\r\n  function connect(): void {\r\n    try {\r\n      if (eventSource) {\r\n        console.log(\"[hot-reload] Closing existing EventSource connection\");\r\n        eventSource.close();\r\n      }\r\n\r\n      const endpoint = \"/__fw/hot\";\r\n      eventSource = new EventSource(endpoint);\r\n      \r\n      // Register ping listener FIRST (before message) to catch initial ping\r\n      eventSource.addEventListener(\"ping\", (event: Event) => {\r\n        if ('data' in event) {\r\n          console.log(\"[hot-reload] ✅ Connected to hot reload server\");\r\n        }\r\n        reconnectAttempts = 0;\r\n      });\r\n\r\n      // Register message listener for reload events\r\n      eventSource.addEventListener(\"message\", (event: MessageEvent) => {\r\n        const data = event.data;\r\n        if (data && typeof data === \"string\" && data.startsWith(\"reload:\")) {\r\n          const filePath = data.slice(7);\r\n          console.log(`[hot-reload] 📝 File changed: ${filePath}, reloading...`);\r\n\r\n          // Clear existing timeout to debounce rapid events\r\n          if (reloadTimeout) {\r\n            clearTimeout(reloadTimeout);\r\n          }\r\n\r\n          // Debounce reload - wait a bit in case multiple files change at once\r\n          reloadTimeout = setTimeout(() => {\r\n            try {\r\n              window.location.reload();\r\n            } catch (error) {\r\n              console.error(\"[hot-reload] ❌ Error reloading page:\", error);\r\n              // Fallback: try to reload after a short delay\r\n              setTimeout(() => window.location.reload(), 100);\r\n            }\r\n          }, RELOAD_DELAY);\r\n        }\r\n      });\r\n\r\n      eventSource.onopen = () => {\r\n        reconnectAttempts = 0; // Reset on successful connection\r\n      };\r\n\r\n      eventSource.onerror = (error) => {\r\n        const states = [\"CONNECTING\", \"OPEN\", \"CLOSED\"];\r\n        const state = states[eventSource?.readyState ?? 0] || \"UNKNOWN\";\r\n        \r\n        if (eventSource?.readyState === EventSource.CONNECTING) {\r\n          // Still connecting, this is normal\r\n          console.log(\"[hot-reload] ⏳ Still connecting...\");\r\n          return;\r\n        } else if (eventSource?.readyState === EventSource.OPEN) {\r\n          // Connection is open but error occurred (might be temporary)\r\n          console.warn(\"[hot-reload] ⚠️ Connection error (but connection is open):\", error);\r\n        } else {\r\n          // Connection closed, try to reconnect\r\n          console.warn(`[hot-reload] ❌ Connection closed (readyState: ${state})`);\r\n          \r\n          if (reconnectAttempts < MAX_RECONNECT_ATTEMPTS) {\r\n            reconnectAttempts++;\r\n            const delay = RECONNECT_DELAY * reconnectAttempts; // Exponential backoff\r\n            \r\n            if (reconnectTimeout) {\r\n              clearTimeout(reconnectTimeout);\r\n            }\r\n            \r\n            reconnectTimeout = setTimeout(() => {\r\n              console.log(`[hot-reload] 🔄 Reconnecting... (attempt ${reconnectAttempts}/${MAX_RECONNECT_ATTEMPTS})`);\r\n              connect();\r\n            }, delay);\r\n          } else {\r\n            console.error(\"[hot-reload] ❌ Max reconnect attempts reached. Please refresh the page manually.\");\r\n          }\r\n        }\r\n      };\r\n    } catch (error) {\r\n      console.error(\"[hot-reload] ❌ Failed to create EventSource:\", error);\r\n      console.error(\"[hot-reload] EventSource may not be supported in this browser.\");\r\n    }\r\n  }\r\n\r\n  // Initial connection\r\n  connect();\r\n}\r\n\r\n"],"mappings":"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","names":["import_react","existing","navigate","tagName","import_jsx_runtime","import_jsx_runtime"]}