checkpoint
This commit is contained in:
parent
993951eb89
commit
0c96971a8f
|
|
@ -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({
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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 ")) {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
"packagers": {
|
||||
"*.wasm": "@parcel/packager-wasm"
|
||||
},
|
||||
|
||||
"transformers": {
|
||||
"*.wasm": [
|
||||
"...",
|
||||
|
|
|
|||
|
|
@ -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 {};
|
||||
};
|
||||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue