Handle browser Errors.

This commit is contained in:
2026-03-21 06:34:32 +01:00
parent d893a31d73
commit 7ef114ee70
97 changed files with 849 additions and 277 deletions
+2
View File
@@ -0,0 +1,2 @@
#!/usr/bin/env bun
export {};
+1
View File
@@ -0,0 +1 @@
export {};
+2
View File
@@ -0,0 +1,2 @@
import { transform as wasmTransform, transformStyleAttribute as wasmTransformStyleAttribute, bundle as wasmBundle, bundleAsync as wasmBundleAsync, Features, browserslistToTargets, composeVisitors } from "lightningcss-wasm";
export { wasmTransform as transform, wasmTransformStyleAttribute as transformStyleAttribute, wasmBundle as bundle, wasmBundleAsync as bundleAsync, Features, browserslistToTargets, composeVisitors, };
+2
View File
@@ -0,0 +1,2 @@
import { Command } from "commander";
export default function (): Command;
+2
View File
@@ -0,0 +1,2 @@
import { Command } from "commander";
export default function (): Command;
+26
View File
@@ -0,0 +1,26 @@
#!/usr/bin/env bun
import { type Ora } from "ora";
import type { BundlerCTXMap, BunextConfig, GlobalHMRControllerObject, PageFiles } from "../types";
import type { FileSystemRouter, Server } from "bun";
import type { BuildContext } from "esbuild";
import type { FSWatcher } from "fs";
/**
* # Declare Global Variables
*/
declare global {
var ORA_SPINNER: Ora;
var CONFIG: BunextConfig;
var SERVER: Server | undefined;
var RECOMPILING: boolean;
var WATCHER_TIMEOUT: any;
var ROUTER: FileSystemRouter;
var HMR_CONTROLLERS: GlobalHMRControllerObject[];
var LAST_BUILD_TIME: number;
var BUNDLER_CTX: BuildContext | undefined;
var BUNDLER_CTX_MAP: BundlerCTXMap[] | undefined;
var IS_FIRST_BUNDLE_READY: boolean;
var BUNDLER_REBUILDS: 0;
var PAGES_SRC_WATCHER: FSWatcher | undefined;
var CURRENT_VERSION: string | undefined;
var PAGE_FILES: PageFiles[];
}
+2
View File
@@ -0,0 +1,2 @@
import { Command } from "commander";
export default function (): Command;
+7
View File
@@ -0,0 +1,7 @@
export declare const AppData: {
readonly DefaultCacheExpiryTimeSeconds: number;
readonly DefaultCronInterval: 30000;
readonly BunextStaticFilesCacheExpiry: number;
readonly ClientHMRPath: "__bunext_client_hmr__";
readonly BunextClientHydrationScriptID: "bunext-client-hydration-script";
};
+10
View File
@@ -0,0 +1,10 @@
import type { BundlerCTXMap } from "../../types";
type Params = {
watch?: boolean;
exit_after_first_build?: boolean;
post_build_fn?: (params: {
artifacts: BundlerCTXMap[];
}) => Promise<void>;
};
export default function allPagesBundler(params?: Params): Promise<void>;
export {};
+2 -1
View File
@@ -56,6 +56,7 @@ export default async function allPagesBundler(params) {
}
const elapsed = (performance.now() - buildStart).toFixed(0);
log.success(`[Built] in ${elapsed}ms`);
global.RECOMPILING = false;
if (params?.exit_after_first_build) {
process.exit();
}
@@ -84,6 +85,6 @@ export default async function allPagesBundler(params) {
await ctx.rebuild();
if (params?.watch) {
global.BUNDLER_CTX = ctx;
global.BUNDLER_CTX.watch();
// global.BUNDLER_CTX.watch();
}
}
@@ -0,0 +1,8 @@
import * as esbuild from "esbuild";
import type { BundlerCTXMap, PageFiles } from "../../types";
type Params = {
result: esbuild.BuildResult<esbuild.BuildOptions>;
pages: PageFiles[];
};
export default function grabArtifactsFromBundledResults({ result, pages, }: Params): BundlerCTXMap[] | undefined;
export {};
@@ -0,0 +1,5 @@
type Params = {
page_local_path: string;
};
export default function grabClientHydrationScript({ page_local_path }: Params): string;
export {};
+5 -3
View File
@@ -38,15 +38,17 @@ export default function grabClientHydrationScript({ page_local_path }) {
// txt += `window.__JSX_RUNTIME__ = JSXRuntime;\n\n`;
txt += `const pageProps = window.__PAGE_PROPS__ || {};\n`;
if (does_root_exist) {
txt += `const component = <Root {...pageProps}><Page {...pageProps} /></Root>\n`;
txt += `const component = <Root suppressHydrationWarning={true} {...pageProps}><Page {...pageProps} /></Root>\n`;
}
else {
txt += `const component = <Page {...pageProps} />\n`;
txt += `const component = <Page suppressHydrationWarning={true} {...pageProps} />\n`;
}
txt += `if (window.${ClientRootComponentWindowName}?.render) {\n`;
txt += ` window.${ClientRootComponentWindowName}.render(component);\n`;
txt += `} else {\n`;
txt += ` const root = hydrateRoot(document.getElementById("${ClientRootElementIDName}"), component);\n\n`;
txt += ` const root = hydrateRoot(document.getElementById("${ClientRootElementIDName}"), component, { onRecoverableError: () => {\n\n`;
txt += ` console.log(\`Hydration Error.\`)\n\n`;
txt += ` } });\n\n`;
txt += ` window.${ClientRootComponentWindowName} = root;\n`;
txt += ` window.__BUNEXT_RERENDER__ = (NewPage) => {\n`;
txt += ` const props = window.__PAGE_PROPS__ || {};\n`;
+6
View File
@@ -0,0 +1,6 @@
type Params = {
key: string;
paradigm?: "html" | "json";
};
export default function getCache({ key, paradigm }: Params): string | undefined;
export {};
+9
View File
@@ -0,0 +1,9 @@
type Params = {
key: string;
paradigm?: "html" | "json";
};
export default function grabCacheNames({ key, paradigm }: Params): {
cache_name: string;
cache_meta_name: string;
};
export {};
+1
View File
@@ -0,0 +1 @@
export default function trimAllCache(): Promise<undefined>;
+6
View File
@@ -0,0 +1,6 @@
import type { APIResponseObject } from "../../types";
type Params = {
key: string;
};
export default function trimCacheKey({ key, }: Params): Promise<APIResponseObject>;
export {};
+9
View File
@@ -0,0 +1,9 @@
import type { APIResponseObject } from "../../types";
type Params = {
key: string;
value: string;
paradigm?: "html" | "json";
expiry_seconds?: number;
};
export default function writeCache({ key, value, paradigm, expiry_seconds, }: Params): Promise<APIResponseObject>;
export {};
+2
View File
@@ -0,0 +1,2 @@
import type { BunextConfig } from "../types";
export default function grabConfig(): Promise<BunextConfig | undefined>;
+1
View File
@@ -0,0 +1 @@
export default function (): Promise<void>;
+5
View File
@@ -0,0 +1,5 @@
type Params = {
req: Request;
};
export default function bunextRequestHandler({ req, }: Params): Promise<Response>;
export {};
+57
View File
@@ -0,0 +1,57 @@
import grabAppPort from "../../utils/grab-app-port";
import handleWebPages from "./web-pages/handle-web-pages";
import handleRoutes from "./handle-routes";
import isDevelopment from "../../utils/is-development";
import grabConstants from "../../utils/grab-constants";
import { AppData } from "../../data/app-data";
import handleHmr from "./handle-hmr";
import handleHmrUpdate from "./handle-hmr-update";
import handlePublic from "./handle-public";
import handleFiles from "./handle-files";
export default async function bunextRequestHandler({ req, }) {
const is_dev = isDevelopment();
try {
const url = new URL(req.url);
const { config } = grabConstants();
let response = undefined;
if (config?.middleware) {
const middleware_res = await config.middleware({
req,
url,
});
if (typeof middleware_res == "object") {
return middleware_res;
}
}
if (url.pathname == `/${AppData["ClientHMRPath"]}`) {
response = await handleHmrUpdate({ req });
}
else if (url.pathname === "/__hmr" && is_dev) {
response = await handleHmr({ req });
}
else if (url.pathname.startsWith("/api/")) {
response = await handleRoutes({ req });
}
else if (url.pathname.startsWith("/public/")) {
response = await handlePublic({ req });
}
else if (url.pathname.match(/\..*$/)) {
response = await handleFiles({ req });
}
else {
response = await handleWebPages({ req });
}
if (!response) {
throw new Error(`No Response generated`);
}
if (is_dev) {
response.headers.set("Cache-Control", "no-cache, no-store, must-revalidate");
}
return response;
}
catch (error) {
return new Response(`Server Error: ${error.message}`, {
status: 500,
});
}
}
+1
View File
@@ -0,0 +1 @@
export default function cron(): Promise<void>;
+5
View File
@@ -0,0 +1,5 @@
type Params = {
req: Request;
};
export default function ({ req }: Params): Promise<Response>;
export {};
+1 -1
View File
@@ -3,7 +3,7 @@ import path from "path";
import isDevelopment from "../../utils/is-development";
import { existsSync } from "fs";
const { PUBLIC_DIR } = grabDirNames();
export default async function ({ req, server }) {
export default async function ({ req }) {
try {
const is_dev = isDevelopment();
const url = new URL(req.url);
+5
View File
@@ -0,0 +1,5 @@
type Params = {
req: Request;
};
export default function ({ req }: Params): Promise<Response>;
export {};
+2 -2
View File
@@ -4,8 +4,8 @@ import path from "path";
import grabRootFile from "./web-pages/grab-root-file";
import grabPageBundledReactComponent from "./web-pages/grab-page-bundled-react-component";
import writeHMRTsxModule from "./web-pages/write-hmr-tsx-module";
const { PUBLIC_DIR, BUNX_HYDRATION_SRC_DIR } = grabDirNames();
export default async function ({ req, server }) {
const { BUNX_HYDRATION_SRC_DIR } = grabDirNames();
export default async function ({ req }) {
try {
const url = new URL(req.url);
const target_href = url.searchParams.get("href");
+5
View File
@@ -0,0 +1,5 @@
type Params = {
req: Request;
};
export default function ({ req }: Params): Promise<Response>;
export {};
+1 -1
View File
@@ -1,7 +1,7 @@
import grabRouteParams from "../../utils/grab-route-params";
import grabConstants from "../../utils/grab-constants";
import grabRouter from "../../utils/grab-router";
export default async function ({ req, server }) {
export default async function ({ req }) {
const referer_url = new URL(req.headers.get("referer") || "");
const match = global.ROUTER.match(referer_url.pathname);
const target_map = match?.filePath
+5
View File
@@ -0,0 +1,5 @@
type Params = {
req: Request;
};
export default function ({ req }: Params): Promise<Response>;
export {};
+2 -2
View File
@@ -2,8 +2,8 @@ import grabDirNames from "../../utils/grab-dir-names";
import path from "path";
import isDevelopment from "../../utils/is-development";
import { existsSync } from "fs";
const { PUBLIC_DIR, BUNX_HYDRATION_SRC_DIR } = grabDirNames();
export default async function ({ req, server }) {
const { PUBLIC_DIR } = grabDirNames();
export default async function ({ req }) {
try {
const is_dev = isDevelopment();
const url = new URL(req.url);
+5
View File
@@ -0,0 +1,5 @@
type Params = {
req: Request;
};
export default function ({ req }: Params): Promise<Response>;
export {};
+9 -3
View File
@@ -1,8 +1,10 @@
import grabRouteParams from "../../utils/grab-route-params";
import grabConstants from "../../utils/grab-constants";
import grabRouter from "../../utils/grab-router";
export default async function ({ req, server }) {
import isDevelopment from "../../utils/is-development";
export default async function ({ req }) {
const url = new URL(req.url);
const is_dev = isDevelopment();
const { MBInBytes, ServerDefaultRequestBodyLimitBytes } = grabConstants();
const router = grabRouter();
const match = router.match(url.pathname);
@@ -19,7 +21,9 @@ export default async function ({ req, server }) {
});
}
const routeParams = await grabRouteParams({ req });
const module = await import(match.filePath);
const now = Date.now();
const import_path = is_dev ? `${match.filePath}?t=${now}` : match.filePath;
const module = await import(import_path);
const config = module.config;
const contentLength = req.headers.get("content-length");
if (contentLength) {
@@ -40,7 +44,9 @@ export default async function ({ req, server }) {
}
const res = await module["default"]({
...routeParams,
server,
});
if (is_dev) {
res.headers.set("Cache-Control", "no-cache, no-store, must-revalidate");
}
return res;
}
+1
View File
@@ -0,0 +1 @@
export default function rebuildBundler(): Promise<void>;
+6
View File
@@ -0,0 +1,6 @@
import type { ServeOptions } from "bun";
type Params = {
dev?: boolean;
};
export default function (params?: Params): Promise<ServeOptions>;
export {};
+3 -54
View File
@@ -1,66 +1,15 @@
import grabAppPort from "../../utils/grab-app-port";
import handleWebPages from "./web-pages/handle-web-pages";
import handleRoutes from "./handle-routes";
import isDevelopment from "../../utils/is-development";
import grabConstants from "../../utils/grab-constants";
import { AppData } from "../../data/app-data";
import handleHmr from "./handle-hmr";
import handleHmrUpdate from "./handle-hmr-update";
import handlePublic from "./handle-public";
import handleFiles from "./handle-files";
import bunextRequestHandler from "./bunext-req-handler";
export default async function (params) {
const port = grabAppPort();
const is_dev = isDevelopment();
return {
async fetch(req, server) {
try {
const url = new URL(req.url);
const { config } = grabConstants();
let response = undefined;
if (config?.middleware) {
const middleware_res = await config.middleware({
req,
url,
server,
});
if (typeof middleware_res == "object") {
return middleware_res;
}
}
if (url.pathname == `/${AppData["ClientHMRPath"]}`) {
response = await handleHmrUpdate({ req, server });
}
else if (url.pathname === "/__hmr" && is_dev) {
response = await handleHmr({ req, server });
}
else if (url.pathname.startsWith("/api/")) {
response = await handleRoutes({ req, server });
}
else if (url.pathname.startsWith("/public/")) {
response = await handlePublic({ req, server });
}
else if (url.pathname.match(/\..*$/)) {
response = await handleFiles({ req, server });
}
else {
response = await handleWebPages({ req });
}
if (!response) {
throw new Error(`No Response generated`);
}
if (is_dev) {
response.headers.set("Cache-Control", "no-cache, no-store, must-revalidate");
}
return response;
}
catch (error) {
return new Response(`Server Error: ${error.message}`, {
status: 500,
});
}
return await bunextRequestHandler({ req });
},
port,
idleTimeout: 0,
// idleTimeout: 0,
development: {
hmr: true,
},
+6
View File
@@ -0,0 +1,6 @@
import type { BundlerCTXMap } from "../../types";
type Params = {
artifacts: BundlerCTXMap[];
};
export default function serverPostBuildFn({ artifacts }: Params): Promise<void>;
export {};
+5
View File
@@ -0,0 +1,5 @@
type Params = {
dev?: boolean;
};
export default function startServer(params?: Params): Promise<import("bun").Server>;
export {};
+6
View File
@@ -43,5 +43,11 @@ export default async function startServer(params) {
const server = Bun.serve(serverParams);
global.SERVER = server;
log.server(`http://localhost:${server.port}`);
/**
* First Rebuild to Avoid errors
*/
if (params?.dev && global.BUNDLER_CTX) {
await global.BUNDLER_CTX.rebuild();
}
return server;
}
+1
View File
@@ -0,0 +1 @@
export default function watcher(): void;
+9 -1
View File
@@ -11,8 +11,16 @@ export default function watcher() {
}, async (event, filename) => {
if (!filename)
return;
if (event !== "rename")
if (event !== "rename") {
if (filename.match(/\.(tsx?|jsx?|css)$/) &&
global.BUNDLER_CTX) {
if (global.RECOMPILING)
return;
global.RECOMPILING = true;
await global.BUNDLER_CTX.rebuild();
}
return;
}
if (!filename.match(/^pages\//))
return;
if (filename.match(/\/(--|\()/))
@@ -0,0 +1,2 @@
import type { LivePageDistGenParams } from "../../../types";
export default function genWebHTML({ component, pageProps, bundledMap, head: Head, module, meta, routeParams, debug, }: LivePageDistGenParams): Promise<string>;
@@ -0,0 +1,2 @@
import type { GrabPageComponentRes } from "../../../types";
export default function generateWebPageResponseFromComponentReturn({ component, module, bundledMap, head, meta, routeParams, serverRes, debug, }: GrabPageComponentRes): Promise<Response>;
@@ -0,0 +1,6 @@
type Params = {
file_path: string;
out_file?: string;
};
export default function grabFilePathModule<T extends any = any>({ file_path, out_file, }: Params): Promise<T>;
export {};
@@ -0,0 +1,8 @@
import type { GrabPageReactBundledComponentRes } from "../../../types";
type Params = {
file_path: string;
root_file?: string;
server_res?: any;
};
export default function grabPageBundledReactComponent({ file_path, root_file, server_res, }: Params): Promise<GrabPageReactBundledComponentRes | undefined>;
export {};
@@ -4,13 +4,13 @@ import grabTsxStringModule from "./grab-tsx-string-module";
export default async function grabPageBundledReactComponent({ file_path, root_file, server_res, }) {
try {
let tsx = ``;
const server_res_json = EJSON.stringify(server_res || {})?.replace(/"/g, '\\"');
const server_res_json = JSON.stringify(EJSON.stringify(server_res || {}) ?? "{}");
if (root_file) {
tsx += `import Root from "${root_file}"\n`;
}
tsx += `import Page from "${file_path}"\n`;
tsx += `export default function Main() {\n\n`;
tsx += `const props = JSON.parse("${server_res_json}")\n\n`;
tsx += `const props = JSON.parse(${server_res_json})\n\n`;
tsx += ` return (\n`;
if (root_file) {
tsx += ` <Root suppressHydrationWarning={true} {...props}><Page {...props} /></Root>\n`;
@@ -0,0 +1,8 @@
import type { GrabPageComponentRes } from "../../../types";
type Params = {
req?: Request;
file_path?: string;
debug?: boolean;
};
export default function grabPageComponent({ req, file_path: passed_file_path, debug, }: Params): Promise<GrabPageComponentRes>;
export {};
+6 -2
View File
@@ -9,6 +9,7 @@ class NotFoundError extends Error {
export default async function grabPageComponent({ req, file_path: passed_file_path, debug, }) {
const url = req?.url ? new URL(req.url) : undefined;
const router = global.ROUTER;
const now = Date.now();
let routeParams = undefined;
try {
routeParams = req ? await grabRouteParams({ req }) : undefined;
@@ -42,7 +43,7 @@ export default async function grabPageComponent({ req, file_path: passed_file_pa
log.info(`bundledMap:`, bundledMap);
}
const { root_file } = grabRootFile();
const module = await import(file_path);
const module = await import(`${file_path}?t=${now}`);
if (debug) {
log.info(`module:`, module);
}
@@ -68,7 +69,10 @@ export default async function grabPageComponent({ req, file_path: passed_file_pa
};
try {
if (routeParams) {
const serverData = await module["server"]?.(routeParams);
const serverData = await module["server"]?.({
...routeParams,
query: { ...routeParams.query, ...match?.query },
});
return {
...serverData,
...default_props,
@@ -0,0 +1,8 @@
import type { BunxRouteParams, GrabPageComponentRes } from "../../../types";
type Params = {
error?: any;
routeParams?: BunxRouteParams;
is404?: boolean;
};
export default function grabPageErrorComponent({ error, routeParams, is404, }: Params): Promise<GrabPageComponentRes>;
export {};
+3
View File
@@ -0,0 +1,3 @@
export default function grabRootFile(): {
root_file: string | undefined;
};
@@ -0,0 +1,6 @@
type Params = {
tsx: string;
file_path: string;
};
export default function grabTsxStringModule<T extends any = any>({ tsx, file_path, }: Params): Promise<T>;
export {};
@@ -0,0 +1,6 @@
import type { BunextPageModuleMeta } from "../../../types";
type Params = {
meta: BunextPageModuleMeta;
};
export default function grabWebMetaHTML({ meta }: Params): string;
export {};
@@ -0,0 +1,6 @@
import type { BundlerCTXMap } from "../../../types";
type Params = {
bundledMap?: BundlerCTXMap;
};
export default function ({ bundledMap }: Params): Promise<string>;
export {};
@@ -3,8 +3,9 @@ export default async function ({ bundledMap }) {
let script = "";
script += `console.log(\`Development Environment\`);\n\n`;
script += `const hmr = new EventSource("/__hmr");\n`;
script += `window.addEventListener("beforeunload", () => hmr.close());\n`;
script += `hmr.addEventListener("update", async (event) => {\n`;
script += ` if (event.data) {\n`;
script += ` if (event?.data) {\n`;
script += ` console.log(\`HMR Changes Detected. Updating ...\`);\n`;
script += ` try {\n`;
script += ` const data = JSON.parse(event.data);\n`;
+5
View File
@@ -0,0 +1,5 @@
type Params = {
req: Request;
};
export default function handleWebPages({ req, }: Params): Promise<Response>;
export {};
@@ -0,0 +1,3 @@
import * as esbuild from "esbuild";
declare const tailwindEsbuildPlugin: esbuild.Plugin;
export default tailwindEsbuildPlugin;
@@ -0,0 +1,7 @@
import type { BundlerCTXMap } from "../../../types";
type Params = {
tsx: string;
out_file: string;
};
export default function writeHMRTsxModule({ tsx, out_file }: Params): Promise<Pick<BundlerCTXMap, "css_path" | "path" | "hash" | "type"> | undefined>;
export {};
+5
View File
@@ -0,0 +1,5 @@
import bunextRequestHandler from "./functions/server/bunext-req-handler";
declare const bunext: {
bunextRequestHandler: typeof bunextRequestHandler;
};
export default bunext;
+4 -1
View File
@@ -1,2 +1,5 @@
const bunext = {};
import bunextRequestHandler from "./functions/server/bunext-req-handler";
const bunext = {
bunextRequestHandler,
};
export default bunext;
+2
View File
@@ -0,0 +1,2 @@
declare const config: {};
export default config;
+2
View File
@@ -0,0 +1,2 @@
import type { PropsWithChildren } from "react";
export default function DefaultNotFoundPage({ children }: PropsWithChildren): import("react/jsx-runtime").JSX.Element;
+2
View File
@@ -0,0 +1,2 @@
import type { PropsWithChildren } from "react";
export default function DefaultServerErrorPage({ children, }: PropsWithChildren): import("react/jsx-runtime").JSX.Element;
+260
View File
@@ -0,0 +1,260 @@
import type { MatchedRoute, Server } from "bun";
import type { FC, JSX, ReactNode } from "react";
export type ServerProps = {
params: Record<string, string>;
searchParams: Record<string, string>;
headers: Headers;
cookies: Record<string, string>;
body: any;
method: string;
url: string;
pathname: string;
query: Record<string, string>;
search: string;
hash: string;
};
export type StaticProps = {
params: Record<string, string>;
searchParams: Record<string, string>;
headers: Headers;
cookies: Record<string, string>;
body: any;
method: string;
url: string;
pathname: string;
query: Record<string, string>;
search: string;
hash: string;
};
export type StaticPaths = string[];
export type StaticParams = Record<string, string>;
export type PageModule = {
component: React.ComponentType<any>;
serverProps: ServerProps;
staticProps: StaticProps;
staticPaths: StaticPaths;
staticParams: StaticParams;
};
export type BunextConfig = {
distDir?: string;
assetsPrefix?: string;
origin?: string;
globalVars?: {
[k: string]: any;
};
port?: number;
development?: boolean;
middleware?: (params: BunextConfigMiddlewareParams) => Promise<Response | undefined> | Response | undefined;
defaultCacheExpiry?: number;
};
export type BunextConfigMiddlewareParams = {
req: Request;
url: URL;
};
export type GetRouteReturn = {
match: MatchedRoute;
module: PageModule;
component: React.ComponentType<any>;
serverProps: ServerProps;
staticProps: StaticProps;
staticPaths: StaticPaths;
staticParams: StaticParams;
};
export type BunxRouteParams = {
req: Request;
url: URL;
body?: any;
query?: any;
/**
* Intercept and Transform the response object
*/
resTransform?: (res: Response) => Promise<Response> | Response;
server?: Server;
};
export interface PostInsertReturn {
fieldCount?: number;
affectedRows?: number;
insertId?: number;
serverStatus?: number;
warningCount?: number;
message?: string;
protocol41?: boolean;
changedRows?: number;
}
export type APIResponseObject<T extends {
[k: string]: any;
} = {
[k: string]: any;
}> = {
success: boolean;
payload?: T[] | null;
singleRes?: T | null;
stringRes?: string | null;
numberRes?: number | null;
postInsertReturn?: PostInsertReturn | null;
payloadBase64?: string;
payloadThumbnailBase64?: string;
payloadURL?: string;
payloadThumbnailURL?: string;
error?: any;
msg?: string;
queryObject?: any;
countQueryObject?: any;
status?: number;
count?: number;
errors?: any[];
debug?: any;
batchPayload?: any[][] | null;
errorData?: any;
token?: string;
csrf?: string;
cookieNames?: any;
key?: string;
userId?: string | number;
code?: string;
createdAt?: number;
email?: string;
requestOptions?: any;
logoutUser?: boolean;
redirect?: string;
};
export type BunextServerRouteConfig = {
maxRequestBodyMB?: number;
};
export type PageDistGenParams = {
pageName: string;
page_file: string;
};
export type LivePageDistGenParams = {
component: ReactNode;
head?: FC<BunextPageHeadFCProps>;
pageProps?: any;
module?: BunextPageModule;
bundledMap?: BundlerCTXMap;
meta?: BunextPageModuleMeta;
routeParams?: BunxRouteParams;
debug?: boolean;
};
export type BunextPageHeadFCProps = {
serverRes: BunextPageModuleServerReturn;
ctx?: BunxRouteParams;
};
export type BunextPageModule = {
default: FC<any>;
server?: BunextPageServerFn;
meta?: BunextPageModuleMeta | BunextPageModuleMetaFn;
Head?: FC<BunextPageHeadFCProps>;
config?: BunextRouteConfig;
};
export type BunextPageModuleMetaFn = (params: {
ctx: BunxRouteParams;
serverRes?: BunextPageModuleServerReturn;
}) => Promise<BunextPageModuleMeta>;
export type BunextPageModuleMeta = {
title?: string;
description?: string;
keywords?: string | string[];
author?: string;
robots?: string;
canonical?: string;
themeColor?: string;
og?: {
title?: string;
description?: string;
image?: string;
url?: string;
type?: string;
siteName?: string;
locale?: string;
};
twitter?: {
card?: "summary" | "summary_large_image" | "app" | "player";
title?: string;
description?: string;
image?: string;
site?: string;
creator?: string;
};
};
export type BunextPageServerFn<T extends {
[k: string]: any;
} = {
[k: string]: any;
}> = (ctx: Omit<BunxRouteParams, "body">) => Promise<BunextPageModuleServerReturn<T>>;
export type BunextRouteConfig = {
cachePage?: boolean;
/**
* Expiry time of the cache in seconds
*/
cacheExpiry?: number;
};
export type BunextPageModuleServerReturn<T extends {
[k: string]: any;
} = {
[k: string]: any;
}, Q extends {
[k: string]: any;
} = {
[k: string]: any;
}> = {
props?: T;
query?: Q;
redirect?: BunextPageModuleServerRedirect;
responseOptions?: ResponseInit;
cachePage?: boolean;
/**
* Expiry time of the cache in seconds
*/
cacheExpiry?: number;
url?: BunextPageModuleServerReturnURLObject;
};
export type BunextPageModuleServerReturnURLObject = URL & {};
export type BunextPageModuleServerRedirect = {
destination: string;
permanent?: boolean;
status_code?: number;
};
export type BunextPageModuleMetadata = {
title?: string;
description?: string;
};
export type GrabPageComponentRes = {
component: JSX.Element;
serverRes?: BunextPageModuleServerReturn;
routeParams?: BunxRouteParams;
bundledMap?: BundlerCTXMap;
module: BunextPageModule;
meta?: BunextPageModuleMeta;
head?: FC<BunextPageHeadFCProps>;
debug?: boolean;
};
export type GrabPageReactBundledComponentRes = {
component: JSX.Element;
server_res?: BunextPageModuleServerReturn;
tsx?: string;
};
export type PageFiles = {
local_path: string;
url_path: string;
file_name: string;
};
export type BundlerCTXMap = {
path: string;
hash: string;
type: string;
entrypoint: string;
local_path: string;
url_path: string;
file_name: string;
css_path?: string;
};
export type GlobalHMRControllerObject = {
controller: ReadableStreamDefaultController<string>;
page_url: string;
target_map?: BundlerCTXMap;
};
export type BunextCacheFileMeta = {
date_created: number;
paradigm: "html" | "json";
expiry_seconds?: number;
};
+31
View File
@@ -0,0 +1,31 @@
import { type ExecSyncOptions } from "child_process";
declare const BuildKeys: readonly [{
readonly key: "production";
}, {
readonly key: "bytecode";
}, {
readonly key: "conditions";
}, {
readonly key: "format";
}, {
readonly key: "root";
}, {
readonly key: "splitting";
}, {
readonly key: "cdd-chunking";
}];
type Params = {
src: string;
out_dir: string;
entry_naming?: string;
minify?: boolean;
exec_options?: ExecSyncOptions;
debug?: boolean;
sourcemap?: boolean;
target?: "browser" | "node" | "bun";
build_options?: {
[k in (typeof BuildKeys)[number]["key"]]: string | boolean;
};
};
export default function bundle({ out_dir, src, minify, exec_options, debug, entry_naming, sourcemap, target, build_options, }: Params): void;
export {};
+8
View File
@@ -0,0 +1,8 @@
/**
* # Convert Serialized Query back to object
*/
export default function deserializeQuery(query: string | {
[s: string]: any;
}): {
[s: string]: any;
};
+17
View File
@@ -0,0 +1,17 @@
/**
* # EJSON parse string
*/
declare function parse(string: string | null | number, reviver?: (this: any, key: string, value: any) => any): {
[s: string]: any;
} | {
[s: string]: any;
}[] | undefined;
/**
* # EJSON stringify object
*/
declare function stringify(value: any, replacer?: ((this: any, key: string, value: any) => any) | null, space?: string | number): string | undefined;
declare const EJSON: {
parse: typeof parse;
stringify: typeof stringify;
};
export default EJSON;
+1
View File
@@ -0,0 +1 @@
export default function exitWithError(msg: string, code?: number): void;
+6
View File
@@ -0,0 +1,6 @@
import type { PageFiles } from "../types";
type Params = {
exclude_api?: boolean;
};
export default function grabAllPages(params?: Params): PageFiles[];
export {};
+1 -1
View File
@@ -26,7 +26,7 @@ function grabPageDirRecursively({ page_dir }) {
if (page.match(new RegExp(`${AppNames["RootPagesComponentName"]}`))) {
continue;
}
if (page.match(/\(|\)|--/)) {
if (page.match(/\(|\)|--|\/api\//)) {
continue;
}
const page_stat = statSync(full_page_path);
+9
View File
@@ -0,0 +1,9 @@
declare const AppNames: {
readonly defaultPort: 7000;
readonly defaultAssetPrefix: "_bunext/static";
readonly name: "Bunext";
readonly version: "1.0.1";
readonly defaultDistDir: ".bunext";
readonly RootPagesComponentName: "__root";
};
export default AppNames;
+1
View File
@@ -0,0 +1 @@
export default function grabAppPort(): number;
+1
View File
@@ -0,0 +1 @@
export default function grabAssetsPrefix(): string;
+9
View File
@@ -0,0 +1,9 @@
export default function grabConstants(): {
readonly ClientRootElementIDName: "__bunext";
readonly ClientWindowPagePropsName: "__PAGE_PROPS__";
readonly MBInBytes: number;
readonly ServerDefaultRequestBodyLimitBytes: number;
readonly ClientRootComponentWindowName: "BUNEXT_ROOT";
readonly MaxBundlerRebuilds: 5;
readonly config: import("../types").BunextConfig;
};
+21
View File
@@ -0,0 +1,21 @@
export default function grabDirNames(): {
ROOT_DIR: string;
SRC_DIR: string;
PAGES_DIR: string;
API_DIR: string;
PUBLIC_DIR: string;
HYDRATION_DST_DIR: string;
BUNX_ROOT_DIR: string;
CONFIG_FILE: string;
BUNX_TMP_DIR: string;
BUNX_HYDRATION_SRC_DIR: string;
BUNX_ROOT_SRC_DIR: string;
BUNX_ROOT_PRESETS_DIR: string;
BUNX_ROOT_500_PRESET_COMPONENT: string;
BUNX_ROOT_500_FILE_NAME: string;
BUNX_ROOT_404_PRESET_COMPONENT: string;
BUNX_ROOT_404_FILE_NAME: string;
HYDRATION_DST_DIR_MAP_JSON_FILE: string;
BUNEXT_CACHE_DIR: string;
BUNX_CWD_MODULE_CACHE_DIR: string;
};
+1
View File
@@ -0,0 +1 @@
export default function grabOrigin(): string;
+5
View File
@@ -0,0 +1,5 @@
type Params = {
path: string;
};
export default function grabPageName(params: Params): string;
export {};
+6
View File
@@ -0,0 +1,6 @@
import type { BunxRouteParams } from "../types";
type Params = {
req: Request;
};
export default function grabRouteParams({ req, }: Params): Promise<BunxRouteParams>;
export {};
+1
View File
@@ -0,0 +1 @@
export default function grabRouter(): import("bun").FileSystemRouter;
+1
View File
@@ -0,0 +1 @@
export default function isDevelopment(): boolean;
+10
View File
@@ -0,0 +1,10 @@
export declare const log: {
info: (msg: string, log?: any) => void;
success: (msg: string, log?: any) => void;
error: (msg: string | Error) => void;
warn: (msg: string) => void;
build: (msg: string) => void;
watch: (msg: string) => void;
server: (url: string) => void;
banner: () => void;
};
+2
View File
@@ -0,0 +1,2 @@
export default function numberfy(num: any, decimals?: number): number;
export declare const _n: typeof numberfy;
+1
View File
@@ -0,0 +1 @@
export default function refreshRouter(): void;
+1
View File
@@ -0,0 +1 @@
export default function registerDevPlugin(): void;