checkpoint

This commit is contained in:
Rizky 2024-05-06 17:35:23 +07:00
parent 993951eb89
commit 0c96971a8f
16 changed files with 148 additions and 111 deletions

View File

@ -34,10 +34,13 @@ export const _ = {
if (!(await file.exists())) {
const root = `/code/${site_id}/site/src`;
await initFrontEnd(root, site_id);
return new Response("Code file not found", { status: 403 });
return new Response("", { status: 403 });
}
const body = Bun.gzipSync(await file.arrayBuffer());
return new Response(file);
return new Response(body, {
headers: { "content-type": file.type, "content-encoding": "gzip" },
});
}
case "route": {
const site = await _db.site.findFirst({

View File

@ -11,8 +11,8 @@ export const _ = {
const root = `/code/${id_site}/site/src`;
delete frontend[id_site];
delete server[id_site];
await initFrontEnd(root, id_site);
await initServer(root, id_site);
await initFrontEnd(root, id_site, true);
await initServer(root, id_site, true);
return "ok";
},

View File

@ -6,19 +6,20 @@
"@hyrious/esbuild-plugin-style": "^0.3.5",
"@node-rs/argon2": "^1.5.2",
"@paralleldrive/cuid2": "^2.2.2",
"@types/lodash.isequal": "^4.5.8",
"@types/mime-types": "^2.1.4",
"recast": "^0.23.4",
"esbuild": "^0.20.2",
"esbuild-clean-plugin": "^1.0.0",
"lmdb": "^2.9.2",
"lodash.isequal": "^4.5.0",
"mime-types": "^2.1.35",
"msgpackr": "^1.10.0",
"radix3": "^1.1.0",
"recast": "^0.23.4",
"uuid": "^9.0.1",
"y-pojo": "^0.0.8",
"yjs": "^13.6.10",
"yjs-types": "^0.0.1",
"lodash.isequal": "^4.5.0",
"@types/lodash.isequal": "^4.5.8"
"yjs-types": "^0.0.1"
},
"devDependencies": {
"bun-types": "^1.0.30"

View File

@ -1,28 +1,34 @@
import globalExternals from "@fal-works/esbuild-plugin-global-externals";
import style from "@hyrious/esbuild-plugin-style";
import { dir } from "dir";
import { BuildOptions, BuildResult, context } from "esbuild";
import { removeAsync } from "fs-jetpack";
import { BuildOptions, BuildResult, context, formatMessages } from "esbuild";
import { cleanPlugin } from "esbuild-clean-plugin";
import isEqual from "lodash.isequal";
import { appendFile } from "node:fs/promises";
import { code } from "../../code";
import { buildTypes } from "./typings";
const decoder = new TextDecoder();
export const initFrontEnd = async (root: string, id_site: string) => {
export const initFrontEnd = async (
root: string,
id_site: string,
force?: boolean
) => {
let existing = code.internal.frontend[id_site];
if (existing) {
try {
await existing.dispose();
delete code.internal.frontend[id_site];
} catch (e) {}
if (force) {
try {
await existing.dispose();
delete code.internal.frontend[id_site];
} catch (e) {}
} else {
return;
}
}
try {
await isInstalling(id_site);
const out_dir = dir.data(`code/${id_site}/site/build`);
await removeAsync(out_dir);
const existing = await context({
absWorkingDir: dir.data(root),
entryPoints: ["index.tsx"],
@ -36,6 +42,7 @@ export const initFrontEnd = async (root: string, id_site: string) => {
sourcemap: true,
metafile: true,
plugins: [
cleanPlugin(),
style(),
globalExternals({
react: {
@ -58,13 +65,15 @@ export const initFrontEnd = async (root: string, id_site: string) => {
});
setup.onEnd(async (res) => {
if (res.errors.length > 0) {
if (!(await installDeps(root, res, id_site))) {
await codeError(
id_site,
res.errors.map((e) => e.text).join("\n\n")
);
}
await codeError(
id_site,
(await formatMessages(res.errors, { kind: "error" })).join(
"\n\n"
)
);
await installDeps(root, res, id_site);
} else {
await codeError(id_site, "");
await buildTypes(root, id_site);
}
});
@ -135,8 +144,6 @@ const installDeps = async (
const pkgjson = await readPackageJSON(id_site);
const imports = new Set<string>();
if (!(await isInstalling(id_site))) await codeError(id_site, "");
if (res.errors.length > 0) {
for (const err of res.errors) {
if (err.notes?.[0].text.startsWith("You can mark the path ")) {

View File

@ -3,10 +3,18 @@ import { context } from "esbuild";
import { dirAsync, existsAsync, removeAsync, writeAsync } from "fs-jetpack";
import { code } from "../../code";
export const initServer = async (root: string, id_site: string) => {
export const initServer = async (
root: string,
id_site: string,
force?: boolean
) => {
const existing = code.internal.server[id_site];
if (existing) {
await existing.dispose();
if (force) {
await existing.dispose();
} else {
return;
}
}
const build_path = code.path(id_site, "server", "build");
@ -84,4 +92,6 @@ export const initServer = async (root: string, id_site: string) => {
}`,
},
});
await code.internal.server[id_site].watch();
};

View File

@ -9,8 +9,12 @@ import { prodIndex } from "../../../../util/prod-index";
import { code } from "../../code/code";
import "./server-runtime";
if (!g.server_main_handler) {
g.server_main_handler = {};
}
const serverMain = () => ({
handler: {} as Record<string, PrasiServer>,
handler: g.server_main_handler as Record<string, PrasiServer>,
init_timeout: null as any,
ws(action: keyof WebSocketHandler<WSData>, ...arg: any[]) {
const id = arg[0].data.site_id;
@ -29,42 +33,45 @@ const serverMain = () => ({
init(site_id: string) {
clearTimeout(this.init_timeout);
this.init_timeout = setTimeout(async () => {
// const server_src_path = code.path(site_id, "server", "build", "index.js");
// try {
// delete require.cache[server_src_path];
// const svr = require(server_src_path);
// if (svr && typeof svr.server === "object") {
// this.handler[site_id] = svr.server;
// this.handler[site_id].site_id = site_id;
// if (typeof svr.server.init === "function") {
// svr.server.init({});
// }
// Bun.write(
// Bun.file(code.path(site_id, "site", "src", "server.log")),
// ""
// );
// } else {
// const file = await Bun.file(server_src_path).text();
// const log_path = code.path(site_id, "site", "src", "server.log");
// if (file.length === 0) {
// await Bun.write(Bun.file(log_path), "server.ts is empty");
// } else {
// await Bun.write(
// Bun.file(log_path),
// "server.ts does not return server object"
// );
// }
// }
// } catch (e: any) {
// const file = await Bun.file(server_src_path).text();
// const log_path = code.path(site_id, "site", "src", "server.log");
// if (file.length === 0) {
// await Bun.write(Bun.file(log_path), "server.ts is empty");
// } else {
// await Bun.write(Bun.file(log_path), e.message);
// console.log(`Failed to init server ${site_id}\n`, log_path);
// }
// }
const server_src_path = code.path(site_id, "server", "build", "index.js");
const file = Bun.file(server_src_path);
if (!this.handler[site_id] && (await file.exists()) && file.length) {
try {
delete require.cache[server_src_path];
const svr = require(server_src_path);
if (svr && typeof svr.server === "object") {
this.handler[site_id] = svr.server;
this.handler[site_id].site_id = site_id;
if (typeof svr.server.init === "function") {
svr.server.init({});
}
Bun.write(
Bun.file(code.path(site_id, "site", "src", "server.log")),
""
);
} else {
const file = await Bun.file(server_src_path).text();
const log_path = code.path(site_id, "site", "src", "server.log");
if (file.length === 0) {
await Bun.write(Bun.file(log_path), "server.ts is empty");
} else {
await Bun.write(
Bun.file(log_path),
"server.ts does not return server object"
);
}
}
} catch (e: any) {
const file = await Bun.file(server_src_path).text();
const log_path = code.path(site_id, "site", "src", "server.log");
if (file.length === 0) {
await Bun.write(Bun.file(log_path), "server.ts is empty");
} else {
await Bun.write(Bun.file(log_path), e.message);
console.log(`Failed to init server ${site_id}\n`, log_path);
}
}
}
}, 10);
},
async http(

View File

@ -9,7 +9,6 @@
"packagers": {
"*.wasm": "@parcel/packager-wasm"
},
"transformers": {
"*.wasm": [
"...",

View File

@ -0,0 +1,24 @@
export const loadCode = async (id_site: string, ts?: number) => {
const url = `/prod/${id_site}/_prasi/code/index.js?ts=${ts}`;
const fn = new Function(
"callback",
`
import("${url}")
.catch((e) => console.error("Failed to load site code\\n\\n", e))
.then(callback)`
);
try {
return await new Promise<any>((resolve) => {
try {
fn((exports: any) => {
resolve(exports);
});
} catch (e) {
console.log("Failed to load site code", e);
}
});
} catch (e) {
console.log("Failed to load site code", e);
}
return {};
};

View File

@ -10,6 +10,7 @@ import { reloadPage } from "./ed-route";
import { loadSite } from "./ed-site";
import { updateComponentMeta } from "./comp/load";
import { createRouter, RadixRouter } from "radix3";
import { loadCode } from "./code-loader";
const decoder = new TextDecoder();
@ -185,24 +186,10 @@ export const edInitSync = (p: PG) => {
async code_changes({ ts }) {
const w = window as any;
const url = `/prod/${p.site.id}/_prasi/code/index.js?ts=${ts}`;
const fn = new Function(
"callback",
`import("${url}").then(callback)`
);
try {
await new Promise<void>((resolve) => {
fn((exports: any) => {
p.site_exports = {};
for (const [k, v] of Object.entries(exports)) {
p.site_exports[k] = v;
w[k] = v;
}
resolve();
});
});
} catch (e) {
console.log("Failed to load site code", e);
const exports = await loadCode(p.site.id, ts);
for (const [k, v] of Object.entries(exports)) {
w[k] = v;
p.site_exports[k] = v;
}
await treeRebuild(p);
p.render();

View File

@ -338,7 +338,6 @@ export const EdScriptMonaco: FC<{}> = () => {
}
} else {
editorLocalValue[active.item_id] = null;
const code_result = await p.sync.code.edit({
type: "adv",
mode: mode,

View File

@ -6,6 +6,7 @@ import { w } from "../../../utils/types/general";
import { PG } from "../../ed/logic/ed-global";
import { treeRebuild } from "../../ed/logic/tree/build";
import { simpleHash } from "../utils/simple-hash";
import { loadCode } from "../../ed/logic/code-loader";
const encoder = new TextEncoder();
export const viLoadSnapshot = async (p: PG) => {
@ -62,31 +63,5 @@ export const applyEnv = async (p: PG) => {
w.api = apiProxy(p.site.config.api_url);
}
const url = `/prod/${p.site.id}/_prasi/code/index.js?ts=${p.site_tstamp}`;
const fn = new Function(
"callback",
`
try {
return import("${url}")
} catch(e) {
console.log("Failed to load site code", e);
}`
);
await new Promise<void>(async (resolve) => {
try {
const exports = await fn();
if (exports) {
p.site_exports = {};
for (const [k, v] of Object.entries(exports)) {
p.site_exports[k] = v;
w[k] = v;
}
}
resolve();
} catch (e) {
console.log("Failed to load site code", e);
resolve();
}
});
await loadCode(p.site.id, p.site_tstamp);
};

View File

@ -18,6 +18,30 @@ export const monacoTypings = async (
monaco: Monaco,
prop: { values: Record<string, any>; types: Record<string, string> }
) => {
register(
monaco,
`
declare module "momo" {
export type MO = "123";
export const MUU = "123";
}
`,
"ts: momo.d.ts"
);
register(
monaco,
`
declare global {
import * as _ from "momo"
const MUU = _.MUU;
}
export {}
`,
"ts: coba.d.ts"
);
if (!map.has(prop.values)) {
map.set(prop.values, true);
} else {

BIN
bun.lockb

Binary file not shown.

View File

@ -21,6 +21,7 @@ type SingleRoute = {
export const g = global as unknown as {
status: "init" | "ready";
server_main_handler: any;
server_hook?: (arg: {
url: URL;
req: Request;