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)) { if (!edInitSync(p)) {
return <Loading note="init sync" />; return <Loading note="init sync" />;
} }
return <EdBase />; return <EdBase />;
}, },
}); });

View File

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

View File

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

View File

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

View File

@ -1,9 +1,12 @@
import { ReactElement } from "react";
import { EdMeta } from "../../ed/logic/ed-global"; import { EdMeta } from "../../ed/logic/ed-global";
export const ViewGlobal = { 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>, meta: {} as Record<string, EdMeta>,
entry: [] as string[], entry: [] as string[],
bodyCache: null as null | ReactElement,
}; };
export type VG = typeof ViewGlobal & { render: () => void }; export type VG = typeof ViewGlobal & { render: () => void };

View File

@ -1,9 +1,15 @@
import { useGlobal } from "web-utils"; import { VG } from "./global";
import { VG, ViewGlobal } from "./global";
import { VLoad } from "./types"; import { VLoad } from "./types";
export const VInit = (v: VG, load: VLoad) => { export const vInit = (
v.mode = "ready"; 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") { if (load.mode === "tree_meta") {
v.meta = load.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 { FC } from "react";
import { ISection } from "../../../utils/types/section"; import { ViewMeta } from "./meta";
export const VSection: FC<{ item: ISection; children: ReactNode }> = ({ export const VSection: FC<{ id: string }> = ({ id }) => {
item, return <ViewMeta id={id} />;
children,
}) => {
console.log(item);
return <div></div>;
}; };

View File

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