fix
This commit is contained in:
parent
7b5b9bb9a0
commit
e0984794de
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { apiContext } from "service-srv";
|
||||||
|
|
||||||
|
export const _ = {
|
||||||
|
url: "/_web/comp/:id",
|
||||||
|
async api(id: string) {
|
||||||
|
const { req, res } = apiContext(this);
|
||||||
|
return await db.component.findFirst({ where: { id } });
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { apiContext } from "service-srv";
|
||||||
|
|
||||||
|
export const _ = {
|
||||||
|
url: "/_web/page/:id",
|
||||||
|
async api(id: string) {
|
||||||
|
const { req, res } = apiContext(this);
|
||||||
|
return await db.page.findFirst({ where: { id } });
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
@ -1,15 +1,19 @@
|
||||||
import { validate } from "uuid";
|
import { validate } from "uuid";
|
||||||
import { page } from "web-utils";
|
import { page } from "web-utils";
|
||||||
|
import { devLoader } from "../../render/live/dev-loader";
|
||||||
import { Live } from "../../render/live/live";
|
import { Live } from "../../render/live/live";
|
||||||
import { defaultLoader } from "../../render/live/logic/default-loader";
|
|
||||||
|
|
||||||
export default page({
|
export default page({
|
||||||
url: "/live/:domain/**",
|
url: "/live/:domain/**",
|
||||||
component: ({}) => {
|
component: ({}) => {
|
||||||
params.site_id = params.domain;
|
params.site_id = params.domain;
|
||||||
|
let pathname = `/${params._ === "_" ? "" : params._}`;
|
||||||
if (validate(params._)) {
|
if (validate(params._)) {
|
||||||
params.page_id = params._;
|
const arr = params._.split("/");
|
||||||
|
params.page_id = arr.shift();
|
||||||
|
pathname = `/${arr.join("/")}`;
|
||||||
}
|
}
|
||||||
|
(window as any).pathname = pathname;
|
||||||
|
|
||||||
navigator.serviceWorker.controller?.postMessage({
|
navigator.serviceWorker.controller?.postMessage({
|
||||||
type: "add-cache",
|
type: "add-cache",
|
||||||
|
|
@ -18,10 +22,9 @@ export default page({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Live
|
<Live
|
||||||
mode={"dev"}
|
domain_or_siteid={params.domain}
|
||||||
domain={params.domain}
|
pathname={pathname}
|
||||||
pathname={`/${params._ === "_" ? "" : params._}`}
|
loader={devLoader}
|
||||||
loader={defaultLoader}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,12 @@ import {
|
||||||
initApi,
|
initApi,
|
||||||
reloadDBAPI,
|
reloadDBAPI,
|
||||||
} from "../../../utils/script/init-api";
|
} from "../../../utils/script/init-api";
|
||||||
import { defaultLoader } from "../../live/logic/default-loader";
|
|
||||||
import { LSite } from "../../live/logic/global";
|
import { LSite } from "../../live/logic/global";
|
||||||
import { validateLayout } from "../../live/logic/layout";
|
import { validateLayout } from "../../live/logic/layout";
|
||||||
import { jscript } from "../panel/script/script-element";
|
import { jscript } from "../panel/script/script-element";
|
||||||
import importModule from "../tools/dynamic-import";
|
import importModule from "../tools/dynamic-import";
|
||||||
import { PG } from "./global";
|
import { PG } from "./global";
|
||||||
|
import { devLoader } from "../../live/dev-loader";
|
||||||
|
|
||||||
export const w = window as unknown as {
|
export const w = window as unknown as {
|
||||||
basepath: string;
|
basepath: string;
|
||||||
|
|
@ -70,7 +70,10 @@ export const initEditor = async (p: PG, site_id: string) => {
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
|
||||||
const querySite = async () => {
|
const querySite = async () => {
|
||||||
const site = await defaultLoader.site(p as any, { id: site_id });
|
const site = await devLoader.site(p as any, {
|
||||||
|
type: "siteid",
|
||||||
|
id: site_id,
|
||||||
|
});
|
||||||
|
|
||||||
localStorage.setItem(`prasi-site-${site_id}`, JSON.stringify(site));
|
localStorage.setItem(`prasi-site-${site_id}`, JSON.stringify(site));
|
||||||
return site;
|
return site;
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ const PassProp: FC<Record<string,any> & {children: React.ReactNode; }>;
|
||||||
const PassChild: FC<{name: string}>;
|
const PassChild: FC<{name: string}>;
|
||||||
const Preload: FC<{url: string[]}>;
|
const Preload: FC<{url: string[]}>;
|
||||||
const apiurl: string;
|
const apiurl: string;
|
||||||
const prasiPageID: string;
|
const pageid: string;
|
||||||
type ITEM = {
|
type ITEM = {
|
||||||
id: string
|
id: string
|
||||||
name: string;
|
name: string;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,117 @@
|
||||||
|
import { LSite, Loader } from "./logic/global";
|
||||||
|
|
||||||
|
const cache = { site: null as any, pages: [] as any, api: null };
|
||||||
|
const config = { serverurl: "" };
|
||||||
|
|
||||||
|
export const devLoader: Loader = {
|
||||||
|
async site(p, where) {
|
||||||
|
config.serverurl = serverurl;
|
||||||
|
const site = (await db.site.findFirst({
|
||||||
|
where:
|
||||||
|
where.type === "siteid" ? { id: where.id } : { domain: where.domain },
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
config: true,
|
||||||
|
domain: true,
|
||||||
|
name: true,
|
||||||
|
js: true,
|
||||||
|
responsive: true,
|
||||||
|
js_compiled: true,
|
||||||
|
},
|
||||||
|
})) as unknown as LSite;
|
||||||
|
|
||||||
|
if (!site) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const cgroups = await db.site_use_comp.findMany({
|
||||||
|
where: { id_site: site.id },
|
||||||
|
select: { use_id_site: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (cgroups) {
|
||||||
|
site.cgroup_ids = [];
|
||||||
|
for (const id of cgroups.map((c: any) => c.use_id_site)) {
|
||||||
|
site.cgroup_ids.push(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const layout = await db.page.findFirst({
|
||||||
|
where: {
|
||||||
|
id_site: site.id,
|
||||||
|
name: { startsWith: "layout:" },
|
||||||
|
is_default_layout: true,
|
||||||
|
is_deleted: false,
|
||||||
|
},
|
||||||
|
select: { content_tree: true, id: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (layout) {
|
||||||
|
const childs = (layout.content_tree as any).childs;
|
||||||
|
if (childs && childs.length > 0) {
|
||||||
|
site.layout = childs[0];
|
||||||
|
site.layout_id = layout.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cache.site = site;
|
||||||
|
|
||||||
|
return site;
|
||||||
|
},
|
||||||
|
async comp(p, id) {
|
||||||
|
const comp = await load(`${config.serverurl}/_web/comp/${id}`);
|
||||||
|
p.comps.all[id] = comp;
|
||||||
|
return comp;
|
||||||
|
},
|
||||||
|
npm(p, type, id) {
|
||||||
|
if (type === "site") {
|
||||||
|
return `${config.serverurl}/npm/site/${id}/site.js`;
|
||||||
|
}
|
||||||
|
return `${config.serverurl}/npm/page/${id}/page.js`;
|
||||||
|
},
|
||||||
|
async page(p, id) {
|
||||||
|
return await load(`${config.serverurl}/_web/page/${id}`);
|
||||||
|
},
|
||||||
|
async pages(p, id) {
|
||||||
|
let pages = [] as any;
|
||||||
|
/** load pages */
|
||||||
|
const pagesLocal = localStorage.getItem(`prasi-pages-[${id}]`);
|
||||||
|
if (pagesLocal) {
|
||||||
|
try {
|
||||||
|
pages = JSON.parse(pagesLocal);
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadPages = async () => {
|
||||||
|
return await db.page.findMany({
|
||||||
|
where: {
|
||||||
|
id_site: cache.site.id,
|
||||||
|
is_deleted: false,
|
||||||
|
name: { not: { startsWith: "layout:" } },
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
name: true,
|
||||||
|
url: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (pages.length === 0) {
|
||||||
|
pages = await loadPages();
|
||||||
|
localStorage.setItem(`prasi-pages-[${id}]`, JSON.stringify(pages));
|
||||||
|
} else {
|
||||||
|
loadPages().then((pages) => {
|
||||||
|
localStorage.setItem(`prasi-pages-[${id}]`, JSON.stringify(pages));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return pages;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const load = async (url: string) => {
|
||||||
|
const res = await fetch(url);
|
||||||
|
const text = await res.text();
|
||||||
|
const json = JSON.parse(text);
|
||||||
|
return json;
|
||||||
|
};
|
||||||
|
|
@ -7,7 +7,7 @@ export const LPage = () => {
|
||||||
const p = useGlobal(LiveGlobal, "LIVE");
|
const p = useGlobal(LiveGlobal, "LIVE");
|
||||||
const mode = p.mode;
|
const mode = p.mode;
|
||||||
|
|
||||||
let childs = Object.values(p.page?.content_tree.childs || []);
|
let childs = Object.values(p.page?.content_tree?.childs || []);
|
||||||
if (p.layout.section && p.layout.content) {
|
if (p.layout.section && p.layout.content) {
|
||||||
childs = [p.layout.section];
|
childs = [p.layout.section];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,10 @@ import { initLive, w } from "./logic/init";
|
||||||
import { preload, routeLive } from "./logic/route";
|
import { preload, routeLive } from "./logic/route";
|
||||||
|
|
||||||
export const Live: FC<{
|
export const Live: FC<{
|
||||||
domain: string;
|
domain_or_siteid: string;
|
||||||
pathname: string;
|
pathname: string;
|
||||||
loader: Loader;
|
loader: Loader;
|
||||||
mode: "dev" | "prod";
|
}> = ({ domain_or_siteid, pathname, loader }) => {
|
||||||
}> = ({ domain, pathname, loader, mode = "dev" }) => {
|
|
||||||
const p = useGlobal(LiveGlobal, "LIVE");
|
const p = useGlobal(LiveGlobal, "LIVE");
|
||||||
p.loader = loader;
|
p.loader = loader;
|
||||||
|
|
||||||
|
|
@ -19,8 +18,6 @@ export const Live: FC<{
|
||||||
preload(p, url);
|
preload(p, url);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (mode === "prod") p.prod = true;
|
|
||||||
|
|
||||||
if (p.site.id) {
|
if (p.site.id) {
|
||||||
if (!p.mode && !!p.site.responsive) {
|
if (!p.mode && !!p.site.responsive) {
|
||||||
if (p.site.responsive === "all") {
|
if (p.site.responsive === "all") {
|
||||||
|
|
@ -58,12 +55,20 @@ export const Live: FC<{
|
||||||
}, [p.site.responsive]);
|
}, [p.site.responsive]);
|
||||||
|
|
||||||
if (p.status === "init") {
|
if (p.status === "init") {
|
||||||
initLive(p, domain);
|
initLive(p, domain_or_siteid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p.site.id) {
|
if (p.site.id) {
|
||||||
routeLive(p, pathname);
|
routeLive(p, pathname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p.status === "not-found")
|
||||||
|
return (
|
||||||
|
<div className="absolute inset-0 flex items-center justify-center flex-col">
|
||||||
|
<div className="text-[40px]">404</div>
|
||||||
|
<div>NOT FOUND</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
return <LPage />;
|
return <LPage />;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -44,29 +44,18 @@ export const loadComponent = async (
|
||||||
if (typeof itemOrID !== "string") {
|
if (typeof itemOrID !== "string") {
|
||||||
tree = itemOrID;
|
tree = itemOrID;
|
||||||
} else {
|
} else {
|
||||||
if (!!p.comps.pending[itemOrID]) {
|
await loadComponentById(p, itemOrID);
|
||||||
await p.comps.pending[itemOrID];
|
|
||||||
} else {
|
|
||||||
loadSingleComponent(p, itemOrID);
|
|
||||||
const res = await p.comps.pending[itemOrID];
|
|
||||||
tree = res.content_tree;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
scanComponent(tree, compIds);
|
scanComponent(tree, compIds);
|
||||||
const promises = [...compIds]
|
const promises = [...compIds]
|
||||||
.filter((id) => {
|
.filter((id) => {
|
||||||
if (p.prod) {
|
if (!p.comps.all[id] && !p.comps.pending[id]) return true;
|
||||||
if (!p.comps.all[id] && !p.comps.pending[id]) return true;
|
|
||||||
} else {
|
|
||||||
if (!p.comps.doc[id] && !p.comps.pending[id]) return true;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
})
|
})
|
||||||
.map(async (id) => {
|
.map(async (id) => {
|
||||||
const res = await loadSingleComponent(p, id);
|
const comp = await loadComponentById(p, id);
|
||||||
await loadComponent(p, res.content_tree);
|
await loadComponent(p, comp.content_tree);
|
||||||
return res;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (promises.length > 0) {
|
if (promises.length > 0) {
|
||||||
|
|
@ -74,8 +63,14 @@ export const loadComponent = async (
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadSingleComponent = (p: PG, comp_id: string) => {
|
const loadComponentById = async (p: PG, id: string) => {
|
||||||
return p.loader.comp(p, comp_id);
|
if (!!p.comps.pending[id]) {
|
||||||
|
return await p.comps.pending[id];
|
||||||
|
}
|
||||||
|
const res = p.loader.comp(p, id);
|
||||||
|
p.comps.pending[id] = res;
|
||||||
|
p.comps.all[id] = await res;
|
||||||
|
return p.comps.all[id];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const instantiateComp = (
|
export const instantiateComp = (
|
||||||
|
|
|
||||||
|
|
@ -1,119 +0,0 @@
|
||||||
import { PRASI_COMPONENT } from "../../../utils/types/render";
|
|
||||||
import { WS_MSG_GET_COMP } from "../../../utils/types/ws";
|
|
||||||
import { LPage, LSite, Loader } from "./global";
|
|
||||||
import { wsend } from "./ws";
|
|
||||||
|
|
||||||
export const defaultLoader: Loader = {
|
|
||||||
async site(_, where) {
|
|
||||||
const site = (await db.site.findFirst({
|
|
||||||
where,
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
config: true,
|
|
||||||
domain: true,
|
|
||||||
name: true,
|
|
||||||
js: true,
|
|
||||||
responsive: true,
|
|
||||||
js_compiled: true,
|
|
||||||
},
|
|
||||||
})) as unknown as LSite;
|
|
||||||
|
|
||||||
if (!site) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const cgroups = await db.site_use_comp.findMany({
|
|
||||||
where: { id_site: site.id },
|
|
||||||
select: { use_id_site: true },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (cgroups) {
|
|
||||||
site.cgroup_ids = [];
|
|
||||||
for (const id of cgroups.map((c: any) => c.use_id_site)) {
|
|
||||||
site.cgroup_ids.push(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const layout = await db.page.findFirst({
|
|
||||||
where: {
|
|
||||||
id_site: site.id,
|
|
||||||
name: { startsWith: "layout:" },
|
|
||||||
is_default_layout: true,
|
|
||||||
is_deleted: false,
|
|
||||||
},
|
|
||||||
select: { content_tree: true, id: true },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (layout) {
|
|
||||||
const childs = (layout.content_tree as any).childs;
|
|
||||||
if (childs && childs.length > 0) {
|
|
||||||
site.layout = childs[0];
|
|
||||||
site.layout_id = layout.id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return site;
|
|
||||||
},
|
|
||||||
async comp(p, comp_id) {
|
|
||||||
p.comps.pending[comp_id] = new Promise<PRASI_COMPONENT>(async (resolve) => {
|
|
||||||
p.comps.resolve[comp_id] = async (comp: PRASI_COMPONENT) => {
|
|
||||||
resolve(comp);
|
|
||||||
};
|
|
||||||
await wsend(
|
|
||||||
p,
|
|
||||||
JSON.stringify({
|
|
||||||
type: "get_comp",
|
|
||||||
comp_id: comp_id,
|
|
||||||
} as WS_MSG_GET_COMP)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
return p.comps.pending[comp_id];
|
|
||||||
},
|
|
||||||
npm(p, type, id) {
|
|
||||||
if (type === "site") {
|
|
||||||
return `${serverurl}/npm/site/${id}/site.js`;
|
|
||||||
} else if (type === "page") {
|
|
||||||
return `${serverurl}/npm/page/${id}/page.js`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null as any;
|
|
||||||
},
|
|
||||||
async page(p, id) {
|
|
||||||
const res = await db.page.findFirst({
|
|
||||||
where: { id: id, name: { not: { startsWith: "layout:" } } },
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
url: true,
|
|
||||||
name: true,
|
|
||||||
content_tree: true,
|
|
||||||
js_compiled: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
let page: LPage;
|
|
||||||
|
|
||||||
if (res) {
|
|
||||||
page = {
|
|
||||||
id: res.id,
|
|
||||||
content_tree: res.content_tree as any,
|
|
||||||
js: res.js_compiled as any,
|
|
||||||
name: res.name,
|
|
||||||
url: res.url,
|
|
||||||
};
|
|
||||||
|
|
||||||
return page;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null as unknown as LPage;
|
|
||||||
},
|
|
||||||
async pages(p, site_id: string) {
|
|
||||||
return (await db.page.findMany({
|
|
||||||
where: {
|
|
||||||
id_site: site_id,
|
|
||||||
name: { not: { startsWith: "layout:" } },
|
|
||||||
is_deleted: false,
|
|
||||||
},
|
|
||||||
select: { id: true, url: true },
|
|
||||||
})) as unknown as LPage[];
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
@ -16,7 +16,6 @@ export type ItemMeta = {
|
||||||
comp?: {
|
comp?: {
|
||||||
id: string;
|
id: string;
|
||||||
propval?: any;
|
propval?: any;
|
||||||
mcomp?: MItem;
|
|
||||||
child_ids: Record<string, string>;
|
child_ids: Record<string, string>;
|
||||||
};
|
};
|
||||||
className?: string;
|
className?: string;
|
||||||
|
|
@ -36,7 +35,7 @@ export type LPage = {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
url: string;
|
url: string;
|
||||||
content_tree: IRoot;
|
content_tree?: IRoot;
|
||||||
js: string;
|
js: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -60,7 +59,7 @@ export type LSite = {
|
||||||
export type Loader = {
|
export type Loader = {
|
||||||
site: (
|
site: (
|
||||||
p: PG,
|
p: PG,
|
||||||
where: { domain: string } | { id: string }
|
where: { type: "domain"; domain: string } | { type: "siteid"; id: string }
|
||||||
) => Promise<LSite | null>;
|
) => Promise<LSite | null>;
|
||||||
page: (p: PG, id: string) => Promise<LPage | null>;
|
page: (p: PG, id: string) => Promise<LPage | null>;
|
||||||
pages: (p: PG, site_id: string) => Promise<LPage[]>;
|
pages: (p: PG, site_id: string) => Promise<LPage[]>;
|
||||||
|
|
@ -112,7 +111,6 @@ export const LiveGlobal = {
|
||||||
comps: {
|
comps: {
|
||||||
pending: {} as Record<string, Promise<PRASI_COMPONENT>>,
|
pending: {} as Record<string, Promise<PRASI_COMPONENT>>,
|
||||||
resolve: {} as Record<string, (comp: PRASI_COMPONENT) => void>,
|
resolve: {} as Record<string, (comp: PRASI_COMPONENT) => void>,
|
||||||
doc: {} as Record<string, CompDoc>,
|
|
||||||
all: {} as Record<string, PRASI_COMPONENT>,
|
all: {} as Record<string, PRASI_COMPONENT>,
|
||||||
},
|
},
|
||||||
script: {
|
script: {
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ export const w = window as unknown as {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const initLive = async (p: PG, domain: string) => {
|
export const initLive = async (p: PG, domain_or_siteid: string) => {
|
||||||
if (p.status === "init") {
|
if (p.status === "init") {
|
||||||
p.status = "loading";
|
p.status = "loading";
|
||||||
|
|
||||||
|
|
@ -68,30 +68,12 @@ export const initLive = async (p: PG, domain: string) => {
|
||||||
|
|
||||||
/** load site */
|
/** load site */
|
||||||
let site = null as null | LSite;
|
let site = null as null | LSite;
|
||||||
if (!p.prod) {
|
site = await p.loader.site(
|
||||||
try {
|
p,
|
||||||
site = JSON.parse(localStorage.getItem(`prasi-site-${domain}`) || "");
|
validate(domain_or_siteid)
|
||||||
} catch (e) {}
|
? { type: "siteid", id: domain_or_siteid }
|
||||||
|
: { type: "domain", domain: domain_or_siteid }
|
||||||
if (!site) {
|
);
|
||||||
site = await p.loader.site(
|
|
||||||
p,
|
|
||||||
validate(domain) ? { id: domain } : { domain }
|
|
||||||
);
|
|
||||||
localStorage.setItem(`prasi-site-${domain}`, JSON.stringify(site));
|
|
||||||
} else {
|
|
||||||
p.loader
|
|
||||||
.site(p, validate(domain) ? { id: domain } : { domain })
|
|
||||||
.then((site) => {
|
|
||||||
localStorage.setItem(`prasi-site-${domain}`, JSON.stringify(site));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
site = await p.loader.site(
|
|
||||||
p,
|
|
||||||
validate(domain) ? { id: domain } : { domain }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (site) {
|
if (site) {
|
||||||
/** import site module */
|
/** import site module */
|
||||||
|
|
@ -112,59 +94,11 @@ export const initLive = async (p: PG, domain: string) => {
|
||||||
|
|
||||||
await validateLayout(p);
|
await validateLayout(p);
|
||||||
|
|
||||||
if (p.prod) {
|
p.site.api_url = await initApi(site.config, "prod");
|
||||||
p.site.api_url = await initApi(site.config, "prod");
|
|
||||||
} else {
|
|
||||||
w.externalAPI = {
|
|
||||||
mode: (localStorage.getItem(`prasi-ext-api-mode-${p.site.id}`) ||
|
|
||||||
"prod") as any,
|
|
||||||
devUrl: localStorage.getItem(`prasi-ext-dev-url-${p.site.id}`) || "",
|
|
||||||
prodUrl:
|
|
||||||
localStorage.getItem(`prasi-ext-prod-url-${p.site.id}`) || "",
|
|
||||||
};
|
|
||||||
p.site.api_url = await initApi(site.config);
|
|
||||||
|
|
||||||
if (w.externalAPI.prodUrl !== p.site.api_url) {
|
|
||||||
w.externalAPI.prodUrl = p.site.api_url;
|
|
||||||
localStorage.setItem(
|
|
||||||
`prasi-ext-prod-url-${p.site.id}`,
|
|
||||||
p.site.api_url
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (w.externalAPI.mode === "dev" && w.externalAPI.devUrl) {
|
|
||||||
p.site.api_url = w.externalAPI.devUrl;
|
|
||||||
await reloadDBAPI(w.externalAPI.devUrl, "dev");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.apiurl = p.site.api_url;
|
w.apiurl = p.site.api_url;
|
||||||
|
|
||||||
let pages = [];
|
let pages = await p.loader.pages(p, site.id);
|
||||||
if (!p.prod) {
|
|
||||||
/** load pages */
|
|
||||||
const pagesLocal = localStorage.getItem(`prasi-pages-[${domain}]`);
|
|
||||||
if (pagesLocal) {
|
|
||||||
try {
|
|
||||||
pages = JSON.parse(pagesLocal);
|
|
||||||
} catch (e) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pages.length === 0) {
|
|
||||||
pages = await p.loader.pages(p, site.id);
|
|
||||||
localStorage.setItem(
|
|
||||||
`prasi-pages-[${domain}]`,
|
|
||||||
JSON.stringify(pages)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
p.loader.pages(p, site.id).then((pages) => {
|
|
||||||
localStorage.setItem(
|
|
||||||
`prasi-pages-[${domain}]`,
|
|
||||||
JSON.stringify(pages)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pages = await p.loader.pages(p, site.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** execute site module */
|
/** execute site module */
|
||||||
const exec = (fn: string, scopes: any) => {
|
const exec = (fn: string, scopes: any) => {
|
||||||
|
|
@ -198,9 +132,11 @@ export const initLive = async (p: PG, domain: string) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** create router */
|
/** create router */
|
||||||
|
p.pages = {};
|
||||||
p.route = createRouter({ strictTrailingSlash: false });
|
p.route = createRouter({ strictTrailingSlash: false });
|
||||||
if (pages && pages.length > 0) {
|
if (pages && pages.length > 0) {
|
||||||
for (const page of pages) {
|
for (const page of pages) {
|
||||||
|
p.pages[page.id] = page;
|
||||||
p.route.insert(page.url, page);
|
p.route.insert(page.url, page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,18 +4,16 @@ import { w } from "../../../utils/types/general";
|
||||||
import { WS_MSG_GET_PAGE } from "../../../utils/types/ws";
|
import { WS_MSG_GET_PAGE } from "../../../utils/types/ws";
|
||||||
import importModule from "../../editor/tools/dynamic-import";
|
import importModule from "../../editor/tools/dynamic-import";
|
||||||
import { loadComponent } from "./comp";
|
import { loadComponent } from "./comp";
|
||||||
import { LPage, LiveGlobal, PG } from "./global";
|
import { LPage, PG } from "./global";
|
||||||
import { liveWS, wsend } from "./ws";
|
|
||||||
import { rebuildTree } from "./tree-logic";
|
import { rebuildTree } from "./tree-logic";
|
||||||
|
import { liveWS, wsend } from "./ws";
|
||||||
|
|
||||||
export const routeLive = (p: PG, pathname: string) => {
|
export const routeLive = (p: PG, pathname: string) => {
|
||||||
if (p.status !== "loading") {
|
if (p.status !== "loading" && p.status !== "not-found") {
|
||||||
let page_id = "";
|
let page_id = params.page_id;
|
||||||
if (validate(pathname.substring(1))) {
|
|
||||||
page_id = pathname.substring(1);
|
|
||||||
} else {
|
|
||||||
const found = p.route.lookup(pathname);
|
|
||||||
|
|
||||||
|
if (!page_id) {
|
||||||
|
const found = p.route.lookup(pathname);
|
||||||
if (!found) {
|
if (!found) {
|
||||||
p.status = "not-found";
|
p.status = "not-found";
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -30,48 +28,34 @@ export const routeLive = (p: PG, pathname: string) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (page_id) {
|
if (page_id) {
|
||||||
(window as any).prasiPageID = page_id;
|
(window as any).pageid = page_id;
|
||||||
const promises: Promise<void>[] = [];
|
const promises: Promise<void>[] = [];
|
||||||
if (page_id !== p.page?.id) {
|
if (page_id !== p.page?.id) {
|
||||||
p.page = p.pages[page_id];
|
p.page = p.pages[page_id];
|
||||||
p.treeMeta = {};
|
p.treeMeta = {};
|
||||||
p.portal = {};
|
p.portal = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!p.page || !p.page.content_tree) {
|
if (!p.page || !p.page.content_tree) {
|
||||||
promises.push(loadNpmPage(p, page_id));
|
promises.push(loadNpmPage(p, page_id));
|
||||||
|
promises.push(loadPage(p, page_id));
|
||||||
if (!p.prod) {
|
|
||||||
promises.push(streamPage(p, page_id));
|
|
||||||
} else {
|
|
||||||
promises.push(loadPage(p, page_id));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!p.prod) {
|
|
||||||
streamPage(p, page_id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (promises.length > 0) {
|
if (promises.length > 0) {
|
||||||
|
p.status = "loading";
|
||||||
Promise.all(promises).then(async () => {
|
Promise.all(promises).then(async () => {
|
||||||
await pageLoaded(p);
|
p.page = p.pages[page_id];
|
||||||
p.status = "ready";
|
if (p.page) {
|
||||||
p.render();
|
await pageLoaded(p);
|
||||||
|
p.render();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (p.prod && !firstRender[page_id]) {
|
if (!firstRender[page_id]) {
|
||||||
firstRender[page_id] = true;
|
firstRender[page_id] = true;
|
||||||
pageLoaded(p).then(p.render);
|
pageLoaded(p).then(p.render);
|
||||||
} else {
|
} else {
|
||||||
if (!p.prod) {
|
pageLoaded(p);
|
||||||
pageLoaded(p).then(() => {
|
|
||||||
if (stream.page_id !== page_id) {
|
|
||||||
stream.page_id = page_id;
|
|
||||||
p.render();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
pageLoaded(p);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -91,7 +75,11 @@ const pageLoaded = async (p: PG) => {
|
||||||
export const preload = async (p: PG, pathname: string) => {
|
export const preload = async (p: PG, pathname: string) => {
|
||||||
const found = p.route.lookup(pathname);
|
const found = p.route.lookup(pathname);
|
||||||
if (found) {
|
if (found) {
|
||||||
if (!p.pages[found.id] && !p.pagePreload[found.id]) {
|
if (
|
||||||
|
(!p.pages[found.id] ||
|
||||||
|
(p.pages[found.id] && !p.pages[found.id].content_tree)) &&
|
||||||
|
!p.pagePreload[found.id]
|
||||||
|
) {
|
||||||
p.pagePreload[found.id] = true;
|
p.pagePreload[found.id] = true;
|
||||||
const dbpage = await p.loader.page(p, found.id);
|
const dbpage = await p.loader.page(p, found.id);
|
||||||
if (dbpage) {
|
if (dbpage) {
|
||||||
|
|
@ -139,6 +127,7 @@ const loadPage = async (p: PG, id: string) => {
|
||||||
content_tree: page.content_tree as any,
|
content_tree: page.content_tree as any,
|
||||||
js: (page as any).js_compiled as any,
|
js: (page as any).js_compiled as any,
|
||||||
};
|
};
|
||||||
|
console.log(p.pages[page.id]);
|
||||||
|
|
||||||
const cur = p.pages[page.id];
|
const cur = p.pages[page.id];
|
||||||
if (cur && cur.content_tree) {
|
if (cur && cur.content_tree) {
|
||||||
|
|
@ -147,36 +136,6 @@ const loadPage = async (p: PG, id: string) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const stream = { page_id: "" };
|
|
||||||
|
|
||||||
const streamPage = (p: PG, id: string) => {
|
|
||||||
return new Promise<void>(async (resolve) => {
|
|
||||||
await liveWS(p);
|
|
||||||
p.mpageLoaded = async (mpage) => {
|
|
||||||
const dbpage = mpage.getMap("map").toJSON() as page;
|
|
||||||
p.pages[dbpage.id] = {
|
|
||||||
id: dbpage.id,
|
|
||||||
url: dbpage.url,
|
|
||||||
name: dbpage.name,
|
|
||||||
content_tree: dbpage.content_tree as any,
|
|
||||||
js: dbpage.js_compiled as any,
|
|
||||||
};
|
|
||||||
const page = p.pages[dbpage.id];
|
|
||||||
if (page && page.content_tree) {
|
|
||||||
await loadComponent(p, page.content_tree);
|
|
||||||
}
|
|
||||||
resolve();
|
|
||||||
};
|
|
||||||
wsend(
|
|
||||||
p,
|
|
||||||
JSON.stringify({
|
|
||||||
type: "get_page",
|
|
||||||
page_id: id,
|
|
||||||
} as WS_MSG_GET_PAGE)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const extractNavigate = (str: string) => {
|
export const extractNavigate = (str: string) => {
|
||||||
return [
|
return [
|
||||||
...findBetween(str, `navigate(`, `)`),
|
...findBetween(str, `navigate(`, `)`),
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,12 @@ export const rebuildTree = async (
|
||||||
p: PG,
|
p: PG,
|
||||||
_: { note: string; render?: boolean; reset?: boolean }
|
_: { note: string; render?: boolean; reset?: boolean }
|
||||||
) => {
|
) => {
|
||||||
|
if (!p.page?.content_tree) return;
|
||||||
|
|
||||||
p.treePending = new Promise<void>(async (resolve) => {
|
p.treePending = new Promise<void>(async (resolve) => {
|
||||||
const treeMeta = p.treeMeta;
|
const treeMeta = p.treeMeta;
|
||||||
if (p.page) {
|
if (p.page) {
|
||||||
let childs = Object.values(p.page.content_tree.childs || []);
|
let childs = Object.values(p.page.content_tree?.childs || []);
|
||||||
if (
|
if (
|
||||||
p.layout.section &&
|
p.layout.section &&
|
||||||
p.layout.content &&
|
p.layout.content &&
|
||||||
|
|
@ -22,7 +24,7 @@ export const rebuildTree = async (
|
||||||
|
|
||||||
p.layout.content.type = "item";
|
p.layout.content.type = "item";
|
||||||
if (p.layout.content.type === "item") {
|
if (p.layout.content.type === "item") {
|
||||||
p.layout.content.childs = p.page.content_tree.childs.map((e) => ({
|
p.layout.content.childs = p.page.content_tree?.childs.map((e) => ({
|
||||||
...e,
|
...e,
|
||||||
type: "item",
|
type: "item",
|
||||||
})) as IItem[];
|
})) as IItem[];
|
||||||
|
|
@ -66,7 +68,7 @@ const walk = async (
|
||||||
const treeMeta = val.treeMeta;
|
const treeMeta = val.treeMeta;
|
||||||
let item = val.item as IContent;
|
let item = val.item as IContent;
|
||||||
|
|
||||||
if (item.hidden === 'all') return;
|
if (item.hidden === "all") return;
|
||||||
|
|
||||||
if (val.parent_comp) {
|
if (val.parent_comp) {
|
||||||
const pchild_ids = val.parent_comp.comp?.child_ids;
|
const pchild_ids = val.parent_comp.comp?.child_ids;
|
||||||
|
|
@ -85,9 +87,6 @@ const walk = async (
|
||||||
comp = {
|
comp = {
|
||||||
id: item.component.id,
|
id: item.component.id,
|
||||||
child_ids: {},
|
child_ids: {},
|
||||||
mcomp: p.prod
|
|
||||||
? undefined
|
|
||||||
: p.comps.doc[item.component.id]?.getMap("map").get("content_tree"),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,119 +106,48 @@ const walk = async (
|
||||||
|
|
||||||
if (item.type === "item" && item.component?.id) {
|
if (item.type === "item" && item.component?.id) {
|
||||||
const cid = item.component.id;
|
const cid = item.component.id;
|
||||||
if (p.prod) {
|
let comp = p.comps.all[cid];
|
||||||
let comp = p.comps.all[cid];
|
if (!comp) {
|
||||||
if (!comp) {
|
await loadComponent(p, cid);
|
||||||
await loadComponent(p, cid);
|
comp = p.comps.all[cid];
|
||||||
comp = p.comps.all[cid];
|
}
|
||||||
|
|
||||||
|
if (comp) {
|
||||||
|
if (!p.compInstance[item.id]) {
|
||||||
|
p.compInstance[item.id] = {};
|
||||||
|
}
|
||||||
|
const child_ids = p.compInstance[item.id];
|
||||||
|
const itemnew = instantiateComp(
|
||||||
|
p,
|
||||||
|
item,
|
||||||
|
{ type: "i", item: comp },
|
||||||
|
child_ids
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const [k, v] of Object.entries(itemnew)) {
|
||||||
|
if (k !== "id") (item as any)[k] = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (comp) {
|
const cprops = comp.content_tree.component?.props;
|
||||||
if (!p.compInstance[item.id]) {
|
const iprops = item.component.props;
|
||||||
p.compInstance[item.id] = {};
|
|
||||||
}
|
|
||||||
const child_ids = p.compInstance[item.id];
|
|
||||||
const itemnew = instantiateComp(
|
|
||||||
p,
|
|
||||||
item,
|
|
||||||
{ type: "i", item: comp },
|
|
||||||
child_ids
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const [k, v] of Object.entries(itemnew)) {
|
if (cprops && iprops) {
|
||||||
if (k !== "id") (item as any)[k] = v;
|
for (const [name, mprop] of Object.entries(cprops)) {
|
||||||
}
|
const jsx_prop = iprops[name];
|
||||||
|
|
||||||
const cprops = comp.content_tree.component?.props;
|
if (jsx_prop) {
|
||||||
const iprops = item.component.props;
|
if (mprop.meta?.type === "content-element") {
|
||||||
|
let icontent = jsx_prop.content;
|
||||||
|
|
||||||
if (cprops && iprops) {
|
if (icontent)
|
||||||
for (const [name, mprop] of Object.entries(cprops)) {
|
await walk(p, {
|
||||||
const jsx_prop = iprops[name];
|
treeMeta,
|
||||||
|
item: icontent,
|
||||||
if (jsx_prop) {
|
parent_id: item.id,
|
||||||
if (mprop.meta?.type === "content-element") {
|
parent_comp: val.parent_comp,
|
||||||
let icontent = jsx_prop.content;
|
idx: mprop.idx,
|
||||||
|
isLayout: meta.isLayout,
|
||||||
if (icontent)
|
});
|
||||||
await walk(p, {
|
|
||||||
treeMeta,
|
|
||||||
item: icontent,
|
|
||||||
parent_id: item.id,
|
|
||||||
parent_comp: val.parent_comp,
|
|
||||||
idx: mprop.idx,
|
|
||||||
isLayout: meta.isLayout,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let doc = p.comps.doc[cid];
|
|
||||||
if (!doc) {
|
|
||||||
await loadComponent(p, cid);
|
|
||||||
doc = p.comps.doc[cid];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (doc) {
|
|
||||||
const mcomp = doc.getMap("map").get("content_tree") as MItem;
|
|
||||||
if (mcomp) {
|
|
||||||
if (!p.compInstance[item.id]) {
|
|
||||||
p.compInstance[item.id] = {};
|
|
||||||
}
|
|
||||||
const child_ids = p.compInstance[item.id];
|
|
||||||
|
|
||||||
const itemnew = instantiateComp(
|
|
||||||
p,
|
|
||||||
item,
|
|
||||||
{ type: "m", item: mcomp },
|
|
||||||
child_ids
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const [k, v] of Object.entries(itemnew)) {
|
|
||||||
if (k !== "id") (item as any)[k] = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
meta.comp = {
|
|
||||||
id: cid,
|
|
||||||
mcomp,
|
|
||||||
child_ids,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
let cprops: [string, FNCompDef][] = Object.entries(
|
|
||||||
item.component?.props || {}
|
|
||||||
).sort((a, b) => {
|
|
||||||
return a[1].idx - b[1].idx;
|
|
||||||
});
|
|
||||||
if (mcomp) {
|
|
||||||
const mprops = mcomp.get("component")?.get("props");
|
|
||||||
const iprops = item.component.props;
|
|
||||||
|
|
||||||
if (mprops && iprops) {
|
|
||||||
for (const [name, cprop] of cprops) {
|
|
||||||
let mp = mprops.get(name);
|
|
||||||
if (mp) {
|
|
||||||
const mprop = mp?.toJSON() as FNCompDef;
|
|
||||||
const jsx_prop = iprops[name];
|
|
||||||
|
|
||||||
if (jsx_prop) {
|
|
||||||
if (mprop.meta?.type === "content-element") {
|
|
||||||
let icontent = jsx_prop.content;
|
|
||||||
|
|
||||||
if (icontent)
|
|
||||||
await walk(p, {
|
|
||||||
treeMeta,
|
|
||||||
item: cprop.content,
|
|
||||||
parent_id: item.id,
|
|
||||||
parent_comp: meta as any,
|
|
||||||
idx: mprop.idx,
|
|
||||||
isLayout: meta.isLayout,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { FC, useState } from "react";
|
import { FC, useState } from "react";
|
||||||
import { createRoot } from "react-dom/client";
|
import { createRoot } from "react-dom/client";
|
||||||
import { GlobalContext, defineReact, defineWindow } from "web-utils";
|
import { GlobalContext, defineReact, defineWindow } from "web-utils";
|
||||||
import { SiteLoader } from "./site-loader";
|
import { siteLoader } from "./site-loader";
|
||||||
|
|
||||||
const w = window as unknown as {
|
const w = window as unknown as {
|
||||||
prasiContext: any;
|
prasiContext: any;
|
||||||
|
|
@ -25,8 +25,7 @@ const Root: FC<{ url: URL; Live: any }> = ({ url, Live }) => {
|
||||||
<Live
|
<Live
|
||||||
domain={url.host}
|
domain={url.host}
|
||||||
pathname={location.pathname}
|
pathname={location.pathname}
|
||||||
loader={SiteLoader}
|
loader={siteLoader}
|
||||||
mode="prod"
|
|
||||||
/>
|
/>
|
||||||
</Provider>
|
</Provider>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ export const startDevWatcher = async () => {
|
||||||
import { apiContext } from "service-srv";
|
import { apiContext } from "service-srv";
|
||||||
|
|
||||||
export const _ = {
|
export const _ = {
|
||||||
url: "/${filename?.substring(0, filename.length - 3)})}",
|
url: "/${filename?.substring(0, filename.length - 3)}",
|
||||||
async api() {
|
async api() {
|
||||||
const { req, res } = apiContext(this);
|
const { req, res } = apiContext(this);
|
||||||
return "This is ${filename}";
|
return "This is ${filename}";
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue