UNPKG

one

Version:

One is a React framework for web, iOS, and Android apps.

186 lines (178 loc) • 6.67 kB
import { DarkTheme, DefaultTheme } from "./fork/theme.mjs"; import { useUserScheme } from "@vxrn/color-scheme"; import { StrictMode, createContext, useContext, useId, useLayoutEffect, useState } from "react"; import { SERVER_CONTEXT_KEY, isNative } from "./constants.mjs"; import { initScreensFeatureFlags } from "./screensFeatureFlags.mjs"; import { SpaShellContext } from "./router/SpaShellContext.mjs"; import { NavigationContainer } from "./fork/NavigationContainer.mjs"; import { getURL } from "./getURL.mjs"; import { FlagsContext } from "./router/FlagsContext.mjs"; import { getResolvedLinking } from "./router/linkingConfig.mjs"; import { handleNavigationContainerStateChange } from "./router/router.mjs"; import { ServerLocationContext } from "./router/serverLocationContext.mjs"; import { useInitializeOneRouter } from "./router/useInitializeOneRouter.mjs"; import { useViteRoutes } from "./router/useViteRoutes.mjs"; import { evictOldest } from "./utils/evictOldest.mjs"; import { ServerRenderID } from "./useServerHeadInsertion.mjs"; import { PreloadLinks } from "./views/PreloadLinks.mjs"; import { SafeAreaProvider, initialWindowMetrics } from "./safe-area-context/index.mjs"; import { RootErrorBoundary } from "./views/RootErrorBoundary.mjs"; import { ScrollBehavior } from "./views/ScrollBehavior.mjs"; import { Fragment, jsx, jsxs } from "react/jsx-runtime"; const ssrLocationCache = /* @__PURE__ */ new Map(); function getCachedSSRLocation(path) { let url = ssrLocationCache.get(path); if (url) return url; url = new URL(path, getURL()); evictOldest(ssrLocationCache, 5e3, 1e3); ssrLocationCache.set(path, url); return url; } const ServerAsyncLocalIDContext = createContext(null); globalThis["__vxrnGetContextFromReactContext"] = () => useContext(ServerAsyncLocalIDContext); function Root(props) { if (isNative) { initScreensFeatureFlags(); } const { path, routes, routeOptions, isClient, navigationContainerProps, onRenderId, linking } = props; const context = useViteRoutes(routes, props.routerRoot, routeOptions, globalThis["__vxrnVersion"]); const location = isNative ? void 0 : typeof window !== "undefined" && window.location ? new URL(path || window.location.href || "/", window.location.href) : getCachedSSRLocation(path || "/"); const store = useInitializeOneRouter(context, location, linking); const userScheme = useUserScheme(); const Component = store.rootComponent; if (!Component) { throw new Error(`No root component found`); } const id = useId(); onRenderId?.(id); const value = process.env.VERCEL ? globalThis["__oneGlobalContextId"] : globalThis["__vxrnrequestAsyncLocalStore"]?.getStore() || null; const deferredPreloads = props.deferredPreloads; let contents = /* @__PURE__ */ jsx(ServerAsyncLocalIDContext.Provider, { value, children: /* @__PURE__ */ jsxs(ServerRenderID.Provider, { value: id, children: [ typeof window === "undefined" && deferredPreloads?.map((src) => /* @__PURE__ */ jsx("link", { rel: "modulepreload", fetchPriority: "low", href: src }, src)), /* @__PURE__ */ jsx(SafeAreaProvider, { initialMetrics: initialWindowMetrics, children: /* @__PURE__ */ jsx(NavigationContainer, { ref: store.navigationRef, initialState: store.initialState, linking: getResolvedLinking(), onUnhandledAction, onStateChange: handleNavigationContainerStateChange, theme: userScheme.value === "dark" ? DarkTheme : DefaultTheme, documentTitle: { enabled: false }, ...navigationContainerProps, children: /* @__PURE__ */ jsx(ServerLocationContext.Provider, { value: location, children: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(ScrollBehavior, {}), /* @__PURE__ */ jsx(RootErrorBoundary, { children: /* @__PURE__ */ jsx(Component, {}) })] }) }) }) }), typeof window !== "undefined" && /* @__PURE__ */ jsx(PreloadLinks, {}, "preload-links") ] }) }); if (props.flags) { contents = /* @__PURE__ */ jsx(FlagsContext.Provider, { value: props.flags, children: contents }); } if (!process.env.ONE_DISABLE_STRICT_MODE) { contents = /* @__PURE__ */ jsx(StrictMode, { children: contents }); } if (isClient) { const serverMode = globalThis[SERVER_CONTEXT_KEY]?.mode; if (serverMode === "spa") { const [show, setShow] = useState(false); useLayoutEffect(() => { setShow(true); }, []); return show ? contents : null; } if (serverMode === "spa-shell") { const [isSpaShell, setIsSpaShell] = useState(true); useLayoutEffect(() => { setIsSpaShell(false); }, []); useLayoutEffect(() => { if (!isSpaShell) { const initialPath = window.location.pathname + window.location.search; requestAnimationFrame(() => { if (window.location.pathname + window.location.search !== initialPath) return; const nav = store.navigationRef?.current; if (!nav) return; const linking2 = getResolvedLinking(); if (linking2?.getStateFromPath) { const freshState = linking2.getStateFromPath(initialPath, linking2.config); if (freshState) { nav.resetRoot(freshState); } } }); } }, [isSpaShell]); return /* @__PURE__ */ jsx(SpaShellContext.Provider, { value: isSpaShell, children: contents }); } return contents; } if (props.mode === "spa-shell") { return /* @__PURE__ */ jsx(SpaShellContext.Provider, { value: true, children: contents }); } return contents; } let onUnhandledAction; if (process.env.NODE_ENV !== "production") { onUnhandledAction = (action) => { const payload = action.payload; let message = `The action '${action.type}'${payload ? ` with payload ${JSON.stringify(action.payload)}` : ""} was not handled by any navigator.`; switch (action.type) { case "NAVIGATE": case "PUSH": case "REPLACE": case "JUMP_TO": if (payload?.name) { message += ` Do you have a route named '${payload.name}'?`; } else { message += ` You need to pass the name of the screen to navigate to. This may be a bug.`; } break; case "GO_BACK": case "POP": case "POP_TO_TOP": message += ` Is there any screen to go back to?`; break; case "OPEN_DRAWER": case "CLOSE_DRAWER": case "TOGGLE_DRAWER": message += ` Is your screen inside a Drawer navigator?`; break; } message += ` This is a development-only warning and won't be shown in production.`; if (process.env.NODE_ENV === "test") { throw new Error(message); } console.error(message); }; } else { onUnhandledAction = () => {}; } export { Root }; //# sourceMappingURL=Root.mjs.map