wip fix
This commit is contained in:
+13
-47
@@ -1,5 +1,6 @@
|
||||
import { gzipSync } from "bun";
|
||||
import brotliPromise from "brotli-wasm"; // Import the default export
|
||||
import { simpleHash } from "utils/cache";
|
||||
import { g } from "utils/global";
|
||||
const brotli = await brotliPromise;
|
||||
|
||||
const parseQueryParams = (ctx: any) => {
|
||||
@@ -38,12 +39,6 @@ export const apiContext = (ctx: any) => {
|
||||
};
|
||||
};
|
||||
|
||||
const cache = {
|
||||
gz: {} as Record<string, Uint8Array>,
|
||||
br: {} as Record<string, Uint8Array>,
|
||||
br_timeout: new Set<string>(),
|
||||
};
|
||||
|
||||
export const createResponse = (
|
||||
existingRes: any,
|
||||
body: any,
|
||||
@@ -57,31 +52,18 @@ export const createResponse = (
|
||||
if (cache_accept) {
|
||||
const content_hash = simpleHash(content);
|
||||
if (cache_accept.toLowerCase().includes("br")) {
|
||||
if (cache.br[content_hash]) {
|
||||
content = cache.br[content_hash];
|
||||
if (g.cache.br[content_hash]) {
|
||||
content = g.cache.br[content_hash];
|
||||
headers["content-encoding"] = "br";
|
||||
} else {
|
||||
if (!cache.br_timeout.has(content_hash)) {
|
||||
cache.br_timeout.add(content_hash);
|
||||
if (!g.cache.br_timeout.has(content_hash)) {
|
||||
g.cache.br_timeout.add(content_hash);
|
||||
setTimeout(() => {
|
||||
cache.br[content_hash] = brotli.compress(Buffer.from(content));
|
||||
cache.br_timeout.delete(content_hash);
|
||||
g.cache.br[content_hash] = brotli.compress(Buffer.from(content));
|
||||
g.cache.br_timeout.delete(content_hash);
|
||||
});
|
||||
}
|
||||
}
|
||||
headers["content-encoding"] = "br";
|
||||
}
|
||||
|
||||
if (
|
||||
cache_accept.toLowerCase().includes("gz") &&
|
||||
!headers["content-encoding"]
|
||||
) {
|
||||
if (cache.gz[content_hash]) {
|
||||
content = cache.gz[content_hash];
|
||||
} else {
|
||||
cache.gz[content_hash] = gzipSync(content);
|
||||
content = cache.gz[content_hash];
|
||||
}
|
||||
headers["content-encoding"] = "gzip";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,33 +76,17 @@ export const createResponse = (
|
||||
: undefined
|
||||
);
|
||||
|
||||
if (typeof body === "object") {
|
||||
res.headers.append("content-type", "application/json");
|
||||
}
|
||||
for (const [k, v] of Object.entries(headers)) {
|
||||
res.headers.append(k, v);
|
||||
}
|
||||
|
||||
const cur = existingRes as Response;
|
||||
cur.headers.forEach((value, key) => {
|
||||
res.headers.append(key, value);
|
||||
});
|
||||
|
||||
if (typeof body === "object" && !res.headers.has("content-type")) {
|
||||
res.headers.append("content-type", "application/json");
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const simpleHash = (str: string, seed = 0) => {
|
||||
let h1 = 0xdeadbeef ^ seed,
|
||||
h2 = 0x41c6ce57 ^ seed;
|
||||
for (let i = 0, ch; i < str.length; i++) {
|
||||
ch = str.charCodeAt(i);
|
||||
h1 = Math.imul(h1 ^ ch, 2654435761);
|
||||
h2 = Math.imul(h2 ^ ch, 1597334677);
|
||||
}
|
||||
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507);
|
||||
h1 ^= Math.imul(h2 ^ (h2 >>> 13), 3266489909);
|
||||
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507);
|
||||
h2 ^= Math.imul(h1 ^ (h1 >>> 13), 3266489909);
|
||||
|
||||
return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString();
|
||||
};
|
||||
|
||||
+53
-2
@@ -1,15 +1,20 @@
|
||||
import { file } from "bun";
|
||||
import { inspectAsync, listAsync } from "fs-jetpack";
|
||||
import { existsAsync, inspectAsync, listAsync } from "fs-jetpack";
|
||||
import { join } from "path";
|
||||
import { createRouter } from "radix3";
|
||||
import { dir } from "../utils/dir";
|
||||
import { g } from "../utils/global";
|
||||
import { parseArgs } from "./parse-args";
|
||||
import { serveAPI } from "./serve-api";
|
||||
import { serveWeb } from "./serve-web";
|
||||
|
||||
export const createServer = async () => {
|
||||
g.router = createRouter({ strictTrailingSlash: true });
|
||||
g.api = {};
|
||||
g.cache = {
|
||||
br: {},
|
||||
br_timeout: new Set(),
|
||||
};
|
||||
const scan = async (path: string, root?: string) => {
|
||||
const apis = await listAsync(path);
|
||||
if (apis) {
|
||||
@@ -64,13 +69,59 @@ export const createServer = async () => {
|
||||
return api;
|
||||
}
|
||||
|
||||
if (g.deploy.gz && g.deploy.index) {
|
||||
const core = g.deploy.gz.code.core;
|
||||
const site = g.deploy.gz.code.site;
|
||||
|
||||
let pathname = url.pathname;
|
||||
if (url.pathname[0] === "/") pathname = pathname.substring(1);
|
||||
|
||||
if (
|
||||
!pathname ||
|
||||
pathname === "index.html" ||
|
||||
pathname === "index.htm"
|
||||
) {
|
||||
return await serveWeb({
|
||||
content: g.deploy.index.render(),
|
||||
pathname: "index.html",
|
||||
});
|
||||
}
|
||||
|
||||
let content = "";
|
||||
if (core[pathname]) content = core[pathname];
|
||||
else if (site[pathname]) content = site[pathname];
|
||||
|
||||
if (content) {
|
||||
return await serveWeb({ content, pathname });
|
||||
}
|
||||
}
|
||||
|
||||
return new Response(`404 Not Found`, {
|
||||
status: 404,
|
||||
statusText: "Not Found",
|
||||
});
|
||||
};
|
||||
|
||||
if (g.deploy.gz?.code.server) {
|
||||
if (!url.pathname.startsWith("/_deploy")) {
|
||||
if (
|
||||
!g.deploy.server &&
|
||||
(await existsAsync(dir(`app/web/server/index.js`)))
|
||||
) {
|
||||
const res = require(dir(`app/web/server/index.js`));
|
||||
if (res && res.server) {
|
||||
g.deploy.server = res.server;
|
||||
}
|
||||
}
|
||||
if (g.deploy.server && g.deploy.index) {
|
||||
return await g.deploy.server.http({
|
||||
handle,
|
||||
mode: "prod",
|
||||
req,
|
||||
server: g.server,
|
||||
url: { pathname: url.pathname, raw: url },
|
||||
index: g.deploy.index,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return handle(req);
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
const decoder = new TextDecoder();
|
||||
|
||||
function humanFileSize(bytes: any, si = false, dp = 1) {
|
||||
const thresh = si ? 1000 : 1024;
|
||||
|
||||
if (Math.abs(bytes) < thresh) {
|
||||
return bytes + " B";
|
||||
}
|
||||
|
||||
const units = si
|
||||
? ["kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]
|
||||
: ["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"];
|
||||
let u = -1;
|
||||
const r = 10 ** dp;
|
||||
|
||||
do {
|
||||
bytes /= thresh;
|
||||
++u;
|
||||
} while (
|
||||
Math.round(Math.abs(bytes) * r) / r >= thresh &&
|
||||
u < units.length - 1
|
||||
);
|
||||
|
||||
return bytes.toFixed(dp) + " " + units[u];
|
||||
}
|
||||
@@ -1,30 +1,11 @@
|
||||
import { statSync } from "fs";
|
||||
import { join } from "path";
|
||||
import { dir } from "utils/dir";
|
||||
import mime from "mime";
|
||||
|
||||
export const serveWeb = async (url: URL, req: Request) => {
|
||||
return {};
|
||||
};
|
||||
|
||||
export const generateIndexHtml = (base_url: string, site_id: string) => {
|
||||
const base = base_url.endsWith("/")
|
||||
? base_url.substring(0, base_url.length - 1)
|
||||
: base_url;
|
||||
|
||||
return `
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title></title>
|
||||
<link rel="stylesheet" href="${base}/index.css?fresh">
|
||||
</head>
|
||||
<body class="flex-col flex-1 w-full min-h-screen flex opacity-0">
|
||||
<div style="position:absolute;opacity:0.1;top:0;left:0"> </div>
|
||||
<div id="root"></div>
|
||||
<script src="${base}/site.js" type="module"></script>
|
||||
<script>window.id_site = "${site_id}";</script>
|
||||
</body>
|
||||
</html>`;
|
||||
export const serveWeb = async (arg: { pathname: string; content: string }) => {
|
||||
const type = mime.getType(arg.pathname);
|
||||
|
||||
return new Response(arg.content, {
|
||||
headers: !type ? undefined : { "content-type": type },
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user