wip fix load-code

This commit is contained in:
Rizky 2023-11-19 14:26:22 +07:00
parent 619b244046
commit f8263e99b1
13 changed files with 185 additions and 42 deletions

35
app/srv/api/nova-load.ts Normal file
View File

@ -0,0 +1,35 @@
import { dir } from "dir";
import { apiContext } from "service-srv";
import { g } from "utils/global";
export const _ = {
url: "/nova-load/:mode/:id/**",
async api(mode: "site" | "page" | "code", id: string) {
const { req, res } = apiContext(this);
if (mode === "site") {
const code = await db.code.findFirst({ where: { id_site: id } });
if (code) {
const file = Bun.file(
dir.path(`${g.datadir}/site/build/${code.id}/${req.params["*"]}`)
);
if (await file.exists()) {
return new Response(file as any);
}
}
}
if (mode === "page") {
const code = await db.code_assign.findMany({ where: { id_page: id } });
return code.map((e) => e.id);
} else if (mode === "code") {
const file = Bun.file(
dir.path(`${g.datadir}/site/build/${id}/${req.params["*"]}`)
);
if (await file.exists()) {
return new Response(file as any);
}
}
return "This is nova-load.ts";
},
};

View File

@ -13,7 +13,7 @@ export default page({
if (!edInitSync(p)) {
return <Loading note="init sync" />;
}
return <EdBase />;
},
});

View File

@ -1,17 +1,17 @@
import { useGlobal } from "web-utils";
import { Loading } from "../../utils/ui/loading";
import { EdLeft } from "./ed-left";
import { EdRight } from "./ed-right";
import { EDGlobal } from "./logic/ed-global";
import { edInit } from "./logic/ed-init";
import { edRoute } from "./logic/ed-route";
import { edUndoManager } from "./logic/ed-undo";
import { EdMain } from "./panel/main/main";
import { EdPane } from "./panel/main/pane-resize";
import { EdPopCode } from "./panel/popup/code/code";
import { EdPopCompGroup } from "./panel/popup/comp/comp-group";
import { EdPopSite } from "./panel/popup/site/site";
import { EdScriptInit } from "./panel/script/monaco/init";
import { EdRight } from "./ed-right";
import { EdPopCode } from "./panel/popup/code/code";
export const EdBase = () => {
const p = useGlobal(EDGlobal, "EDITOR");
@ -19,12 +19,12 @@ export const EdBase = () => {
edUndoManager(p);
if (p.status === "init") {
edInit(p);
edInit(p)
}
edRoute(p);
if (p.status === "loading" || p.status === "init") {
if (p.status === "loading") {
return <Loading note={`${p.status}-page`} />;
}
if (p.status === "site-not-found" || p.status === "page-not-found") {

View File

@ -82,6 +82,7 @@ export const EDGlobal = {
meta: {} as Record<string, EdMeta>,
entry: [] as string[],
tree: [] as NodeModel<EdMeta>[],
render: () => {},
},
comp: {
cur: EmptyComp,

View File

@ -3,7 +3,7 @@ import { PG } from "./ed-global";
import { treeRebuild } from "./tree/build";
export const edRoute = async (p: PG) => {
if (p.status === "ready") {
if (p.status === "ready" || p.status === "init") {
if (!p.site.domain && !p.site.name) {
p.status = "loading";
const site = await p.sync.site.load(p.site.id);

View File

@ -15,6 +15,11 @@ export const EdMain = () => {
meta: p.page.meta,
entry: p.page.entry,
}}
site_id={p.site.id}
page_id={p.page.cur.id}
bind={({ render }) => {
p.page.render = render;
}}
/>
)}
</div>

View File

@ -1,9 +1,12 @@
import { ReactElement } from "react";
import { EdMeta } from "../../ed/logic/ed-global";
export const ViewGlobal = {
mode: "init" as "init" | "ready",
mode: "init" as "init" | "load-code" | "loading-code" | "ready" | "rebuild",
current: { site_id: "", page_id: "" },
meta: {} as Record<string, EdMeta>,
entry: [] as string[],
bodyCache: null as null | ReactElement,
};
export type VG = typeof ViewGlobal & { render: () => void };

View File

@ -1,9 +1,15 @@
import { useGlobal } from "web-utils";
import { VG, ViewGlobal } from "./global";
import { VG } from "./global";
import { VLoad } from "./types";
export const VInit = (v: VG, load: VLoad) => {
v.mode = "ready";
export const vInit = (
v: VG,
arg: { load: VLoad; site_id: string; page_id: string }
) => {
const { load, site_id, page_id } = arg;
v.mode = "load-code";
v.current.site_id = site_id;
v.current.page_id = page_id;
if (load.mode === "tree_meta") {
v.meta = load.meta;

View File

@ -0,0 +1,57 @@
import { VG } from "./global";
export const vLoadCode = async (v: VG) => {
if (v.mode === "load-code") {
v.mode = "loading-code";
const { site_id, page_id } = v.current;
const w = window as any;
const promises = [
new Promise<void>(async (resolve) => {
const module = await importCJS(`/nova-load/site/${site_id}/index.js`);
for (const [k, v] of Object.entries(module)) {
w[k] = v;
}
resolve();
}),
];
const code_ids = await api.nova_load("page", page_id);
for (const id of code_ids) {
promises.push(
new Promise<void>(async (resolve) => {
const module = await importCJS(`/nova-load/code/${id}/index.js`);
for (const [k, v] of Object.entries(module)) {
w[k] = v;
}
resolve();
})
);
}
await Promise.all(promises);
v.mode = "rebuild";
v.render();
}
};
const importCJS = async (url: string) => {
const module = { exports: { __esModule: true as true | undefined } };
const res = await fetch(url);
const src = await res.text();
if (src) {
const fn = new Function("module", src);
await fn(module);
const result = { ...module.exports };
if (result.__esModule) {
delete result.__esModule;
}
return result;
}
return {};
};

View File

@ -0,0 +1,15 @@
import { useGlobal } from "web-utils";
import { ViewGlobal } from "../logic/global";
import { VSection } from "./section";
export const VEntry = () => {
const v = useGlobal(ViewGlobal, "VIEW");
return (
<>
{v.entry.map((section_id) => {
return <VSection id={section_id} key={section_id} />;
})}
</>
);
};

View File

@ -0,0 +1,11 @@
import { FC } from "react";
import { useGlobal } from "web-utils";
import { ViewGlobal } from "../logic/global";
export const ViewMeta: FC<{ id: string }> = ({ id }) => {
const v = useGlobal(ViewGlobal, "VIEW");
const meta = v.meta[id];
const item = meta.item;
return <div></div>;
};

View File

@ -1,10 +1,6 @@
import { FC, ReactNode } from "react";
import { ISection } from "../../../utils/types/section";
import { FC } from "react";
import { ViewMeta } from "./meta";
export const VSection: FC<{ item: ISection; children: ReactNode }> = ({
item,
children,
}) => {
console.log(item);
return <div></div>;
export const VSection: FC<{ id: string }> = ({ id }) => {
return <ViewMeta id={id} />;
};

View File

@ -2,36 +2,50 @@ import { FC } from "react";
import { useGlobal } from "web-utils";
import { Loading } from "../../utils/ui/loading";
import { ViewGlobal } from "./logic/global";
import { VInit } from "./logic/init";
import { vInit } from "./logic/init";
import { vLoadCode } from "./logic/load-code";
import { VLoad } from "./logic/types";
import { VSection } from "./render/section";
import { ISection } from "../../utils/types/section";
import { VEntry } from "./render/entry";
export const View: FC<{
load: VLoad;
}> = ({ load }) => {
site_id: string;
page_id: string;
bind?: (arg: { render: () => void }) => void;
}> = ({ load, site_id, page_id, bind: onLoad }) => {
const v = useGlobal(ViewGlobal, "VIEW");
if (v.mode === "init") {
VInit(v, load);
if (v.current.page_id !== page_id || v.current.site_id !== site_id) {
v.mode = "init";
}
return (
<div className="flex flex-1 flex-col relative">
{v.mode !== "ready" ? (
<Loading backdrop={false} />
) : (
v.entry.map((section_id) => {
const meta = v.meta[section_id];
const section = meta.item as ISection;
if (onLoad) {
onLoad({
render() {
v.mode = "rebuild";
v.render();
},
});
}
return (
<VSection item={section} key={section_id}>
Hello
</VSection>
);
})
)}
</div>
);
if (v.mode === "init") {
vInit(v, { load, page_id, site_id });
if (v.mode === "init") {
return <Loading backdrop={false} note="init" />;
}
}
if (v.mode === "load-code" || v.mode === "loading-code") {
vLoadCode(v);
if (v.mode === "load-code" || v.mode === "loading-code") {
return <Loading backdrop={false} note="load" />;
}
}
if (v.mode === "rebuild") {
v.bodyCache = <VEntry />;
v.mode = "ready";
}
return <div className="flex flex-1 flex-col relative">{v.bodyCache}</div>;
};