diff options
Diffstat (limited to 'packages/bun-framework-next/client.development.tsx')
-rw-r--r-- | packages/bun-framework-next/client.development.tsx | 69 |
1 files changed, 41 insertions, 28 deletions
diff --git a/packages/bun-framework-next/client.development.tsx b/packages/bun-framework-next/client.development.tsx index f3d8d39e5..5d5e96763 100644 --- a/packages/bun-framework-next/client.development.tsx +++ b/packages/bun-framework-next/client.development.tsx @@ -1,10 +1,20 @@ +/// <reference types="react-dom/experimental" /> + globalThis.global = globalThis; globalThis.Bun_disableCSSImports = true; import * as React from "react"; + var onlyChildPolyfill = React.Children.only; -React.Children.only = function (children) { - if (children && typeof children === "object" && children.length == 1) { + +React.Children.only = function only( + children: React.ReactNode | React.ReactNode[] +) { + if ( + children && + typeof children === "object" && + (children as any).length == 1 + ) { return onlyChildPolyfill(children[0]); } @@ -23,9 +33,7 @@ import Router, { PrivateRouteInfo, } from "next/dist/shared/lib/router/router"; -const App = NextApp; - -import * as NextRouteLoader from "next/dist/client/route-loader"; +import NextRouteLoader from "next/dist/client/route-loader"; import { isDynamicRoute } from "next/dist/shared/lib/router/utils/is-dynamic"; import { urlQueryToSearchParams, @@ -41,6 +49,7 @@ import { createRouter, makePublicRouterInstance, } from "next/dist/client/router"; + export const emitter: MittEmitter<string> = mitt(); declare global { @@ -102,7 +111,8 @@ type RenderRouteInfo = PrivateRouteInfo & { const nextDataTag = document.getElementById("__NEXT_DATA__"); -const data: typeof window["__NEXT_DATA__"] = nextDataTag +// pages is added at runtime and doesn't exist in Next types +const data: NEXT_DATA & { pages: Record<string, string[]> } = nextDataTag ? JSON.parse(document.getElementById("__NEXT_DATA__")!.textContent!) : nextDataFromBunData(); @@ -116,12 +126,14 @@ const { buildId, assetPrefix, runtimeConfig, + // Todo, revist this constant when supporting dynamic() dynamicIds, isFallback, locale, locales, domainLocales, isPreview, + pages, } = data; const prefix: string = assetPrefix || ""; @@ -138,24 +150,19 @@ if (hasBasePath(asPath)) { asPath = delBasePath(asPath); } -export const pageLoader: PageLoader = new PageLoader( - buildId, - prefix, - data.pages -); +export const pageLoader: PageLoader = new PageLoader(buildId, prefix, pages); const headManager: { mountedInstances: Set<unknown>; updateHead: (head: JSX.Element[]) => void; } = initHeadManager(); -const appElement: HTMLElement | null = document.getElementById("__next"); export let router: Router; -let CachedApp: AppComponent = App, - onPerfEntry: (metric: any) => void; -export default function boot(EntryPointNamespace, loader) { - _boot(EntryPointNamespace).then(() => {}, false); +let CachedApp: AppComponent = null; + +export default function boot(EntryPointNamespace) { + _boot(EntryPointNamespace, false); } class Container extends React.Component<{ @@ -274,13 +281,17 @@ let reactRoot: any = null; const USE_REACT_18 = "hydrateRoot" in ReactDOM; export async function _boot(EntryPointNamespace, isError) { - NextRouteLoader.default.getClientBuildManifest = () => Promise.resolve({}); + NextRouteLoader.getClientBuildManifest = () => Promise.resolve({}); const PageComponent = EntryPointNamespace.default; const appScripts = globalThis.__NEXT_DATA__.pages["/_app"]; + // Type 'typeof App' is not assignable to type 'ComponentClass<AppProps, any>'. + // Construct signature return types 'App<any, any, any>' and 'Component<AppProps, any, any>' are incompatible. + // @ts-expect-error CachedApp = NextApp; + CachedComponent = PageComponent; if (appScripts && appScripts.length > 0) { let appSrc; @@ -293,6 +304,7 @@ export async function _boot(EntryPointNamespace, isError) { if (appSrc) { const AppModule = await import(appSrc); + console.assert( AppModule.default, appSrc + " must have a default export'd React component" @@ -316,9 +328,12 @@ export async function _boot(EntryPointNamespace, isError) { return render( Object.assign< {}, - Omit<RenderRouteInfo, "App" | "scroll">, - Pick<RenderRouteInfo, "App" | "scroll"> + Omit<RenderRouteInfo, "App" | "scroll" | "Component">, + Pick<RenderRouteInfo, "App" | "scroll" | "Component"> >({}, info, { + // If we don't have an info.Component, we may be shallow routing, + // fallback to current entry point + Component: info.Component || CachedComponent, App, scroll, }) @@ -332,7 +347,9 @@ export async function _boot(EntryPointNamespace, isError) { }); globalThis.next.router = router; + const domEl = document.querySelector("#__next"); + const reactEl = ( <TopLevelRender App={CachedApp} @@ -361,9 +378,9 @@ export async function _boot(EntryPointNamespace, isError) { } } -function TopLevelRender({ App, Component, props, scroll }) { +function TopLevelRender({ App, Component, props }) { return ( - <AppContainer scroll={scroll}> + <AppContainer> <App Component={Component} {...props}></App> </AppContainer> ); @@ -381,18 +398,14 @@ export function render(props) { } export function renderError(e) { - const reactEl = ( - <AppContainer> - <App Component={<div>UH OH!!!!</div>} pageProps={data.props}></App> - </AppContainer> - ); + const reactEl = <AppContainer>{null}</AppContainer>; if (USE_REACT_18) { if (!reactRoot) { const domEl = document.querySelector("#__next"); // Unlike with createRoot, you don't need a separate root.render() call here - reactRoot = ReactDOM.createRoot(domEl, reactEl); + reactRoot = ReactDOM.hydrateRoot(domEl, reactEl); } else { reactRoot.render(reactEl); } @@ -404,7 +417,7 @@ export function renderError(e) { } globalThis.next = { - version: "12.0.3", + version: "12.0.4", emitter, render, renderError, |