Add More Features to pages main component

This commit is contained in:
Benjamin Toby 2026-03-17 18:53:27 +01:00
parent 9e94e20198
commit ee1fb5897e
5 changed files with 52 additions and 153 deletions

View File

@ -141,27 +141,18 @@ export default async function allPagesBundler(params?: Params) {
const final_artifacts = artifacts.filter((a) =>
Boolean(a?.entrypoint),
) as BundlerCTXMap[];
// writeFileSync(
// HYDRATION_DST_DIR_MAP_JSON_FILE,
// JSON.stringify(final_artifacts),
// );
global.BUNDLER_CTX_MAP = final_artifacts;
params?.post_build_fn?.({ artifacts: final_artifacts });
writeFileSync(
HYDRATION_DST_DIR_MAP_JSON_FILE,
JSON.stringify(artifacts),
);
}
console.timeEnd("build");
writeFileSync(
HYDRATION_DST_DIR_MAP_JSON_FILE,
JSON.stringify(artifacts),
);
if (params?.exit_after_first_build) {
// console.log(
// "global.BUNDLER_CTX_MAP",
// global.BUNDLER_CTX_MAP,
// );
process.exit();
}
});
@ -184,7 +175,6 @@ export default async function allPagesBundler(params?: Params) {
),
},
entryNames: "[dir]/[name]/[hash]",
// entryNames: "[name]/[hash]",
metafile: true,
plugins: [tailwindPlugin, virtualPlugin, artifactTracker],
jsx: "automatic",
@ -197,136 +187,3 @@ export default async function allPagesBundler(params?: Params) {
global.BUNDLER_CTX.watch();
}
}
// import plugin from "bun-plugin-tailwind";
// import { readdirSync, statSync, unlinkSync, writeFileSync } from "fs";
// import grabAllPages from "../../utils/grab-all-pages";
// import grabDirNames from "../../utils/grab-dir-names";
// import grabPageName from "../../utils/grab-page-name";
// import writeWebPageHydrationScript from "../server/web-pages/write-web-page-hydration-script";
// import path from "path";
// import bundle from "../../utils/bundle";
// import AppNames from "../../utils/grab-app-names";
// import type { PageFiles } from "../../types";
// import isDevelopment from "../../utils/is-development";
// import { execSync } from "child_process";
// const {
// BUNX_HYDRATION_SRC_DIR,
// HYDRATION_DST_DIR,
// HYDRATION_DST_DIR_MAP_JSON_FILE,
// } = grabDirNames();
// export default async function allPagesBundler() {
// console.time("build");
// const pages = grabAllPages({ exclude_api: true });
// for (let i = 0; i < pages.length; i++) {
// const page = pages[i];
// if (!isPageValid(page)) {
// continue;
// }
// const pageName = grabPageName({ path: page.local_path });
// writeWebPageHydrationScript({
// pageName,
// page_file: page.local_path,
// });
// }
// // const hydration_files = readdirSync(BUNX_HYDRATION_SRC_DIR);
// // for (let i = 0; i < hydration_files.length; i++) {
// // const hydration_file = hydration_files[i];
// // const valid_file = pages.find((p) => {
// // if (!isPageValid(p)) {
// // return false;
// // }
// // const pageName = grabPageName({ path: p.local_path });
// // const file_tsx_name = `${pageName}.tsx`;
// // if (file_tsx_name == hydration_file) {
// // return true;
// // }
// // return false;
// // });
// // if (!valid_file) {
// // unlinkSync(path.join(BUNX_HYDRATION_SRC_DIR, hydration_file));
// // }
// // }
// // const entrypoints = readdirSync(BUNX_HYDRATION_SRC_DIR)
// // .filter((f) => f.endsWith(".tsx"))
// // .map((f) => path.join(BUNX_HYDRATION_SRC_DIR, f))
// // .filter((f) => statSync(f).isFile());
// const entrypoints = pages.map((p) => p.local_path);
// // execSync(`rm -rf ${HYDRATION_DST_DIR}`);
// // bundle({
// // src: entrypoints.join(" "),
// // out_dir: HYDRATION_DST_DIR,
// // exec_options: { stdio: "ignore" },
// // entry_naming: `[dir]/[name]/[hash].js`,
// // minify: true,
// // target: "browser",
// // });
// // console.log(`Bundling ...`);
// const result = await Bun.build({
// entrypoints,
// outdir: HYDRATION_DST_DIR,
// plugins: [plugin],
// minify: true,
// target: "browser",
// // sourcemap: "linked",
// define: {
// "process.env.NODE_ENV": JSON.stringify(
// isDevelopment() ? "development" : "production",
// ),
// },
// naming: "[dir]/[name]/[hash].js",
// });
// const artifacts = result.outputs.map(({ path, hash, type }) => {
// const target_page = pages.find((p) =>
// p.local_path.replace(/src\/pages/, "public/pages"),
// );
// return {
// path,
// hash,
// type,
// ...target_page,
// };
// });
// if (artifacts?.[0]) {
// writeFileSync(
// HYDRATION_DST_DIR_MAP_JSON_FILE,
// JSON.stringify(artifacts),
// );
// }
// console.timeEnd("build");
// }
// function isPageValid(page: PageFiles): boolean {
// if (page.file_name == AppNames["RootPagesComponentName"]) {
// return false;
// }
// if (page.url_path.match(/\(|\)|--/)) {
// return false;
// }
// return true;
// }

