wip fix server side

This commit is contained in:
Rizky 2024-02-09 18:15:16 +07:00
parent 27af6c01af
commit f0a99dbc6a
5 changed files with 126 additions and 55 deletions

View File

@ -2,13 +2,34 @@ import { glb } from "./global";
import { server } from "./ws/sync/editor/code/server-main"; import { server } from "./ws/sync/editor/code/server-main";
glb.npm = { page: {}, site: {} }; glb.npm = { page: {}, site: {} };
glb.ws_hook = {
ping(ws, data) {
server.ws("ping", ws, data);
},
pong(ws, data) {
server.ws("pong", ws, data);
},
drain(ws) {
server.ws("drain", ws);
},
close(ws, code, reason) {
server.ws("close", ws, code, reason);
},
message(ws, message) {
server.ws("message", ws, message);
},
open(ws) {
server.ws("open", ws);
},
};
glb.server_hook = async (arg) => { glb.server_hook = async (arg) => {
const url = arg.url; const url = arg.url;
if (url.pathname.startsWith("/prod")) { if (url.pathname.startsWith("/prod")) {
const arr = url.pathname.split("/"); const arr = url.pathname.split("/");
const site_id = arr[2]; const site_id = arr[2];
return await server.serve(site_id, arg); return await server.http(site_id, arg);
} }
if (arg.handle) return await arg.handle(arg.req); if (arg.handle) return await arg.handle(arg.req);

View File

@ -93,6 +93,7 @@ if (typeof global.server_hook === "function") {
name: "prasi", name: "prasi",
setup(setup) { setup(setup) {
setup.onEnd((res) => { setup.onEnd((res) => {
console.log("en bul");
server.init(id_site); server.init(id_site);
}); });
}, },

View File

@ -1,7 +1,101 @@
import type { Server, WebSocketHandler } from "bun"; import type { Server, WebSocketHandler, ServerWebSocket } from "bun";
import { existsAsync } from "fs-jetpack";
import _fs from "node:fs/promises"; import _fs from "node:fs/promises";
import { g } from "utils/global"; import { g } from "utils/global";
import { waitUntil } from "web-utils";
import { code } from "./util-code"; import { code } from "./util-code";
import { WSData } from "../../../../../../pkgs/core/server/create";
import { codeBuild } from "./build-code";
const serverMain = () => ({
handler: {} as Record<string, PrasiServer>,
init_timeout: null as any,
ws(action: keyof WebSocketHandler<WSData>, ...arg: any[]) {
const id = arg[0].data.site_id;
if (this.handler[id]) {
const handler = this.handler[id].ws;
if (handler) {
const fn = handler[action] as any;
if (typeof fn === "function") {
return fn(...arg);
}
}
}
},
init(site_id: string) {
clearTimeout(this.init_timeout);
this.init_timeout = setTimeout(() => {
console.log("initing", site_id);
try {
const server_src_path = code.path(
site_id,
"server",
"build",
"index.js"
);
delete require.cache[server_src_path];
const svr = require(server_src_path);
if (svr && svr.server) {
this.handler[site_id] = svr.server;
}
Bun.write(
Bun.file(code.path(site_id, "site", "src", "server.log")),
""
);
} catch (e) {
console.log(`Failed to init server ${site_id}`);
}
}, 100);
},
async http(
site_id: string,
arg: Parameters<Exclude<(typeof g)["server_hook"], undefined>>[0]
) {
if (!code.esbuild[site_id]) {
await codeBuild(site_id);
}
if (typeof this.handler[site_id] === "undefined") {
if (
await existsAsync(code.path(site_id, "server", "build", "index.js"))
) {
this.init(site_id);
await waitUntil(200);
}
}
const handler = this.handler[site_id];
if (handler) {
try {
if (
handler.ws &&
arg.req.headers.get("connection")?.toLowerCase() === "upgrade" &&
!arg.wsHandler[arg.url.pathname]
) {
if (
arg.server.upgrade(arg.req, {
data: {
url: new URL(arg.req.url),
site_id,
},
})
) {
return;
}
return new Response("Upgrade failed :(", { status: 500 });
}
return await handler.http(arg);
} catch (e: any) {
_fs.appendFile(
code.path(site_id, "site", "src", "server.log"),
e.message + "\n"
);
}
}
},
});
type PrasiServer = { type PrasiServer = {
ws?: WebSocketHandler<{ url: string }>; ws?: WebSocketHandler<{ url: string }>;
@ -13,54 +107,10 @@ type PrasiServer = {
}) => Promise<Response>; }) => Promise<Response>;
}; };
if (!g._server) { const glb = global as unknown as {
g._server = { _server: ReturnType<typeof serverMain>;
handler: {} as Record<string, PrasiServer>, };
init_timeout: null as any, if (!glb._server) {
init(site_id: string) { glb._server = serverMain();
clearTimeout(this.init_timeout);
this.init_timeout = setTimeout(() => {
console.log("server init", site_id);
try {
const server_src_path = code.path(
site_id,
"server",
"build",
"index.js"
);
delete require.cache[server_src_path];
const svr = require(server_src_path);
if (svr && svr.server) {
this.handler[site_id] = svr.server;
}
Bun.write(
Bun.file(code.path(site_id, "site", "src", "server.log")),
""
);
} catch (e) {
console.log(`Failed to init server ${site_id}`);
}
}, 300);
},
async serve(
site_id: string,
arg: Parameters<Exclude<(typeof g)["server_hook"], undefined>>[0]
) {
const handler = this.handler[site_id];
console.log(this.handler);
if (handler) {
try {
return await handler.http(arg);
} catch (e: any) {
_fs.appendFile(
code.path(site_id, "site", "src", "server.log"),
e.message + "\n"
);
}
}
},
};
} }
export const server = g._server; export const server = glb._server;

View File

@ -28,7 +28,6 @@ export const createServer = async () => {
websocket: await serveWS(wsHandler), websocket: await serveWS(wsHandler),
async fetch(req, server) { async fetch(req, server) {
const url = new URL(req.url); const url = new URL(req.url);
const handle = async (req: Request) => { const handle = async (req: Request) => {
if (wsHandler[url.pathname]) { if (wsHandler[url.pathname]) {
if ( if (
@ -56,7 +55,7 @@ export const createServer = async () => {
}; };
if (g.server_hook) { if (g.server_hook) {
return await g.server_hook({ url, req, server, handle }); return await g.server_hook({ url, req, server, handle, wsHandler });
} else { } else {
return await handle(req); return await handle(req);
} }

View File

@ -15,12 +15,12 @@ type SingleRoute = {
export const g = global as unknown as { export const g = global as unknown as {
status: "init" | "ready"; status: "init" | "ready";
_server: any;
server_hook?: (arg: { server_hook?: (arg: {
url: URL; url: URL;
req: Request; req: Request;
server: Server; server: Server;
handle: (req: Request) => Promise<Response | undefined>; handle: (req: Request) => Promise<Response | undefined>;
wsHandler: Record<string, WebSocketHandler<WSData>>;
}) => Promise<Response | undefined>; }) => Promise<Response | undefined>;
ws_hook?: WebSocketHandler<WSData>; ws_hook?: WebSocketHandler<WSData>;
_db: PrismaClient; _db: PrismaClient;