aboutsummaryrefslogtreecommitdiff
path: root/examples/hello-next/bun-framework-next/client.development.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'examples/hello-next/bun-framework-next/client.development.tsx')
-rw-r--r--examples/hello-next/bun-framework-next/client.development.tsx416
1 files changed, 416 insertions, 0 deletions
diff --git a/examples/hello-next/bun-framework-next/client.development.tsx b/examples/hello-next/bun-framework-next/client.development.tsx
new file mode 100644
index 000000000..0d019e175
--- /dev/null
+++ b/examples/hello-next/bun-framework-next/client.development.tsx
@@ -0,0 +1,416 @@
+import "./bun-error";
+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) {
+ return onlyChildPolyfill(children[0]);
+ }
+
+ return onlyChildPolyfill(children);
+};
+
+import * as ReactDOM from "react-dom";
+import App from "next/app";
+import mitt, { MittEmitter } from "next/dist/shared/lib/mitt";
+import { RouterContext } from "next/dist/shared/lib/router-context";
+import Router, {
+ AppComponent,
+ AppProps,
+ delBasePath,
+ hasBasePath,
+ PrivateRouteInfo,
+} from "next/dist/shared/lib/router/router";
+
+import * as NextRouteLoader from "next/dist/client/route-loader";
+import { isDynamicRoute } from "next/dist/shared/lib/router/utils/is-dynamic";
+import {
+ urlQueryToSearchParams,
+ assign,
+} from "next/dist/shared/lib/router/utils/querystring";
+import { setConfig } from "next/dist/shared/lib/runtime-config";
+import {
+ getURL,
+ loadGetInitialProps,
+ NEXT_DATA,
+ ST,
+} from "next/dist/shared/lib/utils";
+// import { Portal } from "next/dist/client/portal";
+import initHeadManager from "next/dist/client/head-manager";
+import { HeadManagerContext } from "next/dist/shared/lib/head-manager-context";
+import PageLoader from "./page-loader";
+import measureWebVitals from "next/dist/client/performance-relayer";
+import { RouteAnnouncer } from "next/dist/client/route-announcer";
+import {
+ createRouter,
+ makePublicRouterInstance,
+} from "next/dist/client/router";
+export const emitter: MittEmitter<string> = mitt();
+
+declare global {
+ interface Window {
+ /* test fns */
+ __NEXT_HYDRATED?: boolean;
+ __NEXT_HYDRATED_CB?: () => void;
+
+ /* prod */
+ __NEXT_PRELOADREADY?: (ids?: (string | number)[]) => void;
+ __NEXT_DATA__: NEXT_DATA;
+ __NEXT_P: any[];
+ }
+}
+
+function nextDataFromBunData() {
+ const {
+ router: { routes, route, params: paramsList },
+ problems,
+ } = globalThis.__BUN_DATA__;
+
+ const paramsMap = new Map();
+ for (let i = 0; i < paramsList.keys.length; i++) {
+ paramsMap.set(
+ decodeURIComponent(paramsList.keys[i]),
+ decodeURIComponent(paramsList.values[i])
+ );
+ }
+
+ const params = {};
+ var url = new URL(location.href);
+ Object.assign(params, Object.fromEntries(url.searchParams.entries()));
+ Object.assign(params, Object.fromEntries(paramsMap.entries()));
+
+ const pages = routes.reduce((acc, route) => {
+ var name = route.substring(route.indexOf("_next") + "_next/".length);
+
+ while (name.startsWith("/")) {
+ name = name.substring(1);
+ }
+
+ if (name.startsWith("pages")) {
+ name = name.substring("pages".length);
+ }
+
+ while (name.startsWith("/")) {
+ name = name.substring(1);
+ }
+
+ if (name.endsWith(".jsx")) {
+ name = name.substring(0, name.length - ".jsx".length);
+ }
+
+ if (name.endsWith(".tsx")) {
+ name = name.substring(0, name.length - ".tsx".length);
+ }
+
+ if (name.endsWith(".ts")) {
+ name = name.substring(0, name.length - ".ts".length);
+ }
+
+ if (name.endsWith(".js")) {
+ name = name.substring(0, name.length - ".js".length);
+ }
+
+ acc["/" + name] = [route];
+ return acc;
+ }, {});
+
+ return {
+ page: routes[route],
+ buildId: "1234",
+ assetPrefix: "",
+ isPreview: false,
+ locale: null,
+ locales: [],
+ isFallback: false,
+ err: null,
+ props: {},
+ query: params,
+ pages,
+ };
+}
+
+type RenderRouteInfo = PrivateRouteInfo & {
+ App: AppComponent;
+ scroll?: { x: number; y: number } | null;
+};
+type RenderErrorProps = Omit<RenderRouteInfo, "Component" | "styleSheets">;
+
+const nextDataTag = document.getElementById("__NEXT_DATA__");
+
+const data: typeof window["__NEXT_DATA__"] = nextDataTag
+ ? JSON.parse(document.getElementById("__NEXT_DATA__")!.textContent!)
+ : nextDataFromBunData();
+window.__NEXT_DATA__ = data;
+
+const {
+ props: hydrateProps,
+ err: hydrateErr,
+ page,
+ query,
+ buildId,
+ assetPrefix,
+ runtimeConfig,
+ dynamicIds,
+ isFallback,
+ locale,
+ locales,
+ domainLocales,
+ isPreview,
+} = data;
+
+const prefix: string = assetPrefix || "";
+
+setConfig({
+ serverRuntimeConfig: {},
+ publicRuntimeConfig: runtimeConfig || {},
+});
+
+let asPath: string = getURL();
+
+// make sure not to attempt stripping basePath for 404s
+if (hasBasePath(asPath)) {
+ asPath = delBasePath(asPath);
+}
+
+export const pageLoader: PageLoader = new PageLoader(
+ buildId,
+ prefix,
+ data.pages
+);
+
+const headManager: {
+ mountedInstances: Set<unknown>;
+ updateHead: (head: JSX.Element[]) => void;
+} = initHeadManager();
+const appElement: HTMLElement | null = document.getElementById("__next");
+
+let lastRenderReject: (() => void) | null;
+let webpackHMR: any;
+export let router: Router;
+let CachedApp: AppComponent, onPerfEntry: (metric: any) => void;
+
+export default function boot(EntryPointNamespace, loader) {
+ _boot(EntryPointNamespace).then(() => {}, false);
+}
+
+class Container extends React.Component<{
+ fn: (err: Error, info?: any) => void;
+}> {
+ componentDidCatch(componentErr: Error, info: any) {
+ this.props.fn(componentErr, info);
+ }
+
+ componentDidMount() {
+ this.scrollToHash();
+
+ // We need to replace the router state if:
+ // - the page was (auto) exported and has a query string or search (hash)
+ // - it was auto exported and is a dynamic route (to provide params)
+ // - if it is a client-side skeleton (fallback render)
+ if (
+ router.isSsr &&
+ // We don't update for 404 requests as this can modify
+ // the asPath unexpectedly e.g. adding basePath when
+ // it wasn't originally present
+ page !== "/404" &&
+ page !== "/_error" &&
+ (isFallback ||
+ (data.nextExport &&
+ (isDynamicRoute(router.pathname) ||
+ location.search ||
+ process.env.__NEXT_HAS_REWRITES)) ||
+ (hydrateProps &&
+ hydrateProps.__N_SSG &&
+ (location.search || process.env.__NEXT_HAS_REWRITES)))
+ ) {
+ // update query on mount for exported pages
+ router.replace(
+ router.pathname +
+ "?" +
+ String(
+ assign(
+ urlQueryToSearchParams(router.query),
+ new URLSearchParams(location.search)
+ )
+ ),
+ asPath,
+ {
+ // @ts-ignore
+ // WARNING: `_h` is an internal option for handing Next.js
+ // client-side hydration. Your app should _never_ use this property.
+ // It may change at any time without notice.
+ _h: 1,
+ // Fallback pages must trigger the data fetch, so the transition is
+ // not shallow.
+ // Other pages (strictly updating query) happens shallowly, as data
+ // requirements would already be present.
+ shallow: !isFallback,
+ }
+ );
+ }
+ }
+
+ componentDidUpdate() {
+ this.scrollToHash();
+ }
+
+ scrollToHash() {
+ let { hash } = location;
+ hash = hash && hash.substring(1);
+ if (!hash) return;
+
+ const el: HTMLElement | null = document.getElementById(hash);
+ if (!el) return;
+
+ // If we call scrollIntoView() in here without a setTimeout
+ // it won't scroll properly.
+ setTimeout(() => el.scrollIntoView(), 0);
+ }
+
+ render() {
+ return this.props.children;
+ }
+}
+
+let CachedComponent: React.ComponentType;
+
+const wrapApp =
+ (App: AppComponent) =>
+ (wrappedAppProps: Record<string, any>): JSX.Element => {
+ const appProps: AppProps = {
+ ...wrappedAppProps,
+ Component: CachedComponent,
+ err: hydrateErr,
+ router,
+ };
+ return (
+ <AppContainer>
+ <App {...appProps} />
+ </AppContainer>
+ );
+ };
+
+function AppContainer({
+ children,
+}: React.PropsWithChildren<{}>): React.ReactElement {
+ return (
+ <Container fn={(error) => <div>{JSON.stringify(error)}</div>}>
+ <RouterContext.Provider value={makePublicRouterInstance(router)}>
+ <HeadManagerContext.Provider value={headManager}>
+ {children}
+ </HeadManagerContext.Provider>
+ </RouterContext.Provider>
+ </Container>
+ );
+}
+
+export async function _boot(EntryPointNamespace, isError) {
+ NextRouteLoader.default.getClientBuildManifest = () => Promise.resolve({});
+
+ const PageComponent = EntryPointNamespace.default;
+
+ const appScripts = globalThis.__NEXT_DATA__.pages["/_app"];
+ if (appScripts && appScripts.length > 0) {
+ let appSrc;
+ for (let asset of appScripts) {
+ if (!asset.endsWith(".css")) {
+ appSrc = asset;
+ break;
+ }
+ }
+
+ if (appSrc) {
+ const AppModule = await import(appSrc);
+ console.assert(
+ AppModule.default,
+ appSrc + " must have a default export'd React component"
+ );
+
+ CachedApp = AppModule.default;
+ } else {
+ CachedApp = App;
+ }
+ }
+
+ router = createRouter(page, query, asPath, {
+ initialProps: hydrateProps,
+ pageLoader,
+ App: CachedApp,
+ Component: CachedComponent,
+ wrapApp,
+ err: null,
+ isFallback: Boolean(isFallback),
+ subscription: async (info, App, scroll) => {
+ return render(
+ Object.assign<
+ {},
+ Omit<RenderRouteInfo, "App" | "scroll">,
+ Pick<RenderRouteInfo, "App" | "scroll">
+ >({}, info, {
+ App,
+ scroll,
+ })
+ );
+ },
+ locale,
+ locales,
+ defaultLocale: "",
+ domainLocales,
+ isPreview,
+ });
+
+ globalThis.next.router = router;
+
+ if (isError) {
+ ReactDOM.render(
+ <TopLevelRender
+ App={CachedApp}
+ Component={PageComponent}
+ props={{ pageProps: hydrateProps }}
+ />,
+ document.querySelector("#__next")
+ );
+ } else {
+ ReactDOM.hydrate(
+ <TopLevelRender
+ App={CachedApp}
+ Component={PageComponent}
+ props={{ pageProps: hydrateProps }}
+ />,
+ document.querySelector("#__next")
+ );
+ }
+}
+
+function TopLevelRender({ App, Component, props, scroll }) {
+ return (
+ <AppContainer scroll={scroll}>
+ <App Component={Component} {...props}></App>
+ </AppContainer>
+ );
+}
+
+export function render(props) {
+ ReactDOM.render(
+ <TopLevelRender {...props} />,
+ document.querySelector("#__next")
+ );
+}
+
+export function renderError(e) {
+ ReactDOM.render(
+ <AppContainer>
+ <App Component={<div>UH OH!!!!</div>} pageProps={data.props}></App>
+ </AppContainer>,
+ document.querySelector("#__next")
+ );
+}
+
+globalThis.next = {
+ version: "11.1.0",
+ emitter,
+ render,
+ renderError,
+};