View File

@ -10,9 +10,10 @@ export default async function genWebHTML({
component,
pageProps,
bundledMap,
head,
head: Head,
module,
meta,
routeParams,
}: LivePageDistGenParams) {
const { ClientRootElementIDName, ClientWindowPagePropsName } =
await grabContants();
@ -22,7 +23,9 @@ export default async function genWebHTML({
);
const componentHTML = renderToString(component);
const headHTML = head ? renderToString(head) : "";
const headHTML = Head
? renderToString(<Head serverRes={pageProps} ctx={routeParams} />)
: "";
let html = `<!DOCTYPE html>\n`;
html += `<html>\n`;

View File

@ -125,6 +125,7 @@ export default async function grabPageComponent({
: undefined;
const Component = module.default as FC<any>;
const Head = module.head as FC<any>;
const component = RootComponent ? (
<RootComponent {...serverRes}>
@ -141,6 +142,7 @@ export default async function grabPageComponent({
module,
bundledMap,
meta,
head: Head,
};
} catch (error: any) {
return await grabPageErrorComponent({

View File

@ -36,11 +36,23 @@ async function generateRes({
module,
meta,
head,
routeParams,
});
if (serverRes?.redirect?.destination) {
return Response.redirect(
serverRes.redirect.destination,
serverRes.redirect.permanent
? 301
: serverRes.redirect.status_code || 302,
);
}
const res_opts: ResponseInit = {
...serverRes?.responseOptions,
headers: {
"Content-Type": "text/html",
...serverRes?.responseOptions?.headers,
},
};
@ -55,5 +67,9 @@ async function generateRes({
const res = new Response(html, res_opts);
if (routeParams?.resTransform) {
return await routeParams.resTransform(res);
}
return res;
}

View File

@ -65,6 +65,10 @@ export type BunxRouteParams = {
url: URL;
body?: any;
query?: any;
/**
* Intercept and Transform the response object
*/
resTransform?: (res: Response) => Promise<Response> | Response;
};
export interface PostInsertReturn {
@ -125,17 +129,24 @@ export type PageDistGenParams = {
export type LivePageDistGenParams = {
component: ReactNode;
head?: ReactNode;
head?: FC<BunextPageHeadFCProps>;
pageProps?: any;
module?: BunextPageModule;
bundledMap?: BundlerCTXMap;
meta?: BunextPageModuleMeta;
routeParams?: BunxRouteParams;
};
export type BunextPageHeadFCProps = {
serverRes: BunextPageModuleServerReturn;
ctx?: BunxRouteParams;
};
export type BunextPageModule = {
default: FC<any>;
server?: BunextPageServerFn;
meta?: BunextPageModuleMeta | BunextPageModuleMetaFn;
head?: FC<BunextPageHeadFCProps>;
};
export type BunextPageModuleMetaFn = (params: {
@ -172,7 +183,9 @@ export type BunextPageModuleMeta = {
export type BunextPageServerFn<
T extends { [k: string]: any } = { [k: string]: any },
> = (routeParams: BunxRouteParams) => Promise<BunextPageModuleServerReturn<T>>;
> = (
ctx: Omit<BunxRouteParams, "body">,
) => Promise<BunextPageModuleServerReturn<T>>;
export type BunextPageModuleServerReturn<
T extends { [k: string]: any } = { [k: string]: any },
@ -180,6 +193,14 @@ export type BunextPageModuleServerReturn<
> = {
props?: T;
query?: Q;
redirect?: BunextPageModuleServerRedirect;
responseOptions?: ResponseInit;
};
export type BunextPageModuleServerRedirect = {
destination: string;
permanent?: boolean;
status_code?: number;
};
export type BunextPageModuleMetadata = {
@ -194,7 +215,7 @@ export type GrabPageComponentRes = {
bundledMap?: BundlerCTXMap;
module: BunextPageModule;
meta?: BunextPageModuleMeta;
head?: ReactNode;
head?: FC<BunextPageHeadFCProps>;
};
export type PageFiles = {