diff --git a/app/srv/api/auth/login.ts b/app/srv/api/auth/login.ts
index 0f0d909b..f674ee10 100644
--- a/app/srv/api/auth/login.ts
+++ b/app/srv/api/auth/login.ts
@@ -1,4 +1,4 @@
-import { apiContext } from "service-srv";
+import { apiContext } from "../../../../pkgs/core/server/api/api-ctx";
import argon from "@node-rs/argon2";
import { session } from "utils/session";
diff --git a/app/srv/api/auth/logout.ts b/app/srv/api/auth/logout.ts
index 42414062..57d35f9d 100644
--- a/app/srv/api/auth/logout.ts
+++ b/app/srv/api/auth/logout.ts
@@ -1,4 +1,4 @@
-import { apiContext } from "service-srv";
+import { apiContext } from "../../../../pkgs/core/server/api/api-ctx";
import { session } from "utils/session";
export const _ = {
diff --git a/app/srv/api/auth/session.ts b/app/srv/api/auth/session.ts
index 55da5aaf..90531dc0 100644
--- a/app/srv/api/auth/session.ts
+++ b/app/srv/api/auth/session.ts
@@ -1,4 +1,4 @@
-import { apiContext } from "service-srv";
+import { apiContext } from "../../../../pkgs/core/server/api/api-ctx";
import { user } from "dbgen";
import { session } from "utils/session";
diff --git a/app/srv/api/code.ts b/app/srv/api/code.ts
index 93757328..a30f68f1 100644
--- a/app/srv/api/code.ts
+++ b/app/srv/api/code.ts
@@ -1,7 +1,7 @@
import { dirAsync } from "fs-jetpack";
import trim from "lodash.trim";
import { dirname } from "path";
-import { apiContext } from "service-srv";
+import { apiContext } from "../../../pkgs/core/server/api/api-ctx";
import { g } from "utils/global";
import { baseTypings } from "../../web/src/utils/script/types/base";
diff --git a/app/srv/api/comp.ts b/app/srv/api/comp.ts
index 40c46905..89a7e0e3 100644
--- a/app/srv/api/comp.ts
+++ b/app/srv/api/comp.ts
@@ -1,4 +1,4 @@
-import { apiContext } from "service-srv";
+import { apiContext } from "../../../pkgs/core/server/api/api-ctx";
export const _ = {
url: "/_web/comp/:id",
diff --git a/app/srv/api/font.ts b/app/srv/api/font.ts
index f3958d04..0545f84d 100644
--- a/app/srv/api/font.ts
+++ b/app/srv/api/font.ts
@@ -1,4 +1,4 @@
-import { apiContext } from "service-srv";
+import { apiContext } from "../../../pkgs/core/server/api/api-ctx";
export const _ = {
url: "/_font/**",
diff --git a/app/srv/api/img.ts b/app/srv/api/img.ts
index cbcef0f1..44d9cd2c 100644
--- a/app/srv/api/img.ts
+++ b/app/srv/api/img.ts
@@ -1,4 +1,4 @@
-import { apiContext } from "service-srv";
+import { apiContext } from "../../../pkgs/core/server/api/api-ctx";
import { g } from "utils/global";
export const _ = {
diff --git a/app/srv/api/local-ip.ts b/app/srv/api/local-ip.ts
index 8baf9dc5..86057efd 100644
--- a/app/srv/api/local-ip.ts
+++ b/app/srv/api/local-ip.ts
@@ -1,4 +1,4 @@
-import { apiContext } from "service-srv";
+import { apiContext } from "../../../pkgs/core/server/api/api-ctx";
export const _ = {
url: "/local-ip",
async api() {
diff --git a/app/srv/api/nova-load.ts b/app/srv/api/nova-load.ts
index 6a0a4b6b..47244afc 100644
--- a/app/srv/api/nova-load.ts
+++ b/app/srv/api/nova-load.ts
@@ -1,5 +1,5 @@
import { dir } from "dir";
-import { apiContext } from "service-srv";
+import { apiContext } from "../../../pkgs/core/server/api/api-ctx";
import { g } from "utils/global";
export const _ = {
diff --git a/app/srv/api/npm-bundle.ts b/app/srv/api/npm-bundle.ts
index c1f91968..cfa350a5 100644
--- a/app/srv/api/npm-bundle.ts
+++ b/app/srv/api/npm-bundle.ts
@@ -1,4 +1,4 @@
-import { apiContext } from "service-srv";
+import { apiContext } from "../../../pkgs/core/server/api/api-ctx";
import { buildNpm } from "../util/build-npm";
export const _ = {
diff --git a/app/srv/api/npm-size.ts b/app/srv/api/npm-size.ts
index 1b52b704..b338a543 100644
--- a/app/srv/api/npm-size.ts
+++ b/app/srv/api/npm-size.ts
@@ -1,6 +1,6 @@
import { dir } from "dir";
import { stat } from "fs/promises";
-import { apiContext } from "service-srv";
+import { apiContext } from "../../../pkgs/core/server/api/api-ctx";
import { g } from "utils/global";
export const _ = {
diff --git a/app/srv/api/npm.ts b/app/srv/api/npm.ts
index 9872d8b1..4db678d0 100644
--- a/app/srv/api/npm.ts
+++ b/app/srv/api/npm.ts
@@ -2,7 +2,7 @@ import crypto from "crypto";
import { dir } from "dir";
import { readAsync } from "fs-jetpack";
import mime from "mime-types";
-import { apiContext } from "service-srv";
+import { apiContext } from "../../../pkgs/core/server/api/api-ctx";
import { glb } from "../global";
import { g } from "utils/global";
diff --git a/app/srv/api/page.ts b/app/srv/api/page.ts
index 5530d27d..2e790c2c 100644
--- a/app/srv/api/page.ts
+++ b/app/srv/api/page.ts
@@ -1,4 +1,4 @@
-import { apiContext } from "service-srv";
+import { apiContext } from "../../../pkgs/core/server/api/api-ctx";
export const _ = {
url: "/_web/page/:id",
diff --git a/app/srv/api/session.ts b/app/srv/api/session.ts
index 9920af19..b4423f49 100644
--- a/app/srv/api/session.ts
+++ b/app/srv/api/session.ts
@@ -1,4 +1,4 @@
-import { apiContext } from "service-srv";
+import { apiContext } from "../../../pkgs/core/server/api/api-ctx";
import { session } from "utils/session";
import { user } from "dbgen";
diff --git a/app/srv/api/site-bundle.ts b/app/srv/api/site-bundle.ts
index 91c302dc..6baa23d8 100644
--- a/app/srv/api/site-bundle.ts
+++ b/app/srv/api/site-bundle.ts
@@ -1,7 +1,7 @@
import { createHash } from "crypto";
import { dir } from "dir";
import { readAsync } from "fs-jetpack";
-import { apiContext } from "service-srv";
+import { apiContext } from "../../../pkgs/core/server/api/api-ctx";
const cache = {
md5: "",
content: null as any,
diff --git a/app/srv/api/site-dts.ts b/app/srv/api/site-dts.ts
index 1ded005d..29e832fc 100644
--- a/app/srv/api/site-dts.ts
+++ b/app/srv/api/site-dts.ts
@@ -1,4 +1,4 @@
-import { apiContext } from "service-srv";
+import { apiContext } from "../../../pkgs/core/server/api/api-ctx";
import ts from "typescript";
import { createHash } from "crypto";
diff --git a/app/srv/api/site-export.ts b/app/srv/api/site-export.ts
index f46e8798..05ee1399 100644
--- a/app/srv/api/site-export.ts
+++ b/app/srv/api/site-export.ts
@@ -1,4 +1,4 @@
-import { apiContext } from "service-srv";
+import { apiContext } from "../../../pkgs/core/server/api/api-ctx";
import { dir } from "dir";
import fs from "fs";
diff --git a/app/web/src/base/page/ed.tsx b/app/web/src/base/page/ed.tsx
index dd2719d7..1ff436b8 100644
--- a/app/web/src/base/page/ed.tsx
+++ b/app/web/src/base/page/ed.tsx
@@ -7,6 +7,19 @@ import { Loading } from "../../utils/ui/loading";
export default page({
url: "/ed/:site_id/:page_id",
component: ({}) => {
+ console.log("momoka");
+ setTimeout(() => {
+ (async () => {
+ console.log(
+ await fetch("/moka", {
+ method: "POST",
+ body: "{}",
+ })
+ );
+ })();
+ }, 2000);
+ return <>uwuw>;
+
const p = useGlobal(EDGlobal, "EDITOR");
const w = window as any;
diff --git a/app/web/src/index.tsx b/app/web/src/index.tsx
index 0390a7b7..86fa3440 100644
--- a/app/web/src/index.tsx
+++ b/app/web/src/index.tsx
@@ -2,197 +2,30 @@ import { Root as ReactRoot, createRoot } from "react-dom/client";
import { defineReact, defineWindow } from "web-utils";
import { Root } from "./base/root";
import "./index.css";
-import { createAPI, createDB, reloadDBAPI } from "./utils/script/init-api";
-import { w } from "./utils/types/general";
import { registerMobile } from "./render/live/logic/mobile";
-import { isLocalhost } from "./utils/ui/is-localhost";
+import { reloadDBAPI } from "./utils/script/init-api";
+import { w } from "./utils/types/general";
+import { sworkerAddCache, sworkerRegister } from "./sworker-boot";
const start = async () => {
const base = `${location.protocol}//${location.host}`;
let react = {
root: null as null | ReactRoot,
};
- (window as any).mobile = registerMobile();
-
- if (navigator.serviceWorker) {
- if (!isLocalhost()) {
- const sw = await registerServiceWorker();
- const cacheCurrentPage = () => {
- const swController = navigator.serviceWorker.controller;
- if (swController) {
- [location.href, "", "/", "/ed", "/ed/_/_", "/login"].forEach(
- (url) => {
- swController.postMessage({
- type: "add-cache",
- url: url,
- });
- }
- );
- }
- };
- cacheCurrentPage();
- navigator.serviceWorker.addEventListener("message", (e) => {
- cacheCurrentPage();
- if (react.root) {
- if (e.data.type === "offline") {
- w.offline = true;
- const click = () => {
- if (react.root) react.root.render();
- };
- setTimeout(click, 5000);
- react.root.render(
- <>
-
-
- >
- );
- }
-
- if (e.data.type === "activated") {
- if (e.data.shouldRefresh && sw) {
- react.root.render(
- <>
-
-
- >
- );
-
- sw.unregister().then(() => {
- window.location.reload();
- });
- } else {
- const localVersion = localStorage.getItem("prasi-version");
- if (localVersion !== e.data.version) {
- localStorage.setItem("prasi-version", e.data.version);
- const click = () => {
- if (react.root) react.root.render();
- };
- setTimeout(click, 5000);
- react.root.render(
- <>
-
-
-
- Prasi Updated{" "}
- {e.data.version}
-
-
- >
- );
- }
- }
- }
- }
- });
- } else {
- navigator.serviceWorker.getRegistrations().then(function (registrations) {
- for (let registration of registrations) {
- registration.unregister();
- }
- });
- }
- }
+ w.mobile = registerMobile();
+ // sworkerRegister(react);
defineReact();
await defineWindow(false);
- w.serverurl = base;
- await reloadDBAPI(base, "prod");
-
- if (navigator.serviceWorker) {
- const swc = navigator.serviceWorker.controller;
- if (swc) {
- [location.href, "", "/", "/ed", "/ed/_/_", "/login"].forEach((url) => {
- swc.postMessage({
- type: "add-cache",
- url: url,
- });
- });
- if (w.prasiApi && w.prasiApi[base] && w.prasiApi[base].apiEntry) {
- const routes = Object.entries(w.prasiApi[base].apiEntry).map(
- ([k, v]: any) => ({
- url: v.url,
- name: k,
- })
- );
-
- swc.postMessage({
- type: "define-route",
- routes,
- });
- }
- }
- }
- w.api = createAPI(base);
- w.db = createDB(base);
+ // await reloadDBAPI(base, "prod");
+ // sworkerAddCache(base);
const el = document.getElementById("root");
+
if (el) {
react.root = createRoot(el);
react.root.render();
}
};
-const registerServiceWorker = async () => {
- if ("serviceWorker" in navigator) {
- try {
- return await navigator.serviceWorker.register(
- new URL("./sworker.ts", import.meta.url),
- {
- type: "module",
- scope: "/",
- }
- );
- } catch (error) {
- console.error(`Registration failed with ${error}`);
- }
- }
-};
-
start();
diff --git a/app/web/src/nova/ed/logic/ed-init.ts b/app/web/src/nova/ed/logic/ed-init.ts
index cf458806..f39c2c37 100644
--- a/app/web/src/nova/ed/logic/ed-init.ts
+++ b/app/web/src/nova/ed/logic/ed-init.ts
@@ -2,6 +2,7 @@ import init from "wasm-gzip";
import { jscript } from "../../../utils/script/jscript";
import { dbClient } from "../../vi/load/db/client-db";
import { PG } from "./ed-global";
+import { fetchViaProxy } from "../../vi/load/proxy";
let w = window as unknown as { db: ReturnType };
diff --git a/app/web/src/nova/ed/panel/popup/script/snippet.tsx b/app/web/src/nova/ed/panel/popup/script/snippet.tsx
index d0209f3c..6b502a49 100644
--- a/app/web/src/nova/ed/panel/popup/script/snippet.tsx
+++ b/app/web/src/nova/ed/panel/popup/script/snippet.tsx
@@ -16,7 +16,6 @@ export const EdScriptSnippet: FC<{}> = ({}) => {
font-size: 12px;
`)}
onClick={() => {
- console.log(p.script.do_edit);
p.script.do_edit(
`\
diff --git a/app/web/src/sworker-boot.tsx b/app/web/src/sworker-boot.tsx
new file mode 100644
index 00000000..f35c5eec
--- /dev/null
+++ b/app/web/src/sworker-boot.tsx
@@ -0,0 +1,177 @@
+import { Root as ReactRoot } from "react-dom/client";
+import { Root } from "./base/root";
+import { w } from "./utils/types/general";
+import { isLocalhost } from "./utils/ui/is-localhost";
+
+export const sworkerRegister = async (react: { root: null | ReactRoot }) => {
+ if (navigator.serviceWorker) {
+ if (!isLocalhost()) {
+ const sw = await registerServiceWorker();
+ const cacheCurrentPage = () => {
+ const swController = navigator.serviceWorker.controller;
+ if (swController) {
+ [location.href, "", "/", "/ed", "/ed/_/_", "/login"].forEach(
+ (url) => {
+ swController.postMessage({
+ type: "add-cache",
+ url: url,
+ });
+ }
+ );
+ }
+ };
+ cacheCurrentPage();
+ navigator.serviceWorker.addEventListener("message", (e) => {
+ cacheCurrentPage();
+ if (react.root) {
+ if (e.data.type === "offline") {
+ w.offline = true;
+ const click = () => {
+ if (react.root) react.root.render(
);
+ };
+ setTimeout(click, 5000);
+ react.root.render(
+ <>
+
+
+ >
+ );
+ }
+
+ if (e.data.type === "activated") {
+ if (e.data.shouldRefresh && sw) {
+ react.root.render(
+ <>
+
+
+ >
+ );
+
+ sw.unregister().then(() => {
+ window.location.reload();
+ });
+ } else {
+ const localVersion = localStorage.getItem("prasi-version");
+ if (localVersion !== e.data.version) {
+ localStorage.setItem("prasi-version", e.data.version);
+ const click = () => {
+ if (react.root) react.root.render(
);
+ };
+ setTimeout(click, 5000);
+ react.root.render(
+ <>
+
+
+
+ Prasi Updated{" "}
+ {e.data.version}
+
+
+ >
+ );
+ }
+ }
+ }
+ }
+ });
+ } else {
+ navigator.serviceWorker.getRegistrations().then(function (registrations) {
+ for (let registration of registrations) {
+ registration.unregister();
+ }
+ });
+ }
+ }
+};
+
+const registerServiceWorker = async () => {
+ if ("serviceWorker" in navigator) {
+ try {
+ return await navigator.serviceWorker.register(
+ new URL("./sworker.ts", import.meta.url),
+ {
+ type: "module",
+ scope: "/",
+ }
+ );
+ } catch (error) {
+ console.error(`Registration failed with ${error}`);
+ }
+ }
+};
+
+export const sworkerAddCache = (base: string) => {
+ if (navigator.serviceWorker) {
+ if (!isLocalhost()) {
+ const swc = navigator.serviceWorker.controller;
+ if (swc) {
+ [location.href, "", "/", "/ed", "/ed/_/_", "/login"].forEach((url) => {
+ swc.postMessage({
+ type: "add-cache",
+ url: url,
+ });
+ });
+ if (w.prasiApi && w.prasiApi[base] && w.prasiApi[base].apiEntry) {
+ const routes = Object.entries(w.prasiApi[base].apiEntry).map(
+ ([k, v]: any) => ({
+ url: v.url,
+ name: k,
+ })
+ );
+
+ swc.postMessage({
+ type: "define-route",
+ routes,
+ });
+ }
+ }
+ }
+ }
+};
diff --git a/app/web/src/utils/types/general.ts b/app/web/src/utils/types/general.ts
index 9e08fe45..d47ea983 100644
--- a/app/web/src/utils/types/general.ts
+++ b/app/web/src/utils/types/general.ts
@@ -27,6 +27,7 @@ export const w = window as unknown as {
prasiApi: Record
;
loadedFonts: string[];
prasiApiDbPull: boolean;
+ mobile?: any;
params: any;
editorGlbDefault: string;
ts: number;
diff --git a/pkgs/core/api/_api_frm.ts b/pkgs/core/api/_api_frm.ts
index a6d29abf..3ddb7541 100644
--- a/pkgs/core/api/_api_frm.ts
+++ b/pkgs/core/api/_api_frm.ts
@@ -1,4 +1,4 @@
-import { apiContext } from "../server/api-ctx";
+import { apiContext } from "../server/api/api-ctx";
import { g } from "../utils/global";
export const _ = {
diff --git a/pkgs/core/api/_dbs.ts b/pkgs/core/api/_dbs.ts
index 041a0e05..8fd955b9 100644
--- a/pkgs/core/api/_dbs.ts
+++ b/pkgs/core/api/_dbs.ts
@@ -1,4 +1,4 @@
-import { apiContext } from "../server/api-ctx";
+import { apiContext } from "../server/api/api-ctx";
import { DBArg, execQuery } from "../utils/query";
export const _ = {
diff --git a/pkgs/core/api/_file.ts b/pkgs/core/api/_file.ts
index e96b8d2b..99bd2d0c 100644
--- a/pkgs/core/api/_file.ts
+++ b/pkgs/core/api/_file.ts
@@ -1,5 +1,5 @@
import { g } from "utils/global";
-import { apiContext } from "../server/api-ctx";
+import { apiContext } from "../server/api/api-ctx";
import { dir } from "../utils/dir";
export const _ = {
diff --git a/pkgs/core/api/_prasi.ts b/pkgs/core/api/_prasi.ts
index a3eeba3c..ce371c3a 100644
--- a/pkgs/core/api/_prasi.ts
+++ b/pkgs/core/api/_prasi.ts
@@ -1,5 +1,5 @@
import { readAsync } from "fs-jetpack";
-import { apiContext } from "../server/api-ctx";
+import { apiContext } from "../server/api/api-ctx";
import { g } from "../utils/global";
import { dir } from "../utils/dir";
diff --git a/pkgs/core/api/_upload.ts b/pkgs/core/api/_upload.ts
index 63f6eef0..d6d8857a 100644
--- a/pkgs/core/api/_upload.ts
+++ b/pkgs/core/api/_upload.ts
@@ -2,7 +2,7 @@ import mp from "@surfy/multipart-parser";
import { writeAsync } from "fs-jetpack";
import { g } from "utils/global";
-import { apiContext } from "../server/api-ctx";
+import { apiContext } from "../server/api/api-ctx";
import { dir } from "../utils/dir";
export const _ = {
url: "/_upload",
diff --git a/pkgs/core/index.ts b/pkgs/core/index.ts
index 01f57aad..a5ee74ab 100644
--- a/pkgs/core/index.ts
+++ b/pkgs/core/index.ts
@@ -1,7 +1,5 @@
import { parcelBuild } from "utils/parcel";
-import { generateAPIFrm } from "./server/api-frm";
-import { prepareApiRoutes } from "./server/api-scan";
-import { prepareAPITypes } from "./server/prep-api-ts";
+import { prepareAPITypes } from "./server/api/prep-api-ts";
import { startDevWatcher } from "./utils/dev-watcher";
import { ensureNotRunning } from "./utils/ensure";
import { g } from "./utils/global";
@@ -55,14 +53,11 @@ if (!g.apiPrepared) {
await syncActionDefinition();
g.log.info("WS Action defined");
- await generateAPIFrm();
await prepareAPITypes();
g.log.info("API Prepared");
g.apiPrepared = true;
}
-await prepareApiRoutes();
-
if (!g.parcel) {
await parcelBuild();
}
diff --git a/pkgs/core/server/api-frm.ts b/pkgs/core/server/api-frm.ts
deleted file mode 100644
index df941137..00000000
--- a/pkgs/core/server/api-frm.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-import { transform } from "@swc/core";
-import { g } from "../utils/global";
-import { createHash } from "crypto";
-
-export const generateAPIFrm = async () => {
- const res = await transform(
- `
- (BigInt.prototype).toJSON = function () {
- return "BigInt::" + this.toString();
- };
-
- const replacer = (key, value) => {
- if (typeof value === "string" && value.startsWith('BigInt::')) {
- return BigInt(value.substr(8));
- }
- return value;
- }
-
- window.addEventListener('message', (e) => {
- const msg = e.data;
- const init = Object.assign({}, msg.init)
-
- let input = msg.input;
- let url = msg.input;
- if (typeof msg.input === 'string') {
- if (!input.startsWith('http')) {
- url = new URL(\`\$\{location.origin\}\$\{input\}\`)
- } else {
- url = new URL(input)
- }
- }
-
- if (init && init.body && typeof init.body === 'object') {
- if (Array.isArray(init.body)) {
- const body = new FormData();
- body.append("file", init.body[0]);
- init.body = body;
- }
- }
-
-
- fetch(url.pathname, init)
- .then(async (res) => {
- if (res) {
- const body = await res.text();
- if (res.ok) {
- try {
- parent.postMessage({result: JSON.parse(body, replacer), id: msg.id }, '*')
- } catch(e) {
- parent.postMessage({result: body, id: msg.id }, '*')
- }
- } else {
- try {
- parent.postMessage({error: JSON.parse(body, replacer), id: msg.id }, '*')
- } catch(e) {
- parent.postMessage({error: body, id: msg.id }, '*')
- }
- }
- }
- })
- })
- parent.postMessage('initialized', '*')`,
- { minify: true }
- );
-
- g.frm = {
- js: res.code,
- etag: createHash("md5").update(res.code).digest("hex"),
- };
-};
diff --git a/pkgs/core/server/api-ctx.ts b/pkgs/core/server/api/api-ctx.ts
similarity index 100%
rename from pkgs/core/server/api-ctx.ts
rename to pkgs/core/server/api/api-ctx.ts
diff --git a/pkgs/core/server/api-scan.ts b/pkgs/core/server/api/api-scan.ts
similarity index 94%
rename from pkgs/core/server/api-scan.ts
rename to pkgs/core/server/api/api-scan.ts
index 8eacc046..f4893d12 100644
--- a/pkgs/core/server/api-scan.ts
+++ b/pkgs/core/server/api/api-scan.ts
@@ -1,8 +1,8 @@
import { file } from "bun";
import { inspectAsync, listAsync } from "fs-jetpack";
import { join } from "path";
-import { dir } from "../utils/dir";
-import { g } from "../utils/global";
+import { dir } from "../../utils/dir";
+import { g } from "../../utils/global";
import { parseArgs } from "./parse-args";
export const prepareApiRoutes = async () => {
diff --git a/pkgs/core/server/parse-args.ts b/pkgs/core/server/api/parse-args.ts
similarity index 100%
rename from pkgs/core/server/parse-args.ts
rename to pkgs/core/server/api/parse-args.ts
diff --git a/pkgs/core/server/prep-api-ts.ts b/pkgs/core/server/api/prep-api-ts.ts
similarity index 93%
rename from pkgs/core/server/prep-api-ts.ts
rename to pkgs/core/server/api/prep-api-ts.ts
index 27b05fa1..5996c188 100644
--- a/pkgs/core/server/prep-api-ts.ts
+++ b/pkgs/core/server/api/prep-api-ts.ts
@@ -1,7 +1,7 @@
-import { spawn, spawnSync } from "bun";
+import { spawn } from "bun";
import { existsAsync, readAsync } from "fs-jetpack";
-import { dir } from "../utils/dir";
-import { g } from "../utils/global";
+import { dir } from "../../utils/dir";
+import { g } from "../../utils/global";
export const prepareAPITypes = async () => {
const out: string[] = [];
diff --git a/pkgs/core/server/create.ts b/pkgs/core/server/create.ts
index eebdad58..df8a3572 100644
--- a/pkgs/core/server/create.ts
+++ b/pkgs/core/server/create.ts
@@ -1,8 +1,7 @@
-import { WebSocketHandler } from "bun";
-import { lookup } from "mime-types";
import { createRouter } from "radix3";
-import { dir } from "../utils/dir";
import { g } from "../utils/global";
+import { serveWS } from "./serve-ws";
+import { serveStatic } from "./serve-static";
import { serveAPI } from "./serve-api";
export const cache = {
@@ -19,127 +18,24 @@ export const cache = {
export type WSData = { url: URL };
export const createServer = async () => {
- g.router = createRouter({ strictTrailingSlash: false });
+ await serveAPI.init();
+ await serveStatic.init();
- for (const route of Object.values(g.api)) {
- g.router.insert(route.url.replace(/\*/gi, "**"), route);
- }
-
- const { wsHandler } = await import("../../../app/srv/ws/handler");
g.server = Bun.serve({
port: g.port,
- websocket: {
- maxPayloadLength: 9999999,
- closeOnBackpressureLimit: true,
- drain(ws) {
- // console.log("Backpressure relieved...");
- },
- close(ws, code, reason) {
- const pathname = ws.data.url.pathname;
- if (wsHandler[pathname]) {
- const close = wsHandler[pathname].close;
- if (close) {
- close(ws, code, reason);
- }
- }
- },
- message(ws, message) {
- const pathname = ws.data.url.pathname;
- if (wsHandler[pathname]) {
- const msg = wsHandler[pathname].message;
- if (msg) {
- msg(ws, message);
- }
- }
- },
- open(ws) {
- const pathname = ws.data.url.pathname;
- if (wsHandler[pathname]) {
- const open = wsHandler[pathname].open;
- if (open) {
- open(ws);
- }
- }
- },
- } as WebSocketHandler,
+ maxRequestBodySize: 9999999,
+ development: true,
+ websocket: await serveWS(),
async fetch(req, server) {
const url = new URL(req.url);
- const response = async () => {
- if (wsHandler[url.pathname]) {
- if (
- server.upgrade(req, {
- data: {
- url: new URL(req.url),
- },
- })
- ) {
- return;
- }
- return new Response("Upgrade failed :(", { status: 500 });
- }
+ if (serveStatic.exists(url)) {
+ return serveStatic.serve(url);
+ }
- try {
- const api = await serveAPI(url, req);
- if (api) {
- return api;
- }
- } catch (e) {
- g.log.error(e);
- }
+ await serveAPI.serve(url, req);
- const webPath = "app/static";
- try {
- const found = cache.static[url.pathname];
-
- if (found && g.mode === "prod") {
- return responseCached(req, found);
- }
-
- const file = Bun.file(dir.path(`${webPath}${url.pathname}`));
- if (
- (await file.exists()) &&
- file.type !== "application/octet-stream" // is not directory
- ) {
- if (g.mode === "dev") {
- return new Response(file);
- }
-
- if (!cache.static[url.pathname]) {
- cache.static[url.pathname] = {
- type: lookup(url.pathname) || "text/plain",
- content: await file.arrayBuffer(),
- };
- }
-
- const filebr = Bun.file(dir.path(`${webPath}-br${url.pathname}`));
- if (
- (await filebr.exists()) &&
- filebr.type !== "application/octet-stream" // is not directory
- ) {
- cache.static[url.pathname].br = await filebr.arrayBuffer();
- }
-
- const found = cache.static[url.pathname];
- if (found) {
- return responseCached(req, found);
- }
- }
- } catch (e) {
- g.log.error(e);
- }
-
- try {
- return new Response(
- Bun.file(dir.path(`${webPath}/index.html`)) as any
- );
- } catch (e) {
- g.log.error(e);
- return new Response("Loading...");
- }
- };
- const res = await response();
- return res;
+ return serveStatic.serve(url);
},
});
@@ -149,16 +45,3 @@ export const createServer = async () => {
g.log.info(`Started at port: ${g.server.port}`);
}
};
-
-const responseCached = (req: Request, found: (typeof cache.static)[string]) => {
- if (req.headers.get("accept-encoding")?.includes("br") && found.br) {
- const res = new Response(found.br);
- res.headers.set("content-type", found.type);
- res.headers.set("content-encoding", "br");
- return res;
- }
- const res = new Response(found.content);
- res.headers.set("content-type", found.type);
-
- return res;
-};
diff --git a/pkgs/core/server/serve-api.ts b/pkgs/core/server/serve-api.ts
index 73ec21fe..592eff7d 100644
--- a/pkgs/core/server/serve-api.ts
+++ b/pkgs/core/server/serve-api.ts
@@ -1,5 +1,105 @@
-import { createResponse } from "./api-ctx";
-import { g } from "../utils/global";
+import { createRouter } from "radix3";
+import { g } from "utils/global";
+import { createResponse } from "./api/api-ctx";
+import { prepareApiRoutes } from "./api/api-scan";
+
+export const serveAPI = {
+ init: async () => {
+ g.router = createRouter({ strictTrailingSlash: false });
+ for (const route of Object.values(g.api)) {
+ g.router.insert(route.url.replace(/\*/gi, "**"), route);
+ }
+ await prepareApiRoutes();
+ },
+ serve: async (url: URL, req: Request) => {
+ let found = g.router.lookup(url.pathname);
+ if (!found?.url) {
+ if (!url.pathname.endsWith("/")) {
+ found = g.router.lookup(url.pathname + "/");
+ }
+
+ if (!found?.url) {
+ found = null;
+ }
+ }
+
+ if (found) {
+ const params = { ...found.params };
+
+ let args = found.args.map((e) => {
+ return params[e];
+ });
+
+ if (req.method !== "GET") {
+ if (
+ !req.headers.get("content-type")?.startsWith("multipart/form-data")
+ ) {
+ try {
+ const text = await req.text();
+ const json = JSON.parse(text, replacer);
+
+ if (typeof json === "object") {
+ if (Array.isArray(json)) {
+ args = json;
+ for (let i = 0; i < json.length; i++) {
+ const val = json[i];
+ if (found.args[i]) {
+ params[found.args[i]] = val;
+ }
+ }
+ } else {
+ for (const [k, v] of Object.entries(json)) {
+ params[k] = v;
+ }
+ for (const [k, v] of Object.entries(params)) {
+ const idx = found.args.findIndex((arg) => arg === k);
+ if (idx >= 0) {
+ args[idx] = v;
+ }
+ }
+ }
+ }
+ } catch (e) {
+ throw e;
+ }
+ }
+ }
+
+ const current = {
+ req,
+ res: new Response(),
+ ...found,
+ params,
+ };
+
+ const finalResponse = await current.fn(...args);
+
+ if (finalResponse instanceof Response) {
+ return finalResponse;
+ }
+
+ if (finalResponse) {
+ return createResponse(current.res, finalResponse);
+ }
+ if (
+ (current.res as any)._status &&
+ (current.res as any)._status !== current.res.status
+ ) {
+ const res = new Response(current.res.body, {
+ status: (current.res as any)._status,
+ });
+
+ current.res.headers.forEach((v, k) => {
+ res.headers.set(k, v);
+ });
+
+ return res;
+ }
+
+ return current.res;
+ }
+ },
+};
const replacer = (key: string, value: string) => {
if (typeof value === "string" && value.startsWith("BigInt::")) {
@@ -7,90 +107,3 @@ const replacer = (key: string, value: string) => {
}
return value;
};
-
-export const serveAPI = async (url: URL, req: Request) => {
- let found = g.router.lookup(url.pathname);
- if (!found?.url) {
- if (!url.pathname.endsWith("/")) {
- found = g.router.lookup(url.pathname + "/");
- }
-
- if (!found?.url) {
- found = null;
- }
- }
-
- if (found) {
- const params = { ...found.params };
-
- let args = found.args.map((e) => {
- return params[e];
- });
-
- if (req.method !== "GET") {
- if (!req.headers.get("content-type")?.startsWith("multipart/form-data")) {
- try {
- const text = await req.text();
- const json = JSON.parse(text, replacer);
-
- if (typeof json === "object") {
- if (Array.isArray(json)) {
- args = json;
- for (let i = 0; i < json.length; i++) {
- const val = json[i];
- if (found.args[i]) {
- params[found.args[i]] = val;
- }
- }
- } else {
- for (const [k, v] of Object.entries(json)) {
- params[k] = v;
- }
- for (const [k, v] of Object.entries(params)) {
- const idx = found.args.findIndex((arg) => arg === k);
- if (idx >= 0) {
- args[idx] = v;
- }
- }
- }
- }
- } catch (e) {
- g.log.error({ pathname: url.pathname, error: e });
- }
- }
- }
-
- const current = {
- req,
- res: new Response(),
- ...found,
- params,
- };
-
- const finalResponse = await current.fn(...args);
-
- if (finalResponse instanceof Response) {
- return finalResponse;
- }
-
- if (finalResponse) {
- return createResponse(current.res, finalResponse);
- }
- if (
- (current.res as any)._status &&
- (current.res as any)._status !== current.res.status
- ) {
- const res = new Response(current.res.body, {
- status: (current.res as any)._status,
- });
-
- current.res.headers.forEach((v, k) => {
- res.headers.set(k, v);
- });
-
- return res;
- }
-
- return current.res;
- }
-};
diff --git a/pkgs/core/server/serve-static.ts b/pkgs/core/server/serve-static.ts
new file mode 100644
index 00000000..cad6fe8f
--- /dev/null
+++ b/pkgs/core/server/serve-static.ts
@@ -0,0 +1,59 @@
+import { dir } from "dir";
+import { inspectTreeAsync } from "fs-jetpack";
+import { InspectTreeResult } from "fs-jetpack/types";
+import { join } from "path";
+import mime from "mime";
+
+const webPath = "app/static";
+const cache = {
+ static: {} as Record,
+};
+
+export const serveStatic = {
+ init: async () => {
+ const list = await inspectTreeAsync(dir.path(`${webPath}`));
+ const walk = async (
+ list: InspectTreeResult,
+ parent?: InspectTreeResult[]
+ ) => {
+ for (const item of list.children) {
+ if (item.type === "file") {
+ const path = join(
+ ...(parent || [{ name: "static" }]).map((e) => e.name),
+ item.name
+ );
+ const file = await Bun.file(dir.path(`app/${path}`));
+ if (await file.exists()) {
+ cache.static[path.substring("static".length)] = {
+ type: mime.getType(path) || "application/octet-stream",
+ content: await file.arrayBuffer(),
+ };
+ }
+ } else {
+ await walk(item, parent ? [...parent, list] : [list]);
+ }
+ }
+ };
+ if (list) {
+ await walk(list);
+ }
+ },
+ exists: (url: URL) => {
+ return !!cache.static[url.pathname];
+ },
+ serve: (url: URL) => {
+ const file = cache.static[url.pathname];
+ if (file) {
+ return new Response(file.content, {
+ headers: { "content-type": file.type },
+ });
+ }
+
+ const index = cache.static["/index.html"];
+ if (index) {
+ return new Response(index.content, {
+ headers: { "content-type": index.type },
+ });
+ }
+ },
+};
diff --git a/pkgs/core/server/serve-ws.ts b/pkgs/core/server/serve-ws.ts
new file mode 100644
index 00000000..2c9a3c7b
--- /dev/null
+++ b/pkgs/core/server/serve-ws.ts
@@ -0,0 +1,41 @@
+import { WebSocketHandler } from "bun";
+import { WSData } from "./create";
+
+export const serveWS: () => Promise> = async () => {
+ const { wsHandler } = await import("../../../app/srv/ws/handler");
+
+ return {
+ maxPayloadLength: 9999999,
+ closeOnBackpressureLimit: true,
+ drain(ws) {
+ // console.log("Backpressure relieved...");
+ },
+ close(ws, code, reason) {
+ const pathname = ws.data.url.pathname;
+ if (wsHandler[pathname]) {
+ const close = wsHandler[pathname].close;
+ if (close) {
+ close(ws, code, reason);
+ }
+ }
+ },
+ message(ws, message) {
+ const pathname = ws.data.url.pathname;
+ if (wsHandler[pathname]) {
+ const msg = wsHandler[pathname].message;
+ if (msg) {
+ msg(ws, message);
+ }
+ }
+ },
+ open(ws) {
+ const pathname = ws.data.url.pathname;
+ if (wsHandler[pathname]) {
+ const open = wsHandler[pathname].open;
+ if (open) {
+ open(ws);
+ }
+ }
+ },
+ } as WebSocketHandler;
+};
diff --git a/tsconfig.json b/tsconfig.json
index bd06088a..414be545 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -31,7 +31,7 @@
"./node_modules/.prisma/client/index.d.ts"
],
"service-srv": [
- "./pkgs/core/server/api-ctx.ts"
+ "./pkgs/core/server/api/api-ctx.ts"
],
"utils/*": [
"./pkgs/core/utils/*"