wip fix
This commit is contained in:
parent
42c1793880
commit
7497b32195
|
|
@ -1,30 +1,122 @@
|
||||||
import { dir } from "dir";
|
import { dir } from "dir";
|
||||||
import { apiContext } from "service-srv";
|
import { apiContext } from "service-srv";
|
||||||
|
import { g } from "utils/global";
|
||||||
|
import { validate } from "uuid";
|
||||||
|
import { gzipAsync } from "../ws/sync/entity/zlib";
|
||||||
|
import { code } from "../ws/sync/editor/code/util-code";
|
||||||
|
|
||||||
export const _ = {
|
export const _ = {
|
||||||
url: "/deploy/**",
|
url: "/deploy/:site_id/**",
|
||||||
async api() {
|
async api() {
|
||||||
const { req, res } = apiContext(this);
|
const { req, res } = apiContext(this);
|
||||||
|
|
||||||
const pathname = req.params["*"];
|
const pathname: string = req.params["*"] || "";
|
||||||
if (pathname === "index.html" || pathname === "_") {
|
const site_id = req.params.site_id as string;
|
||||||
return new Response(
|
|
||||||
`\
|
const index_html = new Response(
|
||||||
|
`\
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title></title>
|
<title></title>
|
||||||
<link rel="stylesheet" href="https://prasi.app/index.css">
|
<link rel="stylesheet" href="https://prasi.app/index.css">
|
||||||
</head>
|
</head>
|
||||||
<body class="flex-col flex-1 w-full min-h-screen flex opacity-0">
|
<body class="flex-col flex-1 w-full min-h-screen flex opacity-0">
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
<script src="/deploy/main.js" type="module"></script>
|
<script>
|
||||||
|
window._prasi={basepath: "/deploy/${site_id}",site_id:"${site_id}"}
|
||||||
|
</script>
|
||||||
|
<script src="/deploy/${site_id}/main.js" type="module"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>`,
|
</html>`,
|
||||||
{ headers: { "content-type": "text/html" } }
|
{ headers: { "content-type": "text/html" } }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (!validate(site_id))
|
||||||
|
return new Response("site not found", { status: 403 });
|
||||||
|
|
||||||
|
if (pathname.startsWith("_prasi")) {
|
||||||
|
const action = pathname.split("/")[1];
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case "code": {
|
||||||
|
const arr = pathname.split("/").slice(2);
|
||||||
|
const codepath = arr.join("/");
|
||||||
|
const build_path = code.path(site_id, "site", "build", codepath);
|
||||||
|
const file = Bun.file(build_path);
|
||||||
|
if (!(await file.exists()))
|
||||||
|
return new Response("Code file not found", { status: 403 });
|
||||||
|
return new Response(file);
|
||||||
|
}
|
||||||
|
case "route": {
|
||||||
|
const site = await _db.site.findFirst({
|
||||||
|
where: { id: site_id },
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
name: true,
|
||||||
|
domain: true,
|
||||||
|
responsive: true,
|
||||||
|
config: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
let api_url = "";
|
||||||
|
if (site && site.config && (site.config as any).api_url) {
|
||||||
|
api_url = (site.config as any).api_url;
|
||||||
|
delete (site as any).config;
|
||||||
|
}
|
||||||
|
const urls = await _db.page.findMany({
|
||||||
|
where: {
|
||||||
|
id_site: site_id,
|
||||||
|
is_default_layout: false,
|
||||||
|
is_deleted: false,
|
||||||
|
},
|
||||||
|
select: { url: true, id: true },
|
||||||
|
});
|
||||||
|
return gzipAsync(
|
||||||
|
JSON.stringify({ site: { ...site, api_url }, urls }) as any
|
||||||
|
);
|
||||||
|
}
|
||||||
|
case "page": {
|
||||||
|
const page_id = pathname.split("/").pop() as string;
|
||||||
|
if (validate(page_id)) {
|
||||||
|
const page = await _db.page.findFirst({
|
||||||
|
where: { id: page_id },
|
||||||
|
select: { content_tree: true },
|
||||||
|
});
|
||||||
|
if (page) {
|
||||||
|
return gzipAsync(JSON.stringify(page.content_tree) as any);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
case "comp": {
|
||||||
|
const ids = req.params.ids as string[];
|
||||||
|
const result = {} as Record<string, any>;
|
||||||
|
if (Array.isArray(ids)) {
|
||||||
|
const comps = await _db.component.findMany({
|
||||||
|
where: { id: { in: ids } },
|
||||||
|
select: { content_tree: true, id: true },
|
||||||
|
});
|
||||||
|
for (const comp of comps) {
|
||||||
|
result[comp.id] = comp.content_tree;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return gzipAsync(JSON.stringify(result) as any);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Response("action " + action + ": not found");
|
||||||
|
} else if (pathname === "index.html" || pathname === "_") {
|
||||||
|
return index_html;
|
||||||
|
} else {
|
||||||
|
const res = dir.path(`${g.datadir}/deploy/${pathname}`);
|
||||||
|
const file = Bun.file(res);
|
||||||
|
if (!(await file.exists())) {
|
||||||
|
return index_html;
|
||||||
|
}
|
||||||
|
return new Response(file);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
import { RadixRouter, createRouter } from "radix3";
|
||||||
|
import { IRoot } from "../../../utils/types/root";
|
||||||
|
import { PG } from "../../ed/logic/ed-global";
|
||||||
|
import { IMeta } from "../../vi/utils/types";
|
||||||
|
import { IItem } from "../../../utils/types/item";
|
||||||
|
|
||||||
|
const w = window as any;
|
||||||
|
|
||||||
|
export const base = {
|
||||||
|
root: null as unknown as URL,
|
||||||
|
url(...arg: any[]) {
|
||||||
|
const pathname = arg
|
||||||
|
.map((e) => (Array.isArray(e) ? e.join("") : e))
|
||||||
|
.join("");
|
||||||
|
if (pathname.startsWith("/")) return this.root + pathname;
|
||||||
|
else return this.root.toString() + "/" + pathname;
|
||||||
|
},
|
||||||
|
get pathname() {
|
||||||
|
return location.pathname.substring(base.root.pathname.length);
|
||||||
|
},
|
||||||
|
site: { id: w._prasi?.site_id } as {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
responsive: PG["site"]["responsive"];
|
||||||
|
domain: string;
|
||||||
|
api_url: string;
|
||||||
|
code: {
|
||||||
|
mode: "new";
|
||||||
|
};
|
||||||
|
api: any;
|
||||||
|
db: any;
|
||||||
|
},
|
||||||
|
init_local_effect: {} as any,
|
||||||
|
mode: "" as "desktop" | "mobile",
|
||||||
|
route: {
|
||||||
|
status: "init" as "init" | "loading" | "ready",
|
||||||
|
router: null as null | RadixRouter<{ id: string; url: string }>,
|
||||||
|
},
|
||||||
|
comp: {
|
||||||
|
list: {} as Record<string, IItem>,
|
||||||
|
pending: new Set<string>(),
|
||||||
|
},
|
||||||
|
page: {
|
||||||
|
id: "",
|
||||||
|
url: "",
|
||||||
|
root: null as null | IRoot,
|
||||||
|
meta: null as null | Record<string, IMeta>,
|
||||||
|
cache: {} as Record<
|
||||||
|
string,
|
||||||
|
{
|
||||||
|
id: string;
|
||||||
|
url: string;
|
||||||
|
root: IRoot;
|
||||||
|
meta: Record<string, IMeta>;
|
||||||
|
}
|
||||||
|
>,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const initBaseConfig = () => {
|
||||||
|
if (!base.root) {
|
||||||
|
let url = new URL(location.href);
|
||||||
|
if (w._prasi.basepath) {
|
||||||
|
url.pathname = w._prasi.basepath;
|
||||||
|
}
|
||||||
|
|
||||||
|
base.root = new URL(`${url.protocol}//${url.host}${url.pathname}`);
|
||||||
|
if (base.root.pathname.endsWith("/")) {
|
||||||
|
base.root.pathname = base.root.pathname.substring(
|
||||||
|
0,
|
||||||
|
base.root.length - 1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
import { IContent } from "../../../utils/types/general";
|
||||||
|
import { IItem } from "../../../utils/types/item";
|
||||||
|
import { ISection } from "../../../utils/types/section";
|
||||||
|
import { base } from "./base";
|
||||||
|
import { decompressBlob } from "./util";
|
||||||
|
|
||||||
|
export const scanComponent = async (items: IContent[]) => {
|
||||||
|
const comp = base.comp;
|
||||||
|
|
||||||
|
for (const item of items) {
|
||||||
|
if (item && item.type !== "text") {
|
||||||
|
scanSingle(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (comp.pending.size > 0) {
|
||||||
|
try {
|
||||||
|
const raw = await (
|
||||||
|
await fetch(base.url`_prasi/comp`, {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({ ids: [...comp.pending] }),
|
||||||
|
})
|
||||||
|
).blob();
|
||||||
|
const res = JSON.parse(
|
||||||
|
await (await decompressBlob(raw)).text()
|
||||||
|
) as Record<string, IItem>;
|
||||||
|
for (const [id, item] of Object.entries(res)) {
|
||||||
|
comp.pending.delete(id);
|
||||||
|
comp.list[id] = item;
|
||||||
|
}
|
||||||
|
await scanComponent(Object.values(res));
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const scanSingle = (item: IItem | ISection) => {
|
||||||
|
const comp = base.comp;
|
||||||
|
if (item.type === "item") {
|
||||||
|
const comp_id = item.component?.id;
|
||||||
|
if (comp_id) {
|
||||||
|
if (!comp.list[comp_id] && !comp.pending.has(comp_id)) {
|
||||||
|
comp.pending.add(comp_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.childs) {
|
||||||
|
for (const child of item.childs) {
|
||||||
|
if (child && child.type !== "text") {
|
||||||
|
scanSingle(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { base } from "./base";
|
||||||
|
import { IRoot } from "../../../utils/types/root";
|
||||||
|
import { decompressBlob } from "./util";
|
||||||
|
|
||||||
|
export const loadPage = async (page_id: string) => {
|
||||||
|
const raw = await (await fetch(base.url`_prasi/page/${page_id}`)).blob();
|
||||||
|
const res = JSON.parse(await (await decompressBlob(raw)).text()) as IRoot;
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { base } from "./base";
|
||||||
|
import parseUA from "ua-parser-js";
|
||||||
|
|
||||||
|
export const detectResponsiveMode = () => {
|
||||||
|
const p = base;
|
||||||
|
if (p.site.id) {
|
||||||
|
if (!p.mode && !!p.site.responsive) {
|
||||||
|
if (
|
||||||
|
p.site.responsive !== "mobile-only" &&
|
||||||
|
p.site.responsive !== "desktop-only"
|
||||||
|
) {
|
||||||
|
const parsed = parseUA();
|
||||||
|
p.mode = parsed.device.type === "mobile" ? "mobile" : "desktop";
|
||||||
|
} else if (p.site.responsive === "mobile-only") {
|
||||||
|
p.mode = "mobile";
|
||||||
|
} else if (p.site.responsive === "desktop-only") {
|
||||||
|
p.mode = "desktop";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (localStorage.getItem("prasi-editor-mode")) {
|
||||||
|
p.mode = localStorage.getItem("prasi-editor-mode") as any;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
import { createRouter } from "radix3";
|
||||||
|
import { base } from "./base";
|
||||||
|
import { decompressBlob } from "./util";
|
||||||
|
import { IMeta } from "../../vi/utils/types";
|
||||||
|
import { IRoot } from "../../../utils/types/root";
|
||||||
|
import { genMeta } from "../../vi/meta/meta";
|
||||||
|
import { IItem } from "../../../utils/types/item";
|
||||||
|
import { apiProxy } from "../../../base/load/api/api-proxy";
|
||||||
|
import { dbProxy } from "../../../base/load/db/db-proxy";
|
||||||
|
|
||||||
|
export const initBaseRoute = async () => {
|
||||||
|
const raw = await (await fetch(base.url`_prasi/route`)).blob();
|
||||||
|
const router = createRouter<{ id: string; url: string }>();
|
||||||
|
try {
|
||||||
|
const res = JSON.parse(await (await decompressBlob(raw)).text()) as {
|
||||||
|
site: any;
|
||||||
|
urls: {
|
||||||
|
id: string;
|
||||||
|
url: string;
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
|
||||||
|
if (res && res.site && res.urls) {
|
||||||
|
base.site = res.site;
|
||||||
|
base.site.code = { mode: "new" };
|
||||||
|
await injectSiteScript();
|
||||||
|
|
||||||
|
base.site.api = apiProxy(base.site.api_url);
|
||||||
|
base.site.db = dbProxy(base.site.api_url);
|
||||||
|
|
||||||
|
const w = window as any;
|
||||||
|
w.serverurl = base.site.api_url;
|
||||||
|
w.db = base.site.db;
|
||||||
|
w.api = base.site.api;
|
||||||
|
|
||||||
|
|
||||||
|
for (const item of res.urls) {
|
||||||
|
router.insert(item.url, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
return router;
|
||||||
|
};
|
||||||
|
|
||||||
|
const injectSiteScript = () => {
|
||||||
|
return new Promise<void>((done) => {
|
||||||
|
const d = document;
|
||||||
|
const script = d.createElement("script");
|
||||||
|
script.onload = async () => {
|
||||||
|
done();
|
||||||
|
};
|
||||||
|
const url = base.site.api_url;
|
||||||
|
|
||||||
|
if (!localStorage.getItem("api-ts-" + url)) {
|
||||||
|
localStorage.setItem("api-ts-" + url, Date.now().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
const ts = localStorage.getItem("api-ts-" + url);
|
||||||
|
|
||||||
|
script.src = `${url}/_prasi/load.js?url=${url}&v3&ts=${ts}`;
|
||||||
|
|
||||||
|
if (!document.querySelector(`script[src="${script.src}"]`)) {
|
||||||
|
d.body.appendChild(script);
|
||||||
|
} else {
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const rebuildMeta = (meta: Record<string, IMeta>, root: IRoot) => {
|
||||||
|
for (const item of root.childs) {
|
||||||
|
genMeta(
|
||||||
|
{
|
||||||
|
comps: base.comp.list,
|
||||||
|
meta,
|
||||||
|
mode: "page",
|
||||||
|
},
|
||||||
|
{ item }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
export async function decompressBlob(blob: Blob) {
|
||||||
|
let ds = new DecompressionStream("gzip");
|
||||||
|
let decompressedStream = blob.stream().pipeThrough(ds);
|
||||||
|
return await new Response(decompressedStream).blob();
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
import { createRoot } from "react-dom/client";
|
import { createRoot } from "react-dom/client";
|
||||||
import { defineReact, defineWindow } from "web-utils";
|
import { defineReact, defineWindow } from "web-utils";
|
||||||
import { Root } from "./root";
|
import { Root } from "./root";
|
||||||
|
import { initBaseConfig } from "./base/base";
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
|
initBaseConfig();
|
||||||
const div = document.getElementById("root");
|
const div = document.getElementById("root");
|
||||||
if (div) {
|
if (div) {
|
||||||
const root = createRoot(div);
|
const root = createRoot(div);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,129 @@
|
||||||
import { useState } from "react";
|
import { useLocal } from "web-utils";
|
||||||
|
import { DeadEnd } from "../../utils/ui/deadend";
|
||||||
|
import { Loading } from "../../utils/ui/loading";
|
||||||
|
import { base } from "./base/base";
|
||||||
|
import { loadPage } from "./base/page";
|
||||||
|
import { detectResponsiveMode } from "./base/responsive";
|
||||||
|
import { initBaseRoute, rebuildMeta } from "./base/route";
|
||||||
|
import { scanComponent } from "./base/component";
|
||||||
|
import { Vi } from "../vi/vi";
|
||||||
|
import { evalCJS } from "../ed/logic/ed-sync";
|
||||||
|
|
||||||
|
const w = window as any;
|
||||||
|
|
||||||
export const Root = () => {
|
export const Root = () => {
|
||||||
const [_, render] = useState({});
|
const local = useLocal({});
|
||||||
|
|
||||||
return <></>;
|
// #region init
|
||||||
|
if (base.route.status !== "ready") {
|
||||||
|
if (base.route.status === "init") {
|
||||||
|
base.route.status = "loading";
|
||||||
|
initBaseRoute().then(async (router) => {
|
||||||
|
detectResponsiveMode();
|
||||||
|
base.route.status = "ready";
|
||||||
|
base.route.router = router;
|
||||||
|
|
||||||
|
const site_script = evalCJS(
|
||||||
|
await (
|
||||||
|
await fetch(`/deploy/${base.site.id}/_prasi/code/index.js`)
|
||||||
|
).text()
|
||||||
|
);
|
||||||
|
if (site_script) {
|
||||||
|
for (const [k, v] of Object.entries(site_script)) {
|
||||||
|
w[k] = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
local.render();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return <Loading note="Loading router" />;
|
||||||
|
}
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region routing
|
||||||
|
const router = base.route.router;
|
||||||
|
if (!router) return <DeadEnd>Failed to create Router</DeadEnd>;
|
||||||
|
|
||||||
|
const page = router.lookup(base.pathname);
|
||||||
|
if (!page) return <DeadEnd>Page Not Found</DeadEnd>;
|
||||||
|
|
||||||
|
w.params = page.params;
|
||||||
|
|
||||||
|
base.page.id = page.id;
|
||||||
|
base.page.url = page.url;
|
||||||
|
const cache = base.page.cache[page.id];
|
||||||
|
|
||||||
|
if (!cache) {
|
||||||
|
loadPage(page.id)
|
||||||
|
.then(async (root) => {
|
||||||
|
const p = {
|
||||||
|
id: page.id,
|
||||||
|
url: page.url,
|
||||||
|
root,
|
||||||
|
meta: {},
|
||||||
|
};
|
||||||
|
await scanComponent(root.childs);
|
||||||
|
rebuildMeta(p.meta, root);
|
||||||
|
base.page.cache[p.id] = p;
|
||||||
|
local.render();
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
local.render();
|
||||||
|
});
|
||||||
|
|
||||||
|
return <Loading note="Loading page" />;
|
||||||
|
} else {
|
||||||
|
base.page.root = cache.root;
|
||||||
|
base.page.meta = cache.meta;
|
||||||
|
}
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={cx("relative flex flex-1 items-center justify-center")}>
|
||||||
|
<div
|
||||||
|
className={cx(
|
||||||
|
"absolute flex flex-col items-stretch flex-1 bg-white main-content-preview",
|
||||||
|
base.mode === "mobile"
|
||||||
|
? css`
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
border-left: 1px solid #ccc;
|
||||||
|
border-right: 1px solid #ccc;
|
||||||
|
width: 375px;
|
||||||
|
top: 0px;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
bottom: 0px;
|
||||||
|
}
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
left: 0px;
|
||||||
|
right: 0px;
|
||||||
|
top: 0px;
|
||||||
|
bottom: 0px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
: "inset-0 overflow-auto",
|
||||||
|
|
||||||
|
css`
|
||||||
|
contain: content;
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<Vi
|
||||||
|
api_url={base.site.api_url}
|
||||||
|
entry={Object.values(base.page.root.childs)
|
||||||
|
.filter((e) => e)
|
||||||
|
.map((e) => e.id)}
|
||||||
|
meta={base.page.meta}
|
||||||
|
mode={base.mode}
|
||||||
|
page_id={base.page.id}
|
||||||
|
site_id={base.site.id}
|
||||||
|
db={base.site.db}
|
||||||
|
api={base.site.api}
|
||||||
|
script={{ init_local_effect: base.init_local_effect }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,14 @@
|
||||||
import { get, set } from "idb-keyval";
|
import { get, set } from "idb-keyval";
|
||||||
import { IContent } from "../../../../utils/types/general";
|
import { IContent } from "../../../../utils/types/general";
|
||||||
import { IItem, MItem } from "../../../../utils/types/item";
|
import { IItem, MItem } from "../../../../utils/types/item";
|
||||||
|
import { FMCompDef } from "../../../../utils/types/meta-fn";
|
||||||
import { initLoadComp } from "../../../vi/meta/comp/init-comp-load";
|
import { initLoadComp } from "../../../vi/meta/comp/init-comp-load";
|
||||||
import { genMeta } from "../../../vi/meta/meta";
|
import { genMeta } from "../../../vi/meta/meta";
|
||||||
import { nav } from "../../../vi/render/script/extract-nav";
|
import { nav } from "../../../vi/render/script/extract-nav";
|
||||||
import { loadCompSnapshot, loadComponent } from "../comp/load";
|
import { loadCompSnapshot } from "../comp/load";
|
||||||
import { IMeta, PG, active } from "../ed-global";
|
import { IMeta, PG, active } from "../ed-global";
|
||||||
import { assignMitem } from "./assign-mitem";
|
import { assignMitem } from "./assign-mitem";
|
||||||
import { pushTreeNode } from "./build/push-tree";
|
import { pushTreeNode } from "./build/push-tree";
|
||||||
import { createId } from "@paralleldrive/cuid2";
|
|
||||||
import { FMCompDef } from "../../../../utils/types/meta-fn";
|
|
||||||
|
|
||||||
export const treeCacheBuild = async (p: PG, page_id: string) => {
|
export const treeCacheBuild = async (p: PG, page_id: string) => {
|
||||||
const page_cache = p.preview.page_cache[page_id];
|
const page_cache = p.preview.page_cache[page_id];
|
||||||
|
|
@ -30,6 +29,8 @@ export const treeCacheBuild = async (p: PG, page_id: string) => {
|
||||||
page_cache.root as unknown as IItem,
|
page_cache.root as unknown as IItem,
|
||||||
{
|
{
|
||||||
async load(comp_ids) {
|
async load(comp_ids) {
|
||||||
|
if (!p.sync) return;
|
||||||
|
|
||||||
const ids = comp_ids.filter((id) => !p.comp.loaded[id]);
|
const ids = comp_ids.filter((id) => !p.comp.loaded[id]);
|
||||||
const comps = await p.sync.comp.load(ids, true);
|
const comps = await p.sync.comp.load(ids, true);
|
||||||
let result = Object.entries(comps);
|
let result = Object.entries(comps);
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ export const Vi: FC<{
|
||||||
api?: any;
|
api?: any;
|
||||||
db?: any;
|
db?: any;
|
||||||
layout?: VG["layout"];
|
layout?: VG["layout"];
|
||||||
script?: { init_local_effect: Record<string, boolean> };
|
script: { init_local_effect: Record<string, boolean> };
|
||||||
visit?: VG["visit"];
|
visit?: VG["visit"];
|
||||||
render_stat?: "enabled" | "disabled";
|
render_stat?: "enabled" | "disabled";
|
||||||
on_status_changed?: (status: VG["status"]) => void;
|
on_status_changed?: (status: VG["status"]) => void;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { FC } from "react";
|
||||||
|
|
||||||
|
export const DeadEnd: FC<{ children: any }> = ({ children }) => {
|
||||||
|
return (
|
||||||
|
<div className="flex items-center justify-center w-full h-full fixed inset-0">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
import { dir } from "dir";
|
import { dir } from "dir";
|
||||||
import { context } from "esbuild";
|
import { context } from "esbuild";
|
||||||
|
import { g } from "./utils/global";
|
||||||
|
|
||||||
const ctx = await context({
|
const ctx = await context({
|
||||||
bundle: true,
|
bundle: true,
|
||||||
absWorkingDir: dir.path(""),
|
absWorkingDir: dir.path(""),
|
||||||
entryPoints: [dir.path("app/web/src/nova/deploy/main.tsx")],
|
entryPoints: [dir.path("app/web/src/nova/deploy/main.tsx")],
|
||||||
outdir: dir.path("app/static/deploy"),
|
outdir: dir.path(`${g.datadir}/deploy`),
|
||||||
splitting: true,
|
splitting: true,
|
||||||
format: "esm",
|
format: "esm",
|
||||||
jsx: "transform",
|
jsx: "transform",
|
||||||
|
|
@ -77,6 +77,8 @@ if (!g.parcel) {
|
||||||
await parcelBuild();
|
await parcelBuild();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await import("./build-deploy");
|
||||||
|
|
||||||
const { createServer } = await import("./server/create");
|
const { createServer } = await import("./server/create");
|
||||||
await createServer();
|
await createServer();
|
||||||
g.status = "ready";
|
g.status = "ready";
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { join } from "path";
|
||||||
|
|
||||||
export const dir = {
|
export const dir = {
|
||||||
path: (path: string) => {
|
path: (path: string) => {
|
||||||
return join(process.cwd(), path);
|
const final_path = path.split("/").filter((e) => e !== "..").join('/');
|
||||||
|
return join(process.cwd(), final_path);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue