// modules/react/hooks/useBroadcastChannel/index.tsx
import { useEffect, useState, useRef, useCallback } from "react";
var useBroadcastChannel = (channelName) => {
  const [message, setMessage] = useState(null);
  const channelRef = useRef(null);
  useEffect(() => {
    if (!channelRef.current && typeof window !== "undefined") {
      channelRef.current = new BroadcastChannel(channelName);
    }
    const channel = channelRef.current;
    if (!channel) return;
    const handleMessage = (event) => {
      setMessage(event.data);
    };
    channel.onmessage = handleMessage;
    return () => {
      if (channelRef.current) {
        channelRef.current.close();
        channelRef.current = null;
      }
    };
  }, [channelName]);
  const sendMessage = useCallback((msg) => {
    if (channelRef.current) {
      channelRef.current.postMessage(msg);
    }
  }, []);
  return { message, sendMessage };
};

// modules/react/hooks/useRouter/index.ts
import { useState as useState2, useEffect as useEffect2, useCallback as useCallback2, useContext as useContext2, useRef as useRef2 } from "react";

// modules/runtime/client/RouterContext.tsx
import { createContext, useContext } from "react";
var RouterContext = createContext(null);

// modules/runtime/client/constants.ts
var WINDOW_DATA_KEY = "__FW_DATA__";
var ROUTER_DATA_KEY = "__LOLY_ROUTER_DATA__";
var ROUTER_NAVIGATE_KEY = "__LOLY_ROUTER_NAVIGATE__";

// modules/runtime/client/window-data.ts
function getWindowData() {
  if (typeof window === "undefined") {
    return null;
  }
  return window[WINDOW_DATA_KEY] ?? null;
}
function getRouterData() {
  if (typeof window === "undefined") {
    return null;
  }
  return window[ROUTER_DATA_KEY] ?? null;
}

// modules/react/hooks/useRouter/index.ts
function useRouter() {
  const context = useContext2(RouterContext);
  const navigate = context?.navigate;
  const navigateRef = useRef2(navigate);
  useEffect2(() => {
    navigateRef.current = navigate;
  }, [navigate]);
  const [routeData, setRouteData] = useState2(() => {
    if (typeof window === "undefined") {
      return {
        pathname: "",
        query: {},
        searchParams: {},
        params: {}
      };
    }
    const data = getWindowData();
    const routerData = getRouterData();
    const searchParams = routerData?.searchParams || parseQueryString(window.location.search);
    return {
      pathname: routerData?.pathname || data?.pathname || window.location.pathname,
      query: searchParams,
      // For backward compatibility
      searchParams,
      params: routerData?.params || data?.params || {}
    };
  });
  useEffect2(() => {
    if (typeof window === "undefined") return;
    const handleDataRefresh = () => {
      const data = getWindowData();
      const routerData = getRouterData();
      const currentPathname = window.location.pathname;
      const currentSearch = window.location.search;
      const searchParams = routerData?.searchParams || parseQueryString(currentSearch);
      setRouteData({
        pathname: routerData?.pathname || data?.pathname || currentPathname,
        query: searchParams,
        // For backward compatibility
        searchParams,
        params: routerData?.params || data?.params || {}
      });
    };
    window.addEventListener("fw-data-refresh", handleDataRefresh);
    window.addEventListener("fw-router-data-refresh", handleDataRefresh);
    const handlePopState = () => {
      handleDataRefresh();
    };
    window.addEventListener("popstate", handlePopState);
    return () => {
      window.removeEventListener("fw-data-refresh", handleDataRefresh);
      window.removeEventListener("fw-router-data-refresh", handleDataRefresh);
      window.removeEventListener("popstate", handlePopState);
    };
  }, []);
  const push = useCallback2(
    async (url, options) => {
      const fullUrl = url.startsWith("/") ? url : `/${url}`;
      const getCurrentNavigate = () => {
        if (navigateRef.current) return navigateRef.current;
        if (navigate) return navigate;
        if (typeof window !== "undefined" && window[ROUTER_NAVIGATE_KEY]) {
          return window[ROUTER_NAVIGATE_KEY];
        }
        return null;
      };
      let currentNavigate = getCurrentNavigate();
      if (typeof window === "undefined") {
        return;
      }
      if (!currentNavigate) {
        for (let i = 0; i < 10; i++) {
          await new Promise((resolve) => setTimeout(resolve, 10));
          currentNavigate = getCurrentNavigate();
          if (currentNavigate) break;
        }
      }
      if (!currentNavigate) {
        window.location.href = fullUrl;
        return;
      }
      const currentUrl = window.location.pathname + window.location.search;
      if (fullUrl === currentUrl) {
        return;
      }
      window.history.pushState({}, "", fullUrl);
      await currentNavigate(fullUrl, options);
    },
    [navigate]
    // Include navigate in dependencies so it updates when context becomes available
  );
  const replace = useCallback2(
    async (url, options) => {
      const fullUrl = url.startsWith("/") ? url : `/${url}`;
      const getCurrentNavigate = () => {
        if (navigateRef.current) return navigateRef.current;
        if (navigate) return navigate;
        if (typeof window !== "undefined" && window[ROUTER_NAVIGATE_KEY]) {
          return window[ROUTER_NAVIGATE_KEY];
        }
        return null;
      };
      let currentNavigate = getCurrentNavigate();
      if (typeof window === "undefined") {
        return;
      }
      if (!currentNavigate) {
        for (let i = 0; i < 10; i++) {
          await new Promise((resolve) => setTimeout(resolve, 10));
          currentNavigate = getCurrentNavigate();
          if (currentNavigate) break;
        }
      }
      if (!currentNavigate) {
        window.location.replace(fullUrl);
        return;
      }
      window.history.replaceState({}, "", fullUrl);
      await currentNavigate(fullUrl, options);
    },
    [navigate]
  );
  const back = useCallback2(() => {
    if (typeof window !== "undefined") {
      window.history.back();
    }
  }, []);
  const refresh = useCallback2(async () => {
    const currentUrl = typeof window !== "undefined" ? window.location.pathname + window.location.search : routeData.pathname;
    const getCurrentNavigate = () => {
      if (navigateRef.current) return navigateRef.current;
      if (navigate) return navigate;
      if (typeof window !== "undefined" && window[ROUTER_NAVIGATE_KEY]) {
        return window[ROUTER_NAVIGATE_KEY];
      }
      return null;
    };
    let currentNavigate = getCurrentNavigate();
    if (typeof window === "undefined") {
      return;
    }
    if (!currentNavigate) {
      for (let i = 0; i < 10; i++) {
        await new Promise((resolve) => setTimeout(resolve, 10));
        currentNavigate = getCurrentNavigate();
        if (currentNavigate) break;
      }
    }
    if (!currentNavigate) {
      window.location.reload();
      return;
    }
    await currentNavigate(currentUrl, { revalidate: true });
  }, [navigate, routeData.pathname]);
  return {
    push,
    replace,
    back,
    refresh,
    pathname: routeData.pathname,
    query: routeData.query,
    searchParams: routeData.searchParams,
    params: routeData.params
  };
}
function parseQueryString(search) {
  const params = {};
  if (!search || search.length === 0) return params;
  const queryString = search.startsWith("?") ? search.slice(1) : search;
  const pairs = queryString.split("&");
  for (const pair of pairs) {
    const [key, value] = pair.split("=");
    if (key) {
      params[decodeURIComponent(key)] = value ? decodeURIComponent(value) : "";
    }
  }
  return params;
}
export {
  useBroadcastChannel,
  useRouter
};
//# sourceMappingURL=hooks.js.map