wip fix
This commit is contained in:
parent
18d389b73e
commit
aa6cdbf539
|
|
@ -26,26 +26,10 @@ export const _ = {
|
|||
) {
|
||||
const { res } = apiContext(this);
|
||||
|
||||
if (!g.web[action.id_site]) {
|
||||
g.web[action.id_site] = {
|
||||
current: 0,
|
||||
domains: [],
|
||||
deploying: null,
|
||||
router: null,
|
||||
deploys: [],
|
||||
site_id: action.id_site,
|
||||
cacheKey: 0,
|
||||
cache: null,
|
||||
};
|
||||
}
|
||||
const path = dir(`app/web/${action.id_site}`);
|
||||
const path = dir(`app/web/`);
|
||||
await dirAsync(path);
|
||||
|
||||
const web = g.web[action.id_site];
|
||||
|
||||
if (!web.domains) {
|
||||
web.domains = [];
|
||||
}
|
||||
const web = g.web;
|
||||
|
||||
switch (action.type) {
|
||||
case "check":
|
||||
|
|
@ -53,7 +37,6 @@ export const _ = {
|
|||
now: Date.now(),
|
||||
current: web.current,
|
||||
deploys: web.deploys,
|
||||
domains: web.domains,
|
||||
db: {
|
||||
url: g.dburl || "-",
|
||||
},
|
||||
|
|
@ -100,23 +83,6 @@ datasource db {
|
|||
}, 300);
|
||||
}
|
||||
break;
|
||||
case "domain-add":
|
||||
{
|
||||
web.domains.push(action.domain);
|
||||
await Bun.write(`${path}/domains.json`, JSON.stringify(web.domains));
|
||||
g.domains = null;
|
||||
res.send("ok");
|
||||
}
|
||||
break;
|
||||
case "domain-del":
|
||||
{
|
||||
web.domains = web.domains.filter((e) => e !== action.domain);
|
||||
await Bun.write(`${path}/domains.json`, web.domains);
|
||||
g.domains = null;
|
||||
|
||||
res.send("ok");
|
||||
}
|
||||
break;
|
||||
case "deploy-del":
|
||||
{
|
||||
web.deploys = web.deploys.filter((e) => e !== parseInt(action.ts));
|
||||
|
|
|
|||
|
|
@ -3,9 +3,10 @@ import { apiContext } from "service-srv";
|
|||
import { g } from "utils/global";
|
||||
import { dir } from "utils/dir";
|
||||
|
||||
const cache = {
|
||||
dev: "",
|
||||
prod: "",
|
||||
const generated = {
|
||||
"load.json": "",
|
||||
"load.js.dev": "",
|
||||
"load.js.prod": "",
|
||||
};
|
||||
|
||||
export const _ = {
|
||||
|
|
@ -21,15 +22,8 @@ export const _ = {
|
|||
"load.json": async () => {
|
||||
res.setHeader("content-type", "application/json");
|
||||
res.send(
|
||||
JSON.stringify({
|
||||
apiEntry: getApiEntry(),
|
||||
apiTypes: (await getApiTypes()) || "",
|
||||
prismaTypes: {
|
||||
"prisma.d.ts": await getPrisma("prisma"),
|
||||
"runtime/index.d.ts": await getPrisma("runtime"),
|
||||
"runtime/library.d.ts": await getPrisma("library"),
|
||||
},
|
||||
})
|
||||
await getContent("load.json"),
|
||||
req.headers.get("accept-encoding") || ""
|
||||
);
|
||||
},
|
||||
"load.js": async () => {
|
||||
|
|
@ -39,46 +33,16 @@ export const _ = {
|
|||
? JSON.stringify(req.query_parameters["url"])
|
||||
: "undefined";
|
||||
|
||||
if (!cache.dev) {
|
||||
cache.dev = `\
|
||||
(() => {
|
||||
const baseurl = new URL(location.href);
|
||||
baseurl.pathname = '';
|
||||
const url = ${url} || baseurl.toString();
|
||||
const w = window;
|
||||
if (!w.prasiApi) {
|
||||
w.prasiApi = {};
|
||||
}
|
||||
w.prasiApi[url] = {
|
||||
apiEntry: ${JSON.stringify(getApiEntry())},
|
||||
apiTypes: ${JSON.stringify((await getApiTypes()) || "")},
|
||||
prismaTypes: {
|
||||
"prisma.d.ts": ${await getPrisma("prisma")},
|
||||
"runtime/index.d.ts": ${await getPrisma("runtime")},
|
||||
"runtime/library.d.ts": ${await getPrisma("library")},
|
||||
},
|
||||
};
|
||||
})();`;
|
||||
|
||||
cache.prod = `\
|
||||
(() => {
|
||||
const baseurl = new URL(location.href);
|
||||
baseurl.pathname = '';
|
||||
const url = ${url} || baseurl.toString();
|
||||
const w = window;
|
||||
if (!w.prasiApi) {
|
||||
w.prasiApi = {};
|
||||
}
|
||||
w.prasiApi[url] = {
|
||||
apiEntry: ${JSON.stringify(getApiEntry())},
|
||||
};
|
||||
})();`;
|
||||
}
|
||||
|
||||
if (req.query_parameters["dev"]) {
|
||||
res.send(cache.dev);
|
||||
res.send(
|
||||
await getContent("load.js.dev", url),
|
||||
req.headers.get("accept-encoding") || ""
|
||||
);
|
||||
} else {
|
||||
res.send(cache.prod);
|
||||
res.send(
|
||||
await getContent("load.js.prod", url),
|
||||
req.headers.get("accept-encoding") || ""
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
@ -102,6 +66,58 @@ export const getApiEntry = () => {
|
|||
return res;
|
||||
};
|
||||
|
||||
const getContent = async (type: keyof typeof generated, url?: string) => {
|
||||
if (type === "load.json") {
|
||||
if (!generated[type])
|
||||
generated[type] = JSON.stringify({
|
||||
apiEntry: getApiEntry(),
|
||||
apiTypes: (await getApiTypes()) || "",
|
||||
prismaTypes: {
|
||||
"prisma.d.ts": await getPrisma("prisma"),
|
||||
"runtime/index.d.ts": await getPrisma("runtime"),
|
||||
"runtime/library.d.ts": await getPrisma("library"),
|
||||
},
|
||||
});
|
||||
} else if (type === "load.js.dev") {
|
||||
if (!generated[type])
|
||||
generated[type] = `\
|
||||
(() => {
|
||||
const baseurl = new URL(location.href);
|
||||
baseurl.pathname = '';
|
||||
const url = ${url} || baseurl.toString();
|
||||
const w = window;
|
||||
if (!w.prasiApi) {
|
||||
w.prasiApi = {};
|
||||
}
|
||||
w.prasiApi[url] = {
|
||||
apiEntry: ${JSON.stringify(getApiEntry())},
|
||||
apiTypes: ${JSON.stringify((await getApiTypes()) || "")},
|
||||
prismaTypes: {
|
||||
"prisma.d.ts": ${await getPrisma("prisma")},
|
||||
"runtime/index.d.ts": ${await getPrisma("runtime")},
|
||||
"runtime/library.d.ts": ${await getPrisma("library")},
|
||||
},
|
||||
};
|
||||
})();`;
|
||||
} else if (type === "load.js.prod") {
|
||||
if (!generated[type])
|
||||
generated[type] = `\
|
||||
(() => {
|
||||
const baseurl = new URL(location.href);
|
||||
baseurl.pathname = '';
|
||||
const url = ${url} || baseurl.toString();
|
||||
const w = window;
|
||||
if (!w.prasiApi) {
|
||||
w.prasiApi = {};
|
||||
}
|
||||
w.prasiApi[url] = {
|
||||
apiEntry: ${JSON.stringify(getApiEntry())},
|
||||
});
|
||||
})();`;
|
||||
}
|
||||
return generated[type];
|
||||
};
|
||||
|
||||
const getApiTypes = async () => {
|
||||
return (
|
||||
`\
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { g } from "../utils/global";
|
||||
import { gzipSync } from "bun";
|
||||
|
||||
const parseQueryParams = (ctx: any) => {
|
||||
const pageHref = ctx.req.url;
|
||||
|
|
@ -19,8 +19,8 @@ export const apiContext = (ctx: any) => {
|
|||
req: ctx.req as Request & { params: any; query_parameters: any },
|
||||
res: {
|
||||
...ctx.res,
|
||||
send: (body) => {
|
||||
ctx.res = createResponse(ctx.res, body);
|
||||
send: (body, cache_accept?: string) => {
|
||||
ctx.res = createResponse(ctx.res, body, cache_accept);
|
||||
},
|
||||
sendStatus: (code: number) => {
|
||||
ctx.res._status = code;
|
||||
|
|
@ -29,19 +29,38 @@ export const apiContext = (ctx: any) => {
|
|||
ctx.res.headers.append(key, value);
|
||||
},
|
||||
} as Response & {
|
||||
send: (body?: string | object) => void;
|
||||
send: (body?: string | object, cache_accept?: string) => void;
|
||||
setHeader: (key: string, value: string) => void;
|
||||
sendStatus: (code: number) => void;
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const createResponse = (existingRes: any, body: any) => {
|
||||
const cache = { gz: {} as Record<string, Uint8Array> };
|
||||
|
||||
export const createResponse = (
|
||||
existingRes: any,
|
||||
body: any,
|
||||
cache_accept?: string
|
||||
) => {
|
||||
const status =
|
||||
typeof existingRes._status === "number" ? existingRes._status : undefined;
|
||||
|
||||
let content: any = typeof body === "string" ? body : JSON.stringify(body);
|
||||
const headers = {} as Record<string, string>;
|
||||
if (cache_accept && cache_accept.toLowerCase().includes("gz")) {
|
||||
const content_hash = simpleHash(content);
|
||||
if (content_hash) {
|
||||
content = cache.gz[content_hash];
|
||||
} else {
|
||||
cache.gz[content_hash] = gzipSync(content);
|
||||
content = cache.gz[content_hash];
|
||||
}
|
||||
headers["content-encoding"] = "gz";
|
||||
}
|
||||
|
||||
let res = new Response(
|
||||
typeof body === "string" ? body : JSON.stringify(body),
|
||||
content,
|
||||
status
|
||||
? {
|
||||
status,
|
||||
|
|
@ -52,11 +71,22 @@ export const createResponse = (existingRes: any, body: any) => {
|
|||
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;
|
||||
for (const [key, value] of cur.headers.entries()) {
|
||||
cur.headers.forEach((value, key) => {
|
||||
res.headers.append(key, value);
|
||||
}
|
||||
});
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
function simpleHash(str: string) {
|
||||
let hash = 0;
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
hash = ((hash << 5) - hash + str.charCodeAt(i)) | 0;
|
||||
}
|
||||
return (hash >>> 0).toString(36);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,56 +60,19 @@ export const createServer = async () => {
|
|||
async fetch(req) {
|
||||
const url = new URL(req.url);
|
||||
|
||||
const web = await serveWeb(url, req);
|
||||
let index = ["", ""];
|
||||
if (web) {
|
||||
if (Array.isArray(web)) index = web;
|
||||
else {
|
||||
return web;
|
||||
}
|
||||
}
|
||||
|
||||
const api = await serveAPI(url, req);
|
||||
if (api) {
|
||||
return api;
|
||||
}
|
||||
|
||||
if (index) {
|
||||
let status: any = {};
|
||||
|
||||
if (!["", "index.html"].includes(trim(url.pathname, " /"))) {
|
||||
status = {
|
||||
status: 404,
|
||||
statusText: "Not Found",
|
||||
};
|
||||
const handle = async (req: Request) => {
|
||||
const api = await serveAPI(url, req);
|
||||
if (api) {
|
||||
return api;
|
||||
}
|
||||
|
||||
const [site_id, body] = index;
|
||||
if (g.web[site_id]) {
|
||||
const router = g.web[site_id].router;
|
||||
if (router) {
|
||||
let found = router.lookup(url.pathname);
|
||||
if (!found) {
|
||||
found = router.lookup(url.pathname + "/");
|
||||
}
|
||||
if (found) {
|
||||
status = {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new Response(body, {
|
||||
...status,
|
||||
headers: {
|
||||
"content-type": "text/html",
|
||||
},
|
||||
return new Response(`404 Not Found`, {
|
||||
status: 404,
|
||||
statusText: "Not Found",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return new Response(`404 Not Found`, {
|
||||
status: 404,
|
||||
statusText: "Not Found",
|
||||
});
|
||||
return handle(req);
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -8,15 +8,12 @@ import {
|
|||
removeAsync,
|
||||
writeAsync,
|
||||
} from "fs-jetpack";
|
||||
import { createRouter } from "radix3";
|
||||
import { gunzipSync } from "zlib";
|
||||
import { downloadFile } from "../api/_deploy";
|
||||
import { dir } from "../utils/dir";
|
||||
import { g } from "../utils/global";
|
||||
|
||||
export const loadWeb = async () => {
|
||||
g.web = {};
|
||||
|
||||
await dirAsync(dir(`app/static`));
|
||||
const siteZip = `${
|
||||
g.mode === "dev" ? "http://localhost:4550" : "https://prasi.app"
|
||||
|
|
@ -53,39 +50,14 @@ export const loadWeb = async () => {
|
|||
if (!deploy) {
|
||||
await dirAsync(dir(`app/web/${web.name}/deploys`));
|
||||
}
|
||||
|
||||
g.web[web.name] = {
|
||||
current: parseInt(
|
||||
(await readAsync(dir(`app/web/${web.name}/current`))) || "0"
|
||||
),
|
||||
deploys: deploy ? deploy.children.map((e) => parseInt(e.name)) : [],
|
||||
domains:
|
||||
(await readAsync(dir(`app/web/${web.name}/domains.json`), "json")) ||
|
||||
[],
|
||||
site_id: web.name,
|
||||
deploying: null,
|
||||
cacheKey: 0,
|
||||
router: null,
|
||||
cache: null,
|
||||
};
|
||||
|
||||
const cur = g.web[web.name];
|
||||
|
||||
if (!cur.deploys.includes(cur.current)) {
|
||||
cur.current = 0;
|
||||
}
|
||||
|
||||
if (cur.current) {
|
||||
await loadWebCache(cur.site_id, cur.current);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const decoder = new TextDecoder();
|
||||
export const loadWebCache = async (site_id: string, ts: number | string) => {
|
||||
const web = g.web[site_id];
|
||||
const web = g.web;
|
||||
if (web) {
|
||||
const path = dir(`app/web/${site_id}/deploys/${ts}`);
|
||||
const path = dir(`app/web/deploys/${ts}`);
|
||||
if (await existsAsync(path)) {
|
||||
const fileContent = await readAsync(path, "buffer");
|
||||
if (fileContent) {
|
||||
|
|
@ -94,11 +66,6 @@ export const loadWebCache = async (site_id: string, ts: number | string) => {
|
|||
);
|
||||
|
||||
const res = gunzipSync(fileContent);
|
||||
web.cache = JSON.parse(decoder.decode(res));
|
||||
web.router = createRouter();
|
||||
for (const p of web.cache?.pages || []) {
|
||||
web.router.insert(p.url, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { statSync } from "fs";
|
||||
import { join } from "path";
|
||||
import { g } from "../utils/global";
|
||||
import { dir } from "utils/dir";
|
||||
|
||||
const index = {
|
||||
|
|
@ -13,28 +12,13 @@ const index = {
|
|||
};
|
||||
|
||||
export const serveWeb = async (url: URL, req: Request) => {
|
||||
const domain = url.hostname;
|
||||
let site_id = "";
|
||||
if (!g.domains) {
|
||||
g.domains = {};
|
||||
for (const web of Object.values(g.web)) {
|
||||
for (const d of web.domains) {
|
||||
const durl = new URL(d);
|
||||
g.domains[durl.hostname] = web.site_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (typeof g.domains[domain] === "undefined") {
|
||||
g.domains[domain] = "";
|
||||
}
|
||||
site_id = g.domains[domain];
|
||||
|
||||
if (!site_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const base = dir(`app/static/site`);
|
||||
// const base = `/Users/r/Developer/prasi/.output/app/srv/site`;
|
||||
|
||||
let path = join(base, url.pathname);
|
||||
|
||||
|
|
@ -73,7 +57,7 @@ export const serveWeb = async (url: URL, req: Request) => {
|
|||
index.html = generateIndexHtml("", site_id);
|
||||
}
|
||||
|
||||
return [site_id, index.html];
|
||||
return { site_id, index: index.html };
|
||||
};
|
||||
|
||||
export const generateIndexHtml = (base_url: string, site_id: string) => {
|
||||
|
|
@ -95,10 +79,6 @@ export const generateIndexHtml = (base_url: string, site_id: string) => {
|
|||
<div id="root"></div>
|
||||
<script src="${base}/site.js" type="module"></script>
|
||||
<script>window.id_site = "${site_id}";</script>
|
||||
<script
|
||||
src="https://js.sentry-cdn.com/a2dfb8b1128f4018b83bdc9c08d18da2.min.js"
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
</body>
|
||||
</html>`;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -20,65 +20,19 @@ export const g = global as unknown as {
|
|||
mode: "dev" | "prod";
|
||||
server: Server;
|
||||
log: Logger;
|
||||
firebaseInit: boolean,
|
||||
firebaseInit: boolean;
|
||||
firebase: admin.app.App;
|
||||
notif: {
|
||||
db: Database;
|
||||
};
|
||||
api: Record<string, SingleRoute>;
|
||||
domains: null | Record<string, string>;
|
||||
web: Record<
|
||||
string,
|
||||
{
|
||||
site_id: string;
|
||||
current: number;
|
||||
deploying: null | { status: string; received: number; total: number };
|
||||
deploys: number[];
|
||||
domains: string[];
|
||||
router: null | RadixRouter<{ id: string }>;
|
||||
cacheKey: number;
|
||||
cache: null | {
|
||||
site: {
|
||||
id: string;
|
||||
name: string;
|
||||
favicon: string;
|
||||
domain: string;
|
||||
id_user: string;
|
||||
created_at: Date | null;
|
||||
id_org: string | null;
|
||||
updated_at: Date | null;
|
||||
responsive: string;
|
||||
} | null;
|
||||
pages: {
|
||||
id: string;
|
||||
name: string;
|
||||
url: string;
|
||||
content_tree: any;
|
||||
id_site: string;
|
||||
created_at: Date | null;
|
||||
js_compiled: string | null;
|
||||
js: string | null;
|
||||
updated_at: Date | null;
|
||||
id_folder: string | null;
|
||||
is_deleted: boolean;
|
||||
}[];
|
||||
npm: {
|
||||
site: Record<string, string>;
|
||||
pages: Record<string, Record<string, string>>;
|
||||
};
|
||||
comps: {
|
||||
id: string;
|
||||
name: string;
|
||||
content_tree: any;
|
||||
created_at: Date | null;
|
||||
updated_at: Date | null;
|
||||
type: string;
|
||||
id_component_group: string | null;
|
||||
props: any;
|
||||
}[];
|
||||
};
|
||||
}
|
||||
>;
|
||||
web: {
|
||||
site_id: string;
|
||||
current: number;
|
||||
deploying: null | { status: string; received: number; total: number };
|
||||
deploys: number[];
|
||||
router: RadixRouter<SingleRoute>;
|
||||
};
|
||||
router: RadixRouter<SingleRoute>;
|
||||
port: number;
|
||||
frm: {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { gzip, gunzip } from "zlib";
|
||||
|
||||
export const gzipAsync = (bin: Uint8Array) => {
|
||||
export const gzipAsync = (bin: Uint8Array | string) => {
|
||||
return new Promise<Buffer>((resolve, reject) => {
|
||||
gzip(bin, (err, res) => {
|
||||
if (err) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue